{"version":3,"file":"main.js","mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AClzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7EA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AAGA;AAIA;AAMA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/GA;AAUA;AACA;AAEA;AAIA;AAMA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxBA;AACA;AAEA;AAQA;AACA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAMA;AAEA;AAcA;AAKA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3EA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAMA;AASA;AACA;AACA;AACA;AACA;AAGA;AAKA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;AACA;;AAAA;AACA;;AAAA;AAIA;AACA;AACA;AACA;AAMA;AACA;AAeA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AAQA;AAkBA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxSA;AACA;AACA;AAEA;AACA;AACA;AAgBA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AAEA;AACA;AAGA;AAEA;AAEA;AAGA;AAMA;;AAAA;AAOA;AAEA;AAEA;AAIA;AAEA;AAOA;AAMA;AACA;AAQA;AAEA;AAuBA;AAQA;AACA;AAOA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChMA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AAAA;;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAKA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAMA;AACA;AACA;AACA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AAOA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAWA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/MA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AAGA;AAmBA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9CA;AAEA;AACA;AACA;AAMA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAKA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AAEA;AAEA;AACA;AACA;AACA;AACA;;AAAA;AAEA;;AAAA;AACA;;AAAA;AAGA;AAKA;AACA;AACA;AAMA;AAEA;AAEA;AAIA;AAEA;;AAAA;AAEA;AAUA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtNA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AAGA;AAYA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AAMA;AACA;AAEA;AAEA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;AACA;;AAAA;AACA;;AAAA;AAGA;AACA;AAMA;AACA;AAQA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClKA;AACA;AACA;AACA;AAaA;;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AAMA;AAGA;AACA;AACA;AACA;AAYA;AACA;AAWA;AACA;AAYA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AAMA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAKA;AAIA;AAaA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrTA;AACA;AACA;AACA;AAEA;AAeA;;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAIA;AAEA;AAIA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAGA;AASA;AACA;AAKA;AACA;AAGA;AASA;AACA;AAMA;AACA;AACA;AAGA;AAUA;AACA;AAKA;AACA;AAGA;AACA;AAOA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAUA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClVA;AACA;AAQA;;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAWA;AAMA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjGA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAQA;;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAKA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAKA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AAQA;AAEA;AAKA;AAGA;AAQA;AACA;AACA;AACA;AACA;AAQA;AAIA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AAOA;AAKA;AAEA;AAEA;AAKA;AAAA;AAaA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3bA;AAEA;AACA;AACA;AACA;AACA;AAYA;;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;;;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;;AACA;AAEA;AAEA;AAYA;AAGA;AACA;AAIA;AACA;AAGA;AACA;AAIA;AASA;AAcA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrKA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAKA;AACA;AACA;AACA;AAEA;AAEA;AAKA;AACA;AACA;AAEA;AAKA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5EA;AACA;AACA;AACA;AASA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAGA;;AACA;AAGA;AACA;AAGA;AAEA;AAIA;AACA;AACA;AACA;;AAAA;AAQA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1DA;AACA;AACA;AACA;AAEA;AACA;AAQA;;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAKA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAIA;AAEA;AAIA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAKA;AACA;AAEA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAIA;AAMA;AACA;AACA;AAUA;AAMA;AACA;AACA;AACA;AAGA;AAIA;AACA;AAUA;AAMA;AAMA;AACA;AAGA;AAMA;AAcA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpOA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAWA;;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AAEA;AAEA;;AACA;AAEA;AAIA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAIA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAMA;AAMA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAQA;AAGA;AACA;AACA;AACA;AACA;AAIA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAMA;AACA;;AACA;AAEA;AAEA;AACA;AAUA;AAaA;AAEA;AACA;AAUA;AAUA;AACA;AACA;AAEA;AAMA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AAEA;AACA;AAcA;AAGA;AAcA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChcA;AACA;AACA;AACA;AAEA;AACA;AASA;;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AAIA;AAMA;AAEA;AAUA;AAMA;AAcA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnKA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAUA;;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AAIA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAMA;AAyBA;AACA;AAMA;AAeA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClQA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAYA;;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAMA;AACA;AAAA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAKA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAKA;AACA;AACA;AAEA;AACA;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AAMA;AACA;AAEA;AAQA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AASA;AAIA;;AAAA;AAKA;AACA;AAQA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAMA;AAEA;AACA;AACA;AAMA;AACA;AAOA;AAKA;AAYA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAwBA;AACA;AAMA;AAeA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7cA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAuBA;;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAIA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAKA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAIA;AACA;AAEA;AACA;AAIA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAKA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AAKA;AAIA;AAMA;AAMA;AACA;AACA;AACA;AAKA;AAKA;AACA;AACA;AACA;AAIA;AAIA;AACA;AAEA;AACA;AACA;AAEA;AAMA;AACA;AACA;AAEA;AAIA;AACA;AAIA;AACA;AACA;AAMA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAOA;AAEA;AACA;AAIA;AAIA;AAMA;AAIA;AAIA;AAMA;AAoBA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtlBA;AAEA;AAEA;AACA;AAYA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAOA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAGA;AAKA;AACA;AACA;AACA;AACA;AAAA;;AAAA;AACA;AACA;AAMA;AAIA;AAOA;AAIA;AACA;AAEA;AAGA;AAIA;AACA;;AAAA;AAMA;AACA;AACA;AACA;;AAAA;AAUA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3HA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAQA;;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AAUA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAKA;AAAA;AACA;AAKA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAQA;AAOA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAOA;AAEA;AAOA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAQA;AAOA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAUA;AAEA;AAUA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAWA;AAUA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AAGA;AAMA;AAGA;AACA;AACA;AAOA;AAEA;AACA;AAOA;AAIA;AAEA;AAGA;AAGA;AACA;AACA;AAWA;AAMA;AACA;AAUA;AAUA;AAEA;AAGA;AAGA;AACA;AACA;AAWA;AAMA;AACA;AAUA;AAOA;AAGA;AACA;AACA;AAUA;AAMA;AACA;AASA;AACA;AAQA;AAEA;AAMA;AACA;AACA;AACA;AAEA;AACA;AAKA;AAEA;AACA;AAGA;AAMA;AACA;AASA;AACA;AAUA;AAGA;AACA;AACA;AAcA;AAOA;AACA;AASA;AACA;AAUA;AAMA;AACA;AAUA;AAMA;AACA;AAUA;AAMA;AACA;AASA;AACA;AAaA;AACA;AAeA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACptBA;AACA;AACA;AACA;AACA;AAEA;AACA;AASA;;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AAEA;AACA;AAOA;AAEA;AACA;AAEA;AAOA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAQA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AAGA;AAMA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AACA;AACA;AAeA;AACA;AAGA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAOA;AAEA;AACA;AAGA;AAEA;AACA;AAEA;AAMA;AACA;AAeA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvSA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAUA;;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AAKA;AACA;AAEA;AAQA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AAEA;AAEA;;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAQA;AAEA;AACA;AAEA;AACA;AACA;AAKA;AACA;AAEA;AAIA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAIA;AAEA;AAIA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AASA;AAYA;AAWA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChNA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAYA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAKA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAKA;AACA;AAEA;AAIA;AAEA;AAEA;AAEA;AACA;AAQA;AACA;AAEA;AACA;AASA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AAEA;AAIA;AAEA;AAEA;AAEA;AAWA;AAcA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvLA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAcA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAKA;AACA;AAEA;AAIA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAKA;AACA;AAEA;AAIA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AAEA;AAIA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AAQA;AASA;AAUA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAUA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;AAEA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AAEA;AACA;;AAAA;AACA;;AAAA;;AAAA;AACA;AAGA;AACA;AACA;;AAAA;AAEA;AACA;;AAAA;AACA;;AAAA;;AAAA;AACA;AAIA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;;AAAA;AACA;;AAAA;;AAAA;AACA;AAGA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;AACA;;AAAA;AACA;;AAAA;;AAAA;AACA;AAGA;AACA;AAGA;;AAAA;AAEA;AACA;;AAAA;AACA;;AAAA;;AAAA;AACA;AAQA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/GA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAGA;AACA;AAAA;;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;;AAAA;AAKA;AACA;AACA;AACA;AACA;AAEA;;AAAA;AAEA;AACA;AACA;AAEA;;AAAA;AAQA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjFA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAMA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AAIA;AACA;AACA;AACA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AAEA;;AAAA;AACA;;AAAA;AACA;;AAAA;AAKA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAMA;AA4BA;AACA;AACA;AACA;AAEA;AAQA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AASA;AAIA;;AAAA;AAKA;AACA;AAQA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAMA;AAEA;AACA;AACA;AAMA;AACA;AAOA;AAKA;AAYA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AA2BA;AACA;AACA;AAuBA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvkBA;AACA;AAMA;AACA;AACA;AAkBA;;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAIA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAIA;AAEA;AAKA;AACA;AAEA;AAEA;AAEA;;;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;AACA;AAEA;;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAIA;AACA;AAEA;AAEA;AAMA;AAGA;AACA;AACA;AAGA;AASA;AAEA;AACA;AAGA;AASA;AAGA;AACA;AACA;AAGA;AAQA;AAEA;AACA;AAGA;AASA;AAGA;AACA;AACA;AACA;AAGA;AAQA;AAEA;AACA;AAGA;AAQA;AAGA;AACA;AACA;AAGA;AAQA;AAEA;AAEA;AAGA;AAMA;AAEA;AAIA;AAIA;AAGA;AAQA;AAIA;AACA;AACA;AAGA;AAQA;AAEA;AACA;AAGA;AAUA;AAGA;AAKA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAKA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpmBA;AACA;AAIA;AACA;AASA;;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAKA;AAIA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AAYA;AAkCA;AACA;AAGA;AAWA;AAMA;AAEA;AAGA;AAWA;AAOA;AACA;AAGA;AAGA;AACA;AAIA;AAEA;AACA;AACA;AAEA;AACA;AAIA;AAMA;AACA;AAGA;AAUA;AACA;AAGA;AAWA;AAMA;AACA;AAGA;AAWA;AAMA;AACA;AAGA;AAWA;AAMA;AACA;AAGA;AAUA;AACA;AAGA;AAcA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpWA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AAKA;AAQA;AAQA;AACA;AACA;AAEA;AAEA;AAOA;AAUA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAEA;AACA;AAGA;AAUA;AAOA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvVA;AACA;AAIA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AAGA;AAMA;AACA;AAEA;AAEA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAAA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;AACA;;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;;AAAA;AACA;;AAAA;AAGA;AAGA;AACA;AAMA;AAAA;AACA;AAIA;AACA;AAGA;AACA;AAiBA;AAQA;AAEA;AASA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5YA;AACA;AAGA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AAAA;AACA;AAEA;AAEA;AACA;AACA;AAQA;AACA;AAQA;AACA;AAUA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5DA;AACA;AACA;AACA;AACA;AAEA;AAgBA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAUA;AACA;AACA;AASA;AACA;AAUA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9GA;AACA;AAEA;AACA;AAWA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AASA;AACA;AACA;AACA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAKA;AACA;AACA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAKA;AACA;AACA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAMA;AACA;AACA;AAIA;AACA;AACA;AAAA;AACA;AACA;AACA;AAOA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvMA;AACA;AAGA;AACA;AAWA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AAeA;AACA;AAkBA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAIA;AAGA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAIA;AAMA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1PA;AAOA;AACA;AAEA;AACA;AAGA;AACA;AAMA;AAMA;AAUA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvCA;AACA;AAYA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnDA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAKA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtBA;AAOA;AAEA;AAOA;AAgBA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChCA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxCA;AAIA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpBA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACDA;AAEA;AAEA;AAIA;AAEA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZA;AAGA;AAGA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7FA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClHA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAIA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACbA;AAOA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AAEA;AAAA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChBA;AAWA;;AACA;AAAA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrDA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACPA;AAoBA;AAkBA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3GA;AAcA;AASA;AAEA;AACA;AACA;AACA;AAEA;;AAKA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAGA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjGA;AAEA;AACA;AACA;AAeA;AAaA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAAA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AA4BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AAiBA;AAWA;AAVA;AACA;AAWA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9GA;AAIA;AAEA;AACA;AAEA;AAEA;AAAA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACbA;AAMA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7BA;AAKA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5DA;AAiBA;AAYA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjFA;AACA;AACA;AACA;AACA;AAaA;AAUA;AATA;AAEA;AACA;AAOA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9FA;AACA;AACA;AAQA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnBA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtCA;AACA;AACA;AAQA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAQA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvEA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxBA;AACA;AAOA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrCA;AAEA;AAUA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5DA;AAUA;AAMA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAOA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAaA;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAYA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrMA;AACA;AACA;AAQA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1BA;AAQA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxBA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACJA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACJA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNA;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAMA;AACA;AAEA;AACA;AACA;AAEA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AASA;AAMA;AAEA;AACA;AACA;AAOA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAgBA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AAEA;AAEA;;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAKA;AACA;AACA;AAAA;AACA;AACA;;AACA;AACA;AACA;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AACA;AAEA;AACA;AAIA;AAEA;AACA;AAIA;AAEA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAKA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAQA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAQA;AAEA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AASA;AAIA;AAEA;AACA;AAWA;AAIA;AAEA;AACA;AAaA;AAIA;AAEA;AACA;AAOA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAQA;AAEA;AACA;AASA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAUA;AACA;AAKA;AACA;AACA;AACA;AAYA;AACA;AAcA;AACA;AAKA;AACA;AACA;AACA;AAaA;AACA;AAOA;AAoBA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AAGA;AACA;AAEA;;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AAEA;AACA;AACA;AACA;AACA;AAOA;AAMA;AAMA;AAWA;AASA;AACA;AAMA;AACA;AAcA;AAWA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5YA;AAeA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAGA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9tBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;AACA;AACA;AACA;AACA;;;;;ACJA;AACA;AACA;AACA;AACA;;;;;ACJA;;;;;ACAA;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACNA;AACA;AACA;AACA;AACA;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACrYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACvFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACzhBA;;;;;AEAA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack://OptionsCard/./src/components/Application.scss","webpack://OptionsCard/./src/pages/BuyGiftCardPage.scss","webpack://OptionsCard/./src/pages/RegiftCardPage.scss","webpack://OptionsCard/./src/scss/stepsProgressBar.scss","webpack://OptionsCard/./src/components/Application.scss?f5e7","webpack://OptionsCard/./src/pages/BuyGiftCardPage.scss?3089","webpack://OptionsCard/./src/pages/RegiftCardPage.scss?6368","webpack://OptionsCard/./src/scss/stepsProgressBar.scss?84a0","webpack://OptionsCard/./src/components/Application.tsx","webpack://OptionsCard/./src/components/atoms/LabeledCheckbox.tsx","webpack://OptionsCard/./src/components/giftCard/BuyGiftCardMailTemplate.tsx","webpack://OptionsCard/./src/components/giftCard/CheckMyBalanceStep.tsx","webpack://OptionsCard/./src/components/giftCard/GiftCardDetails.tsx","webpack://OptionsCard/./src/components/giftCard/RecipientDetails.tsx","webpack://OptionsCard/./src/components/giftCard/RegiftCardCustomizeStep.tsx","webpack://OptionsCard/./src/components/giftCard/RegiftCardPaymentStep.tsx","webpack://OptionsCard/./src/components/giftCard/RegiftCardRecipientsStep.tsx","webpack://OptionsCard/./src/components/giftCard/RegiftCardStep.tsx","webpack://OptionsCard/./src/components/giftCard/activate-giftcard/ActivateGiftCardForm.tsx","webpack://OptionsCard/./src/components/giftCard/activate-giftcard/BillingDetailsStep.tsx","webpack://OptionsCard/./src/components/giftCard/activate-giftcard/ChooseLoadAmountStep.tsx","webpack://OptionsCard/./src/components/giftCard/activate-giftcard/LoadAndPayForm.tsx","webpack://OptionsCard/./src/components/giftCard/activate-giftcard/LoadGiftCardForm.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/shared/StepsProgressBar.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/shared/SummarySection.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/ChoooseCardsStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/ChooseRecipientsStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/ChooseSenderStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/CustomiseGiftCardStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/CustomiseMailStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/ReviewAndPayPaymentStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/ReviewAndPayReviewStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/ReviewAndPaySenderInfoStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/steps/ReviewAndPayWhenToSendStep.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/subpages/ChooseCardSubpage.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/subpages/CustomiseCardSubpage.tsx","webpack://OptionsCard/./src/components/giftCard/buy-giftcard/subpages/ReviewAndPaySubpage.tsx","webpack://OptionsCard/./src/components/giftCard/debug-mode/DebugRegiftDataPreivewComponent.tsx","webpack://OptionsCard/./src/components/giftCard/shared/BasketDetails.tsx","webpack://OptionsCard/./src/components/giftCard/shared/CustomizeStep.tsx","webpack://OptionsCard/./src/components/giftCard/shared/ElavonPayment.tsx","webpack://OptionsCard/./src/components/giftCard/shared/InvoiceDetails.tsx","webpack://OptionsCard/./src/components/giftCard/shared/MediaUploader.tsx","webpack://OptionsCard/./src/components/giftCard/shared/RecipientsStep.tsx","webpack://OptionsCard/./src/components/giftCard/shared/RecipientsStepHowToSend.tsx","webpack://OptionsCard/./src/components/giftCard/shared/RecipientsStepRecipientsDetails.tsx","webpack://OptionsCard/./src/components/giftCard/shared/RecipientsStepSenderDetails.tsx","webpack://OptionsCard/./src/components/giftCard/shared/RecipientsStepWhenToSend.tsx","webpack://OptionsCard/./src/components/giftCard/shared/StepsProgressBar.tsx","webpack://OptionsCard/./src/components/shared/ErrorBoundary.tsx","webpack://OptionsCard/./src/components/shared/ErrorComponent.tsx","webpack://OptionsCard/./src/components/shared/LoadingComponent.tsx","webpack://OptionsCard/./src/constants/global.ts","webpack://OptionsCard/./src/debounce/debounce.ts","webpack://OptionsCard/./src/debounce/index.ts","webpack://OptionsCard/./src/debounce/use-debounce.ts","webpack://OptionsCard/./src/helpers/GiftCardHelper.ts","webpack://OptionsCard/./src/helpers/Utils.ts","webpack://OptionsCard/./src/main.tsx","webpack://OptionsCard/./src/models/CheckBalanceStep.model.ts","webpack://OptionsCard/./src/models/CustomizeStep.model.ts","webpack://OptionsCard/./src/models/GiftCardCheckoutResult.model.ts","webpack://OptionsCard/./src/models/InvoiceDetails.model.ts","webpack://OptionsCard/./src/models/RecipientDetails.model.ts","webpack://OptionsCard/./src/models/RecipientsStep.model.ts","webpack://OptionsCard/./src/models/RegiftCard.model.ts","webpack://OptionsCard/./src/models/RegiftCardStep.model.ts","webpack://OptionsCard/./src/models/RegiftPaymentStep.model.ts","webpack://OptionsCard/./src/models/ScheduleSendDetails.model.ts","webpack://OptionsCard/./src/models/SenderDetails.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/BuyGiftCard.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/choose-card/ChooseCardSubpage.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/choose-card/ChooseCardsStep.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/choose-card/ChooseRecipientsStep.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/choose-card/ChooseSenderStep.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/customise-card/CustomiseCardStep.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/customise-card/CustomiseCardSubpage.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/customise-card/CustomiseMailStep.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/review-pay/ReviewAndPayPaymentStep.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/review-pay/ReviewAndPaySenderInfoStep.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/review-pay/ReviewAndPaySubpage.model.ts","webpack://OptionsCard/./src/models/buy-giftcard/review-pay/ReviewAndPayWhenToSendStep.model.ts","webpack://OptionsCard/./src/models/enums/BuyGiftCardStateEnum.ts","webpack://OptionsCard/./src/models/enums/BuyGiftCardSubpageEnum.ts","webpack://OptionsCard/./src/models/enums/GiftCardSendTypeEnum.ts","webpack://OptionsCard/./src/models/enums/PaymentTypeEnum.ts","webpack://OptionsCard/./src/models/enums/RegiftCardStateEnum.ts","webpack://OptionsCard/./src/models/enums/WorkflowTypeEnum.ts","webpack://OptionsCard/./src/pages/ActivateGiftCardPage.tsx","webpack://OptionsCard/./src/pages/BuyGiftCardPageNew.tsx","webpack://OptionsCard/./src/pages/RegiftCardPage.tsx","webpack://OptionsCard/./src/services/DataService.service.ts","webpack://OptionsCard/webpack/bootstrap","webpack://OptionsCard/webpack/runtime/chunk loaded","webpack://OptionsCard/webpack/runtime/compat get default export","webpack://OptionsCard/webpack/runtime/define property getters","webpack://OptionsCard/webpack/runtime/get javascript update chunk filename","webpack://OptionsCard/webpack/runtime/get mini-css chunk filename","webpack://OptionsCard/webpack/runtime/get update manifest filename","webpack://OptionsCard/webpack/runtime/getFullHash","webpack://OptionsCard/webpack/runtime/global","webpack://OptionsCard/webpack/runtime/hasOwnProperty shorthand","webpack://OptionsCard/webpack/runtime/load script","webpack://OptionsCard/webpack/runtime/make namespace object","webpack://OptionsCard/webpack/runtime/node module decorator","webpack://OptionsCard/webpack/runtime/hot module replacement","webpack://OptionsCard/webpack/runtime/publicPath","webpack://OptionsCard/webpack/runtime/react refresh","webpack://OptionsCard/webpack/runtime/css loading","webpack://OptionsCard/webpack/runtime/jsonp chunk loading","webpack://OptionsCard/webpack/runtime/nonce","webpack://OptionsCard/webpack/before-startup","webpack://OptionsCard/webpack/startup","webpack://OptionsCard/webpack/after-startup"],"sourcesContent":["// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nimport ___CSS_LOADER_GET_URL_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/getUrl.js\";\nvar ___CSS_LOADER_URL_IMPORT_0___ = new URL(\"../../assets/optionsCard-bkg.png\", import.meta.url);\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\nvar ___CSS_LOADER_URL_REPLACEMENT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_0___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `body {\n position: relative;\n}\nbody.options-card-bkg::before {\n content: \"\";\n background-image: url(${___CSS_LOADER_URL_REPLACEMENT_0___});\n background-attachment: fixed;\n background-repeat: no-repeat;\n background-size: cover;\n height: 100%;\n width: 100%;\n position: absolute;\n z-index: -1;\n}\n@media (max-width: 1260px) {\n body.options-card-bkg::before {\n background-size: contain;\n background-position: bottom;\n }\n}\nbody.options-card-bkg section {\n background-color: transparent !important;\n}\n\n.buy-options-card .container {\n font-family: var(--ff--dm-sans);\n}\n.buy-options-card .container > .flex-container {\n margin-top: 73px;\n}\n.buy-options-card .container > .flex-container .forms {\n gap: 15px;\n}\n.buy-options-card .container input[type=email],\n.buy-options-card .container input[type=number],\n.buy-options-card .container input[type=text],\n.buy-options-card .container select {\n border-color: var(--cl-r-primary-600);\n}\n.buy-options-card .container input[type=checkbox],\n.buy-options-card .container input[type=radio] {\n border-color: var(--cl-r-hero-text);\n}\n.buy-options-card .container .react-tel-input .form-control {\n height: 41px;\n width: 100%;\n}\n@media (max-width: 1100px) {\n .buy-options-card .container .react-tel-input .form-control {\n height: 38px;\n }\n}\n.buy-options-card .container .react-tel-input .country-list {\n width: max-content;\n margin: 0px 0 0px -1px;\n}\n.buy-options-card .container .react-tel-input .country-list .country {\n padding: 5px 9px;\n}\n.buy-options-card .container label {\n margin: 0;\n font-weight: var(--fw--medium);\n color: var(--cl-r-primary-900);\n}\n.buy-options-card .container .btn__secondary {\n border-color: var(--cl-r-mint);\n}\n.buy-options-card .container .switch-input:checked ~ div .switch .switch__slider {\n background: var(--cl--primary-800);\n}\n.buy-options-card .container .switch-input:checked ~ div .switch .switch__slider::before {\n transform: translate(22px, -10px);\n}\n.buy-options-card .container .buttons {\n display: flex;\n gap: 17px;\n /*@media (max-width: 1260px) {\n display: none;\n }*/\n}\n.buy-options-card .container .review-and-pay .form-field {\n flex: 1 1 48%;\n}\n\n.box > input[type=checkbox] {\n display: none;\n}\n.box > input[type=checkbox]:checked ~ .action-card > .show {\n grid-template-rows: 1fr;\n}\n.box > input[type=checkbox]:checked ~ .action-card .slide-content {\n visibility: visible;\n}\n.box > input[type=checkbox]:checked ~ .action-card .box-arrow {\n top: 4px;\n transform: rotate(225deg);\n -webkit-transform: rotate(225deg);\n}\n.box > input[type=checkbox]:checked ~ .action-card .head-options div {\n opacity: 1;\n visibility: visible;\n}\n.box .action-card {\n display: block;\n}\n@media (max-width: 600px) {\n .box .action-card .how-like-send {\n flex-direction: column;\n align-items: flex-start;\n gap: 16px;\n }\n .box .action-card .how-like-send ul {\n gap: 26px;\n }\n}\n@media (max-width: 350px) {\n .box .action-card .how-like-send ul {\n gap: 14px;\n }\n}\n.box .box-heading {\n display: grid;\n grid-template-columns: 40px 1fr 15px;\n align-items: center;\n gap: 13px;\n color: var(--cl-r-purple);\n font-size: var(--heading--desktop-3);\n}\n.box .box-heading .box-icon {\n background-color: var(--cl-r-purple);\n border-radius: 50%;\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.box .box-heading .box-arrow {\n border: solid var(--cl-r-purple);\n border-width: 0 2px 2px 0;\n display: inline-block;\n transform: rotate(45deg);\n -webkit-transform: rotate(45deg);\n position: relative;\n top: 0;\n display: block;\n width: 10px;\n height: 10px;\n transition: 0.3s ease;\n}\n@media (max-width: 640px) {\n .box .box-heading .box-icon {\n grid-column: 1;\n grid-row: 1;\n }\n .box .box-heading .head-options {\n grid-column: 1/span 2;\n grid-row: 1/span 2;\n flex-direction: column;\n gap: 30px;\n }\n .box .box-heading .head-options span {\n margin: 10px 0 0 53px;\n }\n}\n@media (max-width: 450px) {\n .box .box-heading .head-options div ul {\n align-items: flex-start;\n flex-direction: column;\n }\n}\n.box .box-heading.show-edit-icon {\n grid-template-columns: 40px 1fr 82px 15px;\n}\n.box .box-heading.show-edit-icon .edit-icon {\n display: flex;\n gap: 5px;\n align-items: center;\n justify-content: center;\n font-size: 1.28571rem;\n line-height: 1.9285714rem;\n font-weight: var(--fw--bold);\n color: var(--cl-r-primary-900);\n cursor: pointer;\n}\n.box .box-heading .edit-icon {\n display: none;\n}\n\n.buy-options-card .form-field {\n margin-top: 16px;\n flex: initial;\n}\n.buy-options-card .form-field.quantity {\n flex-basis: 16%;\n}\n@media (max-width: 530px) {\n .buy-options-card .form-field.quantity {\n flex-basis: 48%;\n }\n}\n.buy-options-card .form-field.currency {\n flex-basis: 27%;\n}\n@media (max-width: 530px) {\n .buy-options-card .form-field.currency {\n flex-basis: 48%;\n }\n}\n.buy-options-card .form-field.currency input {\n width: 98%;\n}\n.buy-options-card .form-field.currency i {\n margin-left: 2px;\n}\n@media (max-width: 400px) {\n .buy-options-card .form-field.quantity, .buy-options-card .form-field.currency {\n flex-basis: auto;\n }\n}\n.buy-options-card .btn {\n margin-top: 18px;\n}\n\n.recipients .head-options {\n display: flex;\n justify-content: space-between;\n}\n.recipients .head-options div {\n visibility: hidden;\n opacity: 0;\n transition: 0.3s linear;\n margin-right: 5px;\n}\n.recipients .head-options div ul {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n.recipients .head-options div ul li {\n display: flex;\n gap: 7px;\n align-items: center;\n font-size: var(--fs--default);\n color: var(--cl-r-primary-900);\n font-weight: var(--fw--medium);\n}\n.recipients .head-options div ul li label {\n letter-spacing: 0.1px;\n}\n.recipients .how-like-send {\n display: flex;\n align-items: center;\n justify-content: space-between;\n border-top: 2px solid #d1d5db;\n border-bottom: 2px solid #9363d9;\n margin: 10px 0;\n padding: 15px 0;\n}\n.recipients .how-like-send p {\n font-size: var(--fs--medium);\n font-weight: var(--fw--medium);\n}\n.recipients .how-like-send ul {\n display: flex;\n gap: 33px;\n align-items: center;\n}\n.recipients .how-like-send ul li {\n display: flex;\n align-items: center;\n gap: 7px;\n}\n@media (max-width: 326px) {\n .recipients .how-like-send ul li {\n gap: 4px;\n }\n}\n.recipients .input-content > ul:first-of-type {\n display: flex;\n flex-direction: column;\n gap: 16px;\n counter-reset: rs;\n margin: 16px 0 0;\n}\n.recipients .input-content > ul:first-of-type > li {\n display: grid;\n grid-template-columns: 10px 1fr 1fr;\n gap: 15px;\n border-bottom: 1px solid var(--cl-r-primary-400);\n padding-bottom: 20px;\n align-items: center;\n counter-increment: rs;\n}\n.recipients .input-content > ul:first-of-type > li::before {\n content: counter(rs) \".\";\n font-size: var(--fs--large);\n color: var(--cl-r-purple);\n font-weight: var(--fw--bold);\n}\n.recipients .input-content > ul:first-of-type > li:last-of-type {\n border: none;\n}\n.recipients .input-content > ul:first-of-type > li.full-width {\n grid-template-columns: 10px 1fr;\n}\n@media (max-width: 500px) {\n .recipients .input-content > ul:first-of-type > li.full-width {\n grid-template-columns: auto;\n }\n}\n@media (max-width: 500px) {\n .recipients .input-content > ul:first-of-type > li {\n grid-template-columns: auto;\n }\n}\n.recipients .btn {\n margin: 0;\n}\n\n.choose-sender p {\n color: var(--cl-r-purple);\n font-size: var(--heading--desktop-5);\n margin-top: 12px;\n}\n\n.who-from {\n margin: 6px 0 0;\n}\n\n.summary-box table {\n width: 100%;\n margin: 20px 0 0;\n}\n.summary-box table tr {\n background-color: var(--cl-white);\n}\n.summary-box table tr:nth-child(2n+1) {\n background-color: var(--cl-r-primary-100);\n}\n.summary-box table tr td {\n font-size: var(--fs--default);\n font-weight: var(--fw--medium);\n color: var(--cl-r-table-fr);\n padding: 16px 25px;\n}\n.summary-box table tr td:last-of-type {\n text-align: right;\n}\n.summary-box table tfoot td:first-of-type {\n font-weight: var(--fw--bold);\n}\n\n.buy-options-card .container > .flex-container .sidebar {\n display: flex;\n flex-direction: column;\n gap: 15px;\n}\n.buy-options-card .container > .flex-container .sidebar .card-animation {\n filter: drop-shadow(0px 5px 15px rgba(0, 0, 0, 0.1));\n display: grid;\n align-items: end;\n}\n.buy-options-card .container > .flex-container .sidebar .card-animation img {\n position: relative;\n z-index: -1;\n}\n.buy-options-card .container > .flex-container .sidebar .box-heading.show-edit-icon {\n grid-template-columns: 1fr 61px;\n}\n\n.buy-options-card .container > .flex-container .sidebar .my-card {\n position: initial;\n}\n@media (max-width: 1260px) {\n .buy-options-card .container > .flex-container .sidebar .my-card {\n z-index: 1;\n position: initial;\n }\n}\n.buy-options-card .container > .flex-container .sidebar .my-card h3 {\n color: var(--cl-r-purple);\n}\n.buy-options-card .container > .flex-container .sidebar .my-card .card-new {\n margin: 24px 0 0;\n}\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code {\n display: flex;\n justify-content: space-between;\n margin: -1px 0 0 0;\n color: var(--cl--white);\n font-size: 1.714rem;\n font-weight: var(--fw--bold);\n background: #7844c6;\n width: 100%;\n padding: 9% 5% 3%;\n border-bottom-right-radius: 24px;\n border-bottom-left-radius: 24px;\n}\n@media (max-width: 500px) {\n .buy-options-card .container > .flex-container .sidebar .my-card .value-and-code {\n font-size: var(--fs--large);\n }\n}\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .value,\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .code {\n position: relative;\n}\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .value::before,\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .code::before {\n content: attr(data-label);\n position: absolute;\n top: calc(-100% - 4px);\n font-size: var(--fs--medium);\n}\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .code::before {\n right: 0;\n}\n.buy-options-card .container > .flex-container .sidebar .my-card .buttons {\n display: none;\n}\n@media (max-width: 1260px) {\n .buy-options-card .container > .flex-container .sidebar .my-card .buttons {\n display: block;\n }\n .buy-options-card .container > .flex-container .sidebar .my-card .buttons .btn__secondary {\n border-color: var(--cl--black);\n }\n}\n\n.card-customization .card-cover {\n display: flex;\n gap: 24px;\n margin: 11px 0 0 0;\n}\n.card-customization .card-cover li {\n display: flex;\n gap: 9px;\n}\n.card-customization .card-templates {\n display: grid;\n grid-template-columns: repeat(3, minmax(94px, 191px));\n margin: 15px 0 0;\n gap: 13px 12px;\n}\n@media (max-width: 400px) {\n .card-customization .card-templates {\n gap: 13px 8px;\n }\n}\n@media (max-width: 380px) {\n .card-customization .card-templates {\n grid-template-columns: repeat(2, minmax(94px, 191px));\n }\n}\n.card-customization .card-templates img {\n width: 100%;\n height: auto;\n border-radius: 14px;\n cursor: pointer;\n}\n@media (max-width: 680px) {\n .card-customization .card-templates img {\n border-radius: 10px;\n }\n}\n@media (max-width: 400px) {\n .card-customization .card-templates img {\n border-radius: 8px;\n }\n}\n.card-customization .card-templates img.selected {\n border: 3px solid orange;\n}\n.card-customization .card-upload {\n display: flex;\n margin: 24px 0 7px 0;\n gap: 27px;\n}\n@media (max-width: 500px) {\n .card-customization .card-upload {\n display: grid;\n border: 1px dashed var(--cl--neutral-300);\n gap: 10px;\n padding: 16px 0;\n border-radius: 6px;\n }\n .card-customization .card-upload label.upload-info {\n grid-row: 2;\n border: none;\n width: 100%;\n }\n .card-customization .card-upload label.upload-info img {\n display: none;\n }\n .card-customization .card-upload .imgUpload {\n grid-row: 1;\n transform: translateX(-50%);\n left: 50%;\n position: relative;\n }\n}\n.card-customization .card-upload .upload-info {\n width: 70%;\n height: auto;\n padding: 0;\n}\n.card-customization .card-upload .upload-info img {\n margin: 16px 0 0;\n}\n.card-customization .card-upload .imgUpload {\n width: 153px;\n display: grid;\n position: relative;\n}\n.card-customization .card-upload .imgUpload i {\n background-color: var(--cl-r-mint);\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n position: absolute;\n right: 5px;\n top: 7px;\n}\n\n.mail-customization .personal-message .message-details,\n.mail-customization .personal-message .add-multimedia-gif {\n display: block;\n}\n.mail-customization .personal-message .message-details .switch-label-box,\n.mail-customization .personal-message .add-multimedia-gif .switch-label-box {\n margin: 25px 0 0 0;\n display: flex;\n gap: 5px;\n align-items: center;\n justify-content: space-between;\n}\n.mail-customization .personal-message .message-details .switch-label-box p,\n.mail-customization .personal-message .add-multimedia-gif .switch-label-box p {\n font-size: 1.28571rem;\n}\n.mail-customization .personal-message .message-details .msg,\n.mail-customization .personal-message .add-multimedia-gif .msg {\n --minHeight: 180px;\n margin: 8px 0 0 0;\n min-height: var(--minHeight);\n width: 100%;\n}\n.mail-customization .personal-message .message-details .msg textarea,\n.mail-customization .personal-message .add-multimedia-gif .msg textarea {\n min-height: var(--minHeight);\n padding: 0;\n}\n.mail-customization .personal-message .message-details .remaining-chars,\n.mail-customization .personal-message .add-multimedia-gif .remaining-chars {\n text-align: right;\n font-size: var(--fs--default);\n margin: 12px 0px 0 0;\n}\n.mail-customization .card-cover {\n display: flex;\n gap: 24px;\n margin: 11px 0 0 0;\n}\n.mail-customization .card-cover li {\n display: flex;\n gap: 9px;\n}\n.mail-customization .card-upload {\n display: flex;\n margin: 24px 0 7px 0;\n gap: 27px;\n}\n@media (max-width: 500px) {\n .mail-customization .card-upload {\n display: grid;\n border: 1px dashed var(--cl--neutral-300);\n gap: 10px;\n padding: 16px 0;\n border-radius: 6px;\n }\n .mail-customization .card-upload label.upload-info {\n grid-row: 2;\n border: none;\n width: 100%;\n }\n .mail-customization .card-upload label.upload-info img {\n display: none;\n }\n .mail-customization .card-upload .imgUpload {\n grid-row: 1;\n transform: translateX(-50%);\n left: 50%;\n position: relative;\n }\n}\n.mail-customization .card-upload .upload-info {\n width: 70%;\n height: auto;\n padding: 0;\n}\n.mail-customization .card-upload .upload-info img {\n margin: 16px 0 0;\n}\n.mail-customization .card-upload .imgUpload {\n width: 153px;\n display: grid;\n position: relative;\n}\n.mail-customization .card-upload .imgUpload i {\n background-color: var(--cl-r-mint);\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n position: absolute;\n right: 5px;\n top: 7px;\n}\n\n.OptionsCardCub {\n --optionsCub-radius-box: 8px;\n}\n.OptionsCardCub .oc-box {\n box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n}\n.OptionsCardCub .oc-box h3 {\n font-size: 1.71428571rem;\n color: var(--cl-r-purple);\n}\n.OptionsCardCub .oc-box h5 {\n background-color: var(--cl-r-purple);\n color: var(--cl--white);\n display: flex;\n justify-content: flex-start;\n align-items: center;\n padding: 14px 0px 10px 23px;\n font-size: 1.428571rem;\n border-top-left-radius: var(--optionsCub-radius-box);\n border-top-right-radius: var(--optionsCub-radius-box);\n}\n.OptionsCardCub .oc-box p {\n padding: 24px 24px 15px;\n}\n.OptionsCardCub .oc-box img {\n margin: 0 auto 38px;\n display: block;\n}\n@media (max-width: 400px) {\n .OptionsCardCub .oc-box img {\n width: 100%;\n height: auto;\n }\n}\n.OptionsCardCub .oc-box h6 {\n background-color: var(--cl-r-primary-200);\n padding: 11px 23px;\n border-bottom-left-radius: var(--optionsCub-radius-box);\n border-bottom-right-radius: var(--optionsCub-radius-box);\n}\n\n.review-and-pay {\n display: flex;\n flex-direction: column;\n gap: 15px;\n}\n.review-and-pay h5 {\n font-size: 1.28571rem;\n line-height: 1.9285714rem;\n font-weight: var(--fw--bold);\n color: var(--cl-r-purple);\n margin: 17px 0 0;\n letter-spacing: 0.1px;\n}\n.review-and-pay .sending-to {\n width: 100%;\n margin: 12px 0 0;\n border-top-left-radius: 8px;\n border-top-right-radius: 10px;\n border-collapse: separate;\n border: 1px solid #eaecf0;\n}\n.review-and-pay .sending-to th {\n font-size: var(--fs--default);\n font-weight: var(--fw--medium);\n padding: 11px 25px;\n background-color: var(--cl-r-magnolia);\n}\n.review-and-pay .sending-to th:first-of-type {\n width: 87%;\n}\n.review-and-pay .sending-to th:last-of-type {\n text-align: right;\n}\n.review-and-pay .sending-to td {\n font-size: 1.28571rem;\n line-height: 1.9285714rem;\n font-weight: var(--fw--bold);\n padding: 8px 25px;\n background-color: var(--cl-white);\n}\n.review-and-pay .sending-to td:last-of-type {\n font-size: 1.142857rem;\n}\n.review-and-pay .your-info p {\n margin: 13px 0 0 0;\n letter-spacing: 0.1px;\n}\n.review-and-pay .send-options {\n margin: 18px 0 0 2px;\n}\n.review-and-pay .send-options ul {\n display: flex;\n gap: 22px;\n}\n.review-and-pay .send-options ul li {\n display: flex;\n gap: 10px;\n}\n.review-and-pay .send-options ul li input {\n font-weight: var(--fw--medium);\n}\n.review-and-pay .payment-type .slide-content input[type=radio] {\n display: none;\n}\n.review-and-pay .payment-type .services {\n gap: 23px;\n}\n@media (max-width: 660px) {\n .review-and-pay .payment-type .services {\n flex-direction: column;\n gap: 0;\n }\n}\n.review-and-pay .payment-type .services label {\n border: 1px solid var(--cl-r-primary-400);\n width: 48%;\n padding: 14px 17px;\n margin: 19px 0 0 0;\n border-radius: 8px;\n font-size: var(--fs--default);\n font-weight: var(--fw--medium);\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: 16px;\n height: 64px;\n cursor: pointer;\n}\n@media (max-width: 660px) {\n .review-and-pay .payment-type .services label {\n width: 100%;\n }\n}\n.review-and-pay .payment-type .payment-form-content > div {\n display: none;\n margin: 24px 0 0;\n}\n.review-and-pay .payment-type .payment-form-content > div .form-field {\n margin-top: 24px;\n}\n.review-and-pay .payment-type .payment-form-content > div .form-field:nth-of-type(-n + 2) {\n margin-top: 0;\n}\n@media (max-width: 500px) {\n .review-and-pay .payment-type .payment-form-content > div .form-field {\n flex: 1 1 100%;\n }\n .review-and-pay .payment-type .payment-form-content > div .form-field:nth-of-type(2) {\n margin-top: 24px;\n }\n}\n.review-and-pay .payment-type #credit-debit-card:checked ~ .services label:nth-of-type(1),\n.review-and-pay .payment-type #bank-transfer:checked ~ .services label:nth-of-type(2) {\n border-color: var(--cl-r-mint);\n background-color: #f0fdfa;\n}\n.review-and-pay .payment-type #credit-debit-card:checked ~ .services label:nth-of-type(1) svg path {\n fill: var(--cl-r-mint);\n}\n.review-and-pay .payment-type #bank-transfer:checked ~ .services label:nth-of-type(2) svg path {\n stroke: var(--cl-r-mint);\n}\n.review-and-pay .payment-type #credit-debit-card:checked ~ .payment-form-content > div:nth-of-type(1),\n.review-and-pay .payment-type #bank-transfer:checked ~ .payment-form-content > div:nth-of-type(2) {\n display: flex;\n}\n.review-and-pay .payment-type .terms-conditions {\n border-top: 1px solid red;\n margin: 24px 0 0 0;\n padding-top: 24px;\n border-color: var(--cl-r-purple);\n}\n.review-and-pay .buttons {\n margin: 26px 0 0;\n}\n.review-and-pay .buttons button {\n margin: 0 !important;\n}\n\n.review-pay-box {\n margin: 20px 0 0;\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/scss/theme.scss\",\"webpack://./src/components/Application.scss\"],\"names\":[],\"mappings\":\"AAAA;EACE,kBAAA;ACCF;ADCI;EACE,WAAA;EACA,yDAAA;EACA,4BAAA;EACA,4BAAA;EACA,sBAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,WAAA;ACCN;ADCI;EACE;IACE,wBAAA;IACA,2BAAA;ECCN;AACF;ADCI;EACE,wCAAA;ACCN;;ADGA;EACE,+BAAA;ACAF;ADCE;EACE,gBAAA;ACCJ;ADAI;EACE,SAAA;ACEN;ADEE;;;;EAIE,qCAAA;ACAJ;ADEE;;EAEE,mCAAA;ACAJ;ADGE;EACE,YAAA;EACA,WAAA;ACDJ;ADGE;EACE;IACI,YAAA;ECDN;AACF;ADGE;EACE,kBAAA;EACA,sBAAA;ACDJ;ADGE;EACE,gBAAA;ACDJ;ADIE;EACE,SAAA;EACA,8BAAA;EACA,8BAAA;ACFJ;ADIE;EACE,8BAAA;ACFJ;ADMM;EACE,kCAAA;ACJR;ADKQ;EACE,iCAAA;ACHV;ADSE;EACE,aAAA;EACA,SAAA;EACA;;IAAA;ACLJ;ADWI;EACE,aAAA;ACTN;;ADeE;EACE,aAAA;ACZJ;ADeM;EACE,uBAAA;ACbR;ADgBM;EACE,mBAAA;ACdR;ADgBM;EACE,QAAA;EACA,yBAAA;EACA,iCAAA;ACdR;ADiBQ;EACE,UAAA;EACA,mBAAA;ACfV;ADqBE;EACE,cAAA;ACnBJ;ADoBI;EACE;IACE,sBAAA;IACA,uBAAA;IACA,SAAA;EClBN;EDmBM;IACE,SAAA;ECjBR;AACF;ADqBI;EAEQ;IACI,SAAA;ECpBd;AACF;ADyBE;EACE,aAAA;EACA,oCAAA;EACA,mBAAA;EACA,SAAA;EACA,yBAAA;EACA,oCAAA;ACvBJ;ADwBI;EACE,oCAAA;EACA,kBAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;ACtBN;ADwBI;EACE,gCAAA;EACA,yBAAA;EACA,qBAAA;EAEA,wBAAA;EACA,gCAAA;EACA,kBAAA;EACA,MAAA;EACA,cAAA;EACA,WAAA;EACA,YAAA;EACA,qBAAA;ACvBN;AD0BI;EACE;IACE,cAAA;IACA,WAAA;ECxBN;ED0BI;IACE,qBAAA;IACA,kBAAA;IACA,sBAAA;IACA,SAAA;ECxBN;ED0BM;IACE,qBAAA;ECxBR;AACF;AD2BI;EAGM;IACE,uBAAA;IACA,sBAAA;EC3BV;AACF;ADgCI;EACE,yCAAA;AC9BN;AD+BM;EACE,aAAA;EACA,QAAA;EACA,mBAAA;EACA,uBAAA;EACA,qBAAA;EACA,yBAAA;EACA,4BAAA;EACA,8BAAA;EACA,eAAA;AC7BR;ADiCI;EACE,aAAA;AC/BN;;ADqCE;EACE,gBAAA;EACA,aAAA;AClCJ;ADmCI;EACE,eAAA;ACjCN;ADkCM;EAFF;IAGI,eAAA;EC/BN;AACF;ADiCI;EACE,eAAA;AC/BN;ADgCM;EAFF;IAGI,eAAA;EC7BN;AACF;AD8BM;EACE,UAAA;AC5BR;AD8BM;EACE,gBAAA;AC5BR;AD+BI;EACE;IAEE,gBAAA;EC9BN;AACF;ADiCE;EACE,gBAAA;AC/BJ;;ADoCE;EACE,aAAA;EACA,8BAAA;ACjCJ;ADkCI;EACE,kBAAA;EACA,UAAA;EACA,uBAAA;EACA,iBAAA;AChCN;ADiCM;EACE,aAAA;EACA,mBAAA;EACA,SAAA;AC/BR;ADgCQ;EACE,aAAA;EACA,QAAA;EACA,mBAAA;EACA,6BAAA;EACA,8BAAA;EACA,8BAAA;AC9BV;AD+BU;EACE,qBAAA;AC7BZ;ADmCE;EACE,aAAA;EACA,mBAAA;EACA,8BAAA;EACA,6BAAA;EACA,gCAAA;EACA,cAAA;EACA,eAAA;ACjCJ;ADkCI;EACE,4BAAA;EACA,8BAAA;AChCN;ADmCI;EACE,aAAA;EACA,SAAA;EACA,mBAAA;ACjCN;ADkCM;EACE,aAAA;EACA,mBAAA;EACA,QAAA;AChCR;ADkCM;EACI;IACI,QAAA;EChCZ;AACF;ADqCI;EACE,aAAA;EACA,sBAAA;EACA,SAAA;EACA,iBAAA;EACA,gBAAA;ACnCN;ADoCM;EACE,aAAA;EACA,mCAAA;EACA,SAAA;EACA,gDAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;AClCR;ADmCQ;EACE,wBAAA;EACA,2BAAA;EACA,yBAAA;EACA,4BAAA;ACjCV;ADmCQ;EACE,YAAA;ACjCV;ADmCQ;EACE,+BAAA;ACjCV;ADkCU;EAFF;IAGI,2BAAA;EC/BV;AACF;ADiCQ;EAvBF;IAwBI,2BAAA;EC9BR;AACF;ADmCE;EACE,SAAA;ACjCJ;;ADsCI;EACI,yBAAA;EACA,oCAAA;EACA,gBAAA;ACnCR;;ADuCA;EACI,eAAA;ACpCJ;;ADwCE;EACE,WAAA;EACA,gBAAA;ACrCJ;ADsCI;EACE,iCAAA;ACpCN;ADsCM;EACE,yCAAA;ACpCR;ADsCM;EACE,6BAAA;EACA,8BAAA;EACA,2BAAA;EACA,kBAAA;ACpCR;ADqCQ;EACE,iBAAA;ACnCV;ADyCQ;EACE,4BAAA;ACvCV;;AD6CA;EACE,aAAA;EACA,sBAAA;EACA,SAAA;AC1CF;AD2CE;EACE,oDAAA;EACA,aAAA;EACA,gBAAA;ACzCJ;AD8CI;EACE,kBAAA;EACA,WAAA;AC5CN;ADgDI;EACE,+BAAA;AC9CN;;ADmDA;EACE,iBAAA;AChDF;ADiDE;EAFF;IAGI,UAAA;IACA,iBAAA;EC9CF;AACF;AD+CE;EACE,yBAAA;AC7CJ;AD+CE;EACE,gBAAA;AC7CJ;AD+CE;EACE,aAAA;EACA,8BAAA;EACA,kBAAA;EACA,uBAAA;EACA,mBAAA;EACA,4BAAA;EACA,mBAAA;EACA,WAAA;EACA,iBAAA;EACA,gCAAA;EACA,+BAAA;AC7CJ;AD8CI;EAZF;IAaI,2BAAA;EC3CJ;AACF;AD6CI;;EAEE,kBAAA;AC3CN;AD4CM;;EACE,yBAAA;EACA,kBAAA;EACA,sBAAA;EACA,4BAAA;ACzCR;AD6CM;EACE,QAAA;AC3CR;AD+CE;EACE,aAAA;AC7CJ;AD8CI;EAFF;IAGI,cAAA;EC3CJ;ED4CI;IACE,8BAAA;EC1CN;AACF;;ADgDE;EACE,aAAA;EACA,SAAA;EACA,kBAAA;AC7CJ;AD8CI;EACE,aAAA;EACA,QAAA;AC5CN;AD+CE;EACE,aAAA;EACA,qDAAA;EACA,gBAAA;EACA,cAAA;AC7CJ;AD8CI;EALF;IAMI,aAAA;EC3CJ;AACF;AD4CI;EARF;IASI,qDAAA;ECzCJ;AACF;AD0CI;EACE,WAAA;EACA,YAAA;EACA,mBAAA;EACA,eAAA;ACxCN;ADyCM;EALF;IAMI,mBAAA;ECtCN;AACF;ADuCM;EARF;IASI,kBAAA;ECpCN;AACF;ADqCM;EACE,wBAAA;ACnCR;ADwCE;EACE,aAAA;EACA,oBAAA;EACA,SAAA;ACtCJ;ADwCI;EALF;IAMI,aAAA;IACA,yCAAA;IACA,SAAA;IACA,eAAA;IACA,kBAAA;ECrCJ;EDsCI;IACE,WAAA;IACA,YAAA;IAIA,WAAA;ECvCN;EDoCM;IACE,aAAA;EClCR;EDsCI;IACE,WAAA;IACA,2BAAA;IACA,SAAA;IACA,kBAAA;ECpCN;AACF;ADuCI;EACE,UAAA;EACA,YAAA;EACA,UAAA;ACrCN;ADsCM;EACE,gBAAA;ACpCR;ADuCI;EACE,YAAA;EACA,aAAA;EACA,kBAAA;ACrCN;ADsCM;EACE,kCAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA;EACA,kBAAA;EACA,UAAA;EACA,QAAA;ACpCR;;AD4CI;;EAEE,cAAA;ACzCN;AD0CM;;EACE,kBAAA;EACA,aAAA;EACA,QAAA;EACA,mBAAA;EACA,8BAAA;ACvCR;ADwCQ;;EACE,qBAAA;ACrCV;ADwCM;;EACE,kBAAA;EACA,iBAAA;EACA,4BAAA;EACA,WAAA;ACrCR;ADuCQ;;EACE,4BAAA;EACA,UAAA;ACpCV;ADwCM;;EACE,iBAAA;EACA,6BAAA;EACA,oBAAA;ACrCR;ADyCE;EACE,aAAA;EACA,SAAA;EACA,kBAAA;ACvCJ;ADwCI;EACE,aAAA;EACA,QAAA;ACtCN;ADyCE;EACE,aAAA;EACA,oBAAA;EACA,SAAA;ACvCJ;ADyCI;EALF;IAMI,aAAA;IACA,yCAAA;IACA,SAAA;IACA,eAAA;IACA,kBAAA;ECtCJ;EDuCI;IACE,WAAA;IACA,YAAA;IAIA,WAAA;ECxCN;EDqCM;IACE,aAAA;ECnCR;EDuCI;IACE,WAAA;IACA,2BAAA;IACA,SAAA;IACA,kBAAA;ECrCN;AACF;ADwCI;EACE,UAAA;EACA,YAAA;EACA,UAAA;ACtCN;ADuCM;EACE,gBAAA;ACrCR;ADwCI;EACE,YAAA;EACA,aAAA;EACA,kBAAA;ACtCN;ADuCM;EACE,kCAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA;EACA,kBAAA;EACA,UAAA;EACA,QAAA;ACrCR;;AD2CA;EACE,4BAAA;ACxCF;ADyCE;EACE,2CAAA;EACA,mBAAA;ACvCJ;ADwCI;EACE,wBAAA;EACA,yBAAA;ACtCN;ADwCI;EACE,oCAAA;EACA,uBAAA;EACA,aAAA;EACA,2BAAA;EACA,mBAAA;EACA,2BAAA;EACA,sBAAA;EACA,oDAAA;EACA,qDAAA;ACtCN;ADwCI;EACE,uBAAA;ACtCN;ADwCI;EACE,mBAAA;EACA,cAAA;ACtCN;ADuCM;EAHF;IAII,WAAA;IACA,YAAA;ECpCN;AACF;ADsCI;EACE,yCAAA;EACA,kBAAA;EACA,uDAAA;EACA,wDAAA;ACpCN;;ADyCA;EACE,aAAA;EACA,sBAAA;EACA,SAAA;ACtCF;ADwCE;EACE,qBAAA;EACA,yBAAA;EACA,4BAAA;EACA,yBAAA;EACA,gBAAA;EACA,qBAAA;ACtCJ;ADwCE;EACE,WAAA;EAEA,gBAAA;EACA,2BAAA;EACA,6BAAA;EACA,yBAAA;EACA,yBAAA;ACvCJ;ADwCI;EACE,6BAAA;EACA,8BAAA;EACA,kBAAA;EACA,sCAAA;ACtCN;ADuCM;EACE,UAAA;ACrCR;ADuCM;EACE,iBAAA;ACrCR;ADwCI;EACE,qBAAA;EACA,yBAAA;EACA,4BAAA;EACA,iBAAA;EACA,iCAAA;ACtCN;ADuCM;EACE,sBAAA;ACrCR;AD2CI;EACE,kBAAA;EACA,qBAAA;ACzCN;AD4CE;EACE,oBAAA;AC1CJ;AD2CI;EACE,aAAA;EACA,SAAA;ACzCN;AD0CM;EACE,aAAA;EACA,SAAA;ACxCR;ADyCQ;EACE,8BAAA;ACvCV;AD8CM;EACE,aAAA;AC5CR;AD+CI;EACE,SAAA;AC7CN;AD8CM;EAFF;IAGI,sBAAA;IACA,MAAA;EC3CN;AACF;AD4CM;EACE,yCAAA;EACA,UAAA;EACA,kBAAA;EACA,kBAAA;EACA,kBAAA;EACA,6BAAA;EACA,8BAAA;EACA,aAAA;EACA,mBAAA;EACA,2BAAA;EACA,SAAA;EACA,YAAA;EACA,eAAA;AC1CR;AD2CQ;EAdF;IAeI,WAAA;ECxCR;AACF;AD4CM;EACE,aAAA;EACA,gBAAA;AC1CR;AD2CQ;EAIE,gBAAA;AC5CV;ADyCU;EACE,aAAA;ACvCZ;AD0CU;EALF;IAMI,cAAA;ECvCV;EDwCU;IACE,gBAAA;ECtCZ;AACF;AD4CI;;EAEE,8BAAA;EACA,yBAAA;AC1CN;AD6CM;EACE,sBAAA;AC3CR;AD+CM;EACE,wBAAA;AC7CR;ADiDI;;EAEE,aAAA;AC/CN;ADiDI;EACE,yBAAA;EACA,kBAAA;EACA,iBAAA;EACA,gCAAA;AC/CN;ADmDE;EACE,gBAAA;ACjDJ;ADkDI;EACE,oBAAA;AChDN;;ADoDA;EACE,gBAAA;ACjDF\",\"sourcesContent\":[\"body {\\r\\n position: relative;\\r\\n &.options-card-bkg {\\r\\n &::before {\\r\\n content: \\\"\\\";\\r\\n background-image: url(\\\"../../assets/optionsCard-bkg.png\\\");\\r\\n background-attachment: fixed;\\r\\n background-repeat: no-repeat;\\r\\n background-size: cover;\\r\\n height: 100%;\\r\\n width: 100%;\\r\\n position: absolute;\\r\\n z-index: -1;\\r\\n }\\r\\n @media (max-width: 1260px) {\\r\\n &::before {\\r\\n background-size: contain;\\r\\n background-position: bottom;\\r\\n }\\r\\n }\\r\\n section {\\r\\n background-color: transparent !important;\\r\\n }\\r\\n }\\r\\n}\\r\\n.buy-options-card .container {\\r\\n font-family: var(--ff--dm-sans);\\r\\n > .flex-container {\\r\\n margin-top: 73px;\\r\\n .forms {\\r\\n gap: 15px;\\r\\n }\\r\\n }\\r\\n\\r\\n input[type=\\\"email\\\"],\\r\\n input[type=\\\"number\\\"],\\r\\n input[type=\\\"text\\\"],\\r\\n select {\\r\\n border-color: var(--cl-r-primary-600);\\r\\n }\\r\\n input[type=\\\"checkbox\\\"],\\r\\n input[type=\\\"radio\\\"] {\\r\\n border-color: var(--cl-r-hero-text);\\r\\n }\\r\\n\\r\\n .react-tel-input .form-control {\\r\\n height: 41px;\\r\\n width: 100%;\\r\\n }\\r\\n @media (max-width: 1100px) {\\r\\n .react-tel-input .form-control {\\r\\n height: 38px;\\r\\n }\\r\\n }\\r\\n .react-tel-input .country-list {\\r\\n width: max-content;\\r\\n margin: 0px 0 0px -1px;\\r\\n }\\r\\n .react-tel-input .country-list .country {\\r\\n padding: 5px 9px;\\r\\n }\\r\\n\\r\\n label {\\r\\n margin: 0;\\r\\n font-weight: var(--fw--medium);\\r\\n color: var(--cl-r-primary-900);\\r\\n }\\r\\n .btn__secondary {\\r\\n border-color: var(--cl-r-mint);\\r\\n }\\r\\n .switch-input:checked ~ div {\\r\\n .switch {\\r\\n .switch__slider {\\r\\n background: var(--cl--primary-800);\\r\\n &::before {\\r\\n transform: translate(22px, -10px);\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n .buttons {\\r\\n display: flex;\\r\\n gap: 17px;\\r\\n /*@media (max-width: 1260px) {\\r\\n display: none;\\r\\n }*/\\r\\n }\\r\\n\\r\\n .review-and-pay {\\r\\n .form-field {\\r\\n flex: 1 1 48%;\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n.box {\\r\\n > input[type=\\\"checkbox\\\"] {\\r\\n display: none;\\r\\n\\r\\n &:checked ~ .action-card {\\r\\n > .show {\\r\\n grid-template-rows: 1fr;\\r\\n }\\r\\n\\r\\n .slide-content {\\r\\n visibility: visible;\\r\\n }\\r\\n .box-arrow {\\r\\n top: 4px;\\r\\n transform: rotate(225deg);\\r\\n -webkit-transform: rotate(225deg);\\r\\n }\\r\\n .head-options {\\r\\n div {\\r\\n opacity: 1;\\r\\n visibility: visible;\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n .action-card {\\r\\n display: block;\\r\\n @media (max-width: 600px) {\\r\\n .how-like-send {\\r\\n flex-direction: column;\\r\\n align-items: flex-start;\\r\\n gap: 16px;\\r\\n ul {\\r\\n gap: 26px;\\r\\n }\\r\\n }\\r\\n\\r\\n }\\r\\n @media (max-width: 350px) {\\r\\n .how-like-send {\\r\\n ul {\\r\\n gap: 14px;\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n .box-heading {\\r\\n display: grid;\\r\\n grid-template-columns: 40px 1fr 15px;\\r\\n align-items: center;\\r\\n gap: 13px;\\r\\n color: var(--cl-r-purple);\\r\\n font-size: var(--heading--desktop-3);\\r\\n .box-icon {\\r\\n background-color: var(--cl-r-purple);\\r\\n border-radius: 50%;\\r\\n width: 40px;\\r\\n height: 40px;\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n }\\r\\n .box-arrow {\\r\\n border: solid var(--cl-r-purple);\\r\\n border-width: 0 2px 2px 0;\\r\\n display: inline-block;\\r\\n // padding: 4px;\\r\\n transform: rotate(45deg);\\r\\n -webkit-transform: rotate(45deg);\\r\\n position: relative;\\r\\n top: 0;\\r\\n display: block;\\r\\n width: 10px;\\r\\n height: 10px;\\r\\n transition: 0.3s ease;\\r\\n }\\r\\n\\r\\n @media (max-width: 640px) {\\r\\n .box-icon {\\r\\n grid-column: 1;\\r\\n grid-row: 1;\\r\\n }\\r\\n .head-options {\\r\\n grid-column: 1 / span 2;\\r\\n grid-row: 1 / span 2;\\r\\n flex-direction: column;\\r\\n gap: 30px;\\r\\n\\r\\n span {\\r\\n margin: 10px 0 0 53px;\\r\\n }\\r\\n }\\r\\n }\\r\\n @media (max-width: 450px) {\\r\\n .head-options {\\r\\n div {\\r\\n ul {\\r\\n align-items: flex-start;\\r\\n flex-direction: column;\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n &.show-edit-icon {\\r\\n grid-template-columns: 40px 1fr 82px 15px;\\r\\n .edit-icon {\\r\\n display: flex;\\r\\n gap: 5px;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n font-size: 1.28571rem;\\r\\n line-height: 1.9285714rem;\\r\\n font-weight: var(--fw--bold);\\r\\n color: var(--cl-r-primary-900);\\r\\n cursor: pointer;\\r\\n }\\r\\n }\\r\\n\\r\\n .edit-icon {\\r\\n display: none;\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n.buy-options-card {\\r\\n .form-field {\\r\\n margin-top: 16px;\\r\\n flex: initial;\\r\\n &.quantity {\\r\\n flex-basis: 16%;\\r\\n @media (max-width: 530px) {\\r\\n flex-basis: 48%;\\r\\n }\\r\\n }\\r\\n &.currency {\\r\\n flex-basis: 27%;\\r\\n @media (max-width: 530px) {\\r\\n flex-basis: 48%;\\r\\n }\\r\\n input {\\r\\n width: 98%;\\r\\n }\\r\\n i {\\r\\n margin-left: 2px;\\r\\n }\\r\\n }\\r\\n @media (max-width: 400px) {\\r\\n &.quantity,\\r\\n &.currency {\\r\\n flex-basis: auto;\\r\\n }\\r\\n }\\r\\n }\\r\\n .btn {\\r\\n margin-top: 18px;\\r\\n }\\r\\n}\\r\\n\\r\\n.recipients {\\r\\n .head-options {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n div {\\r\\n visibility: hidden;\\r\\n opacity: 0;\\r\\n transition: 0.3s linear;\\r\\n margin-right: 5px;\\r\\n ul {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 12px;\\r\\n li {\\r\\n display: flex;\\r\\n gap: 7px;\\r\\n align-items: center;\\r\\n font-size: var(--fs--default);\\r\\n color: var(--cl-r-primary-900);\\r\\n font-weight: var(--fw--medium);\\r\\n label {\\r\\n letter-spacing: 0.1px;\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n .how-like-send {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n border-top: 2px solid #d1d5db;\\r\\n border-bottom: 2px solid #9363d9;\\r\\n margin: 10px 0;\\r\\n padding: 15px 0;\\r\\n p {\\r\\n font-size: var(--fs--medium);\\r\\n font-weight: var(--fw--medium);\\r\\n }\\r\\n\\r\\n ul {\\r\\n display: flex;\\r\\n gap: 33px;\\r\\n align-items: center;\\r\\n li {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 7px;\\r\\n }\\r\\n @media (max-width: 326px) {\\r\\n li {\\r\\n gap: 4px;\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n .input-content {\\r\\n > ul:first-of-type {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 16px;\\r\\n counter-reset: rs;\\r\\n margin: 16px 0 0;\\r\\n > li {\\r\\n display: grid;\\r\\n grid-template-columns: 10px 1fr 1fr;\\r\\n gap: 15px;\\r\\n border-bottom: 1px solid var(--cl-r-primary-400);\\r\\n padding-bottom: 20px;\\r\\n align-items: center;\\r\\n counter-increment: rs;\\r\\n &::before {\\r\\n content: counter(rs) \\\".\\\";\\r\\n font-size: var(--fs--large);\\r\\n color: var(--cl-r-purple);\\r\\n font-weight: var(--fw--bold);\\r\\n }\\r\\n &:last-of-type {\\r\\n border: none;\\r\\n }\\r\\n &.full-width {\\r\\n grid-template-columns: 10px 1fr;\\r\\n @media (max-width:500px){\\r\\n grid-template-columns: auto;\\r\\n }\\r\\n }\\r\\n @media (max-width:500px){\\r\\n grid-template-columns: auto;\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n .btn {\\r\\n margin: 0;\\r\\n }\\r\\n}\\r\\n\\r\\n.choose-sender {\\r\\n p {\\r\\n color: var(--cl-r-purple);\\r\\n font-size: var(--heading--desktop-5);\\r\\n margin-top: 12px;\\r\\n }\\r\\n}\\r\\n\\r\\n.who-from {\\r\\n margin: 6px 0 0;\\r\\n}\\r\\n\\r\\n.summary-box {\\r\\n table {\\r\\n width: 100%;\\r\\n margin: 20px 0 0;\\r\\n tr {\\r\\n background-color: var(--cl-white);\\r\\n\\r\\n &:nth-child(2n + 1) {\\r\\n background-color: var(--cl-r-primary-100);\\r\\n }\\r\\n td {\\r\\n font-size: var(--fs--default);\\r\\n font-weight: var(--fw--medium);\\r\\n color: var(--cl-r-table-fr);\\r\\n padding: 16px 25px;\\r\\n &:last-of-type {\\r\\n text-align: right;\\r\\n }\\r\\n }\\r\\n }\\r\\n tfoot {\\r\\n td {\\r\\n &:first-of-type {\\r\\n font-weight: var(--fw--bold);\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n.buy-options-card .container > .flex-container .sidebar {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 15px;\\r\\n .card-animation {\\r\\n filter: drop-shadow(0px 5px 15px rgba(0, 0, 0, 0.1));\\r\\n display: grid;\\r\\n align-items: end;\\r\\n // > * {\\r\\n // grid-row: 1;\\r\\n // grid-column: 1;\\r\\n // }\\r\\n img {\\r\\n position: relative;\\r\\n z-index: -1;\\r\\n }\\r\\n }\\r\\n .box-heading {\\r\\n &.show-edit-icon {\\r\\n grid-template-columns: 1fr 61px;\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n.buy-options-card .container > .flex-container .sidebar .my-card {\\r\\n position: initial;\\r\\n @media (max-width: 1260px) {\\r\\n z-index: 1;\\r\\n position: initial;\\r\\n }\\r\\n h3 {\\r\\n color: var(--cl-r-purple);\\r\\n }\\r\\n .card-new {\\r\\n margin: 24px 0 0;\\r\\n }\\r\\n .value-and-code {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n margin: -1px 0 0 0;\\r\\n color: var(--cl--white);\\r\\n font-size: 1.714rem;\\r\\n font-weight: var(--fw--bold);\\r\\n background: #7844c6;\\r\\n width: 100%;\\r\\n padding: 9% 5% 3%;\\r\\n border-bottom-right-radius: 24px;\\r\\n border-bottom-left-radius: 24px;\\r\\n @media (max-width: 500px) {\\r\\n font-size: var(--fs--large);\\r\\n // margin:0 5% 4%;\\r\\n }\\r\\n .value,\\r\\n .code {\\r\\n position: relative;\\r\\n &::before {\\r\\n content: attr(data-label);\\r\\n position: absolute;\\r\\n top: calc(-100% - 4px);\\r\\n font-size: var(--fs--medium);\\r\\n }\\r\\n }\\r\\n .code {\\r\\n &::before {\\r\\n right: 0;\\r\\n }\\r\\n }\\r\\n }\\r\\n .buttons {\\r\\n display: none;\\r\\n @media (max-width: 1260px) {\\r\\n display: block;\\r\\n .btn__secondary {\\r\\n border-color: var(--cl--black);\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n.card-customization {\\r\\n .card-cover {\\r\\n display: flex;\\r\\n gap: 24px;\\r\\n margin: 11px 0 0 0;\\r\\n li {\\r\\n display: flex;\\r\\n gap: 9px;\\r\\n }\\r\\n }\\r\\n .card-templates {\\r\\n display: grid;\\r\\n grid-template-columns: repeat(3, minmax(94px, 191px));\\r\\n margin: 15px 0 0;\\r\\n gap: 13px 12px;\\r\\n @media (max-width: 400px) {\\r\\n gap: 13px 8px;\\r\\n }\\r\\n @media (max-width: 380px) {\\r\\n grid-template-columns: repeat(2, minmax(94px, 191px));\\r\\n }\\r\\n img {\\r\\n width: 100%;\\r\\n height: auto;\\r\\n border-radius: 14px;\\r\\n cursor: pointer;\\r\\n @media(max-width: 680px) {\\r\\n border-radius: 10px;\\r\\n }\\r\\n @media(max-width: 400px) {\\r\\n border-radius: 8px;\\r\\n }\\r\\n &.selected {\\r\\n border: 3px solid orange;\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n .card-upload {\\r\\n display: flex;\\r\\n margin: 24px 0 7px 0;\\r\\n gap: 27px;\\r\\n\\r\\n @media (max-width: 500px) {\\r\\n display: grid;\\r\\n border: 1px dashed var(--cl--neutral-300);\\r\\n gap: 10px;\\r\\n padding: 16px 0;\\r\\n border-radius: 6px;\\r\\n label.upload-info {\\r\\n grid-row: 2;\\r\\n border: none;\\r\\n img {\\r\\n display: none;\\r\\n }\\r\\n width: 100%;\\r\\n }\\r\\n .imgUpload {\\r\\n grid-row: 1;\\r\\n transform: translateX(-50%);\\r\\n left: 50%;\\r\\n position: relative;\\r\\n }\\r\\n }\\r\\n\\r\\n .upload-info {\\r\\n width: 70%;\\r\\n height: auto;\\r\\n padding: 0;\\r\\n img {\\r\\n margin: 16px 0 0;\\r\\n }\\r\\n }\\r\\n .imgUpload {\\r\\n width: 153px;\\r\\n display: grid;\\r\\n position: relative;\\r\\n i {\\r\\n background-color: var(--cl-r-mint);\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n width: 20px;\\r\\n height: 20px;\\r\\n border-radius: 50%;\\r\\n position: absolute;\\r\\n right: 5px;\\r\\n top: 7px;\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n.mail-customization {\\r\\n .personal-message {\\r\\n .message-details,\\r\\n .add-multimedia-gif {\\r\\n display: block;\\r\\n .switch-label-box {\\r\\n margin: 25px 0 0 0;\\r\\n display: flex;\\r\\n gap: 5px;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n p {\\r\\n font-size: 1.28571rem;\\r\\n }\\r\\n }\\r\\n .msg {\\r\\n --minHeight: 180px;\\r\\n margin: 8px 0 0 0;\\r\\n min-height: var(--minHeight);\\r\\n width: 100%;\\r\\n\\r\\n textarea {\\r\\n min-height: var(--minHeight);\\r\\n padding: 0;\\r\\n }\\r\\n }\\r\\n\\r\\n .remaining-chars {\\r\\n text-align: right;\\r\\n font-size: var(--fs--default);\\r\\n margin: 12px 0px 0 0;\\r\\n }\\r\\n }\\r\\n }\\r\\n .card-cover {\\r\\n display: flex;\\r\\n gap: 24px;\\r\\n margin: 11px 0 0 0;\\r\\n li {\\r\\n display: flex;\\r\\n gap: 9px;\\r\\n }\\r\\n }\\r\\n .card-upload {\\r\\n display: flex;\\r\\n margin: 24px 0 7px 0;\\r\\n gap: 27px;\\r\\n\\r\\n @media (max-width: 500px) {\\r\\n display: grid;\\r\\n border: 1px dashed var(--cl--neutral-300);\\r\\n gap: 10px;\\r\\n padding: 16px 0;\\r\\n border-radius: 6px;\\r\\n label.upload-info {\\r\\n grid-row: 2;\\r\\n border: none;\\r\\n img {\\r\\n display: none;\\r\\n }\\r\\n width: 100%;\\r\\n }\\r\\n .imgUpload {\\r\\n grid-row: 1;\\r\\n transform: translateX(-50%);\\r\\n left: 50%;\\r\\n position: relative;\\r\\n }\\r\\n }\\r\\n\\r\\n .upload-info {\\r\\n width: 70%;\\r\\n height: auto;\\r\\n padding: 0;\\r\\n img {\\r\\n margin: 16px 0 0;\\r\\n }\\r\\n }\\r\\n .imgUpload {\\r\\n width: 153px;\\r\\n display: grid;\\r\\n position: relative;\\r\\n i {\\r\\n background-color: var(--cl-r-mint);\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n width: 20px;\\r\\n height: 20px;\\r\\n border-radius: 50%;\\r\\n position: absolute;\\r\\n right: 5px;\\r\\n top: 7px;\\r\\n }\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n.OptionsCardCub {\\r\\n --optionsCub-radius-box: 8px;\\r\\n .oc-box {\\r\\n box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.1);\\r\\n border-radius: 10px;\\r\\n h3 {\\r\\n font-size: 1.71428571rem;\\r\\n color: var(--cl-r-purple);\\r\\n }\\r\\n h5 {\\r\\n background-color: var(--cl-r-purple);\\r\\n color: var(--cl--white);\\r\\n display: flex;\\r\\n justify-content: flex-start;\\r\\n align-items: center;\\r\\n padding: 14px 0px 10px 23px;\\r\\n font-size: 1.428571rem;\\r\\n border-top-left-radius: var(--optionsCub-radius-box);\\r\\n border-top-right-radius: var(--optionsCub-radius-box);\\r\\n }\\r\\n p {\\r\\n padding: 24px 24px 15px;\\r\\n }\\r\\n img {\\r\\n margin: 0 auto 38px;\\r\\n display: block;\\r\\n @media (max-width: 400px) {\\r\\n width: 100%;\\r\\n height: auto;\\r\\n }\\r\\n }\\r\\n h6 {\\r\\n background-color: var(--cl-r-primary-200);\\r\\n padding: 11px 23px;\\r\\n border-bottom-left-radius: var(--optionsCub-radius-box);\\r\\n border-bottom-right-radius: var(--optionsCub-radius-box);\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n.review-and-pay {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 15px;\\r\\n\\r\\n h5 {\\r\\n font-size: 1.28571rem;\\r\\n line-height: 1.9285714rem;\\r\\n font-weight: var(--fw--bold);\\r\\n color: var(--cl-r-purple);\\r\\n margin: 17px 0 0;\\r\\n letter-spacing: 0.1px;\\r\\n }\\r\\n .sending-to {\\r\\n width: 100%;\\r\\n\\r\\n margin: 12px 0 0;\\r\\n border-top-left-radius: 8px;\\r\\n border-top-right-radius: 10px;\\r\\n border-collapse: separate;\\r\\n border: 1px solid #eaecf0;\\r\\n th {\\r\\n font-size: var(--fs--default);\\r\\n font-weight: var(--fw--medium);\\r\\n padding: 11px 25px;\\r\\n background-color: var(--cl-r-magnolia);\\r\\n &:first-of-type {\\r\\n width: 87%;\\r\\n }\\r\\n &:last-of-type {\\r\\n text-align: right;\\r\\n }\\r\\n }\\r\\n td {\\r\\n font-size: 1.28571rem;\\r\\n line-height: 1.9285714rem;\\r\\n font-weight: var(--fw--bold);\\r\\n padding: 8px 25px;\\r\\n background-color: var(--cl-white);\\r\\n &:last-of-type {\\r\\n font-size: 1.142857rem;\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n .your-info {\\r\\n p {\\r\\n margin: 13px 0 0 0;\\r\\n letter-spacing: 0.1px;\\r\\n }\\r\\n }\\r\\n .send-options {\\r\\n margin: 18px 0 0 2px;\\r\\n ul {\\r\\n display: flex;\\r\\n gap: 22px;\\r\\n li {\\r\\n display: flex;\\r\\n gap: 10px;\\r\\n input {\\r\\n font-weight: var(--fw--medium);\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n .payment-type {\\r\\n .slide-content {\\r\\n input[type=\\\"radio\\\"] {\\r\\n display: none;\\r\\n }\\r\\n }\\r\\n .services {\\r\\n gap: 23px;\\r\\n @media (max-width: 660px) {\\r\\n flex-direction: column;\\r\\n gap: 0;\\r\\n }\\r\\n label {\\r\\n border: 1px solid var(--cl-r-primary-400);\\r\\n width: 48%;\\r\\n padding: 14px 17px;\\r\\n margin: 19px 0 0 0;\\r\\n border-radius: 8px;\\r\\n font-size: var(--fs--default);\\r\\n font-weight: var(--fw--medium);\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: flex-start;\\r\\n gap: 16px;\\r\\n height: 64px;\\r\\n cursor: pointer;\\r\\n @media (max-width: 660px) {\\r\\n width: 100%;\\r\\n }\\r\\n }\\r\\n }\\r\\n .payment-form-content {\\r\\n > div {\\r\\n display: none;\\r\\n margin: 24px 0 0;\\r\\n .form-field {\\r\\n &:nth-of-type(-n + 2) {\\r\\n margin-top: 0;\\r\\n }\\r\\n margin-top: 24px;\\r\\n @media (max-width: 500px) {\\r\\n flex: 1 1 100%;\\r\\n &:nth-of-type(2) {\\r\\n margin-top: 24px;\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n #credit-debit-card:checked ~ .services label:nth-of-type(1),\\r\\n #bank-transfer:checked ~ .services label:nth-of-type(2) {\\r\\n border-color: var(--cl-r-mint);\\r\\n background-color: #f0fdfa;\\r\\n }\\r\\n #credit-debit-card:checked ~ .services label:nth-of-type(1) {\\r\\n svg path {\\r\\n fill: var(--cl-r-mint);\\r\\n }\\r\\n }\\r\\n #bank-transfer:checked ~ .services label:nth-of-type(2) {\\r\\n svg path {\\r\\n stroke: var(--cl-r-mint);\\r\\n }\\r\\n }\\r\\n\\r\\n #credit-debit-card:checked ~ .payment-form-content > div:nth-of-type(1),\\r\\n #bank-transfer:checked ~ .payment-form-content > div:nth-of-type(2) {\\r\\n display: flex;\\r\\n }\\r\\n .terms-conditions {\\r\\n border-top: 1px solid red;\\r\\n margin: 24px 0 0 0;\\r\\n padding-top: 24px;\\r\\n border-color: var(--cl-r-purple);\\r\\n }\\r\\n }\\r\\n\\r\\n .buttons {\\r\\n margin: 26px 0 0;\\r\\n button {\\r\\n margin: 0 !important;\\r\\n }\\r\\n }\\r\\n}\\r\\n.review-pay-box {\\r\\n margin: 20px 0 0;\\r\\n}\\r\\n\",\"body {\\n position: relative;\\n}\\nbody.options-card-bkg::before {\\n content: \\\"\\\";\\n background-image: url(\\\"../../assets/optionsCard-bkg.png\\\");\\n background-attachment: fixed;\\n background-repeat: no-repeat;\\n background-size: cover;\\n height: 100%;\\n width: 100%;\\n position: absolute;\\n z-index: -1;\\n}\\n@media (max-width: 1260px) {\\n body.options-card-bkg::before {\\n background-size: contain;\\n background-position: bottom;\\n }\\n}\\nbody.options-card-bkg section {\\n background-color: transparent !important;\\n}\\n\\n.buy-options-card .container {\\n font-family: var(--ff--dm-sans);\\n}\\n.buy-options-card .container > .flex-container {\\n margin-top: 73px;\\n}\\n.buy-options-card .container > .flex-container .forms {\\n gap: 15px;\\n}\\n.buy-options-card .container input[type=email],\\n.buy-options-card .container input[type=number],\\n.buy-options-card .container input[type=text],\\n.buy-options-card .container select {\\n border-color: var(--cl-r-primary-600);\\n}\\n.buy-options-card .container input[type=checkbox],\\n.buy-options-card .container input[type=radio] {\\n border-color: var(--cl-r-hero-text);\\n}\\n.buy-options-card .container .react-tel-input .form-control {\\n height: 41px;\\n width: 100%;\\n}\\n@media (max-width: 1100px) {\\n .buy-options-card .container .react-tel-input .form-control {\\n height: 38px;\\n }\\n}\\n.buy-options-card .container .react-tel-input .country-list {\\n width: max-content;\\n margin: 0px 0 0px -1px;\\n}\\n.buy-options-card .container .react-tel-input .country-list .country {\\n padding: 5px 9px;\\n}\\n.buy-options-card .container label {\\n margin: 0;\\n font-weight: var(--fw--medium);\\n color: var(--cl-r-primary-900);\\n}\\n.buy-options-card .container .btn__secondary {\\n border-color: var(--cl-r-mint);\\n}\\n.buy-options-card .container .switch-input:checked ~ div .switch .switch__slider {\\n background: var(--cl--primary-800);\\n}\\n.buy-options-card .container .switch-input:checked ~ div .switch .switch__slider::before {\\n transform: translate(22px, -10px);\\n}\\n.buy-options-card .container .buttons {\\n display: flex;\\n gap: 17px;\\n /*@media (max-width: 1260px) {\\n display: none;\\n }*/\\n}\\n.buy-options-card .container .review-and-pay .form-field {\\n flex: 1 1 48%;\\n}\\n\\n.box > input[type=checkbox] {\\n display: none;\\n}\\n.box > input[type=checkbox]:checked ~ .action-card > .show {\\n grid-template-rows: 1fr;\\n}\\n.box > input[type=checkbox]:checked ~ .action-card .slide-content {\\n visibility: visible;\\n}\\n.box > input[type=checkbox]:checked ~ .action-card .box-arrow {\\n top: 4px;\\n transform: rotate(225deg);\\n -webkit-transform: rotate(225deg);\\n}\\n.box > input[type=checkbox]:checked ~ .action-card .head-options div {\\n opacity: 1;\\n visibility: visible;\\n}\\n.box .action-card {\\n display: block;\\n}\\n@media (max-width: 600px) {\\n .box .action-card .how-like-send {\\n flex-direction: column;\\n align-items: flex-start;\\n gap: 16px;\\n }\\n .box .action-card .how-like-send ul {\\n gap: 26px;\\n }\\n}\\n@media (max-width: 350px) {\\n .box .action-card .how-like-send ul {\\n gap: 14px;\\n }\\n}\\n.box .box-heading {\\n display: grid;\\n grid-template-columns: 40px 1fr 15px;\\n align-items: center;\\n gap: 13px;\\n color: var(--cl-r-purple);\\n font-size: var(--heading--desktop-3);\\n}\\n.box .box-heading .box-icon {\\n background-color: var(--cl-r-purple);\\n border-radius: 50%;\\n width: 40px;\\n height: 40px;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.box .box-heading .box-arrow {\\n border: solid var(--cl-r-purple);\\n border-width: 0 2px 2px 0;\\n display: inline-block;\\n transform: rotate(45deg);\\n -webkit-transform: rotate(45deg);\\n position: relative;\\n top: 0;\\n display: block;\\n width: 10px;\\n height: 10px;\\n transition: 0.3s ease;\\n}\\n@media (max-width: 640px) {\\n .box .box-heading .box-icon {\\n grid-column: 1;\\n grid-row: 1;\\n }\\n .box .box-heading .head-options {\\n grid-column: 1/span 2;\\n grid-row: 1/span 2;\\n flex-direction: column;\\n gap: 30px;\\n }\\n .box .box-heading .head-options span {\\n margin: 10px 0 0 53px;\\n }\\n}\\n@media (max-width: 450px) {\\n .box .box-heading .head-options div ul {\\n align-items: flex-start;\\n flex-direction: column;\\n }\\n}\\n.box .box-heading.show-edit-icon {\\n grid-template-columns: 40px 1fr 82px 15px;\\n}\\n.box .box-heading.show-edit-icon .edit-icon {\\n display: flex;\\n gap: 5px;\\n align-items: center;\\n justify-content: center;\\n font-size: 1.28571rem;\\n line-height: 1.9285714rem;\\n font-weight: var(--fw--bold);\\n color: var(--cl-r-primary-900);\\n cursor: pointer;\\n}\\n.box .box-heading .edit-icon {\\n display: none;\\n}\\n\\n.buy-options-card .form-field {\\n margin-top: 16px;\\n flex: initial;\\n}\\n.buy-options-card .form-field.quantity {\\n flex-basis: 16%;\\n}\\n@media (max-width: 530px) {\\n .buy-options-card .form-field.quantity {\\n flex-basis: 48%;\\n }\\n}\\n.buy-options-card .form-field.currency {\\n flex-basis: 27%;\\n}\\n@media (max-width: 530px) {\\n .buy-options-card .form-field.currency {\\n flex-basis: 48%;\\n }\\n}\\n.buy-options-card .form-field.currency input {\\n width: 98%;\\n}\\n.buy-options-card .form-field.currency i {\\n margin-left: 2px;\\n}\\n@media (max-width: 400px) {\\n .buy-options-card .form-field.quantity, .buy-options-card .form-field.currency {\\n flex-basis: auto;\\n }\\n}\\n.buy-options-card .btn {\\n margin-top: 18px;\\n}\\n\\n.recipients .head-options {\\n display: flex;\\n justify-content: space-between;\\n}\\n.recipients .head-options div {\\n visibility: hidden;\\n opacity: 0;\\n transition: 0.3s linear;\\n margin-right: 5px;\\n}\\n.recipients .head-options div ul {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n}\\n.recipients .head-options div ul li {\\n display: flex;\\n gap: 7px;\\n align-items: center;\\n font-size: var(--fs--default);\\n color: var(--cl-r-primary-900);\\n font-weight: var(--fw--medium);\\n}\\n.recipients .head-options div ul li label {\\n letter-spacing: 0.1px;\\n}\\n.recipients .how-like-send {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n border-top: 2px solid #d1d5db;\\n border-bottom: 2px solid #9363d9;\\n margin: 10px 0;\\n padding: 15px 0;\\n}\\n.recipients .how-like-send p {\\n font-size: var(--fs--medium);\\n font-weight: var(--fw--medium);\\n}\\n.recipients .how-like-send ul {\\n display: flex;\\n gap: 33px;\\n align-items: center;\\n}\\n.recipients .how-like-send ul li {\\n display: flex;\\n align-items: center;\\n gap: 7px;\\n}\\n@media (max-width: 326px) {\\n .recipients .how-like-send ul li {\\n gap: 4px;\\n }\\n}\\n.recipients .input-content > ul:first-of-type {\\n display: flex;\\n flex-direction: column;\\n gap: 16px;\\n counter-reset: rs;\\n margin: 16px 0 0;\\n}\\n.recipients .input-content > ul:first-of-type > li {\\n display: grid;\\n grid-template-columns: 10px 1fr 1fr;\\n gap: 15px;\\n border-bottom: 1px solid var(--cl-r-primary-400);\\n padding-bottom: 20px;\\n align-items: center;\\n counter-increment: rs;\\n}\\n.recipients .input-content > ul:first-of-type > li::before {\\n content: counter(rs) \\\".\\\";\\n font-size: var(--fs--large);\\n color: var(--cl-r-purple);\\n font-weight: var(--fw--bold);\\n}\\n.recipients .input-content > ul:first-of-type > li:last-of-type {\\n border: none;\\n}\\n.recipients .input-content > ul:first-of-type > li.full-width {\\n grid-template-columns: 10px 1fr;\\n}\\n@media (max-width: 500px) {\\n .recipients .input-content > ul:first-of-type > li.full-width {\\n grid-template-columns: auto;\\n }\\n}\\n@media (max-width: 500px) {\\n .recipients .input-content > ul:first-of-type > li {\\n grid-template-columns: auto;\\n }\\n}\\n.recipients .btn {\\n margin: 0;\\n}\\n\\n.choose-sender p {\\n color: var(--cl-r-purple);\\n font-size: var(--heading--desktop-5);\\n margin-top: 12px;\\n}\\n\\n.who-from {\\n margin: 6px 0 0;\\n}\\n\\n.summary-box table {\\n width: 100%;\\n margin: 20px 0 0;\\n}\\n.summary-box table tr {\\n background-color: var(--cl-white);\\n}\\n.summary-box table tr:nth-child(2n+1) {\\n background-color: var(--cl-r-primary-100);\\n}\\n.summary-box table tr td {\\n font-size: var(--fs--default);\\n font-weight: var(--fw--medium);\\n color: var(--cl-r-table-fr);\\n padding: 16px 25px;\\n}\\n.summary-box table tr td:last-of-type {\\n text-align: right;\\n}\\n.summary-box table tfoot td:first-of-type {\\n font-weight: var(--fw--bold);\\n}\\n\\n.buy-options-card .container > .flex-container .sidebar {\\n display: flex;\\n flex-direction: column;\\n gap: 15px;\\n}\\n.buy-options-card .container > .flex-container .sidebar .card-animation {\\n filter: drop-shadow(0px 5px 15px rgba(0, 0, 0, 0.1));\\n display: grid;\\n align-items: end;\\n}\\n.buy-options-card .container > .flex-container .sidebar .card-animation img {\\n position: relative;\\n z-index: -1;\\n}\\n.buy-options-card .container > .flex-container .sidebar .box-heading.show-edit-icon {\\n grid-template-columns: 1fr 61px;\\n}\\n\\n.buy-options-card .container > .flex-container .sidebar .my-card {\\n position: initial;\\n}\\n@media (max-width: 1260px) {\\n .buy-options-card .container > .flex-container .sidebar .my-card {\\n z-index: 1;\\n position: initial;\\n }\\n}\\n.buy-options-card .container > .flex-container .sidebar .my-card h3 {\\n color: var(--cl-r-purple);\\n}\\n.buy-options-card .container > .flex-container .sidebar .my-card .card-new {\\n margin: 24px 0 0;\\n}\\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code {\\n display: flex;\\n justify-content: space-between;\\n margin: -1px 0 0 0;\\n color: var(--cl--white);\\n font-size: 1.714rem;\\n font-weight: var(--fw--bold);\\n background: #7844c6;\\n width: 100%;\\n padding: 9% 5% 3%;\\n border-bottom-right-radius: 24px;\\n border-bottom-left-radius: 24px;\\n}\\n@media (max-width: 500px) {\\n .buy-options-card .container > .flex-container .sidebar .my-card .value-and-code {\\n font-size: var(--fs--large);\\n }\\n}\\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .value,\\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .code {\\n position: relative;\\n}\\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .value::before,\\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .code::before {\\n content: attr(data-label);\\n position: absolute;\\n top: calc(-100% - 4px);\\n font-size: var(--fs--medium);\\n}\\n.buy-options-card .container > .flex-container .sidebar .my-card .value-and-code .code::before {\\n right: 0;\\n}\\n.buy-options-card .container > .flex-container .sidebar .my-card .buttons {\\n display: none;\\n}\\n@media (max-width: 1260px) {\\n .buy-options-card .container > .flex-container .sidebar .my-card .buttons {\\n display: block;\\n }\\n .buy-options-card .container > .flex-container .sidebar .my-card .buttons .btn__secondary {\\n border-color: var(--cl--black);\\n }\\n}\\n\\n.card-customization .card-cover {\\n display: flex;\\n gap: 24px;\\n margin: 11px 0 0 0;\\n}\\n.card-customization .card-cover li {\\n display: flex;\\n gap: 9px;\\n}\\n.card-customization .card-templates {\\n display: grid;\\n grid-template-columns: repeat(3, minmax(94px, 191px));\\n margin: 15px 0 0;\\n gap: 13px 12px;\\n}\\n@media (max-width: 400px) {\\n .card-customization .card-templates {\\n gap: 13px 8px;\\n }\\n}\\n@media (max-width: 380px) {\\n .card-customization .card-templates {\\n grid-template-columns: repeat(2, minmax(94px, 191px));\\n }\\n}\\n.card-customization .card-templates img {\\n width: 100%;\\n height: auto;\\n border-radius: 14px;\\n cursor: pointer;\\n}\\n@media (max-width: 680px) {\\n .card-customization .card-templates img {\\n border-radius: 10px;\\n }\\n}\\n@media (max-width: 400px) {\\n .card-customization .card-templates img {\\n border-radius: 8px;\\n }\\n}\\n.card-customization .card-templates img.selected {\\n border: 3px solid orange;\\n}\\n.card-customization .card-upload {\\n display: flex;\\n margin: 24px 0 7px 0;\\n gap: 27px;\\n}\\n@media (max-width: 500px) {\\n .card-customization .card-upload {\\n display: grid;\\n border: 1px dashed var(--cl--neutral-300);\\n gap: 10px;\\n padding: 16px 0;\\n border-radius: 6px;\\n }\\n .card-customization .card-upload label.upload-info {\\n grid-row: 2;\\n border: none;\\n width: 100%;\\n }\\n .card-customization .card-upload label.upload-info img {\\n display: none;\\n }\\n .card-customization .card-upload .imgUpload {\\n grid-row: 1;\\n transform: translateX(-50%);\\n left: 50%;\\n position: relative;\\n }\\n}\\n.card-customization .card-upload .upload-info {\\n width: 70%;\\n height: auto;\\n padding: 0;\\n}\\n.card-customization .card-upload .upload-info img {\\n margin: 16px 0 0;\\n}\\n.card-customization .card-upload .imgUpload {\\n width: 153px;\\n display: grid;\\n position: relative;\\n}\\n.card-customization .card-upload .imgUpload i {\\n background-color: var(--cl-r-mint);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n width: 20px;\\n height: 20px;\\n border-radius: 50%;\\n position: absolute;\\n right: 5px;\\n top: 7px;\\n}\\n\\n.mail-customization .personal-message .message-details,\\n.mail-customization .personal-message .add-multimedia-gif {\\n display: block;\\n}\\n.mail-customization .personal-message .message-details .switch-label-box,\\n.mail-customization .personal-message .add-multimedia-gif .switch-label-box {\\n margin: 25px 0 0 0;\\n display: flex;\\n gap: 5px;\\n align-items: center;\\n justify-content: space-between;\\n}\\n.mail-customization .personal-message .message-details .switch-label-box p,\\n.mail-customization .personal-message .add-multimedia-gif .switch-label-box p {\\n font-size: 1.28571rem;\\n}\\n.mail-customization .personal-message .message-details .msg,\\n.mail-customization .personal-message .add-multimedia-gif .msg {\\n --minHeight: 180px;\\n margin: 8px 0 0 0;\\n min-height: var(--minHeight);\\n width: 100%;\\n}\\n.mail-customization .personal-message .message-details .msg textarea,\\n.mail-customization .personal-message .add-multimedia-gif .msg textarea {\\n min-height: var(--minHeight);\\n padding: 0;\\n}\\n.mail-customization .personal-message .message-details .remaining-chars,\\n.mail-customization .personal-message .add-multimedia-gif .remaining-chars {\\n text-align: right;\\n font-size: var(--fs--default);\\n margin: 12px 0px 0 0;\\n}\\n.mail-customization .card-cover {\\n display: flex;\\n gap: 24px;\\n margin: 11px 0 0 0;\\n}\\n.mail-customization .card-cover li {\\n display: flex;\\n gap: 9px;\\n}\\n.mail-customization .card-upload {\\n display: flex;\\n margin: 24px 0 7px 0;\\n gap: 27px;\\n}\\n@media (max-width: 500px) {\\n .mail-customization .card-upload {\\n display: grid;\\n border: 1px dashed var(--cl--neutral-300);\\n gap: 10px;\\n padding: 16px 0;\\n border-radius: 6px;\\n }\\n .mail-customization .card-upload label.upload-info {\\n grid-row: 2;\\n border: none;\\n width: 100%;\\n }\\n .mail-customization .card-upload label.upload-info img {\\n display: none;\\n }\\n .mail-customization .card-upload .imgUpload {\\n grid-row: 1;\\n transform: translateX(-50%);\\n left: 50%;\\n position: relative;\\n }\\n}\\n.mail-customization .card-upload .upload-info {\\n width: 70%;\\n height: auto;\\n padding: 0;\\n}\\n.mail-customization .card-upload .upload-info img {\\n margin: 16px 0 0;\\n}\\n.mail-customization .card-upload .imgUpload {\\n width: 153px;\\n display: grid;\\n position: relative;\\n}\\n.mail-customization .card-upload .imgUpload i {\\n background-color: var(--cl-r-mint);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n width: 20px;\\n height: 20px;\\n border-radius: 50%;\\n position: absolute;\\n right: 5px;\\n top: 7px;\\n}\\n\\n.OptionsCardCub {\\n --optionsCub-radius-box: 8px;\\n}\\n.OptionsCardCub .oc-box {\\n box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.1);\\n border-radius: 10px;\\n}\\n.OptionsCardCub .oc-box h3 {\\n font-size: 1.71428571rem;\\n color: var(--cl-r-purple);\\n}\\n.OptionsCardCub .oc-box h5 {\\n background-color: var(--cl-r-purple);\\n color: var(--cl--white);\\n display: flex;\\n justify-content: flex-start;\\n align-items: center;\\n padding: 14px 0px 10px 23px;\\n font-size: 1.428571rem;\\n border-top-left-radius: var(--optionsCub-radius-box);\\n border-top-right-radius: var(--optionsCub-radius-box);\\n}\\n.OptionsCardCub .oc-box p {\\n padding: 24px 24px 15px;\\n}\\n.OptionsCardCub .oc-box img {\\n margin: 0 auto 38px;\\n display: block;\\n}\\n@media (max-width: 400px) {\\n .OptionsCardCub .oc-box img {\\n width: 100%;\\n height: auto;\\n }\\n}\\n.OptionsCardCub .oc-box h6 {\\n background-color: var(--cl-r-primary-200);\\n padding: 11px 23px;\\n border-bottom-left-radius: var(--optionsCub-radius-box);\\n border-bottom-right-radius: var(--optionsCub-radius-box);\\n}\\n\\n.review-and-pay {\\n display: flex;\\n flex-direction: column;\\n gap: 15px;\\n}\\n.review-and-pay h5 {\\n font-size: 1.28571rem;\\n line-height: 1.9285714rem;\\n font-weight: var(--fw--bold);\\n color: var(--cl-r-purple);\\n margin: 17px 0 0;\\n letter-spacing: 0.1px;\\n}\\n.review-and-pay .sending-to {\\n width: 100%;\\n margin: 12px 0 0;\\n border-top-left-radius: 8px;\\n border-top-right-radius: 10px;\\n border-collapse: separate;\\n border: 1px solid #eaecf0;\\n}\\n.review-and-pay .sending-to th {\\n font-size: var(--fs--default);\\n font-weight: var(--fw--medium);\\n padding: 11px 25px;\\n background-color: var(--cl-r-magnolia);\\n}\\n.review-and-pay .sending-to th:first-of-type {\\n width: 87%;\\n}\\n.review-and-pay .sending-to th:last-of-type {\\n text-align: right;\\n}\\n.review-and-pay .sending-to td {\\n font-size: 1.28571rem;\\n line-height: 1.9285714rem;\\n font-weight: var(--fw--bold);\\n padding: 8px 25px;\\n background-color: var(--cl-white);\\n}\\n.review-and-pay .sending-to td:last-of-type {\\n font-size: 1.142857rem;\\n}\\n.review-and-pay .your-info p {\\n margin: 13px 0 0 0;\\n letter-spacing: 0.1px;\\n}\\n.review-and-pay .send-options {\\n margin: 18px 0 0 2px;\\n}\\n.review-and-pay .send-options ul {\\n display: flex;\\n gap: 22px;\\n}\\n.review-and-pay .send-options ul li {\\n display: flex;\\n gap: 10px;\\n}\\n.review-and-pay .send-options ul li input {\\n font-weight: var(--fw--medium);\\n}\\n.review-and-pay .payment-type .slide-content input[type=radio] {\\n display: none;\\n}\\n.review-and-pay .payment-type .services {\\n gap: 23px;\\n}\\n@media (max-width: 660px) {\\n .review-and-pay .payment-type .services {\\n flex-direction: column;\\n gap: 0;\\n }\\n}\\n.review-and-pay .payment-type .services label {\\n border: 1px solid var(--cl-r-primary-400);\\n width: 48%;\\n padding: 14px 17px;\\n margin: 19px 0 0 0;\\n border-radius: 8px;\\n font-size: var(--fs--default);\\n font-weight: var(--fw--medium);\\n display: flex;\\n align-items: center;\\n justify-content: flex-start;\\n gap: 16px;\\n height: 64px;\\n cursor: pointer;\\n}\\n@media (max-width: 660px) {\\n .review-and-pay .payment-type .services label {\\n width: 100%;\\n }\\n}\\n.review-and-pay .payment-type .payment-form-content > div {\\n display: none;\\n margin: 24px 0 0;\\n}\\n.review-and-pay .payment-type .payment-form-content > div .form-field {\\n margin-top: 24px;\\n}\\n.review-and-pay .payment-type .payment-form-content > div .form-field:nth-of-type(-n + 2) {\\n margin-top: 0;\\n}\\n@media (max-width: 500px) {\\n .review-and-pay .payment-type .payment-form-content > div .form-field {\\n flex: 1 1 100%;\\n }\\n .review-and-pay .payment-type .payment-form-content > div .form-field:nth-of-type(2) {\\n margin-top: 24px;\\n }\\n}\\n.review-and-pay .payment-type #credit-debit-card:checked ~ .services label:nth-of-type(1),\\n.review-and-pay .payment-type #bank-transfer:checked ~ .services label:nth-of-type(2) {\\n border-color: var(--cl-r-mint);\\n background-color: #f0fdfa;\\n}\\n.review-and-pay .payment-type #credit-debit-card:checked ~ .services label:nth-of-type(1) svg path {\\n fill: var(--cl-r-mint);\\n}\\n.review-and-pay .payment-type #bank-transfer:checked ~ .services label:nth-of-type(2) svg path {\\n stroke: var(--cl-r-mint);\\n}\\n.review-and-pay .payment-type #credit-debit-card:checked ~ .payment-form-content > div:nth-of-type(1),\\n.review-and-pay .payment-type #bank-transfer:checked ~ .payment-form-content > div:nth-of-type(2) {\\n display: flex;\\n}\\n.review-and-pay .payment-type .terms-conditions {\\n border-top: 1px solid red;\\n margin: 24px 0 0 0;\\n padding-top: 24px;\\n border-color: var(--cl-r-purple);\\n}\\n.review-and-pay .buttons {\\n margin: 26px 0 0;\\n}\\n.review-and-pay .buttons button {\\n margin: 0 !important;\\n}\\n\\n.review-pay-box {\\n margin: 20px 0 0;\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, ``, \"\",{\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\",\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, ``, \"\",{\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\",\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.steps-progress-bar {\n --progress_bar_width: 320px;\n --progress_bar_color: #D1D5DB;\n display: flex;\n align-items: center;\n justify-content: space-between;\n position: relative;\n margin: 0 auto;\n width: var(--progress_bar_width);\n}\n@media (max-width: 400px) {\n .steps-progress-bar {\n --progress_bar_width: 280px;\n }\n}\n.steps-progress-bar::before {\n content: \"\";\n border-top: 2px solid var(--progress_bar_color);\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n left: 0;\n width: inherit;\n}\n.steps-progress-bar li {\n z-index: 1;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background-color: #f9fafb;\n border: 1px solid var(--progress_bar_color);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.steps-progress-bar li.active {\n background-color: #41C184;\n position: relative;\n box-shadow: 0 0 0px 4px #E8F4EF;\n}\n.steps-progress-bar li.active svg path {\n fill: var(--cl--white);\n}\n.steps-progress-bar li.active span {\n font-weight: 900;\n}\n.steps-progress-bar li span {\n position: absolute;\n top: 44px;\n width: 95px;\n text-align: center;\n font-size: 16px;\n line-height: 24px;\n font-weight: 500;\n color: var(--cl--neutral-900);\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/scss/stepsProgressBar.scss\"],\"names\":[],\"mappings\":\"AAAA;EACE,2BAAA;EACA,6BAAA;EAEA,aAAA;EACA,mBAAA;EACA,8BAAA;EACA,kBAAA;EACA,cAAA;EACA,gCAAA;AAAF;AACE;EAVF;IAWI,2BAAA;EAEF;AACF;AADE;EACE,WAAA;EACA,+CAAA;EACA,kBAAA;EACA,QAAA;EACA,2BAAA;EACA,OAAA;EACA,cAAA;AAGJ;AADE;EACE,UAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA;EACA,yBAAA;EACA,2CAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;AAGJ;AAFI;EACE,yBAAA;EACA,kBAAA;EACA,+BAAA;AAIN;AAFQ;EACE,sBAAA;AAIV;AADM;EACE,gBAAA;AAGR;AAAI;EACE,kBAAA;EACA,SAAA;EACA,WAAA;EACA,kBAAA;EACA,eAAA;EACA,iBAAA;EACA,gBAAA;EACA,6BAAA;AAEN\",\"sourcesContent\":[\".steps-progress-bar {\\r\\n --progress_bar_width: 320px;\\r\\n --progress_bar_color: #D1D5DB;\\r\\n\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n position: relative;\\r\\n margin: 0 auto;\\r\\n width: var(--progress_bar_width);\\r\\n @media (max-width:400px){\\r\\n --progress_bar_width: 280px;\\r\\n }\\r\\n &::before {\\r\\n content: \\\"\\\";\\r\\n border-top: 2px solid var(--progress_bar_color);\\r\\n position: absolute;\\r\\n top: 50%;\\r\\n transform: translateY(-50%);\\r\\n left: 0;\\r\\n width:inherit;\\r\\n }\\r\\n li {\\r\\n z-index: 1;\\r\\n width: 36px;\\r\\n height: 36px;\\r\\n border-radius: 50%;\\r\\n background-color: #f9fafb;\\r\\n border:1px solid var(--progress_bar_color);\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n &.active {\\r\\n background-color: #41C184;\\r\\n position: relative;\\r\\n box-shadow: 0 0 0px 4px #E8F4EF;\\r\\n svg {\\r\\n path {\\r\\n fill: var(--cl--white);\\r\\n }\\r\\n }\\r\\n span {\\r\\n font-weight: 900;\\r\\n }\\r\\n }\\r\\n span {\\r\\n position: absolute;\\r\\n top: 44px;\\r\\n width: 95px;\\r\\n text-align: center;\\r\\n font-size: 16px;\\r\\n line-height: 24px;\\r\\n font-weight: 500;\\r\\n color: var(--cl--neutral-900);\\r\\n }\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\n import API from \"!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./Application.scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\nif (module.hot) {\n if (!content.locals || module.hot.invalidate) {\n var isEqualLocals = function isEqualLocals(a, b, isNamedExport) {\n if (!a && b || a && !b) {\n return false;\n }\n var p;\n for (p in a) {\n if (isNamedExport && p === \"default\") {\n // eslint-disable-next-line no-continue\n continue;\n }\n if (a[p] !== b[p]) {\n return false;\n }\n }\n for (p in b) {\n if (isNamedExport && p === \"default\") {\n // eslint-disable-next-line no-continue\n continue;\n }\n if (!a[p]) {\n return false;\n }\n }\n return true;\n};\n var isNamedExport = !content.locals;\n var oldLocals = isNamedExport ? namedExport : content.locals;\n\n module.hot.accept(\n \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./Application.scss\",\n function () {\n if (!isEqualLocals(oldLocals, isNamedExport ? namedExport : content.locals, isNamedExport)) {\n module.hot.invalidate();\n\n return;\n }\n\n oldLocals = isNamedExport ? namedExport : content.locals;\n\n update(content);\n }\n )\n }\n\n module.hot.dispose(function() {\n update();\n });\n}\n\n\nexport * from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./Application.scss\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./BuyGiftCardPage.scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\nif (module.hot) {\n if (!content.locals || module.hot.invalidate) {\n var isEqualLocals = function isEqualLocals(a, b, isNamedExport) {\n if (!a && b || a && !b) {\n return false;\n }\n var p;\n for (p in a) {\n if (isNamedExport && p === \"default\") {\n // eslint-disable-next-line no-continue\n continue;\n }\n if (a[p] !== b[p]) {\n return false;\n }\n }\n for (p in b) {\n if (isNamedExport && p === \"default\") {\n // eslint-disable-next-line no-continue\n continue;\n }\n if (!a[p]) {\n return false;\n }\n }\n return true;\n};\n var isNamedExport = !content.locals;\n var oldLocals = isNamedExport ? namedExport : content.locals;\n\n module.hot.accept(\n \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./BuyGiftCardPage.scss\",\n function () {\n if (!isEqualLocals(oldLocals, isNamedExport ? namedExport : content.locals, isNamedExport)) {\n module.hot.invalidate();\n\n return;\n }\n\n oldLocals = isNamedExport ? namedExport : content.locals;\n\n update(content);\n }\n )\n }\n\n module.hot.dispose(function() {\n update();\n });\n}\n\n\nexport * from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./BuyGiftCardPage.scss\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./RegiftCardPage.scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\nif (module.hot) {\n if (!content.locals || module.hot.invalidate) {\n var isEqualLocals = function isEqualLocals(a, b, isNamedExport) {\n if (!a && b || a && !b) {\n return false;\n }\n var p;\n for (p in a) {\n if (isNamedExport && p === \"default\") {\n // eslint-disable-next-line no-continue\n continue;\n }\n if (a[p] !== b[p]) {\n return false;\n }\n }\n for (p in b) {\n if (isNamedExport && p === \"default\") {\n // eslint-disable-next-line no-continue\n continue;\n }\n if (!a[p]) {\n return false;\n }\n }\n return true;\n};\n var isNamedExport = !content.locals;\n var oldLocals = isNamedExport ? namedExport : content.locals;\n\n module.hot.accept(\n \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./RegiftCardPage.scss\",\n function () {\n if (!isEqualLocals(oldLocals, isNamedExport ? namedExport : content.locals, isNamedExport)) {\n module.hot.invalidate();\n\n return;\n }\n\n oldLocals = isNamedExport ? namedExport : content.locals;\n\n update(content);\n }\n )\n }\n\n module.hot.dispose(function() {\n update();\n });\n}\n\n\nexport * from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./RegiftCardPage.scss\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./stepsProgressBar.scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\nif (module.hot) {\n if (!content.locals || module.hot.invalidate) {\n var isEqualLocals = function isEqualLocals(a, b, isNamedExport) {\n if (!a && b || a && !b) {\n return false;\n }\n var p;\n for (p in a) {\n if (isNamedExport && p === \"default\") {\n // eslint-disable-next-line no-continue\n continue;\n }\n if (a[p] !== b[p]) {\n return false;\n }\n }\n for (p in b) {\n if (isNamedExport && p === \"default\") {\n // eslint-disable-next-line no-continue\n continue;\n }\n if (!a[p]) {\n return false;\n }\n }\n return true;\n};\n var isNamedExport = !content.locals;\n var oldLocals = isNamedExport ? namedExport : content.locals;\n\n module.hot.accept(\n \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./stepsProgressBar.scss\",\n function () {\n if (!isEqualLocals(oldLocals, isNamedExport ? namedExport : content.locals, isNamedExport)) {\n module.hot.invalidate();\n\n return;\n }\n\n oldLocals = isNamedExport ? namedExport : content.locals;\n\n update(content);\n }\n )\n }\n\n module.hot.dispose(function() {\n update();\n });\n}\n\n\nexport * from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./stepsProgressBar.scss\";\n export default content && content.locals ? content.locals : undefined;\n","import React, { useEffect, useState } from 'react';\r\nimport { IRegiftCard } from '../models/RegiftCard.model';\r\nimport IKeyValue from '../models/core/KeyValue.interface';\r\nimport { WorkflowTypeEnum } from '../models/enums/WorkflowTypeEnum';\r\nimport { IActivateCardSettings, IAppSettings, ICardSettings, IElavonSettings, IReCaptchaSettings, ITotalProcessingSettings, IWalletSettings } from \"../models/interfaces/AppSettings.interface\";\r\nimport ActivateGiftCardPage from '../pages/ActivateGiftCardPage';\r\nimport BuyGiftCardPageNew from '../pages/BuyGiftCardPageNew';\r\nimport RegiftCardPage from '../pages/RegiftCardPage';\r\nimport DataService from '../services/DataService.service';\r\nimport './Application.scss';\r\nimport LoadingComponent from \"./shared/LoadingComponent\";\r\n//import _cloneDeep from 'lodash/cloneDeep';\r\n\r\n// Global context of all app settings: culture, labels, general pages and links\r\nexport const AppSettingContext = React.createContext({} as IAppSettings);\r\n\r\n// Global context of RegiftCard page\r\nexport const RegiftCardContext = React.createContext({} as IRegiftCard);\r\n\r\nconst Application = () => {\r\n const [appSettings, setAppSettings] = useState({} as IAppSettings);\r\n const [appWorkflowType, setAppWorkflowType] = useState(WorkflowTypeEnum.BUY_GIFT_CARD);\r\n const [isLoading, setIsLoading] = useState(true); //set to true to delay child components rendering\r\n\r\n // Check app variant based on global app element and its data attribute: data-app-step\r\n const appElement = document.getElementById('app');\r\n const appStep = appElement?.getAttribute(\"data-app-step\"); // buy-gift, regift, activate-giftcard\r\n\r\n // Load app settings\r\n useEffect(() => {\r\n if (appStep.toLowerCase() === \"regift\") {\r\n setAppWorkflowType(WorkflowTypeEnum.REGIFT_CARD);\r\n } else if (appStep.toLowerCase() === \"activate-giftcard\") {\r\n setAppWorkflowType(WorkflowTypeEnum.ACTIVATE_GIFTCARD);\r\n }\r\n\r\n const culture = appElement?.getAttribute(\"data-culture\");\r\n const settingsNodeId = appElement?.getAttribute(\"data-settings-node-id\");\r\n\r\n // Initialize global AppContext \r\n DataService.getAppSettings(culture, settingsNodeId)\r\n .then(result => {\r\n const _appSettings = {} as IAppSettings;\r\n _appSettings.debugMode = false;\r\n _appSettings.culture = culture;\r\n _appSettings.labels = new Map();\r\n _appSettings.cardSettings = {} as ICardSettings;\r\n _appSettings.tpSettings = {} as ITotalProcessingSettings;\r\n _appSettings.elavonSettings = {} as IElavonSettings;\r\n _appSettings.activateSettings = {} as IActivateCardSettings;\r\n _appSettings.walletSettings = {} as IWalletSettings;\r\n _appSettings.reCaptchaSettings = {} as IReCaptchaSettings;\r\n\r\n if (result) {\r\n _appSettings.debugMode = result.debugMode;\r\n _appSettings.culture = result.culture;\r\n _appSettings.links = result.links;\r\n _appSettings.cardSettings = result.cardSettings;\r\n\r\n _appSettings.tpSettings = result.tpSettings;\r\n _appSettings.elavonSettings = result.elavonSettings;\r\n _appSettings.activateSettings = result.activateSettings;\r\n _appSettings.walletSettings = result.walletSettings;\r\n _appSettings.reCaptchaSettings = result.reCaptchaSettings;\r\n\r\n if (result.labels) {\r\n result.labels.forEach((k: IKeyValue, i: number) => {\r\n if (!_appSettings.labels.has(k.key)) {\r\n _appSettings.labels.set(k.key, k.value);\r\n }\r\n });\r\n }\r\n }\r\n\r\n setAppSettings(_appSettings);\r\n }).catch(error => {\r\n console.error(error);\r\n }).finally(() => {\r\n setIsLoading(false);\r\n });\r\n }, []);\r\n\r\n return (\r\n /* When running in React.StrictMode, all child components down the tree are rendered twice - simultaneously */\r\n /**/\r\n <>\r\n {isLoading && (\r\n \r\n )}\r\n\r\n {(!isLoading && appSettings.labels.has(\"GiftCard.App.Steps.ChooseCard\")) && (\r\n \r\n {(appWorkflowType === WorkflowTypeEnum.BUY_GIFT_CARD) && (\r\n /**/\r\n \r\n )}\r\n\r\n {appWorkflowType === WorkflowTypeEnum.REGIFT_CARD && (\r\n \r\n )}\r\n\r\n {appWorkflowType === WorkflowTypeEnum.ACTIVATE_GIFTCARD && (\r\n \r\n )}\r\n \r\n )}\r\n \r\n /**/\r\n );\r\n}\r\n\r\nexport default Application;","import React from \"react\";\r\ninterface ILabeledCheckboxProps {\r\n id: string;\r\n checked: boolean;\r\n onChange(checked: boolean): void;\r\n cssClass: string;\r\n labelCssClass: string;\r\n lableTitle: string;\r\n}\r\n\r\nconst LabeledCheckbox = (props: ILabeledCheckboxProps) => {\r\n return (\r\n <>\r\n props.onChange(e.target.checked)}\r\n />\r\n \r\n \r\n );\r\n};\r\nexport default LabeledCheckbox;","import React, { useContext, useEffect, useState } from \"react\";\r\nimport { isVideoFile } from \"../../helpers/Utils\";\r\nimport { BuyGiftCardSubpageEnum } from \"../../models/enums/BuyGiftCardSubpageEnum\";\r\nimport { AppSettingContext } from \"../Application\";\r\n\r\ntype BuyGiftCardMailTemplateProps = {\r\n subpage: BuyGiftCardSubpageEnum;\r\n personalMessage: string;\r\n mediaUrl: string;\r\n}\r\n\r\nconst BuyGiftCardMailTemplate = (props: BuyGiftCardMailTemplateProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [personalMessage, setPersonalMessage] = useState(labels.get(\"GiftCard.App.Steps.Customise.PersonalMessage.DefaultText\"));\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setPersonalMessage(props.personalMessage);\r\n }, [props.personalMessage]);\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const encodeHTML = (input: string): string => {\r\n return input.replace(/&/g, '&')\r\n .replace(//g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n
\r\n

{labels.get(\"GiftCard.App.V2.Sidebar.Mail.Title\")}

\r\n
\r\n
{labels.get(\"GiftCard.App.V2.Sidebar.Mail.Subtitle\")}
\r\n

\r\n\r\n {props.mediaUrl.trim() && (\r\n
\r\n
\r\n {isVideoFile(props.mediaUrl) ? (\r\n \r\n ) : (\r\n \r\n )}\r\n
\r\n
\r\n )}\r\n\r\n
{labels.get(\"GiftCard.App.V2.Sidebar.Mail.FooterText\")}
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default BuyGiftCardMailTemplate;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport * as GlobalConstants from \"../../constants/global\";\r\nimport { findLinkByAlias } from \"../../helpers/GiftCardHelper\";\r\nimport { CheckBalanceStepModel, ICheckBalanceStep } from \"../../models/CheckBalanceStep.model\";\r\nimport ILink from \"../../models/core/Link.interface\";\r\nimport { IBaseStepProps } from \"../../models/props/BaseStepProps.interface\";\r\nimport { RegiftCardContext } from \"../../pages/RegiftCardPage\";\r\nimport DataService from \"../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../Application\";\r\nimport ErrorComponent from \"../shared/ErrorComponent\";\r\nimport LoadingComponent from \"../shared/LoadingComponent\";\r\n\r\ninterface ICheckMyBalanceStepProps extends IBaseStepProps {\r\n handleCheckBalance(model: ICheckBalanceStep): void;\r\n handleSubmit(model: ICheckBalanceStep): void;\r\n}\r\n\r\nconst CheckMyBalanceStep = (props: ICheckMyBalanceStepProps) => {\r\n const { checkBalanceStep } = useContext(RegiftCardContext);\r\n const { debugMode, labels, links, reCaptchaSettings } = useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [culture, setCulture] = useState('en-GB');\r\n const [pageModel, setPageModel] = useState(undefined);\r\n const [hasToShowBalance, setHasToShowBalance] = useState(false);\r\n const [formattedBalance, setFormattedBalance] = useState(\"\");\r\n const [redeemCodeLink, setRedeemCodeLink] = useState({\r\n url: \"https://redeem.ovationincentives.com/\",\r\n alias: \"\",\r\n targetBlank: false,\r\n title: \"Redeem\"\r\n });\r\n\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [pageError, setPageError] = useState(null);\r\n\r\n const [isButtonWaiting, setIsButtonWaiting] = useState(false);\r\n const [checkCardErrorMessage, setCheckCardErrorMessage] = useState(\"\");\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (checkboxRef && checkboxRef.current) {\r\n checkboxRef.current.checked = true;\r\n }\r\n });\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n setCulture(document.documentElement.lang);\r\n\r\n const redeemLink = findLinkByAlias(GlobalConstants.PAGE_LINKS.REDEEM_CODE, links);\r\n if (redeemLink && redeemLink.url.trim()) {\r\n setRedeemCodeLink(redeemLink);\r\n }\r\n\r\n setPageModel({ ...checkBalanceStep });\r\n }, []);\r\n\r\n useEffect(() => {\r\n setIsLoading(false);\r\n\r\n if (hasToShowBalance) {\r\n let balance = labels.get(\"GiftCard.App.Steps.CheckBalance.BalanceRemaining\");\r\n balance = balance.replace(\"{0}\", `${pageModel.currencySymbol}${pageModel.remainingBalance.toFixed(2)}`);\r\n setFormattedBalance(balance);\r\n }\r\n\r\n props.handleDirtyState(isModelDirty());\r\n }, [pageModel]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleExpandBoxCheck = () => {\r\n if (checkboxRef.current.checked) {\r\n props.handleBeginEdit();\r\n }\r\n };\r\n\r\n const handleCheckBalance = () => {\r\n setIsButtonWaiting(true);\r\n setCheckCardErrorMessage(\"\");\r\n\r\n // @ts-ignore\r\n window.grecaptcha.ready(() => {\r\n // @ts-ignore\r\n window.grecaptcha.execute(\r\n reCaptchaSettings.reCaptchaPublicKey, {\r\n action: 'check_balance'\r\n }).then(async (token: string) => {\r\n // proceed with check balance\r\n let baskedId = localStorage.getItem(GlobalConstants.LOCALSTORAGE_KEY_BASKET_ID);\r\n if (!baskedId) {\r\n baskedId = \"\";\r\n }\r\n\r\n DataService.checkCardBalance(culture, baskedId, pageModel.giftCardCode, token)\r\n .then(response => {\r\n if (typeof response === \"string\") {\r\n setCheckCardErrorMessage(response);\r\n } else {\r\n if (response && response.id && response.id > 0) {\r\n const copyModel = { ...pageModel };\r\n copyModel.currencySymbol = response.currencySymbol;\r\n copyModel.remainingBalance = response.amount;\r\n copyModel.redeemCode = response.redeemCode;\r\n\r\n props.handleCheckBalance(copyModel);\r\n\r\n setHasToShowBalance(true);\r\n setPageModel(copyModel);\r\n setIsButtonWaiting(false);\r\n } else {\r\n setCheckCardErrorMessage(labels.get(\"GiftCard.App.Steps.CheckBalance.Error.InvalidCode\"));\r\n setTimeout(() => {\r\n setIsButtonWaiting(false);\r\n }, 1000);\r\n }\r\n }\r\n }).catch(error => {\r\n console.error(error);\r\n setPageError(\"An error occurred while checking giftcard code.\");\r\n });\r\n });\r\n });\r\n };\r\n\r\n const handleCardCodeChange = (e: React.ChangeEvent) => {\r\n setHasToShowBalance(false);\r\n setPageModel({\r\n ...pageModel,\r\n giftCardCode: e.target.value.toUpperCase()\r\n });\r\n };\r\n\r\n const handleSubmit = (event: React.MouseEvent) => {\r\n event.preventDefault();\r\n props.handleSubmit({\r\n currencySymbol: pageModel.currencySymbol,\r\n giftCardCode: pageModel.giftCardCode,\r\n remainingBalance: pageModel.remainingBalance,\r\n redeemCode: pageModel.redeemCode,\r\n isDirty: false\r\n });\r\n\r\n checkboxRef.current.checked = false;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const isValid = (): boolean => {\r\n return CheckBalanceStepModel.validateModel(pageModel);\r\n };\r\n\r\n const isModelDirty = (): boolean => {\r\n if (!pageModel) {\r\n return false;\r\n }\r\n\r\n if (pageModel.giftCardCode != checkBalanceStep.giftCardCode) {\r\n return true;\r\n }\r\n\r\n if (pageModel.remainingBalance != checkBalanceStep.remainingBalance) {\r\n return true;\r\n }\r\n\r\n if (pageModel.currencySymbol != checkBalanceStep.currencySymbol) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n //#endregion\r\n\r\n return (\r\n <>\r\n {pageError ? (\r\n \r\n ) : (\r\n
\r\n \r\n
\r\n

{labels.get(\"GiftCard.App.Steps.CheckBalance\")}

\r\n
\r\n \r\n
\r\n
\r\n {(isLoading) ? (\r\n \r\n ) : (\r\n
\r\n {debugMode &&\r\n
\r\n

Card code: {pageModel.giftCardCode}

\r\n

Balance: {pageModel.remainingBalance}

\r\n

Currency: {pageModel.currencySymbol}

\r\n

Has to show balance: {String(hasToShowBalance)}

\r\n
\r\n

Is dirty: {String(isModelDirty())}

\r\n

Is valid: {String(isValid())}

\r\n
\r\n }\r\n\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n {isButtonWaiting ? (\r\n \r\n ) : (\r\n labels.get(\"GiftCard.App.Steps.CheckBalance.Btn.CheckBalance\")\r\n )}\r\n \r\n
\r\n
\r\n\r\n {checkCardErrorMessage && (\r\n
\r\n {checkCardErrorMessage}\r\n
\r\n )}\r\n\r\n {hasToShowBalance &&\r\n
0 ? \"balance balance--active fadeIn\" : \"balance balance--inactive fadeIn\"}>\r\n \r\n \r\n \r\n

{formattedBalance}

\r\n \r\n \r\n \r\n
\r\n }\r\n\r\n
{labels.get(\"GiftCard.App.Steps.CheckBalance.DescriptionTitle\")}
\r\n

{labels.get(\"GiftCard.App.Steps.CheckBalance.DescriptionBody\")}

\r\n \r\n {labels.get(\"GiftCard.App.Steps.CheckBalance.Btn.Regift\")}\r\n \r\n\r\n {pageModel.redeemCode.trim() && (\r\n \r\n {labels.get(\"GiftCard.App.Steps.CheckBalance.Btn.Redeem\")}\r\n \r\n )}\r\n
\r\n )}\r\n
\r\n
\r\n
\r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default CheckMyBalanceStep;","import React, { useEffect, useState } from \"react\";\r\nimport { BuyGiftCardSubpageEnum } from '../../../src/models/enums/BuyGiftCardSubpageEnum';\r\nimport { isVideoFile } from \"../../helpers/Utils\";\r\nimport { ICheckBalanceStep } from \"../../models/CheckBalanceStep.model\";\r\nimport { AppSettingContext } from \"../Application\";\r\nimport LoadingComponent from \"../shared/LoadingComponent\";\r\nimport BuyGiftCardMailTemplate from \"./BuyGiftCardMailTemplate\";\r\n\r\ninterface IGiftCardDetails {\r\n isSaving: boolean;\r\n subpage?: BuyGiftCardSubpageEnum,\r\n cardValue: number;\r\n\r\n giftCardUrl: string;\r\n initialTemplateUrl: string;\r\n previewTemplateUrl: string;\r\n previewMediaUrl: string;\r\n previewPersonalMessage: string;\r\n\r\n regiftData?: ICheckBalanceStep;\r\n}\r\n\r\nconst GiftCardDetails = (props: IGiftCardDetails) => {\r\n const { labels, walletSettings } = React.useContext(AppSettingContext);\r\n\r\n const isVideo = isVideoFile(props.previewMediaUrl);\r\n const defaultPersonalMessageText = labels.get(\"GiftCard.App.Steps.Customise.PersonalMessage.DefaultText\");\r\n const personalMessage = props.previewPersonalMessage === defaultPersonalMessageText ? \"\" : props.previewPersonalMessage;\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [animationStarted, setAnimationStarted] = useState(false);\r\n const [templateUrl, setTemplateUrl] = useState(props.previewTemplateUrl ? props.previewTemplateUrl : props.initialTemplateUrl);\r\n const [isLoading, setIsLoading] = useState(true);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsLoading(false);\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (props.previewTemplateUrl.trim()) {\r\n if (!animationStarted) {\r\n setAnimationStarted(true);\r\n setTimeout(() => {\r\n setTemplateUrl(props.previewTemplateUrl);\r\n }, 200);\r\n }\r\n else {\r\n setIsLoading(true);\r\n setTimeout(() => {\r\n setTemplateUrl(props.previewTemplateUrl);\r\n setIsLoading(false);\r\n }, 200);\r\n }\r\n }\r\n }, [props.previewTemplateUrl]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const encodeHTML = (input: string): string => {\r\n return input.replace(/&/g, '&')\r\n .replace(//g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n <>\r\n {!props.subpage && (\r\n \r\n )}\r\n\r\n
\r\n
\r\n

{labels.get(\"GiftCard.App.V2.Sidebar.MyCard.Title\")}

\r\n
\r\n
\r\n
\r\n {templateUrl && (\r\n
\r\n \"Options\r\n\r\n {props.regiftData ? (\r\n
\r\n \r\n {`${props.regiftData.currencySymbol}${props.regiftData.remainingBalance.toFixed(2)}`}\r\n \r\n \r\n {props.regiftData.redeemCode}\r\n \r\n
\r\n ) : (\r\n
\r\n €{props.cardValue.toFixed(2)}\r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n\r\n {(props.regiftData && props.regiftData.redeemCode) && (\r\n
\r\n {walletSettings.appleWalletUrl && (\r\n \r\n \"Apple\r\n \r\n )}\r\n\r\n {walletSettings.googleWalletUrl && (\r\n \r\n \"Google\r\n \r\n )}\r\n
\r\n )}\r\n
\r\n\r\n {isLoading ? (\r\n \r\n ) : (\r\n <>\r\n {!props.subpage && (personalMessage.trim() || props.previewMediaUrl.trim()) && (\r\n
\r\n
\r\n {personalMessage.trim() && (\r\n

\r\n )}\r\n\r\n {props.previewMediaUrl.trim() && (\r\n
\r\n
\r\n {(isVideo) ? (\r\n \r\n ) : (\r\n \r\n )}\r\n
\r\n
\r\n )}\r\n
\r\n
\r\n )}\r\n \r\n )}\r\n\r\n {props.subpage && props.subpage !== BuyGiftCardSubpageEnum.CHOOSE_CARD && (\r\n \r\n )}\r\n\r\n {!props.subpage &&\r\n
\r\n {labels.get(\"GiftCard.App.V2.Sidebar.MyCard.BottomText\")}\r\n
\r\n }\r\n
\r\n \r\n );\r\n};\r\n\r\nexport default GiftCardDetails;","import React, { useState, useRef, useEffect } from \"react\";\r\nimport IRecipientDetailsProps from \"@src/models/props/RecipientDetailsProps.interface\";\r\nimport { GiftCardSendTypeEnum } from \"../../models/enums/GiftCardSendTypeEnum\";\r\nimport { AppSettingContext } from \"../Application\";\r\nimport { IRecipientDetails } from \"../../models/RecipientDetails.model\";\r\nimport { isEmail, hasXSSCharacters } from \"../../helpers/Utils\";\r\nimport PhoneInput, { CountryData } from \"react-phone-input-2\";\r\nimport \"react-phone-input-2/lib/style.css\";\r\nimport { PHONE_NUMBER, PhoneValidationRegexKeys } from \"../../constants/global\";\r\n\r\nconst RecipientDetails = (props: IRecipientDetailsProps) => {\r\n const ref = useRef(true);\r\n\r\n const { labels } = React.useContext(AppSettingContext);\r\n\r\n const [firstName, setFirstName] = useState(props.model.firstName);\r\n const [lastName, setLastName] = useState(props.model.lastName);\r\n const [email, setEmail] = useState(props.model.email);\r\n const [phone, setPhone] = useState(props.model.phone);\r\n\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n const phoneNumberMaxLength = PHONE_NUMBER.VALIDATIONS.MAXLENGTH;\r\n\r\n const phoneInputDropdowns = document.querySelectorAll('.flag-dropdown') as NodeListOf;\r\n const phoneNumberErrorMessages = document.querySelectorAll('.invalid-number-message') as NodeListOf;\r\n\r\n useEffect(() => {\r\n const firstRender = ref.current;\r\n if (firstRender) {\r\n ref.current = false;\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (phoneInputDropdowns && phoneInputDropdowns.length > 0) {\r\n phoneInputDropdowns.forEach(dropdown => {\r\n dropdown.style.borderColor = '#1f2937';\r\n dropdown.style.borderRightColor = '#cacaca';\r\n });\r\n }\r\n\r\n if (phoneNumberErrorMessages && phoneNumberErrorMessages.length > 0) {\r\n phoneNumberErrorMessages.forEach(errorMessage => {\r\n errorMessage.style.left = '0';\r\n errorMessage.style.top = '42px';\r\n errorMessage.classList.add(\"react-input-error-message\");\r\n });\r\n }\r\n }, [phoneInputDropdowns, phoneNumberErrorMessages]);\r\n\r\n useEffect(() => {\r\n const firstRender = ref.current;\r\n if (firstRender == false) {\r\n propagateChanges();\r\n } \r\n }, [firstName, lastName, email, phone]);\r\n\r\n const propagateChanges = () => {\r\n props.handleModelUpdate({\r\n firstName: firstName,\r\n lastName: lastName,\r\n email: email,\r\n phone: phone\r\n } as IRecipientDetails);\r\n };\r\n\r\n if (error) throw error;\r\n return (\r\n
\r\n
{labels.get(\"GiftCard.App.Steps.Recepients.Fields.Recipient\")} {props.index}
\r\n
\r\n
\r\n \r\n {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n } else {\r\n if (!event.target.value.trim()) {\r\n props.model.firstNameIsValid = false;\r\n } else {\r\n props.model.firstNameIsValid = true;\r\n }\r\n\r\n setFirstName(event.target.value);\r\n }\r\n }}\r\n maxLength={150}\r\n name=\"recipients__first-name\" id=\"recipients__first-name\"\r\n placeholder={labels.get(\"GiftCard.App.Steps.Recepients.Fields.RecipientFirstName.Placeholder\")}\r\n className={props.model.firstNameIsValid === false ? \"react-input-error\" : \"\"}\r\n />\r\n {props.model.firstNameIsValid === false &&\r\n
\r\n {labels.get(\"GiftCard.App.Steps.Recepients.Fields.RecipientFirstName.ErrorMessage\")}\r\n
\r\n }\r\n
\r\n
\r\n \r\n {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n } else {\r\n if (!event.target.value.trim()) {\r\n props.model.lastNameIsValid = false;\r\n } else {\r\n props.model.lastNameIsValid = true;\r\n }\r\n\r\n setLastName(event.target.value);\r\n }\r\n }}\r\n maxLength={150}\r\n name=\"recipients__last-name\" id=\"recipients__last-name\"\r\n placeholder={labels.get(\"GiftCard.App.Steps.Recepients.Fields.RecipientLastName.Placeholder\")}\r\n className={props.model.lastNameIsValid === false ? \"react-input-error\" : \"\"}\r\n />\r\n {props.model.lastNameIsValid === false &&\r\n
\r\n {labels.get(\"GiftCard.App.Steps.Recepients.Fields.RecipientLastName.ErrorMessage\")}\r\n
\r\n }\r\n
\r\n\r\n {props.sendBy == GiftCardSendTypeEnum.BY_EMAIL &&\r\n
\r\n \r\n {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n } else {\r\n if (!isEmail(event.target.value)) {\r\n props.model.emailIsValid = false;\r\n } else {\r\n props.model.emailIsValid = true;\r\n }\r\n\r\n setEmail(event.target.value);\r\n }\r\n }}\r\n name=\"recipients__email\" id=\"recipients__email\"\r\n placeholder={labels.get(\"GiftCard.App.Steps.Recepients.Fields.RecipientEmail.Placeholder\")}\r\n className={props.model.emailIsValid === false ? \"react-input-error\" : \"\" }\r\n />\r\n {props.model.emailIsValid === false &&\r\n
\r\n {labels.get(\"GiftCard.App.Steps.Recepients.Fields.RecipientEmail.ErrorMessage\")}\r\n
\r\n }\r\n
\r\n }\r\n\r\n {props.sendBy == GiftCardSendTypeEnum.BY_SMS &&\r\n
\r\n \r\n
\r\n c.toLowerCase())}\r\n countryCodeEditable={false}\r\n value={phone}\r\n onChange={(phone) => {\r\n if (phone.length > phoneNumberMaxLength) {\r\n phone = phone.slice(0, phoneNumberMaxLength)\r\n }\r\n \r\n setPhone(`+${phone}`);\r\n }}\r\n isValid={(inputNumber, data: CountryData) => {\r\n if (!data || !data.iso2) {\r\n return false;\r\n }\r\n\r\n const allowedCountriesAbbr = Object.keys(PHONE_NUMBER.COUNTRIES).map(c => c.toLowerCase());\r\n if (allowedCountriesAbbr.includes(data.iso2.toLowerCase())) {\r\n const regexKey = data.iso2.toUpperCase() as PhoneValidationRegexKeys;\r\n const regex = PHONE_NUMBER.VALIDATIONS.REGEX[regexKey] as RegExp;\r\n\r\n if (regex) {\r\n return regex.test(phone);\r\n }\r\n }\r\n\r\n return false;\r\n }}\r\n inputClass='react-phone-input'\r\n defaultErrorMessage={labels.get(\"GiftCard.App.Steps.Recepients.Fields.RecipientPhone.ErrorMessage\")}\r\n enableLongNumbers={phoneNumberMaxLength}\r\n />\r\n
\r\n
\r\n }\r\n
\r\n
\r\n )\r\n}\r\n\r\nexport default RecipientDetails;","import { WorkflowTypeEnum } from \"@src/models/enums/WorkflowTypeEnum\";\r\nimport { IBuyGiftCustomizeStepProps } from \"@src/models/props/CustomizeStepProps.interface\";\r\nimport React, { useState } from \"react\";\r\nimport { RegiftCardStateEnum } from \"../../models/enums/RegiftCardStateEnum\";\r\nimport { RegiftCardContext } from \"../../pages/RegiftCardPage\";\r\nimport CustomizeStep from \"./shared/CustomizeStep\";\r\nimport { CheckBalanceStepModel } from \"../../models/CheckBalanceStep.model\";\r\nimport { RegiftCardStepModel } from \"../../models/RegiftCardStep.model\";\r\nimport { RecipientsStepModel } from \"../../models/RecipientsStep.model\";\r\n\r\nconst RegiftCardCustomizeStep = (props: IBuyGiftCustomizeStepProps) => {\r\n\r\n const { id, currentState, checkBalanceStep, regiftCardStep, recipientsStep, customizeStep } = React.useContext(RegiftCardContext);\r\n const [error, setError] = useState(null);\r\n\r\n const [model, setModel] = useState(customizeStep);\r\n\r\n const IS_ACTIVE = (checkBalanceStep && CheckBalanceStepModel.validateModel(checkBalanceStep) && !checkBalanceStep.isDirty)\r\n && (regiftCardStep && RegiftCardStepModel.validateModel(regiftCardStep, checkBalanceStep.remainingBalance) && !regiftCardStep.isDirty)\r\n && (recipientsStep && RecipientsStepModel.validateModel(recipientsStep, WorkflowTypeEnum.REGIFT_CARD) && !recipientsStep.isDirty);\r\n\r\n if (error) throw error;\r\n return (\r\n <>\r\n {!props.isSaving &&\r\n }\r\n \r\n )\r\n}\r\n\r\nexport default RegiftCardCustomizeStep;","import { AppSettingContext, RegiftCardContext } from \"@src/components/Application\";\r\nimport { IBuyGiftPaymentStepProps, IRegiftPaymentStepProps } from \"@src/models/props/PaymentStepProps.interface\";\r\nimport React, { useEffect, useRef, useState } from \"react\";\r\nimport { PAGE_LINKS } from \"../../constants/global\";\r\nimport { findLinkByAlias } from \"../../helpers/GiftCardHelper\";\r\nimport { BuyGiftCardModelOld } from \"../../models/BuyGiftCard.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../models/enums/BuyGiftCardStateEnum\";\r\nimport { PaymentTypeEnum } from \"../../models/enums/PaymentTypeEnum\";\r\nimport { IPaymentStep, PaymentStepModel } from \"../../models/PaymentStep.model\";\r\nimport { BuyGiftCardContext } from \"../../pages/BuyGiftCardPage\";\r\nimport DataService from \"../../services/DataService.service\";\r\nimport LoadingComponent from \"../shared/LoadingComponent\";\r\nimport SelectPaymentMethod from \"./SelectPaymentMethod\";\r\nimport BasketDetails from \"./shared/BasketDetails\";\r\nimport * as GlobalConstants from \"@src/constants/global\";\r\nimport StripePayment from \"./shared/StripePayment\";\r\nimport { CheckBalanceStepModel } from \"../../models/CheckBalanceStep.model\";\r\nimport { RegiftCardStepModel } from \"../../models/RegiftCardStep.model\";\r\nimport { RecipientsStepModel } from \"../../models/RecipientsStep.model\";\r\nimport { CustomizeStepModel } from \"../../models/CustomizeStep.model\";\r\nimport { IRegiftPaymentStep, RegiftPaymentStepModel } from \"../../models/RegiftPaymentStep.model\";\r\nimport { RegiftCardStateEnum } from \"../../models/enums/RegiftCardStateEnum\";\r\nimport { WorkflowTypeEnum } from \"../../models/enums/WorkflowTypeEnum\";\r\n\r\n\r\nconst RegiftCardPaymentStep = (props: IRegiftPaymentStepProps) => {\r\n\r\n const { id, currentState, checkBalanceStep, regiftCardStep, recipientsStep, customizeStep, paymentStep } = React.useContext(RegiftCardContext);\r\n const { debugMode, links, labels } = React.useContext(AppSettingContext);\r\n\r\n const IS_ACTIVE = (checkBalanceStep && CheckBalanceStepModel.validateModel(checkBalanceStep) && !checkBalanceStep.isDirty)\r\n && (regiftCardStep && RegiftCardStepModel.validateModel(regiftCardStep, checkBalanceStep.remainingBalance) && !regiftCardStep.isDirty)\r\n && (recipientsStep && RecipientsStepModel.validateModel(recipientsStep, WorkflowTypeEnum.REGIFT_CARD) && !recipientsStep.isDirty)\r\n && (customizeStep && CustomizeStepModel.validateModel(customizeStep) && !customizeStep.isDirty);\r\n\r\n const [pageModel, setPageModel] = useState(undefined);\r\n const [isDirty, setIsDirty] = useState(false);\r\n const [isSaving, setIsSaving] = useState(false);\r\n\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState(null);\r\n\r\n const checkboxRef = useRef(null)\r\n const termsPageUrl = findLinkByAlias(\"terms-page\", links);\r\n const termsLink = labels.get(\"GiftCard.App.Steps.PreviewAndPay.TermsAndConditions\").replace(\"{0}\", termsPageUrl.url ?? \"\");\r\n const defaultPersonalMessageText = labels.get(\"GiftCard.App.Steps.Customise.PersonalMessage.DefaultText\");\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.state == RegiftCardStateEnum.REVIEW_PAY || IS_ACTIVE;\r\n });\r\n\r\n useEffect(() => {\r\n\r\n //local model initialization\r\n setIsLoading(true);\r\n //console.debug(\"paymentStep\", props.giftCard.paymentStep);\r\n\r\n // Page Model\r\n setPageModel({ ...props.giftCard.paymentStep });\r\n }, []);\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n if (pageModel) {\r\n setIsLoading(false);\r\n\r\n const result = checkIfModelIsDirty();\r\n setIsDirty(result);\r\n props.handleDirtyState(result);\r\n }\r\n }, [pageModel]);\r\n\r\n useEffect(() => {\r\n if (error) {\r\n props.handleError(error);\r\n }\r\n }, [error]);\r\n\r\n const isValid = () => {\r\n let copyPageModel = { ...pageModel };\r\n return RegiftPaymentStepModel.validateModel(copyPageModel);\r\n };\r\n\r\n const checkIfModelIsDirty = (): boolean => {\r\n if (!pageModel) return false;\r\n\r\n // check\r\n if (!pageModel.termsAccepted || pageModel.termsAccepted != props.giftCard.paymentStep.termsAccepted) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n //this should be call always\r\n const handleExpandCheck = (e: React.ChangeEvent) => {\r\n if (checkboxRef.current.checked) {\r\n props.handleBeginEdit();\r\n }\r\n }\r\n\r\n const handleCheckout = (e: React.MouseEvent) => {\r\n //do not propagate changes\r\n setIsSaving(true);\r\n\r\n const copyModel = Object.assign({}, props.giftCard);\r\n\r\n //Do not save default message\r\n if (copyModel.customizeStep.personalMessage === defaultPersonalMessageText) {\r\n copyModel.customizeStep.personalMessage = '';\r\n }\r\n\r\n let culture = document.documentElement.lang;\r\n //Proceed with checkout\r\n DataService.checkoutRegiftCard(culture, copyModel.id, copyModel)\r\n .then(response => {\r\n //console.debug(response);\r\n if (response && response.id && response.id.trim()) {\r\n // clear local storage\r\n localStorage.removeItem(GlobalConstants.LOCALSTORAGE_KEY_BASKET_ID)\r\n\r\n //get confirmation page link\r\n let pageLink = findLinkByAlias(PAGE_LINKS.BUY_GIFT_CARD_CONFIRMATION, links);\r\n if (pageLink && pageLink.url.trim()) {\r\n var queryString = {\r\n bid: props.giftCard.id\r\n };\r\n let url = pageLink.url + \"?\" + new URLSearchParams(queryString).toString();\r\n\r\n //redirect to confirmation page\r\n window.location.replace(url);\r\n }\r\n } else {\r\n setError(\"Unable to checkout\");\r\n setIsSaving(false); //in case of an error\r\n }\r\n })\r\n .catch(console.error)\r\n .finally(() => {\r\n //setIsSaving(false); do not do this, wait for a redirect in case of success \r\n });\r\n }\r\n\r\n //if (error) throw error;\r\n return (\r\n
\r\n \r\n\r\n
\r\n

{labels.get(\"GiftCard.App.Steps.PreviewAndPay\")}

\r\n
\r\n {IS_ACTIVE &&\r\n }\r\n
\r\n\r\n
\r\n {!isLoading &&\r\n
\r\n {(debugMode) &&\r\n
\r\n

Terms Accepted: {String(pageModel.termsAccepted)}

\r\n\r\n

Is dirty: {String(isDirty)}

\r\n

Is valid: {String(isValid())}

\r\n
}\r\n\r\n \r\n\r\n\r\n
\r\n
\r\n setPageModel({ ...pageModel, termsAccepted: e.target.checked })}\r\n />\r\n
\r\n
\r\n\r\n {(isSaving) ? (\r\n \r\n ) : (\r\n <>\r\n \r\n \r\n \r\n )}\r\n\r\n
}\r\n
\r\n
\r\n
\r\n )\r\n}\r\n\r\nexport default RegiftCardPaymentStep;","import { WorkflowTypeEnum } from \"@src/models/enums/WorkflowTypeEnum\";\r\nimport { IRegiftRecipientsStepProps } from \"@src/models/props/RecipientsStepProps\";\r\nimport React, { useState, useEffect } from \"react\";\r\nimport { RegiftCardStateEnum } from \"../../models/enums/RegiftCardStateEnum\";\r\nimport { RegiftCardContext } from \"../../pages/RegiftCardPage\";\r\nimport RecipientsStep from \"./shared/RecipientsStep\";\r\nimport { CheckBalanceStepModel } from \"../../models/CheckBalanceStep.model\";\r\nimport { RegiftCardStepModel } from \"../../models/RegiftCardStep.model\";\r\n\r\nconst RegiftCardRecipientsStep = (props: IRegiftRecipientsStepProps) => {\r\n\r\n const { currentState, checkBalanceStep, regiftCardStep, recipientsStep } = React.useContext(RegiftCardContext);\r\n const [error, setError] = useState(null);\r\n\r\n const IS_ACTIVE = (checkBalanceStep && CheckBalanceStepModel.validateModel(checkBalanceStep) && !checkBalanceStep.isDirty)\r\n && (regiftCardStep && RegiftCardStepModel.validateModel(regiftCardStep, checkBalanceStep.remainingBalance) && !regiftCardStep.isDirty);\r\n\r\n if (error) throw error;\r\n return (\r\n <>\r\n {!props.isSaving &&\r\n }\r\n \r\n )\r\n}\r\n\r\nexport default RegiftCardRecipientsStep;","import React, { useState, useEffect, useRef } from \"react\";\r\nimport { RegiftCardContext } from \"../../pages/RegiftCardPage\";\r\nimport { AppSettingContext } from \"../Application\";\r\nimport { IRegiftCardStep, RegiftCardStepModel } from \"../../models/RegiftCardStep.model\";\r\nimport { RegiftCardStateEnum } from \"../../models/enums/RegiftCardStateEnum\";\r\nimport { IBaseStepProps } from \"../../models/props/BaseStepProps.interface\";\r\nimport LoadingComponent from \"../shared/LoadingComponent\";\r\nimport { CheckBalanceStepModel } from \"../../models/CheckBalanceStep.model\";\r\n\r\ninterface IRegiftCardStepProps extends IBaseStepProps {\r\n isSaving: boolean;\r\n handleSubmit(model: IRegiftCardStep): void;\r\n}\r\n\r\nconst RegiftCardStep = (props: IRegiftCardStepProps) => {\r\n //global context\r\n const { currentState, checkBalanceStep, regiftCardStep } = React.useContext(RegiftCardContext);\r\n const { debugMode, labels, links } = React.useContext(AppSettingContext);\r\n const IS_ACTIVE = (checkBalanceStep && CheckBalanceStepModel.validateModel(checkBalanceStep) && !checkBalanceStep.isDirty);\r\n\r\n const [culture, setCulture] = useState('en-GB');\r\n const [pageModel, setPageModel] = useState({value:\"\"});\r\n\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n // internal refs\r\n const checkboxRef = useRef(null)\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = currentState == RegiftCardStateEnum.REGIFT_CARD || IS_ACTIVE;\r\n });\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n setCulture(document.documentElement.lang);\r\n\r\n const modelCopy = Object.assign({}, pageModel);\r\n modelCopy.value = regiftCardStep.value > 0 ? regiftCardStep.value.toString() : \"\";\r\n setPageModel(modelCopy);\r\n\r\n }, []);\r\n\r\n useEffect(() => {\r\n\r\n setIsLoading(false);\r\n\r\n props.handleDirtyState(isModelDirty());\r\n\r\n }, [pageModel]);\r\n\r\n const handleExpandBoxCheck = (e: React.ChangeEvent) => {\r\n if (checkboxRef.current.checked) {\r\n props.handleBeginEdit();\r\n }\r\n };\r\n\r\n const handleValueChange = (e: React.ChangeEvent) => {\r\n console.debug(\"handleCardCodeChange:\", e.target.value);\r\n if (e.target.value == \"\") {\r\n setPageModel({ ...pageModel, value: e.target.value });\r\n }\r\n else {\r\n const value = Math.max(1, Math.min(checkBalanceStep.remainingBalance, Number(e.target.value)));\r\n setPageModel({ ...pageModel, value: value.toString() });\r\n }\r\n };\r\n\r\n const handleSubmit = (event: React.MouseEvent) => {\r\n event.preventDefault();\r\n\r\n setIsSaving(false);\r\n props.handleSubmit({\r\n value: parseInt(pageModel.value),\r\n isDirty: false\r\n });\r\n\r\n checkboxRef.current.checked = false; //collapse the step\r\n };\r\n\r\n const isValid = (): boolean => {\r\n const model = getRegiftCardStepModel();\r\n return RegiftCardStepModel.validateModel(model, checkBalanceStep.remainingBalance);\r\n };\r\n\r\n const isModelDirty = (): boolean => {\r\n if (!pageModel) return false;\r\n\r\n const model = getRegiftCardStepModel();\r\n if (model.value != regiftCardStep.value) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n const getRegiftCardStepModel = (): IRegiftCardStep => {\r\n const model: IRegiftCardStep = {\r\n value: parseInt(pageModel.value),\r\n isDirty: true\r\n };\r\n return model;\r\n };\r\n\r\n const getFormatedText = (): string => {\r\n let balance = labels.get(\"GiftCard.App.Steps.RegiftCard.Description\");\r\n balance = balance.replace(\"{0}\", `${checkBalanceStep.currencySymbol}${checkBalanceStep.remainingBalance.toFixed(2)}`);\r\n return balance;\r\n };\r\n\r\n if (error) throw error;\r\n return (\r\n
\r\n \r\n\r\n
\r\n

{labels.get(\"GiftCard.App.Steps.RegiftCard\")}

\r\n\r\n
\r\n {IS_ACTIVE &&\r\n }\r\n
\r\n
\r\n {(isLoading || isSaving) && }\r\n\r\n {(!isLoading && !isSaving && pageModel) &&\r\n
\r\n {(debugMode) &&\r\n
\r\n

Value: {pageModel.value}

\r\n

Balance: {checkBalanceStep.remainingBalance}

\r\n

Currency: {checkBalanceStep.currencySymbol}

\r\n
\r\n

Is dirty: {String(isModelDirty())}

\r\n

Is valid: {String(isValid())}

\r\n
}\r\n\r\n \r\n \r\n\r\n {getFormatedText()}\r\n \r\n
}\r\n
\r\n
\r\n
\r\n )\r\n}\r\n\r\nexport default RegiftCardStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport DataService from \"../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../Application\";\r\nimport LoadingComponent from \"../../shared/LoadingComponent\";\r\n\r\ninterface IActivateGiftCardFormProps {\r\n cacheActNum: string;\r\n proceedToNextStep(): void;\r\n handleActNumberUpdate(actNumber: string): void;\r\n}\r\n\r\ninterface IActivationNumberStatus {\r\n status: \"\" | \"success\" | \"warning\" | \"error\";\r\n message: string;\r\n}\r\n\r\nconst ActivateGiftCardForm = (props: IActivateGiftCardFormProps) => {\r\n const { labels, activateSettings } = useContext(AppSettingContext);\r\n\r\n const firstRender = useRef(true);\r\n const [fractionRef1, fractionRef2, fractionRef3] = [useRef(null), useRef(null), useRef(null)];\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [actNumber, setActNumber] = useState({\r\n fraction1: props.cacheActNum.slice(0, 4) ?? \"\",\r\n fraction2: props.cacheActNum.slice(4, 8) ?? \"\",\r\n fraction3: props.cacheActNum.slice(8, 12) ?? \"\",\r\n\r\n getFull() {\r\n return this.fraction1 + this.fraction2 + this.fraction3;\r\n }\r\n });\r\n const [actNumberState, setActNumberState] = useState();\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [isStepActive, setIsStepActive] = useState(false);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (firstRender.current && !actNumber.getFull()) {\r\n firstRender.current = false;\r\n return;\r\n }\r\n\r\n setIsLoading(true);\r\n setIsStepActive(true);\r\n\r\n const actNumStr = actNumber.getFull();\r\n props.handleActNumberUpdate(actNumStr);\r\n validateActNumber(actNumStr);\r\n\r\n setIsLoading(false);\r\n\r\n // if there already is activation number stored in the cache\r\n // automatically submit and proceed to next step\r\n if (actNumber.getFull().length > 0 &&\r\n actNumberState?.status !== \"error\" &&\r\n props.cacheActNum.length > 0 &&\r\n actNumber.getFull() === props.cacheActNum\r\n ) {\r\n proceedToNextStep();\r\n }\r\n }, [actNumber]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleActNumberChange = (e: React.ChangeEvent) => {\r\n const pattern = /^\\d*$/;\r\n if (!pattern.test(e.target.value)) {\r\n e.preventDefault();\r\n return;\r\n }\r\n\r\n if (e.target.value.length === 4) {\r\n switch (e.target.name) {\r\n case \"fraction1\":\r\n fractionRef2.current?.focus();\r\n break;\r\n case \"fraction2\":\r\n fractionRef3.current?.focus();\r\n break;\r\n }\r\n }\r\n\r\n setActNumber({ ...actNumber, [e.target.name]: e.target.value });\r\n };\r\n\r\n const handlePaste = (event: React.ClipboardEvent) => {\r\n event.preventDefault();\r\n\r\n const pasteData = event.clipboardData.getData('text');\r\n\r\n const numericPattern = /^\\d*$/;\r\n if (!numericPattern.test(pasteData)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n const fraction1 = pasteData.slice(0, 4);\r\n const fraction2 = pasteData.slice(4, 8);\r\n const fraction3 = pasteData.slice(8, 12);\r\n\r\n setActNumber({ ...actNumber, fraction1, fraction2, fraction3 });\r\n\r\n if (pasteData.length >= 4 && pasteData.length < 8) {\r\n fractionRef2.current?.focus();\r\n } else if (pasteData.length >= 8) {\r\n fractionRef3.current?.focus();\r\n }\r\n };\r\n\r\n //#endregion\r\n\r\n //#region HELPERS\r\n\r\n const validateActNumber = async (actNumber: string) => {\r\n if (actNumber.length !== activateSettings.codeLength) {\r\n setActNumberState({\r\n status: \"\",\r\n message: \"\"\r\n });\r\n\r\n return;\r\n }\r\n\r\n // first check if the activation number could be valid luhn by its pattern\r\n const isValidLuhn = await DataService.checkLuhnPattern(actNumber);\r\n\r\n if (isValidLuhn) {\r\n // pattern is valid\r\n setActNumberState({\r\n status: \"\",\r\n message: \"\"\r\n });\r\n } else {\r\n // pattern is invalid\r\n setActNumberState({\r\n status: \"error\",\r\n message: labels.get(\"GiftCard.App.ActivateLoadCard.Errors.ActivationNo.Error\")\r\n });\r\n }\r\n };\r\n\r\n const proceedToNextStep = async () => {\r\n if (actNumberState?.status === \"error\") {\r\n return;\r\n }\r\n\r\n setIsLoading(true);\r\n\r\n const actNumStr = actNumber.getFull();\r\n const response = await DataService.checkGiftCardCode(actNumStr);\r\n\r\n if (response.status.toLowerCase() === \"ok\") {\r\n setActNumberState({\r\n status: \"success\",\r\n message: labels.get(\"GiftCard.App.ActivateLoadCard.Errors.ActivationNo.Valid\")\r\n });\r\n } else if (response.status.toLowerCase() === \"warning\") {\r\n setActNumberState({\r\n status: \"warning\",\r\n message: labels.get(\"GiftCard.App.ActivateLoadCard.Errors.ActivationNo.Warning\")\r\n });\r\n\r\n setIsLoading(false);\r\n return;\r\n } else if (response.status.toLowerCase() === \"error\") {\r\n console.error(response.message);\r\n\r\n setActNumberState({\r\n status: \"error\",\r\n message: labels.get(\"GiftCard.App.ActivateLoadCard.Errors.ActivationNo.Error\")\r\n });\r\n\r\n setIsLoading(false);\r\n return;\r\n }\r\n\r\n props.proceedToNextStep();\r\n setIsStepActive(false);\r\n setIsLoading(false);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n <>\r\n \r\n
\r\n
\r\n
\r\n handleActNumberChange(e)}\r\n maxLength={4}\r\n name=\"fraction1\"\r\n id=\"actNumber-fraction1\"\r\n placeholder={labels.get(\"GiftCard.App.ActivateLoadCard.Placeholders.ActivationNo1\")}\r\n ref={fractionRef1}\r\n onPaste={handlePaste}\r\n />\r\n -\r\n handleActNumberChange(e)}\r\n maxLength={4}\r\n name=\"fraction2\"\r\n id=\"actNumber-fraction2\"\r\n placeholder={labels.get(\"GiftCard.App.ActivateLoadCard.Placeholders.ActivationNo2\")}\r\n ref={fractionRef2}\r\n />\r\n -\r\n handleActNumberChange(e)}\r\n maxLength={4}\r\n name=\"fraction3\"\r\n id=\"actNumber-fraction3\"\r\n placeholder={labels.get(\"GiftCard.App.ActivateLoadCard.Placeholders.ActivationNo3\")}\r\n ref={fractionRef3}\r\n />\r\n
\r\n {actNumberState?.status && (\r\n
\r\n {actNumberState?.status === 'error' && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n )}\r\n\r\n {actNumberState?.status === 'warning' && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n )}\r\n\r\n {actNumberState?.status === 'success' && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n )}\r\n\r\n {actNumberState.message}\r\n
\r\n )}\r\n
\r\n \r\n {labels.get(\"GiftCard.App.ActivateLoadCard.Btns.Next\")}\r\n \r\n
\r\n \r\n )}\r\n
\r\n );\r\n};\r\n\r\nexport default ActivateGiftCardForm;","import React, { useContext, useEffect, useState } from \"react\";\r\nimport PhoneInput, { CountryData } from \"react-phone-input-2\";\r\nimport { PHONE_NUMBER, PhoneCountryCodeKeys, PhoneValidationRegexKeys } from \"../../../constants/global\";\r\nimport { isEmail } from \"../../../helpers/Utils\";\r\nimport { IActivateBasketFullModel } from \"../../../models/ActivateGiftCard.model\";\r\nimport { AppSettingContext } from \"../../Application\";\r\n\r\ninterface IBillingDetailsStepProps {\r\n cacheBasket: IActivateBasketFullModel,\r\n handleSetBillingDetails(billingDetails: IBillingDetails, isValid: boolean): void;\r\n handleSetCurrentStep(): void;\r\n}\r\n\r\ninterface IBillingDetails {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone: string;\r\n}\r\n\r\nconst BillingDetailsStep = (props: IBillingDetailsStepProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n\r\n const phoneInputDropdowns = document.querySelectorAll('.flag-dropdown') as NodeListOf;\r\n const phoneNumberErrorMessages = document.querySelectorAll('.invalid-number-message') as NodeListOf;\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [billingDetails, setBillingDetails] = useState({\r\n firstName: props.cacheBasket?.firstName ?? \"\",\r\n lastName: props.cacheBasket?.lastName ?? \"\",\r\n email: props.cacheBasket?.email ?? \"\",\r\n phone: props.cacheBasket?.phone ?? \"\"\r\n });\r\n const [errors, setErrors] = useState({\r\n firstName: \"\",\r\n lastName: \"\",\r\n email: \"\",\r\n phone: \"\"\r\n });\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (phoneInputDropdowns && phoneInputDropdowns.length > 0) {\r\n phoneInputDropdowns.forEach(dropdown => {\r\n dropdown.style.borderColor = '#6b7280';\r\n dropdown.style.borderRightColor = '#cacaca';\r\n });\r\n }\r\n\r\n if (phoneNumberErrorMessages && phoneNumberErrorMessages.length > 0) {\r\n phoneNumberErrorMessages.forEach(errorMessage => {\r\n errorMessage.style.left = '0';\r\n errorMessage.style.top = '42px';\r\n errorMessage.classList.add(\"react-input-error-message\");\r\n });\r\n }\r\n }, [phoneInputDropdowns, phoneNumberErrorMessages]);\r\n\r\n useEffect(() => {\r\n formValidations.validateAllFields();\r\n }, [errors]);\r\n\r\n useEffect(() => {\r\n billingDetails.firstName && formValidations.validateFirstName();\r\n billingDetails.lastName && formValidations.validateLastName();\r\n billingDetails.phone && formValidations.validatePhone();\r\n }, [billingDetails]);\r\n\r\n useEffect(() => {\r\n billingDetails.email && formValidations.validateEmail(null);\r\n }, [billingDetails.email]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleChange = (event: React.ChangeEvent) => {\r\n props.handleSetCurrentStep();\r\n\r\n const { name, value } = event.target;\r\n let formattedValue = value;\r\n let error = \"\";\r\n\r\n if (name === \"firstName\") {\r\n formattedValue = formattedValue\r\n .replace(/[^a-zA-Z'-]/g, '')\r\n .trim();\r\n\r\n error = labels.get(\"GiftCard.App.ActivateLoadCard.Errors.FirstName\");\r\n } else if (name === \"lastName\") {\r\n formattedValue = formattedValue\r\n .replace(/[^a-zA-Z'-]/g, '')\r\n .trim();\r\n\r\n error = labels.get(\"GiftCard.App.ActivateLoadCard.Errors.LastName\");\r\n } else if (name === \"email\") {\r\n formattedValue = formattedValue\r\n .replace(/[^a-zA-Z0-9._%+-@]/g, '')\r\n .replace(/[?/;:,<>=]/g, '')\r\n .trim();\r\n\r\n error = labels.get(\"GiftCard.App.ActivateLoadCard.Errors.Email.Required\");\r\n }\r\n\r\n if (!formattedValue) {\r\n setErrors({\r\n ...errors,\r\n [name]: error\r\n });\r\n }\r\n\r\n setBillingDetails({\r\n ...billingDetails,\r\n [name]: formattedValue\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n //#region HELPERS\r\n\r\n const formValidations = {\r\n validateAllFields: () => {\r\n const isFormValid =\r\n billingDetails.firstName && !errors.firstName &&\r\n billingDetails.lastName && !errors.lastName &&\r\n billingDetails.email && !errors.email &&\r\n !errors.phone;\r\n\r\n props.handleSetBillingDetails(billingDetails, isFormValid);\r\n },\r\n\r\n validateFirstName: () => {\r\n const value = billingDetails.firstName.trim();\r\n let error = \"\";\r\n\r\n if (!value) {\r\n error = labels.get(\"GiftCard.App.ActivateLoadCard.Errors.FirstName\");\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n firstName: error\r\n }));\r\n },\r\n validateLastName: () => {\r\n const value = billingDetails.lastName.trim();\r\n let error = \"\";\r\n\r\n if (!value) {\r\n error = labels.get(\"GiftCard.App.ActivateLoadCard.Errors.LastName\");\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n lastName: error\r\n }));\r\n },\r\n validateEmail: (event: React.FocusEvent) => {\r\n const value = billingDetails.email.trim();\r\n let error = \"\";\r\n\r\n if (!value) {\r\n error = labels.get(\"GiftCard.App.ActivateLoadCard.Errors.Email.Required\");\r\n } else if (!isEmail(value)) {\r\n if (event && event.type === \"blur\") {\r\n error = labels.get(\"GiftCard.App.ActivateLoadCard.Errors.Email.Invalid\");\r\n } else {\r\n error = \"still invalid\";\r\n }\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n email: error\r\n }));\r\n },\r\n validatePhone: () => {\r\n const value = billingDetails.phone.trim();\r\n let error = \"\";\r\n\r\n const allowedCountryCodes = [] as string[];\r\n for (const key in PHONE_NUMBER.COUNTRIES) {\r\n allowedCountryCodes.push(PHONE_NUMBER.COUNTRIES[key as PhoneCountryCodeKeys])\r\n }\r\n\r\n if (!value || allowedCountryCodes.includes(value)) {\r\n error = \"\";\r\n } else {\r\n if (PHONE_NUMBER.VALIDATIONS.REGEX.IE.test(value)) {\r\n error = \"\";\r\n } else {\r\n let isValid = true;\r\n\r\n for (const regexKey in PHONE_NUMBER.VALIDATIONS.REGEX) {\r\n const currRegex = PHONE_NUMBER.VALIDATIONS.REGEX[regexKey as PhoneValidationRegexKeys];\r\n isValid = currRegex.test(value);\r\n }\r\n\r\n if (!isValid) {\r\n error = labels.get(\"GiftCard.App.ActivateLoadCard.Errors.Phone\");\r\n }\r\n }\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n phone: error\r\n }));\r\n }\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n

{labels.get(\"GiftCard.App.ActivateLoadCard.Steps.BillingDetails\")}

\r\n
\r\n
\r\n \r\n handleChange(event)}\r\n maxLength={150}\r\n name=\"firstName\"\r\n id=\"load-firstName\"\r\n placeholder={labels.get(\"GiftCard.App.ActivateLoadCard.Placeholders.FirstName\")}\r\n className={errors.firstName ? \"react-input-error\" : \"\"}\r\n />\r\n {errors.firstName &&\r\n
\r\n {errors.firstName}\r\n
\r\n }\r\n
\r\n
\r\n \r\n handleChange(event)}\r\n maxLength={150}\r\n name=\"lastName\"\r\n id=\"load-lastName\"\r\n placeholder={labels.get(\"GiftCard.App.ActivateLoadCard.Placeholders.LastName\")}\r\n className={errors.lastName ? \"react-input-error\" : \"\"}\r\n />\r\n {errors.lastName &&\r\n
\r\n {errors.lastName}\r\n
\r\n }\r\n
\r\n
\r\n
\r\n
\r\n \r\n handleChange(event)}\r\n maxLength={150}\r\n name=\"email\"\r\n id=\"load-email\"\r\n placeholder={labels.get(\"GiftCard.App.ActivateLoadCard.Placeholders.Email\")}\r\n className={(errors.email && errors.email !== \"still invalid\") ? \"react-input-error\" : \"\"}\r\n onBlur={(event) => formValidations.validateEmail(event)}\r\n />\r\n {(errors.email && errors.email !== \"still invalid\") &&\r\n
\r\n {errors.email}\r\n
\r\n }\r\n
\r\n
\r\n \r\n
\r\n c.toLowerCase())}\r\n countryCodeEditable={false}\r\n value={billingDetails.phone}\r\n onChange={(phone) => {\r\n props.handleSetCurrentStep();\r\n\r\n if (phone.length > PHONE_NUMBER.VALIDATIONS.MAXLENGTH) {\r\n phone = phone.slice(0, PHONE_NUMBER.VALIDATIONS.MAXLENGTH)\r\n }\r\n\r\n setBillingDetails({\r\n ...billingDetails,\r\n phone: `+${phone}`\r\n });\r\n }}\r\n isValid={(inputNumber, data: CountryData) => {\r\n const allowedCountryCodes = [] as string[];\r\n for (const key in PHONE_NUMBER.COUNTRIES) {\r\n allowedCountryCodes.push(PHONE_NUMBER.COUNTRIES[key as PhoneCountryCodeKeys])\r\n }\r\n\r\n if (!billingDetails.phone || allowedCountryCodes.includes(billingDetails.phone)) {\r\n return true;\r\n }\r\n\r\n const allowedCountriesAbbr = Object.keys(PHONE_NUMBER.COUNTRIES).map(c => c.toLowerCase());\r\n if (allowedCountriesAbbr.includes(data.iso2.toLowerCase())) {\r\n const regexKey = data.iso2.toUpperCase() as PhoneValidationRegexKeys;\r\n const regex = PHONE_NUMBER.VALIDATIONS.REGEX[regexKey] as RegExp;\r\n\r\n if (regex) {\r\n return regex.test(billingDetails.phone);\r\n }\r\n }\r\n\r\n return false;\r\n }}\r\n inputClass='react-phone-input'\r\n enableLongNumbers={PHONE_NUMBER.VALIDATIONS.MAXLENGTH}\r\n defaultErrorMessage={labels.get(\"GiftCard.App.ActivateLoadCard.Errors.Phone\")}\r\n />\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default BillingDetailsStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport { AppSettingContext } from \"../../Application\";\r\n\r\ninterface IChooseLoadAmountStepProps {\r\n cacheLoadAmount: number;\r\n handleSetLoadAmount(loadAmount: string, isValid: boolean): void;\r\n handleSetCurrentStep(): void;\r\n}\r\n\r\nconst ChooseLoadAmountStep = (props: IChooseLoadAmountStepProps) => {\r\n const { labels, activateSettings } = useContext(AppSettingContext);\r\n\r\n const firstRender = useRef(true);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [value, setValue] = useState(props.cacheLoadAmount?.toString() ?? \"\");\r\n const [isValueValid, setIsValueValid] = useState(true);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (firstRender.current && !props.cacheLoadAmount) {\r\n firstRender.current = false;\r\n return;\r\n }\r\n\r\n if (!value || value.includes('.') || value.includes('-')) {\r\n setIsValueValid(false);\r\n props.handleSetLoadAmount(value, false);\r\n return;\r\n }\r\n\r\n const intValue = parseInt(value);\r\n if (intValue < 1 || intValue > 5000) {\r\n setIsValueValid(false);\r\n props.handleSetLoadAmount(value, false);\r\n return;\r\n }\r\n\r\n setIsValueValid(true);\r\n props.handleSetLoadAmount(value, true);\r\n }, [value]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleChange = (event: React.ChangeEvent) => {\r\n props.handleSetCurrentStep();\r\n\r\n if (event.target.value.includes('.') || event.target.value.includes('-')) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (!event.target.value) {\r\n setValue(\"\");\r\n return;\r\n }\r\n\r\n const newValue = Math.max(1, Math.min(activateSettings.loadMaxValue, Number(event.target.value)));\r\n setValue(newValue.toString());\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n

{labels.get(\"GiftCard.App.ActivateLoadCard.Steps.ChooseAmount\")}

\r\n
\r\n \r\n
\r\n \r\n handleChange(event)}\r\n name=\"load-value\"\r\n id=\"load-value\"\r\n placeholder={labels.get(\"GiftCard.App.ActivateLoadCard.Placeholders.ChooseValue\")}\r\n />\r\n
\r\n \r\n {labels.get(\"GiftCard.App.ActivateLoadCard.Tips.ChooseValue\")}\r\n \r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ChooseLoadAmountStep;","import React, { useEffect, useState } from \"react\";\r\nimport { findLinkByAlias } from \"../../../helpers/GiftCardHelper\";\r\nimport { isNotNullOrEmpty } from \"../../../helpers/Utils\";\r\nimport { IActivateBasketFullModel } from \"../../../models/ActivateGiftCard.model\";\r\nimport { CheckoutBillingAddressData } from \"../../../models/ElavonCheckoutModels\";\r\nimport { CheckoutStatusEnum } from \"../../../models/GiftCardCheckoutResult.model\";\r\nimport { ICheckoutSessionData } from \"../../../models/PaymentStep.model\";\r\nimport { PaymentTypeEnum } from \"../../../models/enums/PaymentTypeEnum\";\r\nimport DataService from \"../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../Application\";\r\nimport LoadingComponent from \"../../shared/LoadingComponent\";\r\nimport ElavonPayment, { HandleElavonCheckout, HandleThreeDSecureAuth } from \"../shared/ElavonPayment\";\r\n\r\ninterface IPaymentTypesStepProps {\r\n loadAmount: string;\r\n basketData: IActivateBasketFullModel;\r\n isSectionActive: boolean;\r\n}\r\n\r\nconst LoadAndPayForm = (props: IPaymentTypesStepProps) => {\r\n const { labels, links, elavonSettings } = React.useContext(AppSettingContext);\r\n\r\n const termsPageUrl = findLinkByAlias(\"terms-page\", links);\r\n const termsLink = labels.get(\"GiftCard.App.Steps.PreviewAndPay.TermsAndConditions\").replace(\"{0}\", termsPageUrl.url ?? \"\");\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [isCardPaymentLoading, setIsCardPaymentLoading] = useState(false);\r\n const [paymentModel, setPaymentModel] = useState({\r\n paymentType: PaymentTypeEnum.CREDIT_CARD,\r\n paymentDetails: {\r\n checkoutKey: \"\",\r\n checkoutExpiry: new Date(),\r\n stripeKey: \"\",\r\n cardAmount: 0,\r\n totalAmount: 0,\r\n totalFees: 0,\r\n currency: \"EUR\"\r\n },\r\n isFormValid: false\r\n });\r\n const [checkoutBillingDetails, setCheckoutBillingDetails] = useState();\r\n const [termsAccepted, setTermsAccepted] = useState(false);\r\n const [isStepActive, setIsStepActive] = useState(props.isSectionActive);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n handleStepInitialization();\r\n }, []);\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n\r\n const amount = parseInt(props.loadAmount);\r\n if (amount) {\r\n const newPaymentDetails = paymentModel.paymentDetails;\r\n newPaymentDetails.cardAmount = amount;\r\n newPaymentDetails.totalAmount = amount;\r\n\r\n setPaymentModel({\r\n ...paymentModel,\r\n paymentDetails: newPaymentDetails\r\n });\r\n }\r\n }, [props.loadAmount]);\r\n\r\n useEffect(() => {\r\n setIsStepActive(props.isSectionActive);\r\n\r\n if (props.isSectionActive) {\r\n handleStepInitialization();\r\n }\r\n }, [props.isSectionActive]);\r\n\r\n useEffect(() => {\r\n const isReadyForPayment = paymentModel &&\r\n paymentModel.paymentDetails &&\r\n paymentModel.paymentDetails.totalAmount &&\r\n paymentModel.paymentDetails.cardAmount &&\r\n paymentModel.paymentDetails.currency;\r\n\r\n if (isReadyForPayment) {\r\n setTimeout(() => {\r\n setIsLoading(false);\r\n }, 500);\r\n }\r\n }, [paymentModel]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleStepInitialization = () => {\r\n if (!elavonSettings.showCheckoutForm) {\r\n setPaymentModel(prevModel => ({\r\n ...prevModel,\r\n paymentType: PaymentTypeEnum.NONE\r\n }));\r\n\r\n return;\r\n }\r\n\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const spErrQueryParam = urlParams.get('sp-err-code');\r\n\r\n setTimeout(() => {\r\n try {\r\n const creditCardRB = document.querySelector(\"input#stripe__credit-debit-card\") as HTMLInputElement;\r\n if (creditCardRB) {\r\n creditCardRB.click();\r\n }\r\n } catch (err) {\r\n console.warn(err);\r\n }\r\n\r\n if (spErrQueryParam) {\r\n setTimeout(() => {\r\n let errMsg = labels.get(`GiftCard.App.Steps.PreviewAndPay.Card.Errors.ThreeDForm${spErrQueryParam}`);\r\n if (!errMsg) {\r\n errMsg = labels.get(\"GiftCard.App.Steps.PreviewAndPay.Card.Errors.ThreeDForm2\");\r\n }\r\n\r\n switch (spErrQueryParam) {\r\n case \"1\": console.error(`3D secure authentication returned status, other than 'Ok'.\\r\\n${errMsg}`); break;\r\n case \"2\": console.error(`Some of the parameters sent to GiftCardService 3D authentication method were invalid.\\r\\n${errMsg}`); break;\r\n case \"3\": console.error(`Services API returned BadRequest.\\r\\n${errMsg}`); break;\r\n case \"4\": console.error(`Unauthorized access to Services API 3D secure endpoint.\\r\\n${errMsg}`); break;\r\n case \"5\": console.error(`Services API returned invalid response.\\r\\n${errMsg}`); break;\r\n case \"6\": console.error(`An unhandled error occurred processing 3D authentication response.\\r\\n${errMsg}`); break;\r\n default: break;\r\n }\r\n\r\n displayError(errMsg);\r\n }, 500);\r\n\r\n const divToScrollto = document.querySelector(\"label[for=stripe__credit-debit-card]\");\r\n if (divToScrollto) {\r\n divToScrollto.scrollIntoView();\r\n }\r\n }\r\n }, 600);\r\n };\r\n\r\n const handleSetCreditCardPaymentType = async () => {\r\n setIsCardPaymentLoading(true);\r\n const checkoutSession = await createNewCheckoutSession(false);\r\n\r\n const currPaymentDetails = paymentModel.paymentDetails;\r\n currPaymentDetails.checkoutKey = checkoutSession.sessionKey;\r\n currPaymentDetails.checkoutExpiry = checkoutSession.expiry;\r\n\r\n setPaymentModel({\r\n ...paymentModel,\r\n paymentType: PaymentTypeEnum.CREDIT_CARD,\r\n paymentDetails: currPaymentDetails\r\n });\r\n setIsCardPaymentLoading(false);\r\n };\r\n\r\n const handleFormVisibility = (visible: boolean) => {\r\n const paymentBoxEl = document.getElementById(\"payment-box\");\r\n if (paymentBoxEl) {\r\n paymentBoxEl.style.opacity = visible ? \"1\" : \"0.2\";\r\n }\r\n\r\n const paymentSubmitBtnEl = document.getElementById(\"paymentSubmitBtn\") as HTMLButtonElement;\r\n if (paymentSubmitBtnEl) {\r\n paymentSubmitBtnEl.disabled = !visible;\r\n }\r\n };\r\n\r\n const handleFormUpdate = (isFormValid: boolean, billingDetails: CheckoutBillingAddressData) => {\r\n setPaymentModel({\r\n ...paymentModel, isFormValid: isFormValid\r\n });\r\n\r\n if (isFormValid) {\r\n setCheckoutBillingDetails(billingDetails);\r\n }\r\n };\r\n\r\n const handleCheckout = async () => {\r\n if (paymentModel.paymentType === PaymentTypeEnum.CREDIT_CARD) {\r\n if (isValid()) {\r\n const paymentForm = document.getElementById('checkout-form') as HTMLFormElement;\r\n if (!paymentForm) {\r\n displayError(\"Unable to find a payment form. Please refresh the page.\");\r\n return;\r\n }\r\n\r\n handleFormVisibility(false);\r\n\r\n if (!paymentModel.paymentDetails.checkoutKey || new Date(paymentModel.paymentDetails.checkoutExpiry) <= new Date()) {\r\n await createNewCheckoutSession(true);\r\n }\r\n\r\n // handle opayo tokenisation and submission\r\n HandleElavonCheckout({\r\n sessionKey: paymentModel.paymentDetails.checkoutKey,\r\n expiry: paymentModel.paymentDetails.checkoutExpiry\r\n });\r\n\r\n setTimeout(async () => {\r\n await creditCardProcessPayment();\r\n }, 600);\r\n } else {\r\n displayError(\"Invalid data\");\r\n }\r\n }\r\n };\r\n\r\n //#endregion\r\n\r\n //#region HELPERS\r\n\r\n const displayError = (errorMessage: string) => {\r\n const errorContainer = document.querySelector(\"#checkout-error\") as HTMLDivElement;\r\n\r\n if (errorContainer) {\r\n errorContainer.style.display = \"block\";\r\n errorContainer.textContent = errorMessage;\r\n\r\n //setTimeout(function () {\r\n // errorContainer.style.removeProperty(\"display\");\r\n // errorContainer.textContent = \"\";\r\n //}, 10000);\r\n }\r\n };\r\n\r\n const isValid = (): boolean => {\r\n const amount = paymentModel.paymentDetails.totalAmount;\r\n const propsAmount = props.basketData.totalAmount;\r\n\r\n if (!amount && !propsAmount) {\r\n return false;\r\n }\r\n\r\n if (!props?.basketData?.basketId) {\r\n return false;\r\n }\r\n\r\n if (!paymentModel.isFormValid) {\r\n return false;\r\n }\r\n\r\n if (!termsAccepted) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n const createNewCheckoutSession = async (setSessionKeyModel: boolean): Promise => {\r\n const amount = paymentModel?.paymentDetails?.totalAmount ?? props?.basketData?.totalAmount;\r\n if (!amount || amount == 0) {\r\n console.error(\"An attempt to create new checkout session was made, but the checkout amount was invalid.\");\r\n return;\r\n }\r\n\r\n const basketId = props?.basketData?.basketId;\r\n if (!basketId) {\r\n console.error(\"An attempt to create new checkout session was made, but the basketId was invalid.\")\r\n return;\r\n }\r\n\r\n const newMerchantSession = await DataService.getCheckoutData(basketId, amount, paymentModel?.paymentDetails?.currency ?? \"EUR\");\r\n\r\n if (!setSessionKeyModel) {\r\n return newMerchantSession;\r\n }\r\n\r\n const newPaymentDetailsObj = paymentModel.paymentDetails;\r\n newPaymentDetailsObj.checkoutKey = newMerchantSession.sessionKey;\r\n newPaymentDetailsObj.checkoutExpiry = newMerchantSession.expiry;\r\n\r\n setPaymentModel(currPaymentModel => ({\r\n ...currPaymentModel,\r\n paymentDetails: newPaymentDetailsObj\r\n }));\r\n\r\n return newMerchantSession;\r\n };\r\n\r\n const creditCardProcessPayment = async () => {\r\n const cardIdentifierField = document.querySelector(\"#cardIdentifier-field\") as HTMLInputElement;\r\n const cardIdentifier = cardIdentifierField.value;\r\n\r\n if (!cardIdentifier) {\r\n console.error(\"Empty card identifier returned from SagePay API.\");\r\n\r\n const errorContainer = document.querySelector(\"#checkout-error\") as HTMLDivElement;\r\n if (errorContainer && (errorContainer.textContent.length === 0 || errorContainer.checkVisibility() === false)) {\r\n displayError(labels.get(\"GiftCard.App.Steps.PreviewAndPay.Card.Errors.SagePay\"));\r\n }\r\n\r\n await createNewCheckoutSession(true);\r\n handleFormVisibility(true);\r\n return;\r\n }\r\n\r\n //console.log(`%cSuccessfully tokenised the card details\\r\\nCard identifier: ${cardIdentifier}`, 'color: green; font-weight: bold;');\r\n\r\n const checkoutRes = await DataService.submitCreditCardPayment('Activate', props.basketData.basketId, paymentModel.paymentDetails.checkoutKey, cardIdentifier, checkoutBillingDetails);\r\n if (checkoutRes) {\r\n //console.log('checkoutRes: ', checkoutRes);\r\n\r\n if (checkoutRes.checkoutStatus == CheckoutStatusEnum.Success) {\r\n if (isNotNullOrEmpty(checkoutRes.thankYouPageUrl)) {\r\n window.location.href = checkoutRes.thankYouPageUrl;\r\n return;\r\n } else {\r\n console.error(\"Invalid ThankYou page url provided\");\r\n window.location.href = \"/\";\r\n }\r\n } else if (checkoutRes.checkoutStatus == CheckoutStatusEnum.Secure3DAuth) {\r\n const handleThreeDError = async (errorMessage: string) => {\r\n const baseErrorMessage = labels.get(\"GiftCard.App.Steps.PreviewAndPay.Card.Errors.ThreeDForm0\");\r\n\r\n console.error(`${baseErrorMessage} ${errorMessage}`);\r\n displayError(baseErrorMessage);\r\n await createNewCheckoutSession(true);\r\n handleFormVisibility(true);\r\n };\r\n\r\n HandleThreeDSecureAuth(checkoutRes, handleThreeDError);\r\n return;\r\n } else if (checkoutRes.checkoutStatus == CheckoutStatusEnum.Failed || checkoutRes.checkoutStatus == CheckoutStatusEnum.Rejected) {\r\n displayError(checkoutRes.statusMessage);\r\n await createNewCheckoutSession(true);\r\n handleFormVisibility(true);\r\n return;\r\n }\r\n }\r\n\r\n setTimeout(() => {\r\n handleFormVisibility(true);\r\n }, 100);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n {!isStepActive ? (\r\n

\r\n {labels.get(\"GiftCard.App.ActivateLoadCard.Labels.LoadAndPay\")}\r\n

\r\n ) : (\r\n <>\r\n

{labels.get(\"GiftCard.App.ActivateLoadCard.Steps.PaymentType\")}

\r\n\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
\r\n {elavonSettings.showCheckoutForm && (\r\n <>\r\n handleSetCreditCardPaymentType()}\r\n defaultChecked={paymentModel.paymentType === PaymentTypeEnum.CREDIT_CARD}\r\n />\r\n\r\n
\r\n \r\n
\r\n \r\n )}\r\n
\r\n\r\n {isCardPaymentLoading && (\r\n \r\n )}\r\n\r\n {(elavonSettings.showCheckoutForm && paymentModel.paymentType === PaymentTypeEnum.CREDIT_CARD) && (\r\n <>\r\n \r\n\r\n
\r\n setTermsAccepted(e.target.checked)}\r\n />\r\n
\r\n \r\n )}\r\n\r\n
\r\n\r\n {(elavonSettings.showCheckoutForm) ? (\r\n <>\r\n \r\n \r\n ) : (\r\n

{labels.get(\"GiftCard.App.ActivateLoadCard.Tips.NoPaymentMethodAvailable\")}

\r\n )}\r\n
\r\n )}\r\n
\r\n \r\n )}\r\n
\r\n );\r\n};\r\n\r\nexport default LoadAndPayForm;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport { IActivateBasketFullModel, IActivateGiftCardBillingDetails } from \"../../../models/ActivateGiftCard.model\";\r\nimport DataService from \"../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../Application\";\r\nimport LoadingComponent from \"../../shared/LoadingComponent\";\r\nimport BillingDetailsStep from \"./BillingDetailsStep\";\r\nimport ChooseLoadAmountStep from \"./ChooseLoadAmountStep\";\r\n\r\ninterface ILoadGiftCardFormProps {\r\n currentStep: string;\r\n activationNumber: string;\r\n basketData: IActivateBasketFullModel;\r\n\r\n setBasketData(basketData: IActivateBasketFullModel): void;\r\n proceedToNextStep(): void;\r\n handleSetCurrentStep(): void;\r\n}\r\n\r\nconst LoadGiftCardForm = (props: ILoadGiftCardFormProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n const firstRender = useRef(true);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [isFormValid, setIsFormValid] = useState(false);\r\n const [chooseAmount, setChooseAmount] = useState({\r\n loadAmount: props.basketData?.amountNoFees?.toString() ?? \"\",\r\n isValid: false\r\n });\r\n const [billingDetails, setBillingDetails] = useState({\r\n billingDetails: {\r\n firstName: props.basketData?.firstName ?? \"\",\r\n lastName: props.basketData?.lastName ?? \"\",\r\n email: props.basketData?.email ?? \"\",\r\n phone: props.basketData?.phone ?? \"\",\r\n } as IActivateGiftCardBillingDetails,\r\n isValid: false\r\n });\r\n const [error, setError] = useState(\"\");\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (chooseAmount.isValid &&\r\n billingDetails.isValid\r\n ) {\r\n setIsFormValid(true);\r\n return;\r\n }\r\n\r\n setIsFormValid(false);\r\n }, [chooseAmount, billingDetails]);\r\n\r\n useEffect(() => {\r\n if (isFormValid && props.basketData && firstRender.current) {\r\n firstRender.current = false;\r\n handleSaveAndContinue();\r\n }\r\n }, [isFormValid]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n async function handleSaveAndContinue() {\r\n setIsLoading(true);\r\n const response = await DataService.updateGiftCardBasket(props.activationNumber, chooseAmount.loadAmount);\r\n\r\n if (response) {\r\n const cacheResponse = await DataService.saveActivateGiftCardBasket({\r\n basketId: response.basketId ?? \"\",\r\n activationNo: response.activationNo ?? \"\",\r\n amountNoFees: response.amountNoFees ?? 0,\r\n fees: response.fees ?? 0,\r\n totalAmount: response.totalAmount ?? Number(chooseAmount.loadAmount),\r\n firstName: billingDetails.billingDetails.firstName,\r\n lastName: billingDetails.billingDetails.lastName,\r\n email: billingDetails.billingDetails.email,\r\n phone: billingDetails.billingDetails.phone\r\n }, null);\r\n\r\n if (cacheResponse.status.toLowerCase() !== \"ok\") {\r\n console.warn(\"Could not save activate basket in cache.\");\r\n }\r\n\r\n props.setBasketData({\r\n basketId: response.basketId,\r\n activationNo: response.activationNo,\r\n amountNoFees: response.amountNoFees,\r\n fees: response.fees,\r\n totalAmount: response.totalAmount,\r\n firstName: billingDetails.billingDetails.firstName,\r\n lastName: billingDetails.billingDetails.lastName,\r\n email: billingDetails.billingDetails.email,\r\n phone: billingDetails.billingDetails.phone\r\n });\r\n\r\n props.proceedToNextStep();\r\n } else {\r\n console.error(\"Error updating uv giftcard.\");\r\n setError(\"Error updating uv giftcard.\");\r\n }\r\n\r\n setIsLoading(false);\r\n }\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n <>\r\n {props.currentStep.toLowerCase() === \"activate\" ? (\r\n

\r\n {labels.get(\"GiftCard.App.ActivateLoadCard.Labels.LoadDetails\")}\r\n

\r\n ) : (\r\n <>\r\n {\r\n setChooseAmount({ loadAmount, isValid });\r\n }}\r\n handleSetCurrentStep={() => props.handleSetCurrentStep()}\r\n />\r\n\r\n
\r\n {\r\n setBillingDetails({ billingDetails, isValid });\r\n }}\r\n handleSetCurrentStep={() => props.handleSetCurrentStep()}\r\n />\r\n\r\n {error && (\r\n \r\n {error}\r\n

\r\n )}\r\n\r\n \r\n {labels.get(\"GiftCard.App.Steps.Customise.Btn.Save\")}\r\n \r\n \r\n )}\r\n \r\n )}\r\n
\r\n );\r\n};\r\n\r\nexport default LoadGiftCardForm;","import React, { useContext } from \"react\";\r\nimport { BuyGiftCardSubpageEnum } from \"../../../../models/enums/BuyGiftCardSubpageEnum\";\r\nimport \"../../../../scss/stepsProgressBar.scss\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\n\r\ninterface IStepsProgressBarProps {\r\n subpage: BuyGiftCardSubpageEnum;\r\n\r\n handleSubpageChange(subpage: BuyGiftCardSubpageEnum): void;\r\n}\r\n\r\nconst StepsProgressBar = (props: IStepsProgressBarProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n\r\n const isCustomiseSubpageActive = props.subpage === BuyGiftCardSubpageEnum.CUSTOMISE_CARD || props.subpage === BuyGiftCardSubpageEnum.REVIEW_PAY;\r\n const isReviewPaySubpageActive = props.subpage === BuyGiftCardSubpageEnum.REVIEW_PAY;\r\n\r\n //#region HANDLERS\r\n\r\n const handleSubpageChange = (subpage: BuyGiftCardSubpageEnum): void => {\r\n if (subpage === BuyGiftCardSubpageEnum.CUSTOMISE_CARD && !isCustomiseSubpageActive) {\r\n return;\r\n } else if (subpage === BuyGiftCardSubpageEnum.REVIEW_PAY && !isReviewPaySubpageActive) {\r\n return;\r\n }\r\n\r\n props.handleSubpageChange(subpage);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n <>\r\n
    \r\n handleSubpageChange(BuyGiftCardSubpageEnum.CHOOSE_CARD)}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {labels.get(\"GiftCard.App.V2.ProgressBar.First\")}\r\n \r\n handleSubpageChange(BuyGiftCardSubpageEnum.CUSTOMISE_CARD)}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n {labels.get(\"GiftCard.App.V2.ProgressBar.Second\")}\r\n \r\n handleSubpageChange(BuyGiftCardSubpageEnum.REVIEW_PAY)}\r\n >\r\n \r\n \r\n \r\n \r\n {labels.get(\"GiftCard.App.V2.ProgressBar.Third\")}\r\n \r\n
\r\n \r\n );\r\n};\r\n\r\nexport default StepsProgressBar;","import React, { useContext } from \"react\";\r\nimport { formatStringWithPlaceholders } from \"../../../../helpers/Utils\";\r\nimport { GiftCardSendTypeEnum } from \"../../../../models/enums/GiftCardSendTypeEnum\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\n\r\ninterface ISummarySectionProps {\r\n cardsQuantity: number;\r\n cardsValue: number;\r\n recipientsCount: number;\r\n sendBy?: GiftCardSendTypeEnum;\r\n}\r\n\r\nconst SummarySection = (props: ISummarySectionProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n\r\n return (\r\n <>\r\n
\r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.Sidebar.Summary.Title\")}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n {formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Sidebar.Summary.Quantity\"), props.cardsQuantity.toString())}\r\n \r\n €{formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Sidebar.Summary.Value\"), props.cardsValue.toString())}\r\n
\r\n {formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Sidebar.Summary.Recipients\"), props.recipientsCount.toString())}\r\n \r\n {props.sendBy === GiftCardSendTypeEnum.BY_EMAIL ? \"Email\"\r\n : props.sendBy === GiftCardSendTypeEnum.BY_SMS ? \"SMS\" : \"PDF\"}\r\n
{labels.get(\"GiftCard.App.V2.Sidebar.Summary.LabelTotal\")}€{props.cardsQuantity * props.cardsValue}
\r\n
\r\n
\r\n \r\n );\r\n};\r\n\r\nexport default SummarySection;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport { formatStringWithPlaceholders } from \"../../../../helpers/Utils\";\r\nimport { ChooseCardStepModel, IChooseCardStepModel } from \"../../../../models/buy-giftcard/choose-card/ChooseCardsStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\n\r\ninterface IChooseCardStepProps extends IBuyGiftCardStepProps {\r\n stepModel: IChooseCardStepModel;\r\n\r\n handleSubmit(stepModel: IChooseCardStepModel): void;\r\n}\r\n\r\nconst ChoooseCardsStep = (props: IChooseCardStepProps) => {\r\n const { labels, cardSettings } = useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [stepModel, setStepModel] = useState({\r\n quantity: props.stepModel?.quantity ?? 1,\r\n value: props.stepModel?.value === 0 ? null : props.stepModel.value\r\n });\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [isModelValid, setIsModelValid] = useState();\r\n const [modelErrors, setModelErrors] = useState({\r\n quantity: '',\r\n value: '',\r\n total: ''\r\n });\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsModelValid(isValid());\r\n }, [stepModel]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.activeStep === BuyGiftCardStateEnum.CHOOSE_CARD_DETAILS;\r\n }, [props.activeStep]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleChange = (e: React.ChangeEvent): void => {\r\n const { name, value } = e.target;\r\n let error = '';\r\n\r\n if (!value) {\r\n setStepModel({\r\n ...stepModel,\r\n [name]: value\r\n });\r\n\r\n error = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.ChooseCard.Error.FieldRequired\"), `${name.charAt(0).toUpperCase()}${name.slice(1)}`);\r\n } else if (/^\\d+$/.test(value) === false || value.includes('.') || value.includes('-')) {\r\n return;\r\n } else {\r\n let max = cardSettings.quantityMax;\r\n\r\n if (name == \"value\") {\r\n max = cardSettings.valueMax\r\n }\r\n\r\n const modifiedValue = Math.max(1, Math.min(max, Number(value)));\r\n\r\n setStepModel({\r\n ...stepModel,\r\n [name]: modifiedValue\r\n });\r\n }\r\n\r\n setModelErrors({\r\n ...modelErrors,\r\n [name]: error\r\n });\r\n };\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n\r\n if (!isValid()) {\r\n return;\r\n }\r\n\r\n props.handleSubmit(stepModel);\r\n checkboxRef.current.checked = false;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const handleExpandBoxCheck = (): void => {\r\n if (checkboxRef.current.checked && props.activeStep !== BuyGiftCardStateEnum.CHOOSE_CARD_DETAILS) {\r\n props.handleSetActiveStep(BuyGiftCardStateEnum.CHOOSE_CARD_DETAILS);\r\n }\r\n };\r\n\r\n const isValid = (): boolean => {\r\n const cardTotal = stepModel.quantity * stepModel.value;\r\n\r\n setModelErrors({\r\n ...modelErrors,\r\n total: cardTotal > cardSettings.totalValueMax ? \"Invalid total amount\" : \"\"\r\n });\r\n\r\n return ChooseCardStepModel.isValid(stepModel, cardSettings);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.ChooseCard.Title\")}\r\n {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n handleExpandBoxCheck();\r\n }}\r\n >\r\n

\r\n\r\n {props.activeStep === BuyGiftCardStateEnum.CHOOSE_CARD_DETAILS && (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
\r\n
\r\n \r\n\r\n {modelErrors.quantity && (\r\n \r\n {modelErrors.quantity}\r\n \r\n )}\r\n
\r\n
\r\n
\r\n
\r\n \r\n {labels.get(\"GiftCard.App.V2.ChooseCard.Separator\")}\r\n \r\n \r\n {labels.get(\"GiftCard.App.V2.ChooseCard.CurrencySymbol\")}\r\n \r\n
\r\n
\r\n \r\n\r\n {modelErrors.value && (\r\n \r\n {modelErrors.value}\r\n \r\n )}\r\n\r\n \r\n {labels.get(\"GiftCard.App.V2.ChooseCard.Tip1\")}\r\n \r\n
\r\n
\r\n
\r\n
\r\n

\r\n {labels.get(\"GiftCard.App.V2.ChooseCard.Tip2\")}\r\n

\r\n

\r\n {labels.get(\"GiftCard.App.V2.ChooseCard.Tip3\")}\r\n

\r\n
\r\n
\r\n\r\n \r\n {labels.get(\"GiftCard.App.V2.ChooseCard.Button.Submit\")}\r\n \r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ChoooseCardsStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport PhoneInput, { CountryData } from \"react-phone-input-2\";\r\nimport { PHONE_NUMBER, PhoneValidationRegexKeys } from \"../../../../constants/global\";\r\nimport { hasXSSCharacters, isEmail, isFullNameValid } from \"../../../../helpers/Utils\";\r\nimport { ChooseRecipientsStepModel, IChooseRecipientsStepModel } from \"../../../../models/buy-giftcard/choose-card/ChooseRecipientsStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { GiftCardSendTypeEnum } from \"../../../../models/enums/GiftCardSendTypeEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\n\r\ninterface IChooseRecipientsStepProps extends IBuyGiftCardStepProps {\r\n stepModel: IChooseRecipientsStepModel;\r\n isAvailable: boolean;\r\n cardsQuantity: number;\r\n\r\n handleSendIndividuallyChange(sendIndividually: boolean): void;\r\n handleSubmit(stepModel: IChooseRecipientsStepModel): void;\r\n}\r\n\r\nconst ChooseRecipientsStep = (props: IChooseRecipientsStepProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n\r\n const phoneNumberMaxLength = PHONE_NUMBER.VALIDATIONS.MAXLENGTH;\r\n let phoneInputDropdowns = document.querySelectorAll('.flag-dropdown') as NodeListOf;\r\n let phoneNumberErrorMessages = document.querySelectorAll('.invalid-number-message') as NodeListOf;\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [stepModel, setStepModel] = useState({\r\n sendIndividually: props.stepModel?.sendIndividually ?? true,\r\n sendBy: props.stepModel?.sendBy ?? GiftCardSendTypeEnum.BY_EMAIL,\r\n recipients: props.stepModel?.recipients\r\n });\r\n const [isModelValid, setIsModelValid] = useState();\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [recipientErrors, setRecipientErrors] = useState(Array<{\r\n fullName: string,\r\n email: string,\r\n }>);\r\n const [recipientFieldsCount, setRecipientFieldsCount] = useState(props.cardsQuantity ?? 0);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n updateRecipientDetailsErrors();\r\n\r\n setStepModel({\r\n ...stepModel,\r\n recipients: props.stepModel.recipients?.slice(0, props.cardsQuantity)\r\n });\r\n }, []);\r\n\r\n useEffect(() => {\r\n handlePhoneNumberInputStyles();\r\n setIsModelValid(isValid());\r\n }, [stepModel]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.activeStep === BuyGiftCardStateEnum.CHOOSE_RECIPIENTS;\r\n }, [props.activeStep]);\r\n\r\n useEffect(() => {\r\n setRecipientFieldsCount(props.cardsQuantity);\r\n }, [props.cardsQuantity]);\r\n\r\n useEffect(() => {\r\n updateRecipientDetailsErrors();\r\n setStepModel(props.stepModel);\r\n }, [props.stepModel]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleExpandBoxCheck = (): void => {\r\n if (props.isAvailable) {\r\n if (checkboxRef.current.checked && props.activeStep !== BuyGiftCardStateEnum.CHOOSE_RECIPIENTS) {\r\n props.handleSetActiveStep(BuyGiftCardStateEnum.CHOOSE_RECIPIENTS);\r\n }\r\n }\r\n };\r\n\r\n const handleSendIndividuallyChange = (sendIndividually: boolean): void => {\r\n props.handleSendIndividuallyChange(sendIndividually);\r\n\r\n if (sendIndividually) {\r\n setRecipientFieldsCount(props.cardsQuantity);\r\n } else {\r\n setRecipientFieldsCount(1);\r\n }\r\n };\r\n\r\n const handleSendByChange = (sendBy: GiftCardSendTypeEnum): void => {\r\n setStepModel({\r\n ...stepModel,\r\n sendBy: sendBy\r\n });\r\n };\r\n\r\n const handleRecipientDetailsChange = (event: React.ChangeEvent, index: number): void => {\r\n const { name, value } = event.target;\r\n\r\n if (hasXSSCharacters(value)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n let errMsg = '';\r\n\r\n if (name === 'fullName') {\r\n if (!value.trim()) {\r\n errMsg = 'Full name is required';\r\n } else if (!isFullNameValid(value.trim())) {\r\n errMsg = 'Invalid full name';\r\n }\r\n } else if (name === 'email') {\r\n if (!value.trim()) {\r\n errMsg = 'Email is required';\r\n } else if (!isEmail(value)) {\r\n errMsg = 'Invalid email';\r\n }\r\n }\r\n\r\n setRecipientErrors((prevModel) =>\r\n prevModel.map((recErr, i) =>\r\n i === index ? { ...recErr, [name]: errMsg } : recErr\r\n )\r\n );\r\n\r\n setStepModel((prevModel) => ({\r\n ...prevModel,\r\n recipients: prevModel.recipients.map((recipient, i) =>\r\n i === index ? { ...recipient, [name]: value } : recipient\r\n )\r\n }));\r\n };\r\n\r\n const handlePhoneNumberInputStyles = (): void => {\r\n phoneInputDropdowns = document.querySelectorAll('.flag-dropdown') as NodeListOf;\r\n phoneNumberErrorMessages = document.querySelectorAll('.invalid-number-message') as NodeListOf;\r\n\r\n if (phoneInputDropdowns && phoneInputDropdowns.length > 0) {\r\n phoneInputDropdowns.forEach(dropdown => {\r\n dropdown.style.borderColor = '#6b7280';\r\n dropdown.style.borderRightColor = '#cacaca';\r\n });\r\n }\r\n\r\n if (phoneNumberErrorMessages && phoneNumberErrorMessages.length > 0) {\r\n phoneNumberErrorMessages.forEach(errorMessage => {\r\n errorMessage.style.left = '0';\r\n errorMessage.style.top = '42px';\r\n errorMessage.classList.add(\"react-input-error-message\");\r\n });\r\n }\r\n };\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n\r\n if (!isValid()) {\r\n return;\r\n }\r\n\r\n props.handleSubmit(stepModel);\r\n checkboxRef.current.checked = false;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const updateRecipientDetailsErrors = (): void => {\r\n const recipientErrors = [];\r\n\r\n for (let i = 0; i < props.cardsQuantity; i++) {\r\n recipientErrors.push({\r\n fullName: '',\r\n email: '',\r\n });\r\n }\r\n\r\n setRecipientErrors(recipientErrors);\r\n };\r\n\r\n const isValid = (): boolean => {\r\n return ChooseRecipientsStepModel.isValid(stepModel);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n
\r\n {labels.get(\"GiftCard.App.V2.ChooseRecipients.Title\")}\r\n\r\n {(props.activeStep === BuyGiftCardStateEnum.CHOOSE_RECIPIENTS && props.cardsQuantity > 1) && (\r\n
\r\n
    \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleSendIndividuallyChange(true);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleSendIndividuallyChange(false);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
\r\n
\r\n )}\r\n
\r\n {\r\n if (props.isAvailable) {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n handleExpandBoxCheck();\r\n }\r\n }}\r\n >\r\n

\r\n\r\n {props.activeStep === BuyGiftCardStateEnum.CHOOSE_RECIPIENTS && (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
\r\n

{labels.get(\"GiftCard.App.V2.ChooseRecipients.Label.HowToSend\")}

\r\n
    \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleSendByChange(GiftCardSendTypeEnum.BY_EMAIL);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleSendByChange(GiftCardSendTypeEnum.BY_SMS);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleSendByChange(GiftCardSendTypeEnum.BY_PDF);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
\r\n
\r\n
\r\n
    \r\n {Array.from({ length: recipientFieldsCount }).map((_, index) => (\r\n \r\n {stepModel.sendBy === GiftCardSendTypeEnum.BY_EMAIL && (\r\n <>\r\n
  • \r\n handleRecipientDetailsChange(e, index)}\r\n />\r\n handleRecipientDetailsChange(e, index)}\r\n />\r\n
  • \r\n \r\n )}\r\n\r\n {stepModel.sendBy === GiftCardSendTypeEnum.BY_SMS && (\r\n <>\r\n
  • \r\n handleRecipientDetailsChange(e, index)}\r\n />\r\n c.toLowerCase())}\r\n countryCodeEditable={false}\r\n inputClass='react-phone-input'\r\n defaultErrorMessage={labels.get(\"GiftCard.App.V2.ChooseRecipients.Error.Phone\")}\r\n enableLongNumbers={phoneNumberMaxLength}\r\n value={stepModel.recipients[index]?.phone ?? \"\"}\r\n onChange={(phone) => {\r\n if (phone.length > phoneNumberMaxLength) {\r\n phone = phone.slice(0, phoneNumberMaxLength);\r\n }\r\n\r\n setStepModel((prevModel) => ({\r\n ...prevModel,\r\n recipients: prevModel.recipients.map((recipient, i) =>\r\n i === index ? { ...recipient, phone: `+${phone}` } : recipient\r\n )\r\n }));\r\n }}\r\n isValid={(inputNumber, data: CountryData) => {\r\n if (!data || !data.iso2) {\r\n return false;\r\n }\r\n\r\n const allowedCountriesAbbr = Object.keys(PHONE_NUMBER.COUNTRIES).map(c => c.toLowerCase());\r\n if (allowedCountriesAbbr.includes(data.iso2.toLowerCase())) {\r\n const regexKey = data.iso2.toUpperCase() as PhoneValidationRegexKeys;\r\n const regex = PHONE_NUMBER.VALIDATIONS.REGEX[regexKey] as RegExp;\r\n\r\n if (regex) {\r\n return regex.test(stepModel.recipients[index]?.phone);\r\n }\r\n }\r\n\r\n return false;\r\n }}\r\n />\r\n
  • \r\n \r\n )}\r\n\r\n {stepModel.sendBy === GiftCardSendTypeEnum.BY_PDF && (\r\n <>\r\n
  • \r\n handleRecipientDetailsChange(e, index)}\r\n />\r\n
  • \r\n \r\n )}\r\n
    \r\n ))}\r\n
\r\n
\r\n \r\n {labels.get(\"GiftCard.App.V2.ChooseRecipients.Button.Submit\")}\r\n \r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ChooseRecipientsStep;","import React, { useEffect, useRef, useState } from \"react\";\r\nimport { hasXSSCharacters } from \"../../../../helpers/Utils\";\r\nimport { ChooseSenderStepModel, IChooseSenderStepModel } from \"../../../../models/buy-giftcard/choose-card/ChooseSenderStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\n\r\ninterface IChooseSenderStepProps extends IBuyGiftCardStepProps {\r\n stepModel: IChooseSenderStepModel;\r\n isAvailable: boolean;\r\n\r\n handleSubmit(stepModel: IChooseSenderStepModel): void;\r\n}\r\n\r\nconst ChooseSenderStep = (props: IChooseSenderStepProps) => {\r\n const { labels } = React.useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [stepModel, setStepModel] = useState({\r\n fullName: props.stepModel?.fullName ?? \"\"\r\n });\r\n const [isModelValid, setIsModelValid] = useState();\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [modelErrors, setModelErrors] = useState({\r\n fullName: ''\r\n });\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsModelValid(isValid());\r\n }, [stepModel]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.activeStep === BuyGiftCardStateEnum.CHOOSE_SENDER;\r\n }, [props.activeStep]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleExpandBoxCheck = (): void => {\r\n if (props.isAvailable) {\r\n if (checkboxRef.current.checked && props.activeStep !== BuyGiftCardStateEnum.CHOOSE_SENDER) {\r\n props.handleSetActiveStep(BuyGiftCardStateEnum.CHOOSE_SENDER);\r\n }\r\n }\r\n };\r\n\r\n const handleFullNameChange = (event: React.ChangeEvent): void => {\r\n const { value } = event.target;\r\n\r\n if (hasXSSCharacters(value)) {\r\n event.preventDefault();\r\n } else {\r\n let errMsg = '';\r\n\r\n if (!value.trim()) {\r\n errMsg = labels.get(\"GiftCard.App.V2.ChooseSender.Error.FieldRequired\");\r\n }\r\n\r\n setModelErrors({ fullName: errMsg });\r\n setStepModel({ fullName: value });\r\n }\r\n };\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n\r\n if (!isValid()) {\r\n return;\r\n }\r\n\r\n props.handleSubmit(stepModel);\r\n checkboxRef.current.checked = false;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const isValid = (): boolean => {\r\n return ChooseSenderStepModel.isValid(stepModel);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.ChooseSender.Title\")}\r\n {\r\n if (props.isAvailable) {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n handleExpandBoxCheck();\r\n }\r\n }}\r\n >\r\n

\r\n\r\n {props.activeStep === BuyGiftCardStateEnum.CHOOSE_SENDER && (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n

{labels.get(\"GiftCard.App.V2.ChooseSender.Subtitle\")}

\r\n\r\n \r\n\r\n {modelErrors.fullName && (\r\n \r\n {modelErrors.fullName}\r\n \r\n )}\r\n\r\n \r\n {labels.get(\"GiftCard.App.V2.ChooseSender.Button.Submit\")}\r\n \r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ChooseSenderStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport IGiftCardTemplate from \"../../../../models/GiftCardTemplate.model\";\r\nimport { CustomiseCardStepModel, ICustomiseCardStepModel } from \"../../../../models/buy-giftcard/customise-card/CustomiseCardStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport DataService from \"../../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\nimport MediaUploader from \"../../shared/MediaUploader\";\r\n\r\ninterface ICustomiseCardStepProps extends IBuyGiftCardStepProps {\r\n stepModel: ICustomiseCardStepModel;\r\n\r\n handleTemplateChange(model: ICustomiseCardStepModel): void;\r\n handleGoBack(): void;\r\n handleSubmit(stepModel: ICustomiseCardStepModel): void;\r\n}\r\n\r\nconst CustomiseGiftCardStep = (props: ICustomiseCardStepProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n const culture = document.documentElement.lang;\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [stepModel, setStepModel] = useState({\r\n giftCardUrl: props.stepModel?.giftCardUrl ?? \"\",\r\n useCardTemplate: props.stepModel?.useCardTemplate,\r\n userGiftCards: []\r\n });\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [isModelValid, setIsModelValid] = useState();\r\n const [templates, setTemplates] = useState(Array(0))\r\n const [lastUploadedTemplate, setLastUploadedTemplate] = useState(\"\");\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n loadAllTemplates();\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (templates && templates.length > 0) {\r\n if (!templates.map(x => x.imageUrl).includes(stepModel.giftCardUrl)) {\r\n setLastUploadedTemplate(stepModel.giftCardUrl);\r\n handleUseCardTemplateChange(false);\r\n }\r\n\r\n setIsLoading(false);\r\n }\r\n }, [templates]);\r\n\r\n useEffect(() => {\r\n setIsModelValid(isValid());\r\n }, [stepModel]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.activeStep === BuyGiftCardStateEnum.CUSTOMISE_CARD;\r\n }, [props.activeStep]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleExpandBoxCheck = (): void => {\r\n if (checkboxRef.current.checked && props.activeStep !== BuyGiftCardStateEnum.CUSTOMISE_CARD) {\r\n props.handleSetActiveStep(BuyGiftCardStateEnum.CUSTOMISE_CARD);\r\n }\r\n };\r\n\r\n const handleUseCardTemplateChange = (useCardTemplate: boolean): void => {\r\n setStepModel({\r\n ...stepModel,\r\n useCardTemplate: useCardTemplate\r\n });\r\n };\r\n\r\n const handleTemplateChange = (templateUrl: string): void => {\r\n if (templateUrl.trim()) {\r\n setStepModel({\r\n ...stepModel,\r\n giftCardUrl: templateUrl\r\n });\r\n\r\n props.handleTemplateChange({\r\n giftCardUrl: templateUrl,\r\n useCardTemplate: stepModel.useCardTemplate,\r\n userGiftCards: stepModel.userGiftCards\r\n });\r\n }\r\n };\r\n\r\n const handleGoBack = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n props.handleGoBack();\r\n };\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n\r\n if (!isValid()) {\r\n return;\r\n }\r\n\r\n props.handleSubmit(stepModel);\r\n checkboxRef.current.checked = false;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const loadAllTemplates = (): void => {\r\n DataService.getGiftCardsTemplates(culture)\r\n .then(response => {\r\n if (response) {\r\n const resTemplates = Array(0);\r\n\r\n response.forEach(item => {\r\n resTemplates.push(item);\r\n });\r\n\r\n setTemplates(resTemplates);\r\n }\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n };\r\n\r\n const isValid = (): boolean => {\r\n return CustomiseCardStepModel.isValid(stepModel);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.CustomiseCard.Title\")}\r\n {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n handleExpandBoxCheck();\r\n }}\r\n >\r\n

\r\n\r\n {props.activeStep === BuyGiftCardStateEnum.CUSTOMISE_CARD && (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
    \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleUseCardTemplateChange(true);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleUseCardTemplateChange(false);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
\r\n\r\n {stepModel.useCardTemplate ? (\r\n
\r\n {templates.map((template, index) => (\r\n handleTemplateChange(template.imageUrl)}\r\n />\r\n ))}\r\n
\r\n ) : (\r\n \r\n )}\r\n\r\n
\r\n \r\n {labels.get(\"GiftCard.App.V2.CustomiseCard.Button.GoBack\")}\r\n \r\n \r\n {labels.get(\"GiftCard.App.V2.CustomiseCard.Button.Submit\")}\r\n \r\n
\r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default CustomiseGiftCardStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport { PERSONAL_MESSAGE_MAX_LENGTH } from \"../../../../constants/global\";\r\nimport { useDebounce } from \"../../../../debounce\";\r\nimport { hasXSSCharacters } from \"../../../../helpers/Utils\";\r\nimport IGiftCardGif from \"../../../../models/GiftCardGif.model\";\r\nimport { CustomiseMailStepModel, ICustomiseMailStepModel } from \"../../../../models/buy-giftcard/customise-card/CustomiseMailStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport DataService from \"../../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\nimport MediaUploader from \"../../shared/MediaUploader\";\r\n\r\ninterface ICustomiseMailStepProps extends IBuyGiftCardStepProps {\r\n stepModel: ICustomiseMailStepModel;\r\n isAvailable: boolean;\r\n\r\n handlePersonalMessageChange(personalMessage: string): void;\r\n handleMediaChange(mediaUrl: string): void;\r\n handleGoBack(): void;\r\n handleSubmit(stepModel: ICustomiseMailStepModel): void;\r\n}\r\n\r\nconst CustomiseMailStep = (props: ICustomiseMailStepProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n const culture = document.documentElement.lang;\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [stepModel, setStepModel] = useState({\r\n writePersonalMessage: props.stepModel?.writePersonalMessage,\r\n personalMessage: props.stepModel?.personalMessage ?? \"\",\r\n addMedia: props.stepModel?.addMedia,\r\n useGif: props.stepModel?.useGif,\r\n mediaUrl: props.stepModel?.mediaUrl,\r\n userMedias: props.stepModel?.userMedias\r\n });\r\n const [isModelValid, setIsModelValid] = useState();\r\n const [lastUploadedTemplate, setLastUploadedTemplate] = useState(\"\");\r\n const [gifs, setGifs] = useState(Array(0));\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [areGifsLoading, setAreGifsLoading] = useState();\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if ((stepModel.mediaUrl && !stepModel.useGif) || (stepModel.mediaUrl && !stepModel.mediaUrl.includes(\"giphy.com\"))) {\r\n setLastUploadedTemplate(stepModel.mediaUrl);\r\n setStepModel({\r\n ...stepModel,\r\n addMedia: true,\r\n useGif: false\r\n });\r\n\r\n props.handleMediaChange(stepModel.mediaUrl);\r\n } else if ((stepModel.mediaUrl && stepModel.useGif) || (stepModel.mediaUrl && stepModel.mediaUrl.includes(\"giphy.com\"))) {\r\n setStepModel({\r\n ...stepModel,\r\n addMedia: true,\r\n useGif: true\r\n });\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n setIsModelValid(isValid());\r\n }, [stepModel]);\r\n\r\n useEffect(() => {\r\n setAreGifsLoading(false);\r\n\r\n setTimeout(() => {\r\n initSlider();\r\n }, 600);\r\n }, [gifs]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.activeStep === BuyGiftCardStateEnum.CUSTOMISE_MAIL;\r\n\r\n setTimeout(() => {\r\n if (stepModel.addMedia && stepModel.useGif) {\r\n loadAllGifs(\"\");\r\n }\r\n }, 200);\r\n }, [props.activeStep]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleExpandBoxCheck = (): void => {\r\n if (props.isAvailable) {\r\n if (checkboxRef.current.checked && props.activeStep !== BuyGiftCardStateEnum.CUSTOMISE_MAIL) {\r\n props.handleSetActiveStep(BuyGiftCardStateEnum.CUSTOMISE_MAIL);\r\n\r\n setTimeout(() => {\r\n if (stepModel.addMedia && stepModel.useGif) {\r\n loadAllGifs(\"\");\r\n }\r\n }, 200);\r\n }\r\n }\r\n };\r\n\r\n const handleWritePersonalMessageSwitch = (event: React.ChangeEvent): void => {\r\n setStepModel({\r\n ...stepModel,\r\n writePersonalMessage: event.target.checked\r\n });\r\n\r\n if (event.target.checked) {\r\n props.handlePersonalMessageChange(stepModel.personalMessage);\r\n } else {\r\n props.handlePersonalMessageChange(\"\");\r\n }\r\n };\r\n\r\n const handlePersonalMessageChange = (event: React.ChangeEvent): void => {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n } else {\r\n setStepModel({\r\n ...stepModel,\r\n personalMessage: event.target.value\r\n });\r\n\r\n props.handlePersonalMessageChange(event.target.value);\r\n }\r\n };\r\n\r\n const handleAddMediaSwitch = (event: React.ChangeEvent): void => {\r\n setStepModel({\r\n ...stepModel,\r\n addMedia: event.target.checked\r\n });\r\n\r\n if (event.target.checked) {\r\n props.handleMediaChange(stepModel.mediaUrl);\r\n loadAllGifs(\"\");\r\n } else {\r\n props.handleMediaChange(\"\");\r\n }\r\n };\r\n\r\n const handleUseGifChange = (useGif: boolean): void => {\r\n if (useGif) {\r\n loadAllGifs(\"\");\r\n }\r\n\r\n setStepModel({\r\n ...stepModel,\r\n useGif: useGif\r\n });\r\n };\r\n\r\n const handleGifSearch = useDebounce>((event) => {\r\n loadAllGifs(event.target.value);\r\n }, 1000);\r\n\r\n const handleMediaChange = (mediaUrl: string): void => {\r\n // deselect if already selected\r\n if (mediaUrl === stepModel.mediaUrl) {\r\n mediaUrl = \"\";\r\n }\r\n\r\n setStepModel({\r\n ...stepModel,\r\n addMedia: true,\r\n mediaUrl: mediaUrl\r\n });\r\n\r\n props.handleMediaChange(mediaUrl);\r\n };\r\n\r\n const handleGoBack = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n props.handleGoBack();\r\n };\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n\r\n if (!isValid()) {\r\n return;\r\n }\r\n\r\n props.handleSubmit(stepModel);\r\n checkboxRef.current.checked = false;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const loadAllGifs = (searchTerm: string): void => {\r\n setAreGifsLoading(true);\r\n\r\n DataService.getGiftCardsGifsTemplates(culture, searchTerm)\r\n .then(response => {\r\n if (response) {\r\n const gifItems = Array(0);\r\n response.forEach((item, index) => {\r\n gifItems.push(item);\r\n });\r\n\r\n setGifs(gifItems);\r\n }\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n };\r\n\r\n const initSlider = (): void => {\r\n if (document.querySelector('.swiper-gif')) {\r\n // @ts-ignore\r\n const swiperGif = new Swiper('.swiper-gif', {\r\n slidesPerView: \"auto\",\r\n spaceBetween: 0,\r\n slidesPerGroup: 2,\r\n grid: {\r\n rows: 2,\r\n },\r\n freeMode: true,\r\n navigation: {\r\n nextEl: '.swiper-gif-button-next',\r\n prevEl: '.swiper-gif-button-prev',\r\n },\r\n });\r\n }\r\n };\r\n\r\n const isValid = (): boolean => {\r\n return CustomiseMailStepModel.isValid(stepModel);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.CustomiseMail.Title\")}\r\n {\r\n if (props.isAvailable) {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n handleExpandBoxCheck();\r\n }\r\n }}\r\n >\r\n

\r\n {props.activeStep === BuyGiftCardStateEnum.CUSTOMISE_MAIL && (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
\r\n
\r\n {/*
{labels.get(\"GiftCard.App.V2.CustomiseMail.Subtitle\")}
*/}\r\n \r\n
\r\n

{labels.get(\"GiftCard.App.V2.CustomiseMail.Label.PersonalMessage\")}

\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n
\r\n \r\n {PERSONAL_MESSAGE_MAX_LENGTH - stepModel.personalMessage.length}/{PERSONAL_MESSAGE_MAX_LENGTH}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n

Add a Photo, Video or GIF

\r\n \r\n
\r\n\r\n {stepModel.addMedia && (\r\n <>\r\n
    \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleUseGifChange(true);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleUseGifChange(false);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
\r\n\r\n {stepModel.useGif ? (\r\n
\r\n
\r\n
\r\n \r\n\r\n
\r\n
\r\n {areGifsLoading ? (\r\n \r\n ) : (\r\n
\r\n {gifs.map((gif, index) => (\r\n
\r\n handleMediaChange(gif.video.trim() ? gif.video : gif.image)}\r\n >\r\n \r\n \r\n
\r\n ))}\r\n
\r\n )}\r\n
\r\n\r\n
\r\n \r\n \r\n \r\n {labels.get(\"GiftCard.App.Steps.Customise.Templates.Btn.Previous\")}\r\n
\r\n
\r\n {labels.get(\"GiftCard.App.Steps.Customise.Templates.Btn.Next\")}\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n ) : (\r\n \r\n )}\r\n \r\n )}\r\n
\r\n
\r\n
\r\n \r\n {labels.get(\"GiftCard.App.V2.CustomiseMail.Button.GoBack\")}\r\n \r\n \r\n {labels.get(\"GiftCard.App.V2.CustomiseMail.Button.Submit\")}\r\n \r\n
\r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n \r\n );\r\n};\r\n\r\nexport default CustomiseMailStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport { findLinkByAlias } from \"../../../../helpers/GiftCardHelper\";\r\nimport { formatStringWithPlaceholders, isNotNullOrEmpty } from \"../../../../helpers/Utils\";\r\nimport { CheckoutBillingAddressData } from \"../../../../models/ElavonCheckoutModels\";\r\nimport { CheckoutStatusEnum } from \"../../../../models/GiftCardCheckoutResult.model\";\r\nimport { IInvoiceDetails } from \"../../../../models/InvoiceDetails.model\";\r\nimport { ICheckoutSessionData } from \"../../../../models/PaymentStep.model\";\r\nimport { IBuyGiftCardModel } from \"../../../../models/buy-giftcard/BuyGiftCard.model\";\r\nimport { IReviewAndPayPaymentStepModel, ReviewAndPayPaymentStepModel } from \"../../../../models/buy-giftcard/review-pay/ReviewAndPayPaymentStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { BuyGiftCardSubpageEnum } from \"../../../../models/enums/BuyGiftCardSubpageEnum\";\r\nimport { PaymentTypeEnum } from \"../../../../models/enums/PaymentTypeEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport DataService from \"../../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\nimport ElavonPayment, { HandleElavonCheckout, HandleThreeDSecureAuth } from \"../../shared/ElavonPayment\";\r\nimport InvoiceDetails from \"../../shared/InvoiceDetails\";\r\n\r\ninterface IReviewAndPayPaymentDetails {\r\n totalAmount: number;\r\n senderInfo: {\r\n isBusinessBuyer: boolean;\r\n fullName: string;\r\n email: string;\r\n companyName: string;\r\n };\r\n}\r\n\r\ninterface IReviewAndPayPaymentStepProps extends IBuyGiftCardStepProps {\r\n stepModel: IReviewAndPayPaymentStepModel;\r\n paymentDetails: IReviewAndPayPaymentDetails;\r\n isAvailable: boolean;\r\n\r\n getPageModel(): IBuyGiftCardModel;\r\n handleError(message: string): void;\r\n handleStateChange(newSubpage: BuyGiftCardSubpageEnum, newState: BuyGiftCardStateEnum): void;\r\n handleSubmit(model: IReviewAndPayPaymentStepModel): void;\r\n}\r\n\r\nconst ReviewAndPayPaymentStep = (props: IReviewAndPayPaymentStepProps) => {\r\n const { labels, elavonSettings, links, cardSettings } = useContext(AppSettingContext);\r\n\r\n const checkboxRef = useRef(null);\r\n const checkboxPaymentFormCompleteRef = useRef(null);\r\n const termsPageUrl = findLinkByAlias(\"terms-page\", links);\r\n const culture = document.documentElement.lang ?? \"en-GB\";\r\n const basketId = (props.getPageModel()).id;\r\n const errQueryParamKey = 'sp-err-code';\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [stepModel, setStepModel] = useState(props.stepModel);\r\n const [isModelValid, setIsModelValid] = useState();\r\n const [isLoading, setIsLoading] = useState(true);\r\n\r\n const [isCardPaymentLoading, setIsCardPaymentLoading] = useState(false);\r\n const [isPaymentSaving, setIsPaymentSaving] = useState(false);\r\n const [checkoutBillingDetails, setCheckoutBillingDetails] = useState();\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n\r\n if (!elavonSettings.showCheckoutForm) {\r\n setStepModel({\r\n ...stepModel,\r\n paymentType: PaymentTypeEnum.BANK\r\n });\r\n\r\n return;\r\n }\r\n\r\n if (props.activeStep === BuyGiftCardStateEnum.REVIEW_PAY_PAYMENT) {\r\n handlePaymentStepInitialization();\r\n } else {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n if (urlParams.has(errQueryParamKey)) {\r\n urlParams.delete(errQueryParamKey);\r\n\r\n const updatedQueryParams = urlParams.size > 0 ? `?${urlParams.toString()}` : \"\";\r\n window.history.replaceState({}, '', `${window.location.pathname}${updatedQueryParams}`);\r\n }\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n setIsModelValid(isValid());\r\n\r\n setTimeout(() => {\r\n setIsCardPaymentLoading(false);\r\n }, 300);\r\n }, [stepModel]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.activeStep === BuyGiftCardStateEnum.REVIEW_PAY_PAYMENT;\r\n\r\n if (props.activeStep !== BuyGiftCardStateEnum.REVIEW_PAY_PAYMENT) {\r\n setStepModel({\r\n ...stepModel,\r\n termsAccepted: false\r\n });\r\n }\r\n }, [props.activeStep]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleExpandBoxCheck = (): void => {\r\n if (props.isAvailable) {\r\n if (checkboxRef.current.checked && props.activeStep !== BuyGiftCardStateEnum.REVIEW_PAY_PAYMENT) {\r\n props.handleSetActiveStep(BuyGiftCardStateEnum.REVIEW_PAY_PAYMENT);\r\n }\r\n }\r\n };\r\n\r\n const handlePaymentTypeChange = async (paymentType: PaymentTypeEnum): Promise => {\r\n setIsCardPaymentLoading(true);\r\n const currPaymentDetails = stepModel.paymentDetails;\r\n\r\n if (paymentType === PaymentTypeEnum.CREDIT_CARD) {\r\n const checkoutSession = await createNewCheckoutSession(false);\r\n currPaymentDetails.checkoutKey = checkoutSession.sessionKey;\r\n currPaymentDetails.checkoutExpiry = checkoutSession.expiry;\r\n }\r\n\r\n setStepModel({\r\n ...stepModel,\r\n paymentType: paymentType,\r\n paymentDetails: currPaymentDetails\r\n });\r\n };\r\n\r\n const handlePaymentStepInitialization = () => {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const spErrQueryParam = urlParams.get(errQueryParamKey);\r\n const newStepModel = { ...stepModel };\r\n\r\n if (spErrQueryParam) {\r\n newStepModel.paymentType = PaymentTypeEnum.CREDIT_CARD;\r\n }\r\n\r\n setStepModel(newStepModel);\r\n\r\n setTimeout(() => {\r\n if (spErrQueryParam) {\r\n handlePaymentTypeChange(PaymentTypeEnum.CREDIT_CARD);\r\n\r\n setTimeout(() => {\r\n let errMsg = labels.get(`GiftCard.App.Steps.PreviewAndPay.Card.Errors.ThreeDForm${spErrQueryParam}`);\r\n if (!errMsg) {\r\n errMsg = labels.get(\"GiftCard.App.Steps.PreviewAndPay.Card.Errors.ThreeDForm2\")\r\n }\r\n\r\n switch (spErrQueryParam) {\r\n case \"1\": console.error(`3D secure authentication returned status, other than 'Ok'.\\r\\n${errMsg}`); break;\r\n case \"2\": console.error(`Some of the parameters sent to GiftCardService 3D authentication method were invalid.\\r\\n${errMsg}`); break;\r\n case \"3\": console.error(`Services API returned BadRequest.\\r\\n${errMsg}`); break;\r\n case \"4\": console.error(`Unauthorized access to Services API 3D secure endpoint.\\r\\n${errMsg}`); break;\r\n case \"5\": console.error(`Services API returned invalid response.\\r\\n${errMsg}`); break;\r\n case \"6\": console.error(`An unhandled error occurred processing 3D authentication response.\\r\\n${errMsg}`); break;\r\n default: break;\r\n }\r\n\r\n displayError(errMsg);\r\n }, 500);\r\n\r\n const checkoutErrorDiv = document.querySelector(\"label[for=credit-debit-card]\");\r\n if (checkoutErrorDiv) {\r\n checkoutErrorDiv.scrollIntoView();\r\n }\r\n }\r\n }, 600);\r\n };\r\n\r\n const handleCreditCardFormUpdate = (isFormValid: boolean, billingDetails: CheckoutBillingAddressData): void => {\r\n const paymentCompletedChk = document.getElementById('chkPaymentCompleted') as HTMLInputElement;\r\n\r\n if (paymentCompletedChk) {\r\n paymentCompletedChk.checked = !isFormValid;\r\n paymentCompletedChk.click();\r\n }\r\n\r\n if (isFormValid) {\r\n setCheckoutBillingDetails(billingDetails);\r\n }\r\n };\r\n\r\n const handleInvoiceUpdate = (invoiceDetails: IInvoiceDetails): void => {\r\n if (invoiceDetails) {\r\n setStepModel({\r\n ...stepModel,\r\n invoiceDetails: invoiceDetails\r\n });\r\n }\r\n };\r\n\r\n const handleTermsAcceptedChange = (event: React.ChangeEvent): void => {\r\n setStepModel({\r\n ...stepModel,\r\n termsAccepted: event.target.checked\r\n });\r\n };\r\n\r\n const handleGoBack = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n props.handleStateChange(BuyGiftCardSubpageEnum.CUSTOMISE_CARD, BuyGiftCardStateEnum.CUSTOMISE_MAIL);\r\n };\r\n\r\n const handleSaveAndContinue = async (event: React.MouseEvent): Promise => {\r\n event.preventDefault();\r\n\r\n if (stepModel.paymentType === PaymentTypeEnum.CREDIT_CARD) {\r\n if (stepModel.paymentCompleted) {\r\n const paymentForm = document.getElementById('checkout-form') as HTMLFormElement;\r\n if (!paymentForm) {\r\n displayError(\"Unable to find a payment form. Please refresh the page.\");\r\n return;\r\n }\r\n\r\n toggleFormVisibility(false);\r\n\r\n if (new Date(stepModel.paymentDetails.checkoutExpiry) <= new Date()) {\r\n await createNewCheckoutSession(true);\r\n }\r\n\r\n HandleElavonCheckout({\r\n sessionKey: stepModel.paymentDetails.checkoutKey,\r\n expiry: stepModel.paymentDetails.checkoutExpiry\r\n });\r\n\r\n setTimeout(async () => {\r\n await creditCardProcessPayment();\r\n }, 600);\r\n }\r\n } else if (stepModel.paymentType === PaymentTypeEnum.BANK) {\r\n setIsPaymentSaving(true);\r\n props.handleSubmit(stepModel);\r\n\r\n setTimeout(() => {\r\n setIsPaymentSaving(false);\r\n }, 3000);\r\n }\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const displayError = (errorMessage: string) => {\r\n const errorContainer = document.querySelector(\"#checkout-error\") as HTMLDivElement;\r\n\r\n if (errorContainer) {\r\n errorContainer.style.display = \"block\";\r\n errorContainer.textContent = errorMessage;\r\n }\r\n };\r\n\r\n const toggleFormVisibility = (visible: boolean) => {\r\n const paymentBoxEl = document.getElementById(\"payment-box\");\r\n if (paymentBoxEl) {\r\n paymentBoxEl.style.opacity = visible ? \"1\" : \"0.2\";\r\n }\r\n\r\n const paymentSubmitBtnEl = document.getElementById(\"paymentSubmitBtn\") as HTMLButtonElement;\r\n if (paymentSubmitBtnEl) {\r\n paymentSubmitBtnEl.disabled = !visible;\r\n }\r\n };\r\n\r\n const getSenderDetailsForCreditCardPayment = () => {\r\n let firstName = \"\";\r\n let lastName = \"\";\r\n\r\n const spaceIdx = props.paymentDetails.senderInfo.fullName.indexOf(\" \");\r\n if (spaceIdx === -1) {\r\n firstName = props.paymentDetails.senderInfo.fullName ?? \"\";\r\n lastName = \"\";\r\n } else {\r\n firstName = props.paymentDetails.senderInfo.fullName.substring(0, spaceIdx) ?? \"\";\r\n lastName = props.paymentDetails.senderInfo.fullName.substring(spaceIdx + 1) ?? \"\";\r\n }\r\n\r\n return {\r\n firstName: firstName,\r\n lastName: lastName,\r\n email: props.paymentDetails.senderInfo.email ?? \"\",\r\n phone: \"\",\r\n };\r\n };\r\n\r\n const createNewCheckoutSession = async (setSessionKeyModel: boolean): Promise => {\r\n const amount = props.paymentDetails.totalAmount;\r\n if (!amount || amount === 0) {\r\n console.error(\"An attempt to create new checkout session was made, but the checkout amount was invalid.\");\r\n return;\r\n }\r\n\r\n if (!basketId) {\r\n console.error(\"An attempt to create new checkout session was made, but the basketId was invalid.\")\r\n return;\r\n }\r\n\r\n const newMerchantSession = await DataService.getCheckoutData(basketId, amount, stepModel.paymentDetails.currency ?? \"EUR\");\r\n //console.log('Newly created merchant session: ', newMerchantSession);\r\n\r\n if (!setSessionKeyModel) {\r\n return newMerchantSession;\r\n }\r\n\r\n const newPaymentDetailsObj = stepModel.paymentDetails;\r\n newPaymentDetailsObj.checkoutKey = newMerchantSession.sessionKey;\r\n newPaymentDetailsObj.checkoutExpiry = newMerchantSession.expiry;\r\n\r\n setStepModel(currStepModel => ({\r\n ...currStepModel,\r\n paymentDetails: newPaymentDetailsObj\r\n }));\r\n\r\n return newMerchantSession;\r\n };\r\n\r\n const creditCardProcessPayment = async () => {\r\n const cardIdentifierField = document.querySelector(\"#cardIdentifier-field\") as HTMLInputElement;\r\n const cardIdentifier = cardIdentifierField.value;\r\n\r\n if (!cardIdentifier) {\r\n console.error(\"Empty card identifier returned from SagePay API.\");\r\n displayError(labels.get(\"GiftCard.App.Steps.PreviewAndPay.Card.Errors.SagePay\"));\r\n\r\n await createNewCheckoutSession(true);\r\n toggleFormVisibility(true);\r\n return;\r\n }\r\n\r\n console.log(`%cSuccessfully tokenised the card details\\r\\nCard identifier: ${cardIdentifier}`, 'color: green; font-weight: bold;');\r\n setIsPaymentSaving(true);\r\n\r\n const pageModel = props.getPageModel();\r\n pageModel.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.checkoutKey = stepModel.paymentDetails.checkoutKey;\r\n pageModel.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.checkoutExpiry = stepModel.paymentDetails.checkoutExpiry;\r\n DataService.updateBuyGiftCardModelCache(pageModel, culture)\r\n .then(async (response) => {\r\n if (response) {\r\n const checkoutRes = await DataService.submitCreditCardPayment('Buy', basketId, stepModel.paymentDetails.checkoutKey, cardIdentifier, checkoutBillingDetails);\r\n if (checkoutRes) {\r\n if (checkoutRes.checkoutStatus == CheckoutStatusEnum.Success) {\r\n if (isNotNullOrEmpty(checkoutRes.thankYouPageUrl)) {\r\n window.location.href = checkoutRes.thankYouPageUrl;\r\n return;\r\n } else {\r\n console.error(\"Invalid ThankYou page url provided\");\r\n window.location.href = \"/\";\r\n }\r\n } else if (checkoutRes.checkoutStatus == CheckoutStatusEnum.Secure3DAuth) {\r\n const handleThreeDError = async (errorMessage: string) => {\r\n const baseErrorMessage = labels.get(\"GiftCard.App.Steps.PreviewAndPay.Card.Errors.ThreeDForm0\");\r\n\r\n console.error(`${baseErrorMessage} ${errorMessage}`);\r\n displayError(baseErrorMessage);\r\n await createNewCheckoutSession(true);\r\n toggleFormVisibility(true);\r\n setIsPaymentSaving(false);\r\n };\r\n\r\n HandleThreeDSecureAuth(checkoutRes, handleThreeDError);\r\n return;\r\n } else if (checkoutRes.checkoutStatus == CheckoutStatusEnum.Failed || checkoutRes.checkoutStatus == CheckoutStatusEnum.Rejected) {\r\n displayError(checkoutRes.statusMessage);\r\n await createNewCheckoutSession(true);\r\n toggleFormVisibility(true);\r\n setIsPaymentSaving(false);\r\n return;\r\n }\r\n }\r\n\r\n setTimeout(() => {\r\n setIsPaymentSaving(false);\r\n toggleFormVisibility(true);\r\n }, 1000);\r\n } else {\r\n setIsPaymentSaving(false);\r\n props.handleError(\"Unable to update basket cache\");\r\n console.error(\"Unable to update basket cache while checking out. Received an invalid response.\");\r\n }\r\n }).catch((error) => {\r\n setIsPaymentSaving(false);\r\n props.handleError(error);\r\n console.error(error);\r\n });\r\n };\r\n\r\n const isValid = (): boolean => {\r\n if (props.paymentDetails.senderInfo.isBusinessBuyer && stepModel.paymentType === PaymentTypeEnum.BANK) {\r\n if (!stepModel.invoiceDetails.companyName || !stepModel.invoiceDetails.companyName.trim()) {\r\n return false;\r\n }\r\n }\r\n\r\n return ReviewAndPayPaymentStepModel.isValid(stepModel);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.ReviewAndPayPayment.Title\")}\r\n {\r\n if (props.isAvailable) {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n handleExpandBoxCheck();\r\n }\r\n }}\r\n >\r\n

\r\n\r\n {/* In case post basket request takes longer to load, display a loader */}\r\n {props.activeStep === BuyGiftCardStateEnum.REVIEW_PAY_WHEN_TO_SEND && isLoading && (\r\n \r\n )}\r\n\r\n {props.activeStep === BuyGiftCardStateEnum.REVIEW_PAY_PAYMENT && (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n {elavonSettings.showCheckoutForm && props.paymentDetails.totalAmount <= (cardSettings.cardPaymentValueMax ?? 5000) && (\r\n {\r\n if (e.target.checked) {\r\n handlePaymentTypeChange(PaymentTypeEnum.CREDIT_CARD);\r\n }\r\n }}\r\n checked={stepModel.paymentType === PaymentTypeEnum.CREDIT_CARD}\r\n />\r\n )}\r\n\r\n {\r\n if (e.target.checked) {\r\n handlePaymentTypeChange(PaymentTypeEnum.BANK);\r\n }\r\n }}\r\n checked={stepModel.paymentType === PaymentTypeEnum.BANK}\r\n />\r\n\r\n {isCardPaymentLoading ? (\r\n \r\n ) : (\r\n <>\r\n
\r\n {elavonSettings.showCheckoutForm && props.paymentDetails.totalAmount <= (cardSettings.cardPaymentValueMax ?? 5000) ? (\r\n \r\n ) : (\r\n \r\n )}\r\n\r\n \r\n
\r\n\r\n {(stepModel.paymentType === PaymentTypeEnum.CREDIT_CARD && elavonSettings.showCheckoutForm && props.paymentDetails.totalAmount <= (cardSettings.cardPaymentValueMax ?? 5000)) &&\r\n \r\n }\r\n\r\n {stepModel.paymentType === PaymentTypeEnum.BANK &&\r\n \r\n }\r\n \r\n )}\r\n\r\n
\r\n
\r\n \r\n
\r\n\r\n {isPaymentSaving ? (\r\n \r\n ) : (\r\n
\r\n {\r\n setStepModel({\r\n ...stepModel,\r\n paymentCompleted: checkboxPaymentFormCompleteRef.current.checked\r\n });\r\n }}\r\n defaultChecked={false}\r\n data-review-pay-box-hide\r\n />\r\n \r\n {labels.get(\"GiftCard.App.V2.ReviewAndPayPayment.Button.GoBack\")}\r\n \r\n \r\n {formatStringWithPlaceholders(\r\n labels.get(\"GiftCard.App.V2.ReviewAndPayPayment.Button.Submit\"),\r\n `${stepModel.paymentDetails.currency ?? \"€\"}${props.paymentDetails.totalAmount.toFixed(2) ?? \"0.00\"}`\r\n )}\r\n \r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ReviewAndPayPaymentStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport { IRecipientDetails } from \"../../../../models/buy-giftcard/choose-card/ChooseRecipientsStep.model\";\r\nimport { GiftCardSendTypeEnum } from \"../../../../models/enums/GiftCardSendTypeEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\n\r\nexport interface IReviewAndPayReviewStepModel {\r\n recipients: Array;\r\n sendBy: GiftCardSendTypeEnum;\r\n totalAmount: number;\r\n}\r\n\r\ninterface IReviewAndPayReviewStepProps extends IBuyGiftCardStepProps {\r\n stepModel: IReviewAndPayReviewStepModel;\r\n}\r\n\r\nconst ReviewAndPayReviewStep = (props: IReviewAndPayReviewStepProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [expandRecipients, setExpandRecipients] = useState(false);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.ReviewAndPayReview.Title\")}\r\n {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n }}\r\n >\r\n

\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
{labels.get(\"GiftCard.App.V2.ReviewAndPayReview.Subtitle\")}
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {expandRecipients && (\r\n \r\n {props.stepModel.recipients.map((recipient, index) => (\r\n \r\n \r\n \r\n \r\n ))}\r\n \r\n )}\r\n \r\n \r\n \r\n \r\n \r\n \r\n
{props.stepModel.recipients.length} Recipient{props.stepModel.recipients.length > 1 ? \"s\" : \"\"}\r\n setExpandRecipients(!expandRecipients)}\r\n >\r\n {expandRecipients ? (\r\n \r\n \r\n \r\n ) : (\r\n \r\n \r\n \r\n )}\r\n \r\n
\r\n

{recipient.fullName}

\r\n\r\n {props.stepModel.sendBy == GiftCardSendTypeEnum.BY_EMAIL && (\r\n

{recipient.email}

\r\n )}\r\n {props.stepModel.sendBy == GiftCardSendTypeEnum.BY_SMS && (\r\n

{recipient.phone}

\r\n )}\r\n
\r\n

€{(props.stepModel.totalAmount / props.stepModel.recipients.length).toFixed(2)}

\r\n
{labels.get(\"GiftCard.App.V2.ReviewAndPayReview.Label.Total\")}€{props.stepModel.totalAmount.toFixed(2)}
\r\n
\r\n )}\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ReviewAndPayReviewStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport { formatStringWithPlaceholders, hasXSSCharacters, isEmail, isFullNameValid } from \"../../../../helpers/Utils\";\r\nimport ICountry from \"../../../../models/Country.interface\";\r\nimport { IReviewAndPaySenderInfoStepModel, ReviewAndPaySenderInfoStepModel } from \"../../../../models/buy-giftcard/review-pay/ReviewAndPaySenderInfoStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport DataService from \"../../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\n\r\ninterface IReviewAndPaySenderInfoStepProps extends IBuyGiftCardStepProps {\r\n stepModel: IReviewAndPaySenderInfoStepModel;\r\n\r\n handleSubmit(stepModel: IReviewAndPaySenderInfoStepModel): void;\r\n}\r\n\r\nconst ReviewAndPaySenderInfoStep = (props: IReviewAndPaySenderInfoStepProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [stepModel, setStepModel] = useState({\r\n usePersonalDetails: props.stepModel.usePersonalDetails,\r\n useBusinessDetails: props.stepModel.useBusinessDetails,\r\n personDetails: props.stepModel.personDetails,\r\n businessDetails: props.stepModel.businessDetails\r\n });\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [isModelValid, setIsModelValid] = useState();\r\n const [modelErrors, setModelErrors] = useState({\r\n personDetails: {\r\n fullName: '',\r\n email: ''\r\n },\r\n businessDetails: {\r\n fullName: '',\r\n email: '',\r\n companyName: '',\r\n tradingAs: '',\r\n businessType: '',\r\n vat: '',\r\n cro: '',\r\n businessAddress: {\r\n country: '',\r\n city: '',\r\n postcode: '',\r\n addressLine1: ''\r\n }\r\n }\r\n });\r\n const [countries, setCountries] = useState([] as ICountry[]);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n getCountries();\r\n\r\n if (!stepModel.businessDetails.businessAddress.country) {\r\n setStepModel({\r\n ...stepModel,\r\n businessDetails: {\r\n ...stepModel.businessDetails,\r\n businessAddress: {\r\n ...stepModel.businessDetails.businessAddress,\r\n country: 'IE'\r\n }\r\n }\r\n });\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n setIsModelValid(isValid());\r\n }, [stepModel]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.activeStep === BuyGiftCardStateEnum.REVIEW_PAY_SENDER_INFO;\r\n }, [props.activeStep]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleExpandBoxCheck = (): void => {\r\n if (checkboxRef.current.checked && props.activeStep !== BuyGiftCardStateEnum.REVIEW_PAY_SENDER_INFO) {\r\n props.handleSetActiveStep(BuyGiftCardStateEnum.REVIEW_PAY_SENDER_INFO);\r\n }\r\n };\r\n\r\n const handleDetailsTypeChange = (event: React.ChangeEvent): void => {\r\n const { id, checked } = event.target;\r\n\r\n if (id === \"usePersonalDetails\") {\r\n setStepModel({\r\n ...stepModel,\r\n usePersonalDetails: checked,\r\n useBusinessDetails: !checked\r\n });\r\n } else if (id === \"useBusinessDetails\") {\r\n setStepModel({\r\n ...stepModel,\r\n usePersonalDetails: !checked,\r\n useBusinessDetails: checked\r\n });\r\n }\r\n };\r\n\r\n const handlePersonDetailsChange = (event: React.ChangeEvent): void => {\r\n const { name, value } = event.target;\r\n\r\n if (hasXSSCharacters(value)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n let errMsg = '';\r\n\r\n if (name === 'fullName') {\r\n if (!value || !value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Full name\");\r\n } else if (!isFullNameValid(value.trim())) {\r\n errMsg = \"Invalid full name\";\r\n }\r\n } else if (name === 'email') {\r\n if (!value || !value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Email\");\r\n } else if (!isEmail(value)) {\r\n errMsg = labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Error.EmailInvalid\");\r\n }\r\n }\r\n\r\n setModelErrors({\r\n ...modelErrors,\r\n personDetails: {\r\n ...modelErrors.personDetails,\r\n [name]: errMsg\r\n }\r\n });\r\n\r\n setStepModel({\r\n ...stepModel,\r\n personDetails: {\r\n ...stepModel.personDetails,\r\n [name]: value\r\n }\r\n });\r\n };\r\n\r\n const handleBusinessDetailsChange = (event: React.ChangeEvent): void => {\r\n const { name, value } = event.target;\r\n\r\n if (hasXSSCharacters(value)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n let errMsg = '';\r\n const requiredTextFields = ['fullName', 'companyName'];\r\n\r\n if (name === 'email') {\r\n if (!value || !value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Email\");\r\n } else if (!isEmail(event.target.value)) {\r\n errMsg = labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Error.EmailInvalid\");\r\n }\r\n } else if (requiredTextFields.includes(name) && (!value || !value.trim())) {\r\n let errSubstitution = '';\r\n\r\n switch (name) {\r\n case 'fullName': errSubstitution = \"Full name\";\r\n break;\r\n case 'companyName': errSubstitution = \"Company name\";\r\n break;\r\n default:\r\n break;\r\n }\r\n\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), errSubstitution);\r\n } else if (name === 'fullName' && !isFullNameValid(value.trim())) {\r\n errMsg = 'Invalid full name';\r\n }\r\n\r\n if (name !== 'tradingAs' && name !== 'vat' && name !== 'cro') {\r\n setModelErrors({\r\n ...modelErrors,\r\n businessDetails: {\r\n ...modelErrors.businessDetails,\r\n [name]: errMsg\r\n }\r\n });\r\n }\r\n\r\n setStepModel({\r\n ...stepModel,\r\n businessDetails: {\r\n ...stepModel.businessDetails,\r\n [name]: value\r\n }\r\n });\r\n };\r\n\r\n const handleBusinessTypeChange = (event: React.ChangeEvent): void => {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n let errMsg = '';\r\n if (!event.target.value || !event.target.value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Business type\");\r\n }\r\n\r\n setModelErrors({\r\n ...modelErrors,\r\n businessDetails: {\r\n ...modelErrors.businessDetails,\r\n businessType: errMsg\r\n }\r\n });\r\n\r\n setStepModel({\r\n ...stepModel,\r\n businessDetails: {\r\n ...stepModel.businessDetails,\r\n businessType: event.target.value\r\n }\r\n });\r\n };\r\n\r\n const handleBusinessAddressChange = (event: React.ChangeEvent): void => {\r\n const { name, value } = event.target;\r\n\r\n if (hasXSSCharacters(value)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n let errMsg = '';\r\n\r\n if (name === 'country' && (!value || !value.trim())) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Country\");\r\n } else if (name === 'city' && (!value || !value.trim())) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"City\");\r\n } else if (name === 'addressLine1' && (!value || !value.trim())) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Address Line 1\");\r\n } else if (name === 'postcode' && value && value.trim() && value.trim().length < 3) {\r\n errMsg = \"Invalid postcode\";\r\n }\r\n\r\n if (name !== 'county' && name !== 'addressLine2' && name !== 'addressLine3') {\r\n setModelErrors({\r\n ...modelErrors,\r\n businessDetails: {\r\n ...modelErrors.businessDetails,\r\n businessAddress: {\r\n ...modelErrors.businessDetails.businessAddress,\r\n [name]: errMsg\r\n }\r\n }\r\n });\r\n }\r\n\r\n setStepModel({\r\n ...stepModel,\r\n businessDetails: {\r\n ...stepModel.businessDetails,\r\n businessAddress: {\r\n ...stepModel.businessDetails.businessAddress,\r\n [name]: value\r\n }\r\n }\r\n });\r\n };\r\n\r\n const handleBusinessCountryChange = (event: React.ChangeEvent): void => {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n let errMsg = '';\r\n\r\n if (!event.target.value || !event.target.value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Country\");\r\n } else if (!countries.map(c => c.code).includes(event.target.value)) {\r\n errMsg = \"Invalid country\";\r\n }\r\n\r\n setModelErrors({\r\n ...modelErrors,\r\n businessDetails: {\r\n ...modelErrors.businessDetails,\r\n businessAddress: {\r\n ...modelErrors.businessDetails.businessAddress,\r\n country: errMsg\r\n }\r\n }\r\n });\r\n\r\n setStepModel({\r\n ...stepModel,\r\n businessDetails: {\r\n ...stepModel.businessDetails,\r\n businessAddress: {\r\n ...stepModel.businessDetails.businessAddress,\r\n country: event.target.value\r\n }\r\n }\r\n });\r\n };\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n\r\n if (!isValid()) {\r\n return;\r\n }\r\n\r\n props.handleSubmit(stepModel);\r\n checkboxRef.current.checked = false;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const getCountries = async () => {\r\n const countriesJson = await DataService.getCountries(document.documentElement.lang ?? \"en-GB\");\r\n const countriesArr = [];\r\n\r\n for (let i = 0; i < countriesJson.length; i++) {\r\n countriesArr.push({\r\n name: countriesJson[i].name,\r\n code: countriesJson[i].code\r\n } as ICountry);\r\n }\r\n\r\n setCountries(countriesArr);\r\n };\r\n\r\n const isValid = (): boolean => {\r\n return ReviewAndPaySenderInfoStepModel.isValid(stepModel, countries);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Title\")}\r\n {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n handleExpandBoxCheck();\r\n }}\r\n >\r\n

\r\n {props.activeStep === BuyGiftCardStateEnum.REVIEW_PAY_SENDER_INFO && (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
\r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Subtitle1\")}\r\n
\r\n
    \r\n
  • \r\n \r\n \r\n
  • \r\n
  • \r\n \r\n \r\n
  • \r\n
\r\n\r\n {stepModel.usePersonalDetails && (\r\n <>\r\n

\r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Subtitle2\")}\r\n

\r\n
\r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Info.Purchaser\")}\r\n
\r\n
\r\n
\r\n \r\n\r\n {modelErrors.personDetails.fullName && (\r\n \r\n {modelErrors.personDetails.fullName}\r\n \r\n )}\r\n
\r\n
\r\n \r\n\r\n {modelErrors.personDetails.email && (\r\n \r\n {modelErrors.personDetails.email}\r\n \r\n )}\r\n
\r\n
\r\n \r\n )}\r\n\r\n {stepModel.useBusinessDetails && (\r\n <>\r\n

\r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Subtitle2\")}\r\n

\r\n
\r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Info.Purchaser\")}\r\n
\r\n
\r\n
\r\n \r\n\r\n {modelErrors.businessDetails.fullName && (\r\n \r\n {modelErrors.businessDetails.fullName}\r\n \r\n )}\r\n
\r\n
\r\n \r\n\r\n {modelErrors.businessDetails.email && (\r\n \r\n {modelErrors.businessDetails.email}\r\n \r\n )}\r\n
\r\n
\r\n
\r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Info.BusinessDetails\")}\r\n
\r\n
\r\n
\r\n \r\n\r\n {modelErrors.businessDetails.companyName && (\r\n \r\n {modelErrors.businessDetails.companyName}\r\n \r\n )}\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n {(() => {\r\n const options = [];\r\n\r\n options.push(\r\n \r\n );\r\n\r\n const optionsFromUmbraco = labels\r\n .get(\"GiftCard.App.V2.ReviewAndPaySender.BusinessTypes\")\r\n .split(\";\")\r\n .map(x => x.trim());\r\n\r\n for (let i = 0; i < optionsFromUmbraco.length; i++) {\r\n options.push(\r\n \r\n );\r\n }\r\n\r\n return options;\r\n })()}\r\n \r\n\r\n {modelErrors.businessDetails.businessType && (\r\n \r\n {modelErrors.businessDetails.businessType}\r\n \r\n )}\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Info.Address\")}\r\n
\r\n
\r\n
\r\n \r\n {countries.map((country, index) => (\r\n \r\n ))}\r\n \r\n\r\n {modelErrors.businessDetails.businessAddress.country && (\r\n \r\n {modelErrors.businessDetails.businessAddress.country}\r\n \r\n )}\r\n
\r\n\r\n
\r\n \r\n
\r\n
\r\n \r\n\r\n {modelErrors.businessDetails.businessAddress.city && (\r\n \r\n {modelErrors.businessDetails.businessAddress.city}\r\n \r\n )}\r\n
\r\n
\r\n \r\n\r\n {modelErrors.businessDetails.businessAddress.postcode && (\r\n \r\n {modelErrors.businessDetails.businessAddress.postcode}\r\n \r\n )}\r\n
\r\n
\r\n \r\n\r\n {modelErrors.businessDetails.businessAddress.addressLine1 && (\r\n \r\n {modelErrors.businessDetails.businessAddress.addressLine1}\r\n \r\n )}\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n )}\r\n\r\n
\r\n \r\n {labels.get(\"GiftCard.App.V2.ReviewAndPaySender.Button.Submit\")}\r\n \r\n
\r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ReviewAndPaySenderInfoStep;","import React, { useContext, useEffect, useRef, useState } from \"react\";\r\nimport DatePicker from \"react-datepicker\";\r\nimport \"react-datepicker/dist/react-datepicker.css\";\r\nimport { IReviewAndPayWhenToSendStepModel, ReviewAndPayWhenToSendStepModel } from \"../../../../models/buy-giftcard/review-pay/ReviewAndPayWhenToSendStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { IBuyGiftCardStepProps } from \"../../../../models/interfaces/BuyGiftCardStep.interface\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport LoadingComponent from \"../../../shared/LoadingComponent\";\r\n\r\ninterface IReviewAndPayWhenToSendStepProps extends IBuyGiftCardStepProps {\r\n stepModel: IReviewAndPayWhenToSendStepModel;\r\n isAvailable: boolean;\r\n\r\n handleSubmit(stepModel: IReviewAndPayWhenToSendStepModel): void;\r\n}\r\n\r\nconst ReviewAndPayWhenToSendStep = (props: IReviewAndPayWhenToSendStepProps) => {\r\n const { labels } = useContext(AppSettingContext);\r\n const checkboxRef = useRef(null);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [stepModel, setStepModel] = useState({\r\n sendLater: props.stepModel.sendLater,\r\n scheduleSendDetails: {\r\n date: props.stepModel.scheduleSendDetails?.date ?? new Date(),\r\n hour: props.stepModel.scheduleSendDetails?.hour ?? (new Date()).getHours(),\r\n minute: props.stepModel.scheduleSendDetails?.minute ?? (new Date()).getMinutes()\r\n }\r\n });\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [isModelValid, setIsModelValid] = useState();\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsModelValid(isValid());\r\n }, [stepModel]);\r\n\r\n useEffect(() => {\r\n setIsLoading(props.isSaving);\r\n }, [props.isSaving]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.activeStep === BuyGiftCardStateEnum.REVIEW_PAY_WHEN_TO_SEND;\r\n }, [props.activeStep]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleExpandBoxCheck = (): void => {\r\n if (props.isAvailable) {\r\n if (checkboxRef.current.checked && props.activeStep !== BuyGiftCardStateEnum.REVIEW_PAY_WHEN_TO_SEND) {\r\n props.handleSetActiveStep(BuyGiftCardStateEnum.REVIEW_PAY_WHEN_TO_SEND);\r\n }\r\n }\r\n };\r\n\r\n const handleSendLaterChange = (sendLater: boolean): void => {\r\n setStepModel({\r\n ...stepModel,\r\n sendLater: sendLater\r\n });\r\n };\r\n\r\n const handleDateChange = (newDate: Date): void => {\r\n setStepModel({\r\n ...stepModel,\r\n scheduleSendDetails: {\r\n ...stepModel.scheduleSendDetails,\r\n date: newDate\r\n }\r\n });\r\n };\r\n\r\n const handleTimeChange = (event: React.ChangeEvent): void => {\r\n const { name, value } = event.target;\r\n\r\n setStepModel({\r\n ...stepModel,\r\n scheduleSendDetails: {\r\n ...stepModel.scheduleSendDetails,\r\n [name]: parseInt(value)\r\n }\r\n });\r\n };\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n\r\n if (!isValid()) {\r\n return;\r\n }\r\n\r\n props.handleSubmit(stepModel);\r\n checkboxRef.current.checked = false;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const addDays = (date: Date, numberOfDaysToAdd: number) => {\r\n if (date) {\r\n date.setDate(date.getDate() + numberOfDaysToAdd);\r\n }\r\n\r\n return date;\r\n };\r\n\r\n const isDateSame = (date: Date) => {\r\n const today = new Date();\r\n\r\n if (date) {\r\n return date.getDate() == today.getDate()\r\n && date.getMonth() == today.getMonth()\r\n && date.getFullYear() == today.getFullYear();\r\n }\r\n\r\n return false;\r\n }\r\n\r\n const isValid = (): boolean => {\r\n return ReviewAndPayWhenToSendStepModel.isValid(stepModel);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n
\r\n

\r\n \r\n \"icon\r\n \r\n {labels.get(\"GiftCard.App.V2.ReviewAndPayWhenToSend.Title\")}\r\n {\r\n if (props.isAvailable) {\r\n checkboxRef.current.checked = !checkboxRef.current.checked;\r\n handleExpandBoxCheck();\r\n }\r\n }}\r\n >\r\n

\r\n {props.activeStep === BuyGiftCardStateEnum.REVIEW_PAY_WHEN_TO_SEND && (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
\r\n
    \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleSendLaterChange(false);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleSendLaterChange(true);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
\r\n\r\n {stepModel.sendLater && (\r\n
\r\n
\r\n \r\n
\r\n \r\n\r\n \"Date\"\r\n \"Select\"\r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n {(() => {\r\n const options = [];\r\n\r\n for (let i = 0; i <= 23; i++) {\r\n if (isDateSame(stepModel.scheduleSendDetails.date) &&\r\n (i < stepModel.scheduleSendDetails.date.getHours())) {\r\n continue;\r\n }\r\n\r\n options.push(\r\n \r\n );\r\n }\r\n\r\n return options;\r\n })()}\r\n \r\n \"Select\"\r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n {(() => {\r\n const options = [];\r\n\r\n for (let i = 0; i <= 59; i++) {\r\n options.push(\r\n \r\n );\r\n }\r\n\r\n return options;\r\n })()}\r\n \r\n \"Select\"\r\n
\r\n
\r\n
\r\n )}\r\n
\r\n
\r\n \r\n {labels.get(\"GiftCard.App.V2.ReviewAndPayWhenToSend.Button.Submit\")}\r\n \r\n
\r\n
\r\n )}\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ReviewAndPayWhenToSendStep;","import React, { useContext, useEffect, useState } from \"react\";\r\nimport { resetRecipientsCountOnRecipientStep } from \"../../../../helpers/GiftCardHelper\";\r\nimport { ChooseCardSubpageModel, IChooseCardSubpageModel } from \"../../../../models/buy-giftcard/choose-card/ChooseCardSubpage.model\";\r\nimport { ChooseCardStepModel, IChooseCardStepModel } from \"../../../../models/buy-giftcard/choose-card/ChooseCardsStep.model\";\r\nimport { ChooseRecipientsStepModel, IChooseRecipientsStepModel } from \"../../../../models/buy-giftcard/choose-card/ChooseRecipientsStep.model\";\r\nimport { ChooseSenderStepModel, IChooseSenderStepModel } from \"../../../../models/buy-giftcard/choose-card/ChooseSenderStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { BuyGiftCardSubpageEnum } from \"../../../../models/enums/BuyGiftCardSubpageEnum\";\r\nimport { IBuyGiftCardSubpageProps } from \"../../../../models/interfaces/BuyGiftCardSubpage.interface\";\r\nimport { AppSettingContext } from \"../../../Application\";\r\nimport ChoooseCardsStep from \"../steps/ChoooseCardsStep\";\r\nimport ChooseRecipientsStep from \"../steps/ChooseRecipientsStep\";\r\nimport ChooseSenderStep from \"../steps/ChooseSenderStep\";\r\n\r\ninterface IChooseCardSubpageProps extends IBuyGiftCardSubpageProps {\r\n subpageModel: IChooseCardSubpageModel;\r\n\r\n handleCardDetailsChange(model: IChooseCardStepModel): void;\r\n handleRecipientsChange(model: IChooseRecipientsStepModel): void;\r\n handleSubpageSubmit(model: IChooseCardSubpageModel): void;\r\n}\r\n\r\nconst ChooseCardSubpage = (props: IChooseCardSubpageProps) => {\r\n const { cardSettings } = useContext(AppSettingContext);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [subpageModel, setSubpageModel] = useState(props.subpageModel);\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [stepsStatus, setStepsStatus] = useState({\r\n chooseCardDetails: ChooseCardStepModel.isValid(props.subpageModel.chooseCardDetails, cardSettings),\r\n chooseRecipients: ChooseRecipientsStepModel.isValid(props.subpageModel.chooseRecipients),\r\n chooseSender: false\r\n });\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (subpageModel) {\r\n setTimeout(() => {\r\n setIsSaving(false);\r\n }, 500);\r\n }\r\n }, [subpageModel]);\r\n\r\n useEffect(() => {\r\n if (stepsStatus.chooseCardDetails && stepsStatus.chooseRecipients && stepsStatus.chooseSender) {\r\n if (ChooseCardSubpageModel.isValid(subpageModel)) {\r\n props.handleSubpageSubmit(subpageModel);\r\n } else {\r\n console.error('Invalid ChooseCard subpage model');\r\n console.error(subpageModel);\r\n }\r\n }\r\n }, [stepsStatus]);\r\n\r\n //#endregion\r\n\r\n //#region CHOOSE CARDS STEP\r\n\r\n const handleChooseCardSubmit = (model: IChooseCardStepModel): void => {\r\n const isModelValid = ChooseCardStepModel.isValid(model, null);\r\n\r\n if (isModelValid) {\r\n setIsSaving(true);\r\n\r\n let newSubpageModel = {\r\n ...subpageModel,\r\n chooseCardDetails: model,\r\n };\r\n\r\n if (!stepsStatus.chooseRecipients) {\r\n const responseModel = resetRecipientsCountOnRecipientStep(model.quantity, subpageModel.chooseRecipients);\r\n\r\n newSubpageModel = {\r\n ...newSubpageModel,\r\n chooseRecipients: {\r\n ...subpageModel.chooseRecipients,\r\n sendIndividually: responseModel.sendIndividually,\r\n recipients: (responseModel as ChooseRecipientsStepModel).recipients,\r\n }\r\n };\r\n }\r\n\r\n setSubpageModel(newSubpageModel);\r\n props.handleCardDetailsChange(model);\r\n }\r\n\r\n setStepsStatus({\r\n ...stepsStatus,\r\n chooseCardDetails: isModelValid\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n //#region CHOOSE RECIPIENTS STEP\r\n\r\n const handleSendIndividuallyChange = (sendIndividually: boolean): void => {\r\n const recipients = [...subpageModel.chooseRecipients.recipients];\r\n\r\n if (sendIndividually) {\r\n while (recipients.length < subpageModel.chooseCardDetails.quantity) {\r\n recipients.push({\r\n fullName: props.subpageModel?.chooseRecipients?.recipients[recipients.length]?.fullName ?? \"\",\r\n email: props.subpageModel?.chooseRecipients?.recipients[recipients.length]?.email ?? \"\",\r\n phone: props.subpageModel?.chooseRecipients?.recipients[recipients.length]?.phone ?? \"\",\r\n });\r\n }\r\n }\r\n\r\n setSubpageModel({\r\n ...subpageModel,\r\n chooseRecipients: {\r\n ...subpageModel.chooseRecipients,\r\n sendIndividually: sendIndividually,\r\n recipients: sendIndividually ? recipients : [subpageModel.chooseRecipients.recipients[0]]\r\n }\r\n });\r\n };\r\n\r\n const handleRecipientsSubmit = (model: IChooseRecipientsStepModel): void => {\r\n const isModelValid = ChooseRecipientsStepModel.isValid(model);\r\n\r\n if (isModelValid) {\r\n setIsSaving(true);\r\n setSubpageModel({\r\n ...subpageModel,\r\n chooseRecipients: model\r\n });\r\n\r\n props.handleRecipientsChange(model);\r\n }\r\n\r\n setStepsStatus({\r\n ...stepsStatus,\r\n chooseRecipients: isModelValid\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n //#region CHOOSE SENDER STEP\r\n\r\n const handleSenderSubmit = (model: IChooseSenderStepModel): void => {\r\n const isModelValid = ChooseSenderStepModel.isValid(model);\r\n if (isModelValid) {\r\n setIsSaving(true);\r\n setSubpageModel({\r\n ...subpageModel,\r\n chooseSender: model\r\n });\r\n }\r\n\r\n setStepsStatus({\r\n ...stepsStatus,\r\n chooseSender: isModelValid\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const handleSetActiveStep = (newState: BuyGiftCardStateEnum): void => {\r\n props.handleStateChange(BuyGiftCardSubpageEnum.CHOOSE_CARD, newState);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n <>\r\n \r\n\r\n \r\n\r\n \r\n \r\n );\r\n};\r\n\r\nexport default ChooseCardSubpage;","import React, { useEffect, useState } from \"react\";\r\nimport { isNullOrWhiteSpace } from \"../../../../helpers/Utils\";\r\nimport { CustomiseCardStepModel, ICustomiseCardStepModel } from \"../../../../models/buy-giftcard/customise-card/CustomiseCardStep.model\";\r\nimport { CustomiseCardSubpageModel, ICustomiseCardSubpageModel } from \"../../../../models/buy-giftcard/customise-card/CustomiseCardSubpage.model\";\r\nimport { CustomiseMailStepModel, ICustomiseMailStepModel } from \"../../../../models/buy-giftcard/customise-card/CustomiseMailStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { BuyGiftCardSubpageEnum } from \"../../../../models/enums/BuyGiftCardSubpageEnum\";\r\nimport { IBuyGiftCardSubpageProps } from \"../../../../models/interfaces/BuyGiftCardSubpage.interface\";\r\nimport CustomiseGiftCardStep from \"../steps/CustomiseGiftCardStep\";\r\nimport CustomiseMailStep from \"../steps/CustomiseMailStep\";\r\n\r\ninterface ICustomiseCardSubpageProps extends IBuyGiftCardSubpageProps {\r\n subpageModel: ICustomiseCardSubpageModel;\r\n\r\n scrollToTop(): void;\r\n handleTemplateChange(model: ICustomiseCardStepModel, isSubmit: boolean): void;\r\n handlePersonalMessageChange(personalMessage: string): void;\r\n handleMediaChange(mediaUrl: string): void;\r\n handleSubpageSubmit(model: ICustomiseCardSubpageModel): void;\r\n}\r\n\r\nconst CustomiseCardSubpage = (props: ICustomiseCardSubpageProps) => {\r\n //#region STATE PROPERTIES\r\n\r\n const [subpageModel, setSubpageModel] = useState(props.subpageModel);\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [stepsStatus, setStepsStatus] = useState({\r\n customiseCard: CustomiseCardStepModel.isValid(props.subpageModel.customiseCard),\r\n customiseMail: false\r\n });\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (subpageModel) {\r\n setTimeout(() => {\r\n setIsSaving(false);\r\n }, 500);\r\n }\r\n }, [subpageModel]);\r\n\r\n useEffect(() => {\r\n if (stepsStatus.customiseCard && stepsStatus.customiseMail) {\r\n if (CustomiseCardSubpageModel.isValid(subpageModel)) {\r\n props.handleSubpageSubmit(subpageModel);\r\n } else {\r\n console.error('Invalid customise subpage model');\r\n console.error(subpageModel);\r\n }\r\n }\r\n }, [stepsStatus]);\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const handleSetActiveStep = (newState: BuyGiftCardStateEnum): void => {\r\n props.handleStateChange(BuyGiftCardSubpageEnum.CUSTOMISE_CARD, newState);\r\n };\r\n\r\n const handleGoBack = (): void => {\r\n let newSubpage = BuyGiftCardSubpageEnum.CUSTOMISE_CARD;\r\n let newStep = BuyGiftCardStateEnum.CUSTOMISE_CARD;\r\n\r\n if (props.activeStep === BuyGiftCardStateEnum.CUSTOMISE_CARD) {\r\n newSubpage = BuyGiftCardSubpageEnum.CHOOSE_CARD;\r\n newStep = BuyGiftCardStateEnum.CHOOSE_SENDER;\r\n }\r\n\r\n props.scrollToTop();\r\n props.handleStateChange(newSubpage, newStep);\r\n };\r\n\r\n //#endregion\r\n\r\n //#region CUSTOMISE CARD STEP\r\n\r\n const handleTemplateChange = (model: ICustomiseCardStepModel): void => {\r\n setSubpageModel({\r\n ...subpageModel,\r\n customiseCard: model\r\n });\r\n\r\n props.handleTemplateChange(model, false);\r\n };\r\n\r\n const handleCustomiseCardSubmit = (model: ICustomiseCardStepModel): void => {\r\n const isModelValid = CustomiseCardStepModel.isValid(model);\r\n\r\n if (isModelValid) {\r\n setIsSaving(true);\r\n setSubpageModel({\r\n ...subpageModel,\r\n customiseCard: model\r\n });\r\n\r\n props.handleTemplateChange(model, true);\r\n }\r\n\r\n setStepsStatus({\r\n ...stepsStatus,\r\n customiseCard: isModelValid\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n //#region CUSTOMISE MAIL STEP\r\n\r\n const handlePersonalMessageChange = (personalMessage: string): void => {\r\n setSubpageModel({\r\n ...subpageModel,\r\n customiseMail: {\r\n ...subpageModel.customiseMail,\r\n personalMessage: personalMessage\r\n }\r\n });\r\n\r\n props.handlePersonalMessageChange(personalMessage);\r\n };\r\n\r\n const handleMediaChange = (mediaUrl: string): void => {\r\n setSubpageModel({\r\n ...subpageModel,\r\n customiseMail: {\r\n ...subpageModel.customiseMail,\r\n mediaUrl: mediaUrl,\r\n addMedia: !isNullOrWhiteSpace(mediaUrl)\r\n }\r\n });\r\n\r\n props.handleMediaChange(mediaUrl);\r\n };\r\n\r\n const handleCustomiseMailSubmit = (model: ICustomiseMailStepModel): void => {\r\n const isModelValid = CustomiseMailStepModel.isValid(model);\r\n if (isModelValid) {\r\n setIsSaving(true);\r\n setSubpageModel({\r\n ...subpageModel,\r\n customiseMail: model\r\n });\r\n }\r\n\r\n setStepsStatus({\r\n ...stepsStatus,\r\n customiseMail: isModelValid\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n <>\r\n \r\n\r\n \r\n \r\n );\r\n};\r\n\r\nexport default CustomiseCardSubpage;","import React, { useEffect, useState } from \"react\";\r\nimport { IBuyGiftCardModel } from \"../../../../models/buy-giftcard/BuyGiftCard.model\";\r\nimport { IReviewAndPayPaymentStepModel, ReviewAndPayPaymentStepModel } from \"../../../../models/buy-giftcard/review-pay/ReviewAndPayPaymentStep.model\";\r\nimport { IReviewAndPaySenderInfoStepModel, ReviewAndPaySenderInfoStepModel } from \"../../../../models/buy-giftcard/review-pay/ReviewAndPaySenderInfoStep.model\";\r\nimport { IReviewAndPaySubpageModel, ReviewAndPaySubpageModel } from \"../../../../models/buy-giftcard/review-pay/ReviewAndPaySubpage.model\";\r\nimport { IReviewAndPayWhenToSendStepModel, ReviewAndPayWhenToSendStepModel } from \"../../../../models/buy-giftcard/review-pay/ReviewAndPayWhenToSendStep.model\";\r\nimport { BuyGiftCardStateEnum } from \"../../../../models/enums/BuyGiftCardStateEnum\";\r\nimport { BuyGiftCardSubpageEnum } from \"../../../../models/enums/BuyGiftCardSubpageEnum\";\r\nimport { IBuyGiftCardSubpageProps } from \"../../../../models/interfaces/BuyGiftCardSubpage.interface\";\r\nimport ReviewAndPayPaymentStep from \"../steps/ReviewAndPayPaymentStep\";\r\nimport ReviewAndPayReviewStep, { IReviewAndPayReviewStepModel } from \"../steps/ReviewAndPayReviewStep\";\r\nimport ReviewAndPaySenderInfoStep from \"../steps/ReviewAndPaySenderInfoStep\";\r\nimport ReviewAndPayWhenToSendStep from \"../steps/ReviewAndPayWhenToSendStep\";\r\n\r\ninterface IReviewAndPaySubpageProps extends IBuyGiftCardSubpageProps {\r\n subpageModel: IReviewAndPaySubpageModel;\r\n reviewModel: IReviewAndPayReviewStepModel;\r\n hasToSaveBasket: boolean;\r\n\r\n getPageModel(): IBuyGiftCardModel;\r\n handleError(message: string): void;\r\n handleSenderInfoSubmit(model: IReviewAndPaySenderInfoStepModel): void;\r\n handleWhenToSendSubmit(model: IReviewAndPayWhenToSendStepModel): void;\r\n handleSubpageSubmit(model: IReviewAndPaySubpageModel): void;\r\n}\r\n\r\nconst ReviewAndPaySubpage = (props: IReviewAndPaySubpageProps) => {\r\n //#region STATE PROPERTIES\r\n\r\n const [subpageModel, setSubpageModel] = useState(props.subpageModel);\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [stepsStatus, setStepsStatus] = useState({\r\n senderInfo: ReviewAndPaySenderInfoStepModel.isValid(props.subpageModel.reviewAndPaySenderInfo, null),\r\n whenToSend: ReviewAndPayWhenToSendStepModel.isValid(props.subpageModel.reviewAndPayWhenToSend),\r\n paymentStep: false\r\n });\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (subpageModel) {\r\n setTimeout(() => {\r\n setIsSaving(false);\r\n }, 500);\r\n }\r\n }, [subpageModel]);\r\n\r\n useEffect(() => {\r\n if (stepsStatus.senderInfo && stepsStatus.whenToSend && stepsStatus.paymentStep) {\r\n if (ReviewAndPaySubpageModel.isValid(subpageModel)) {\r\n props.handleSubpageSubmit(subpageModel);\r\n } else {\r\n console.error('Invalid reviewAndPay subpage model');\r\n console.error(subpageModel);\r\n }\r\n }\r\n }, [stepsStatus]);\r\n\r\n //#endregion\r\n\r\n //#region SENDER INFO STEP\r\n\r\n const handleSenderInfoSubmit = (model: IReviewAndPaySenderInfoStepModel): void => {\r\n const isModelValid = ReviewAndPaySenderInfoStepModel.isValid(model, null);\r\n\r\n if (isModelValid) {\r\n setIsSaving(true);\r\n setSubpageModel({\r\n ...subpageModel,\r\n reviewAndPaySenderInfo: model\r\n });\r\n\r\n props.handleSenderInfoSubmit(model);\r\n }\r\n\r\n setStepsStatus({\r\n ...stepsStatus,\r\n senderInfo: isModelValid\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n //#region WHEN TO SEND STEP\r\n\r\n const handleWhenToSendSubmit = (model: IReviewAndPayWhenToSendStepModel): void => {\r\n const isModelValid = ReviewAndPayWhenToSendStepModel.isValid(model);\r\n \r\n if (isModelValid) {\r\n setIsSaving(true);\r\n setSubpageModel({\r\n ...subpageModel,\r\n reviewAndPayWhenToSend: model\r\n });\r\n\r\n props.handleWhenToSendSubmit(model);\r\n }\r\n\r\n setStepsStatus({\r\n ...stepsStatus,\r\n whenToSend: isModelValid\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n //#region PAYMENT STEP\r\n\r\n const handleError = (message: string): void => {\r\n props.handleError(message);\r\n };\r\n\r\n const handlePaymentSubmit = (model: IReviewAndPayPaymentStepModel): void => {\r\n const isModelValid = ReviewAndPayPaymentStepModel.isValid(model);\r\n if (isModelValid) {\r\n setIsSaving(true);\r\n setSubpageModel({\r\n ...subpageModel,\r\n reviewAndPayPayment: model\r\n });\r\n }\r\n\r\n setStepsStatus({\r\n ...stepsStatus,\r\n paymentStep: isModelValid\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const handleSetActiveStep = (newState: BuyGiftCardStateEnum): void => {\r\n props.handleStateChange(BuyGiftCardSubpageEnum.REVIEW_PAY, newState);\r\n };\r\n\r\n const handleStateChange = (newSubpage: BuyGiftCardSubpageEnum, newState: BuyGiftCardStateEnum): void => {\r\n props.handleStateChange(newSubpage, newState);\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n
\r\n );\r\n};\r\n\r\nexport default ReviewAndPaySubpage;","import React from \"react\";\r\nimport { CheckBalanceStepModel } from \"../../../models/CheckBalanceStep.model\";\r\nimport { CustomizeStepModel } from \"../../../models/CustomizeStep.model\";\r\nimport { RecipientsStepModel } from \"../../../models/RecipientsStep.model\";\r\nimport { RegiftCardStepModel } from \"../../../models/RegiftCardStep.model\";\r\nimport { RegiftPaymentStepModel } from \"../../../models/RegiftPaymentStep.model\";\r\nimport { WorkflowTypeEnum } from \"../../../models/enums/WorkflowTypeEnum\";\r\nimport { RegiftCardContext } from \"../../../pages/RegiftCardPage\";\r\nimport LoadingComponent from \"../../shared/LoadingComponent\";\r\n\r\ninterface IDebugRegiftDataPreivewComponentProps {\r\n isSaving: boolean;\r\n isLoading: boolean;\r\n}\r\n\r\nconst DebugRegiftDataPreivewComponent = (props: IDebugRegiftDataPreivewComponentProps) => {\r\n\r\n const { id, currentState, checkBalanceStep, regiftCardStep, recipientsStep, customizeStep, paymentStep, isValid } = React.useContext(RegiftCardContext);\r\n\r\n const cardBalance = checkBalanceStep ? checkBalanceStep.remainingBalance : 0;\r\n const checkBalanceStepIsValid = (checkBalanceStep && CheckBalanceStepModel.validateModel(checkBalanceStep));\r\n const regiftCardStepIsValid = (checkBalanceStep && RegiftCardStepModel.validateModel(regiftCardStep, cardBalance));\r\n const recipientsStepIsValid = (recipientsStep && RecipientsStepModel.validateModel(recipientsStep, WorkflowTypeEnum.REGIFT_CARD));\r\n const customizeStepIsValid = (customizeStep && CustomizeStepModel.validateModel(customizeStep));\r\n const paymentStepIsValid = (paymentStep && RegiftPaymentStepModel.validateModel(paymentStep));\r\n\r\n return (\r\n <>\r\n {(props.isSaving || props.isSaving) ? (\r\n \r\n ) : (\r\n
\r\n

DEV TESTING (REGIFT)

\r\n

GLOBAL STATE

\r\n

Basket Id: {id}

\r\n

State: {currentState}

\r\n
\r\n\r\n
\r\n

Step 1 - Check my balance

\r\n

card code: {checkBalanceStep.giftCardCode}

\r\n

balance: {checkBalanceStep.remainingBalance}

\r\n

Currency: {checkBalanceStep.currencySymbol}

\r\n\r\n
\r\n

Is Dirty: {String(checkBalanceStep.isDirty)}

\r\n

Is Valid: {checkBalanceStepIsValid && \"VALID\"} {!checkBalanceStepIsValid && \"INVALID\"}

\r\n
\r\n
\r\n\r\n
\r\n

Step 2 - Regift my card

\r\n

Value: {regiftCardStep.value}

\r\n\r\n
\r\n

Is Dirty: {String(regiftCardStep.isDirty)}

\r\n

Is Valid: {regiftCardStepIsValid && \"VALID\"} {!regiftCardStepIsValid && \"INVALID\"}

\r\n
\r\n
\r\n\r\n\r\n
\r\n

Step 3 - Recipients

\r\n

total: {recipientsStep.recipients.length}

\r\n

sendBy: {recipientsStep.sendBy}

\r\n

sendIndividually: {String(recipientsStep.sendIndividually)}

\r\n

sendItLater: {String(recipientsStep.sendItLater)}

\r\n

senderSameAsRecipient: {String(recipientsStep.senderSameAsRecipient)}

\r\n {recipientsStep.recipients.length > 0 &&\r\n <>\r\n

Recepient 1:

\r\n

{`${recipientsStep.recipients[0].firstName} ${recipientsStep.recipients[0].lastName} (${recipientsStep.recipients[0].email})`}

\r\n }\r\n

Sender:

\r\n

{`${recipientsStep.sender.firstName} ${recipientsStep.sender.lastName} (${recipientsStep.sender.email}, ${recipientsStep.sender.email})`}

\r\n\r\n
\r\n

Is Dirty: {String(recipientsStep.isDirty)}

\r\n

Is Valid: {recipientsStepIsValid && \"VALID\"} {!recipientsStepIsValid && \"INVALID\"}

\r\n
\r\n
\r\n\r\n
\r\n

Step 4 - Customize Step

\r\n

Template Url: {customizeStep.giftCardUrl}

\r\n

GIF Url: {customizeStep.mediaUrl}

\r\n

Message: {customizeStep.personalMessage}

\r\n
\r\n

Is Dirty: {String(customizeStep.isDirty)}

\r\n

Is Valid: {customizeStepIsValid && \"VALID\"} {!customizeStepIsValid && \"INVALID\"}

\r\n
\r\n
\r\n\r\n
\r\n

Step 5 - Review And Pay

\r\n\r\n\r\n

Terms Accepted: {String(paymentStep.termsAccepted)}

\r\n\r\n
\r\n

Is Dirty: {String(paymentStep.isDirty)}

\r\n

Is Valid: {paymentStepIsValid && \"VALID\"} {!paymentStepIsValid && \"INVALID\"}

\r\n
\r\n
\r\n\r\n
\r\n )}\r\n\r\n \r\n );\r\n};\r\nexport default DebugRegiftDataPreivewComponent;","import { AppSettingContext } from \"@src/components/Application\";\r\nimport IBasketDetailsProps from \"@src/models/props/BasketDetailsProps.interface\";\r\nimport React, { useEffect, useState } from \"react\";\r\nimport { isAnBuyGiftCard } from \"../../../helpers/GiftCardHelper\";\r\nimport { GiftCardSendTypeEnum } from \"../../../models/enums/GiftCardSendTypeEnum\";\r\n\r\nconst BasketDetails = (props: IBasketDetailsProps) => {\r\n //Page translation\r\n const { labels } = React.useContext(AppSettingContext);\r\n const [cardValue, setCardValue] = useState(0);\r\n\r\n useEffect(() => {\r\n //if (isAnBuyGiftCard(props.giftCard)) {\r\n // setCardValue(props.giftCard.chooseCard.value);\r\n\r\n //} else if (isAnRegiftCard(props.giftCard)) {\r\n // setCardValue(props.giftCard.regiftCardStep.value);\r\n //}\r\n if (isAnBuyGiftCard(props.giftCard)) {\r\n setCardValue(props.giftCard.chooseCard.value);\r\n\r\n } else {\r\n setCardValue(props.giftCard.regiftCardStep.value);\r\n }\r\n\r\n });\r\n\r\n const [error, setError] = useState(null);\r\n if (error) throw error;\r\n return (\r\n <>\r\n
{labels.get(\"GiftCard.App.Steps.PreviewAndPay.Subsection.Options.Title\")}
\r\n

{labels.get(\"GiftCard.App.Steps.PreviewAndPay.Subsection.Options.Subtitle\")}

\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {props.giftCard.recipientsStep.recipients.map((recipient, index) => (\r\n \r\n \r\n \r\n \r\n ))}\r\n \r\n \r\n {props.giftCard.paymentStep.paymentDetails.totalFees > 0 &&\r\n \r\n \r\n \r\n }\r\n \r\n \r\n \r\n \r\n \r\n
{labels.get(\"GiftCard.App.Steps.PreviewAndPay.Subsection.Options.Recipient\")}{labels.get(\"GiftCard.App.Steps.PreviewAndPay.Subsection.Options.Value\")}
\r\n

{recipient.firstName} {recipient.lastName}

\r\n\r\n {props.giftCard.recipientsStep.sendBy == GiftCardSendTypeEnum.BY_EMAIL &&\r\n

{recipient.email}

}\r\n {props.giftCard.recipientsStep.sendBy == GiftCardSendTypeEnum.BY_SMS &&\r\n

{recipient.phone}

}\r\n
\r\n

€{cardValue.toFixed(2)}

\r\n
\r\n
{labels.get(\"GiftCard.App.Steps.PreviewAndPay.Subsection.Options.Fees\")}
\r\n
€{props.giftCard.paymentStep.paymentDetails.totalFees.toFixed(2)}
\r\n
{labels.get(\"GiftCard.App.Steps.PreviewAndPay.Subsection.Options.Total\")}
\r\n
€{props.giftCard.paymentStep.paymentDetails.totalAmount.toFixed(2)}
\r\n
\r\n
\r\n \r\n )\r\n}\r\n\r\nexport default BasketDetails;","import React, { useEffect, useRef, useState } from \"react\";\r\nimport { PERSONAL_MESSAGE_MAX_LENGTH } from \"../../../constants/global\";\r\nimport { useDebounce } from \"../../../debounce\";\r\nimport { hasXSSCharacters } from \"../../../helpers/Utils\";\r\nimport { CustomizeStepModel, ICustomizeStep } from \"../../../models/CustomizeStep.model\";\r\nimport IGiftCardGif from \"../../../models/GiftCardGif.model\";\r\nimport IGiftCardTemplate from \"../../../models/GiftCardTemplate.model\";\r\nimport { ICustomizeStepProps } from \"../../../models/props/CustomizeStepProps.interface\";\r\nimport DataService from \"../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../Application\";\r\nimport LoadingComponent from \"../../shared/LoadingComponent\";\r\nimport MediaUploader from \"./MediaUploader\";\r\n\r\nconst CustomizeStep = (props: ICustomizeStepProps) => {\r\n const { debugMode, labels } = React.useContext(AppSettingContext);\r\n\r\n const [pageModel, setPageModel] = useState(props.model);\r\n const [isDirty, setIsDirty] = useState(false);\r\n const [isLoading, setIsLoading] = useState(true);\r\n\r\n const [useCardTemplate, setUseCardTemplate] = useState(true);\r\n const [templates, setTemplates] = useState(Array(0));\r\n const [lastUploadedTemplate, setLastUploadedTemplate] = useState(\"\");\r\n\r\n const [writePersonalMessage, setWritePersonalMessage] = useState(true);\r\n\r\n const [addMedia, setAddMedia] = useState(false);\r\n const [useGif, setUseGif] = useState(true);\r\n const [areGifsLoading, setAreGifsLoading] = useState(false);\r\n const [gifs, setGifs] = useState(Array(0));\r\n const [lastUploadedMedia, setLastUploadedMedia] = useState(\"\");\r\n\r\n const checkboxRef = useRef(null)\r\n const culture = document.documentElement.lang;\r\n\r\n //useEffect(() => {\r\n // checkboxRef.current.checked = props.expanded;\r\n //});\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n\r\n setPageModel({ ...props.model });\r\n loadAllTemplates();\r\n }, []);\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n\r\n if (pageModel) {\r\n setIsLoading(false);\r\n //console.log(pageModel);\r\n\r\n const result = checkIfModelIsDirty();\r\n setIsDirty(result);\r\n props.handleDirtyState(result);\r\n }\r\n }, [pageModel]);\r\n\r\n useEffect(() => {\r\n if (templates && templates.length > 0) {\r\n if (!templates.map(x => x.imageUrl).includes(pageModel.giftCardUrl)) {\r\n setLastUploadedTemplate(pageModel.giftCardUrl);\r\n setUseCardTemplate(false);\r\n }\r\n }\r\n }, [templates]);\r\n\r\n useEffect(() => {\r\n setAreGifsLoading(false);\r\n\r\n setTimeout(() => {\r\n initSlider();\r\n }, 600);\r\n }, [gifs]);\r\n\r\n useEffect(() => {\r\n setPageModel({ ...pageModel, giftCardUrl: props.model.giftCardUrl });\r\n }, [props.model.giftCardUrl]);\r\n\r\n useEffect(() => {\r\n checkboxRef.current.checked = props.expanded;\r\n\r\n if (props.expanded) {\r\n if (pageModel.mediaUrl && pageModel.mediaUrl.trim()) {\r\n // the user has already selected media\r\n setAddMedia(true);\r\n\r\n if (pageModel.mediaUrl.includes(\"giphy.com\")) {\r\n loadAllGifs(\"\");\r\n handleAddMediaSwitch(true);\r\n handleUseGifChange(true);\r\n } else {\r\n setLastUploadedMedia(pageModel.mediaUrl);\r\n handleAddMediaSwitch(true);\r\n handleUseGifChange(false);\r\n props.handleMediaChange(pageModel.mediaUrl);\r\n }\r\n }\r\n }\r\n }, [props.expanded]);\r\n\r\n const handleExpandCheck = (): void => {\r\n if (checkboxRef.current.checked) {\r\n props.handleBeginEdit();\r\n\r\n setTimeout(() => {\r\n if (addMedia && useGif) {\r\n loadAllGifs(\"\");\r\n }\r\n }, 200);\r\n }\r\n };\r\n\r\n const handleTemplateChange = (templateUrl: string): void => {\r\n if (templateUrl && templateUrl.trim()) {\r\n setPageModel({\r\n ...pageModel,\r\n giftCardUrl: templateUrl\r\n });\r\n\r\n props.handleTemplateChange(templateUrl);\r\n }\r\n };\r\n\r\n const handleWritePersonalMessageSwitch = (event: React.ChangeEvent): void => {\r\n setWritePersonalMessage(event.target.checked);\r\n };\r\n\r\n const handlePersonalMessageChange = (personalMessage: string): void => {\r\n if (hasXSSCharacters(personalMessage)) {\r\n return;\r\n }\r\n\r\n setPageModel({\r\n ...pageModel,\r\n personalMessage: personalMessage\r\n });\r\n };\r\n\r\n const handleMediaChange = (mediaUrl: string): void => {\r\n // deselect if already selected\r\n if (mediaUrl === pageModel.mediaUrl) {\r\n mediaUrl = \"\";\r\n }\r\n\r\n setPageModel({\r\n ...pageModel, mediaUrl: mediaUrl\r\n });\r\n\r\n setAddMedia(true);\r\n\r\n props.handleMediaChange(mediaUrl);\r\n };\r\n\r\n const handleAddMediaSwitch = (addMedia: boolean): void => {\r\n setAddMedia(addMedia);\r\n\r\n if (addMedia) {\r\n props.handleMediaChange(pageModel.mediaUrl);\r\n loadAllGifs(\"\");\r\n } else {\r\n props.handleMediaChange(\"\");\r\n }\r\n };\r\n\r\n const handleUseGifChange = (useGif: boolean): void => {\r\n if (useGif) {\r\n loadAllGifs(\"\");\r\n }\r\n\r\n setUseGif(useGif);\r\n };\r\n\r\n const handleGifSearch = useDebounce>((event) => {\r\n loadAllGifs(event.target.value);\r\n }, 1000);\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent): void => {\r\n event.preventDefault();\r\n\r\n props.handleSubmit({\r\n giftCardUrl: pageModel.giftCardUrl,\r\n mediaUrl: pageModel.mediaUrl,\r\n personalMessage: pageModel.personalMessage,\r\n isDirty: true,\r\n userGiftCards: [],\r\n userMedias: []\r\n });\r\n\r\n setIsDirty(false);\r\n };\r\n\r\n //const handlePreview = (event: React.MouseEvent): void => {\r\n // event.preventDefault();\r\n\r\n // props.handlePreview(personalMessage);\r\n\r\n // //DO NOT UPDATE MODEL like we do in handleSaveAndContinue,\r\n // // but just propagade model and update Preview component (show draft label)\r\n\r\n // props.handleSubmit();\r\n // page model is already updated\r\n // setIsExpanded(false);\r\n // update page model to open recipients\r\n //};\r\n\r\n const loadAllTemplates = (): void => {\r\n DataService.getGiftCardsTemplates(culture)\r\n .then(response => {\r\n if (response) {\r\n const _templates = Array(0);\r\n\r\n response.forEach((item, index) => {\r\n _templates.push(item);\r\n });\r\n\r\n setTemplates(_templates);\r\n }\r\n })\r\n .catch(error => {\r\n console.error(error);\r\n });\r\n };\r\n\r\n const loadAllGifs = (searchTerm: string): void => {\r\n setAreGifsLoading(true);\r\n\r\n DataService.getGiftCardsGifsTemplates(culture, searchTerm)\r\n .then(response => {\r\n if (response) {\r\n const gifItems = Array(0);\r\n response.forEach((item, index) => {\r\n gifItems.push(item);\r\n });\r\n\r\n setGifs(gifItems);\r\n }\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n };\r\n\r\n const initSlider = (): void => {\r\n if (document.querySelector('.swiper-gif')) {\r\n // @ts-ignore\r\n const swiperGif = new Swiper('.swiper-gif', {\r\n slidesPerView: \"auto\",\r\n spaceBetween: 0,\r\n slidesPerGroup: 2,\r\n grid: {\r\n rows: 2,\r\n },\r\n freeMode: true,\r\n navigation: {\r\n nextEl: '.swiper-gif-button-next',\r\n prevEl: '.swiper-gif-button-prev',\r\n },\r\n });\r\n }\r\n };\r\n\r\n const checkIfModelIsDirty = (): boolean => {\r\n if (!pageModel) {\r\n return false;\r\n }\r\n\r\n if (pageModel.giftCardUrl != props.model.giftCardUrl) {\r\n return true;\r\n }\r\n\r\n if (pageModel.mediaUrl != props.model.mediaUrl) {\r\n return true;\r\n }\r\n\r\n if (pageModel.personalMessage != props.model.personalMessage) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n const isValid = (): boolean => {\r\n return CustomizeStepModel.validateModel(pageModel);\r\n };\r\n\r\n return (\r\n
\r\n \r\n\r\n
\r\n

{labels.get(\"GiftCard.App.Steps.Customise\")}

\r\n\r\n
\r\n {(!props.isSaving && props.isActive) &&\r\n \r\n }\r\n
\r\n\r\n
\r\n {(props.isSaving) && (\r\n \r\n )}\r\n\r\n {(!isLoading && !props.isSaving) &&\r\n
\r\n {debugMode &&\r\n
\r\n

Template Url: {pageModel.giftCardUrl ? pageModel.giftCardUrl.replace(/^.*[\\\\\\/]/, '') : \"\"}

\r\n

GIF Url: {pageModel.mediaUrl ? pageModel.mediaUrl.replace(/^.*[\\\\\\/]/, '') : \"\"}

\r\n

Message: {pageModel.personalMessage}

\r\n\r\n

Is dirty: {String(isDirty)}

\r\n

Is valid: {String(isValid())}

\r\n

Is active: {String(props.isActive)}

\r\n
\r\n }\r\n\r\n {/* -------------------- GIFTCARD TEMPLATES -------------------- */}\r\n
\r\n
{labels.get(\"GiftCard.App.V2.CustomiseCard.Title\")}
\r\n
    \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n setUseCardTemplate(true);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n setUseCardTemplate(false);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
\r\n\r\n {useCardTemplate ? (\r\n
\r\n {templates.map((template, index) => (\r\n handleTemplateChange(template.imageUrl)}\r\n />\r\n ))}\r\n
\r\n ) : (\r\n \r\n )}\r\n
\r\n {/* ------------------------------------------------------------ */}\r\n\r\n {/* ------------------------ MAIL MEDIA ------------------------ */}\r\n
\r\n
{labels.get(\"GiftCard.App.V2.CustomiseMail.Title\")}
\r\n
\r\n
\r\n {/*
{labels.get(\"GiftCard.App.V2.CustomiseMail.Subtitle\")}
*/}\r\n \r\n
\r\n

{labels.get(\"GiftCard.App.V2.CustomiseMail.Label.PersonalMessage\")}

\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n handlePersonalMessageChange(e.target.value)}\r\n >\r\n
\r\n \r\n {PERSONAL_MESSAGE_MAX_LENGTH - pageModel.personalMessage.length}/{PERSONAL_MESSAGE_MAX_LENGTH}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n handleAddMediaSwitch(e.target.checked)}\r\n />\r\n
\r\n

Add a Photo, Video or GIF

\r\n \r\n
\r\n\r\n {addMedia && (\r\n <>\r\n
    \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleUseGifChange(true);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
  • \r\n {\r\n if (e.target.checked) {\r\n handleUseGifChange(false);\r\n }\r\n }}\r\n />\r\n \r\n
  • \r\n
\r\n\r\n {useGif ? (\r\n
\r\n
\r\n
\r\n \r\n\r\n
\r\n
\r\n {areGifsLoading ? (\r\n \r\n ) : (\r\n
\r\n {gifs.map((gif, index) => (\r\n
\r\n handleMediaChange(gif.video.trim() ? gif.video : gif.image)}\r\n >\r\n \r\n \r\n
\r\n ))}\r\n
\r\n )}\r\n
\r\n\r\n
\r\n \r\n \r\n \r\n {labels.get(\"GiftCard.App.Steps.Customise.Templates.Btn.Previous\")}\r\n
\r\n
\r\n {labels.get(\"GiftCard.App.Steps.Customise.Templates.Btn.Next\")}\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n ) : (\r\n \r\n )}\r\n \r\n )}\r\n
\r\n
\r\n
\r\n {/* ------------------------------------------------------------ */}\r\n\r\n
\r\n
\r\n \r\n {labels.get(\"GiftCard.App.Steps.Customise.Btn.Save\")}\r\n \r\n\r\n {/**/}\r\n {/* {labels.get(\"GiftCard.App.Steps.Customise.Btn.Preview\")}*/}\r\n {/**/}\r\n
\r\n
\r\n
\r\n }\r\n
\r\n
\r\n \r\n )\r\n};\r\n\r\nexport default CustomizeStep;","import React, { useContext, useEffect, useState } from 'react';\r\nimport { isEmail, isFullNameValid, isNotNullOrEmpty } from '../../../helpers/Utils';\r\nimport ICountry from '../../../models/Country.interface';\r\nimport { CheckoutBillingAddressData } from '../../../models/ElavonCheckoutModels';\r\nimport { IGiftCardCheckoutResult } from '../../../models/GiftCardCheckoutResult.model';\r\nimport { ICardCheckoutModel, ICheckoutSessionData } from '../../../models/PaymentStep.model';\r\nimport IState from '../../../models/State.interface';\r\nimport DataService from '../../../services/DataService.service';\r\nimport { AppSettingContext } from '../../Application';\r\nimport LoadingComponent from '../../shared/LoadingComponent';\r\n\r\ninterface CheckoutPaymentProps {\r\n basketId: string,\r\n senderDetails: {\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n phone: string;\r\n },\r\n paymentData: {\r\n amount: string;\r\n currency: string;\r\n },\r\n handleError(errorMsg: string): void;\r\n handleFormUpdate(isFormValid: boolean, billingDetails: CheckoutBillingAddressData): void;\r\n}\r\n\r\nconst ElavonPayment = (props: CheckoutPaymentProps) => {\r\n const { labels, elavonSettings } = useContext(AppSettingContext);\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [checkoutModel, setCheckoutModel] = useState({\r\n email: props.senderDetails.email,\r\n country: 'IE',\r\n county: '',\r\n city: '',\r\n postcode: '',\r\n addressLine1: '',\r\n addressLine2: '',\r\n cardNumber: '',\r\n expiryDate: '',\r\n cardholder: `${props.senderDetails.firstName} ${props.senderDetails.lastName}`,\r\n securityCode: '',\r\n });\r\n const [errors, setErrors] = useState({\r\n country: '',\r\n county: '',\r\n city: '',\r\n postcode: '',\r\n addressLine1: '',\r\n addressLine2: '',\r\n cardNumber: '',\r\n expiryDate: '',\r\n cardholder: '',\r\n securityCode: '',\r\n });\r\n const [countries, setCountries] = useState([] as ICountry[]);\r\n const [states, setStates] = useState([] as IState[]);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n\r\n addRequiredScripts();\r\n getCountries();\r\n getStates();\r\n\r\n setTimeout(() => {\r\n setIsLoading(false);\r\n }, 500);\r\n }, []);\r\n\r\n useEffect(() => {\r\n formValidations.validateWholeForm();\r\n }, [errors]);\r\n\r\n useEffect(() => {\r\n checkoutModel.country && formValidations.validateAddressFields(\"country\", true, /^[\\p{L}]{2}$/u);\r\n checkoutModel.city && formValidations.validateAddressFields(\"city\", true, /^[\\p{L}0-9\\s-]{2,40}$/u);\r\n checkoutModel.postcode && formValidations.validateAddressFields(\"postcode\", true, /^[\\p{L}0-9\\s-]{3,10}$/u);\r\n checkoutModel.addressLine1 && formValidations.validateAddressFields(\"addressLine1\", true, /^[\\p{L}0-9\\s,\"'.#&/-]{1,50}$/u);\r\n checkoutModel.addressLine2 && formValidations.validateAddressFields(\"addressLine2\", false, /^[\\p{L}0-9\\s,\"'.#&/-]{0,50}$/u);\r\n checkoutModel.addressLine3 && formValidations.validateAddressFields(\"addressLine3\", false, /^[\\p{L}0-9\\s,\"'.#&/-]{0,50}$/u);\r\n checkoutModel.cardNumber && formValidations.validateCardNumber();\r\n checkoutModel.expiryDate && formValidations.validateExpiryDate();\r\n checkoutModel.cardholder && formValidations.validateCardholder();\r\n checkoutModel.securityCode && formValidations.validateCvc();\r\n\r\n formValidations.validateAddressFields(\"county\", checkoutModel.country.toLowerCase() === 'us', /^[\\p{L}0-9\\s-]{2,}$/u);\r\n }, [checkoutModel]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleCardDetailsChange = (event: React.ChangeEvent | React.ChangeEvent) => {\r\n const { id, value } = event.target;\r\n let formattedValue = value;\r\n\r\n let checkoutModelNew = {\r\n ...checkoutModel\r\n };\r\n\r\n if (id === 'email-field') {\r\n formattedValue = formattedValue\r\n .replace(/[^a-zA-Z0-9._%+-@]/g, '')\r\n .replace(/[?/;:,<>=]/g, '')\r\n .trim();\r\n } else if (id === 'cardNumber-field') {\r\n formattedValue = formattedValue\r\n .replace(/\\D/g, '')\r\n .replace(/(\\d{4})/g, '$1 ')\r\n .trim();\r\n } else if (id === 'expiryDate-field') {\r\n formattedValue = formattedValue\r\n .replace(/\\D/g, '')\r\n .replace(/^(\\d{2})(\\d{1,2})/, '$1 / $2')\r\n .trim();\r\n } else if (id === 'securityCode-field') {\r\n formattedValue = formattedValue\r\n .replace(/\\D/g, '')\r\n .trim();\r\n } else if (id === 'country-field') {\r\n formattedValue = formattedValue\r\n .replace(/[<>&;?/=]/g, '');\r\n\r\n checkoutModelNew = {\r\n ...checkoutModelNew,\r\n county: \"\"\r\n };\r\n } else if (\r\n id === 'county-field' ||\r\n id === 'cardholder-field' ||\r\n id === 'city-field' ||\r\n id === 'postcode-field' ||\r\n id === 'addressLine1-field' ||\r\n id === 'addressLine2-field'\r\n ) {\r\n formattedValue = formattedValue\r\n .replace(/[<>&;?/=]/g, '');\r\n }\r\n\r\n const propName = id.replace('-field', '');\r\n\r\n if (!formattedValue && propName !== 'addressLine2' && propName !== 'county') {\r\n setErrors({\r\n ...errors,\r\n [propName]: `${propName.charAt(0).toUpperCase() + propName.slice(1)} is required`\r\n });\r\n }\r\n\r\n checkoutModelNew = {\r\n ...checkoutModelNew,\r\n [propName]: formattedValue\r\n };\r\n\r\n setCheckoutModel(checkoutModelNew);\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n async function getCountries() {\r\n const countriesJson = await DataService.getCountries(document.documentElement.lang ?? \"en-GB\");\r\n const countriesArr = [];\r\n\r\n for (let i = 0; i < countriesJson.length; i++) {\r\n countriesArr.push({\r\n name: countriesJson[i].name,\r\n code: countriesJson[i].code\r\n } as ICountry);\r\n }\r\n\r\n setCountries(countriesArr);\r\n }\r\n\r\n async function getStates() {\r\n const statesJson = await DataService.getUSAStates();\r\n const statesArr = [];\r\n\r\n for (let i = 0; i < statesJson.length; i++) {\r\n statesArr.push({\r\n name: statesJson[i].name,\r\n code: statesJson[i].code\r\n } as IState);\r\n }\r\n\r\n setStates(statesArr);\r\n }\r\n\r\n const addRequiredScripts = () => {\r\n const allScriptSrcs = Array.from(document.querySelectorAll('script')).map(x => x.src);\r\n\r\n if (!allScriptSrcs.some(x => x.includes(elavonSettings.jsScriptUrl))) {\r\n const script = document.createElement('script');\r\n script.src = elavonSettings.jsScriptUrl;\r\n document.body.appendChild(script);\r\n }\r\n\r\n if (!allScriptSrcs.some(x => x.includes(\"static/js/elavon-payment.js\"))) {\r\n const script = document.createElement('script');\r\n script.src = `${window.location.origin}/static/js/elavon-payment.js`;\r\n document.body.appendChild(script);\r\n }\r\n };\r\n\r\n const formValidations = {\r\n validateWholeForm: () => {\r\n const isFormValid =\r\n checkoutModel.country && !errors.country &&\r\n !errors.county &&\r\n checkoutModel.city && !errors.city &&\r\n checkoutModel.postcode && !errors.postcode &&\r\n checkoutModel.addressLine1 && !errors.addressLine1 &&\r\n !errors.addressLine2 &&\r\n checkoutModel.cardNumber && !errors.cardNumber &&\r\n checkoutModel.cardholder && !errors.cardholder &&\r\n checkoutModel.expiryDate && !errors.expiryDate &&\r\n checkoutModel.securityCode && !errors.securityCode;\r\n\r\n props.handleFormUpdate(isFormValid, {\r\n addressLine1: checkoutModel.addressLine1,\r\n addressLine2: checkoutModel.addressLine2,\r\n addressLine3: '',\r\n city: checkoutModel.city,\r\n county: checkoutModel.county,\r\n country: checkoutModel.country,\r\n postcode: checkoutModel.postcode\r\n });\r\n\r\n //const paymentCompletedChk = document.getElementById('chkPaymentCompleted') as HTMLInputElement;\r\n\r\n //if (paymentCompletedChk) {\r\n // paymentCompletedChk.checked = !isFormValid;\r\n // paymentCompletedChk.click();\r\n //}\r\n\r\n //if (isFormValid) {\r\n //props.handleModelChange(checkoutModel);\r\n //}\r\n },\r\n\r\n validateEmail: () => {\r\n const value = checkoutModel.email.trim();\r\n let error = \"\";\r\n\r\n if (!value) {\r\n error = \"Email is required\";\r\n } else if (!isEmail(value)) {\r\n error = \"Invalid email\";\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n email: error\r\n }));\r\n },\r\n validateAddressFields: (fieldName: string, isRequired: boolean, pattern: RegExp) => {\r\n const value = checkoutModel[fieldName].trim();\r\n let error = \"\";\r\n\r\n if (isRequired && !value) {\r\n error = `${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)} is required`;\r\n\r\n if (fieldName.toLowerCase() === 'county') {\r\n error = \"State is required\"\r\n }\r\n } else if (value && pattern.test(value) === false) {\r\n error = `Invalid ${fieldName}`;\r\n\r\n if (fieldName.toLowerCase() === 'county' && isRequired) {\r\n error = \"Invalid state\";\r\n }\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n [fieldName]: error\r\n }));\r\n },\r\n validateCardNumber: () => {\r\n const value = checkoutModel.cardNumber.replaceAll(\" \", \"\").trim();\r\n let error = \"\";\r\n\r\n if (!value) {\r\n error = \"Card number is required\";\r\n } else if (value.length < 13) {\r\n error = \"Invalid card number\";\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n cardNumber: error\r\n }));\r\n },\r\n validateExpiryDate: () => {\r\n const value = checkoutModel.expiryDate.trim();\r\n let error = \"\";\r\n\r\n if (!value) {\r\n error = \"Expiry date is required\";\r\n } else if (value.length < 7) {\r\n error = \"Invalid expiry date\";\r\n }\r\n\r\n if (!error) {\r\n const [month, year] = value.split(\" / \");\r\n const monthInt = parseInt(month);\r\n const yearInt = parseInt(year);\r\n\r\n if (monthInt < 1 || monthInt > 12) {\r\n error = \"Invalid month\";\r\n } else if (yearInt < 0) {\r\n error = \"Invalid year\";\r\n }\r\n\r\n if (!error) {\r\n const currDate = new Date();\r\n const currYear = currDate.getFullYear() % 100; // get the last 2 digits from the year\r\n const currMonth = currDate.getMonth() + 1; // JS months are zero-indexed\r\n\r\n if (yearInt < currYear || (yearInt === currYear && monthInt < currMonth)) {\r\n error = \"Date is in the past\";\r\n }\r\n }\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n expiryDate: error\r\n }));\r\n },\r\n validateCardholder: () => {\r\n const value = checkoutModel.cardholder.trim();\r\n let error = \"\";\r\n\r\n if (!value || !value.trim()) {\r\n error = \"Cardholder is required\";\r\n } else if (!isFullNameValid(value)) {\r\n error = \"Invalid cardholder\";\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n cardholder: error\r\n }));\r\n },\r\n validateCvc: () => {\r\n const value = checkoutModel.securityCode.trim();\r\n let error = \"\";\r\n\r\n if (!value) {\r\n error = \"Security code is required\";\r\n } else if (value.length < 3 || value.length > 4) {\r\n error = \"Invalid security code\";\r\n }\r\n\r\n setErrors(currErrors => ({\r\n ...currErrors,\r\n securityCode: error\r\n }));\r\n }\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n
\r\n {labels.get(\"GiftCard.App.Steps.PreviewAndPay.Card.Subsection.CardDetails\") ?? \"\"}\r\n
\r\n
\r\n
\r\n \r\n \r\n {errors.cardNumber && {errors.cardNumber}}\r\n
\r\n
\r\n \r\n \r\n {errors.expiryDate && {errors.expiryDate}}\r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n {errors.cardholder && {errors.cardholder}}\r\n
\r\n
\r\n \r\n \r\n {errors.securityCode && {errors.securityCode}}\r\n
\r\n
\r\n
{labels.get(\"GiftCard.App.Steps.PreviewAndPay.Card.Subsection.BillingDetails\") ?? \"\"}
\r\n
\r\n
\r\n \r\n \r\n {errors.addressLine1 && {errors.addressLine1}}\r\n
\r\n
\r\n \r\n \r\n {errors.addressLine2 && {errors.addressLine2}}\r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n {errors.city && {errors.city}}\r\n
\r\n {checkoutModel.country.toLowerCase() === 'us' ? (\r\n
\r\n \r\n \r\n \r\n\r\n {states.map((state, index) => (\r\n \r\n ))}\r\n \r\n {errors.county && {errors.county}}\r\n
\r\n ) : (\r\n
\r\n \r\n \r\n {errors.county && {errors.county}}\r\n
\r\n )}\r\n
\r\n
\r\n
\r\n \r\n \r\n {errors.postcode && {errors.postcode}}\r\n
\r\n
\r\n \r\n \r\n {countries.map((country, index) => (\r\n \r\n ))}\r\n \r\n {errors.country && {errors.country}}\r\n
\r\n
\r\n \r\n
\r\n )}\r\n
\r\n );\r\n};\r\n\r\nexport const HandleElavonCheckout = (merchantSession: ICheckoutSessionData) => {\r\n // @ts-ignore\r\n // sets cardIdentifier (card tokenisation token) in the hidden input field\r\n CustomElavonPayment.HandleCreditCardCheckout(merchantSession);\r\n};\r\n\r\nexport const HandleThreeDSecureAuth = (checkoutRes: IGiftCardCheckoutResult, handleThreeDError: (errorMessage: string) => void) => {\r\n if (checkoutRes.secure3DAuth &&\r\n isNotNullOrEmpty(checkoutRes.secure3DAuth.acsUrl) &&\r\n isNotNullOrEmpty(checkoutRes.secure3DAuth.creq) &&\r\n isNotNullOrEmpty(checkoutRes.secure3DAuth.transactionid)) {\r\n\r\n redirectToThreeDSecurePage(\r\n checkoutRes.secure3DAuth.acsUrl,\r\n checkoutRes.secure3DAuth.creq,\r\n checkoutRes.secure3DAuth.transactionid\r\n );\r\n } else {\r\n handleThreeDError(`Status from checkout response: ${checkoutRes.statusMessage}`);\r\n }\r\n};\r\n\r\nexport default ElavonPayment;\r\n\r\n// PRIVATE HELPERS BELOW\r\nfunction redirectToThreeDSecurePage(acsUrl: string, cReq: string, tranId: string) {\r\n const redirectForm = document.createElement('form');\r\n redirectForm.method = 'POST';\r\n redirectForm.action = acsUrl;\r\n\r\n const cReqInput = document.createElement('input');\r\n cReqInput.type = 'hidden';\r\n cReqInput.name = 'creq';\r\n cReqInput.value = cReq;\r\n\r\n const transactionIdInput = document.createElement('input');\r\n transactionIdInput.type = 'hidden';\r\n transactionIdInput.name = 'threeDSSessionData';\r\n transactionIdInput.value = tranId;\r\n\r\n redirectForm.appendChild(cReqInput);\r\n redirectForm.appendChild(transactionIdInput);\r\n\r\n const formContainer = document.querySelector(\"#payment-box #checkout-container\");\r\n formContainer.appendChild(redirectForm);\r\n\r\n redirectForm.submit();\r\n}","import React, { useEffect, useState } from \"react\";\r\nimport { formatStringWithPlaceholders, hasXSSCharacters, isEmail, isFullNameValid } from \"../../../helpers/Utils\";\r\nimport ICountry from \"../../../models/Country.interface\";\r\nimport { IInvoiceDetails } from \"../../../models/InvoiceDetails.model\";\r\nimport { ISenderDetails } from \"../../../models/SenderDetails.model\";\r\nimport DataService from \"../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../Application\";\r\n\r\nexport interface IInvoiceDetailsProps {\r\n isBusinessPurchase?: boolean;\r\n model: IInvoiceDetails;\r\n senderDetails: ISenderDetails;\r\n handleUpdate(model: IInvoiceDetails): void;\r\n}\r\n\r\nconst InvoiceDetails = (props: IInvoiceDetailsProps) => {\r\n const { labels } = React.useContext(AppSettingContext);\r\n const culture = document.documentElement.lang ?? \"en-GB\";\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [model, setModel] = useState({\r\n firstName: props.model?.firstName ?? props.senderDetails?.firstName ?? \"\",\r\n lastName: props.model?.lastName ?? props.senderDetails?.lastName ?? \"\",\r\n fullName: props.model?.fullName ?? props.senderDetails.fullName?.trim() ?? \"\",\r\n email: props.model?.email ?? props.senderDetails?.email ?? \"\",\r\n companyName: props.model?.companyName ?? props.senderDetails?.company ?? \"\",\r\n\r\n country: \"IE\", // by default\r\n county: props.model?.country ?? \"\",\r\n city: props.model?.city ?? \"\",\r\n postcode: props.model?.postcode ?? \"\",\r\n\r\n addressLine1: props.model?.addressLine1 ?? \"\",\r\n addressLine2: props.model?.addressLine2 ?? \"\",\r\n addressLine3: props.model?.addressLine3 ?? \"\",\r\n } as IInvoiceDetails);\r\n const [countries, setCountries] = useState(Array(0));\r\n const [modelErrors, setModelErrors] = useState({\r\n fullName: '',\r\n email: '',\r\n companyName: '',\r\n country: '',\r\n city: '',\r\n postcode: '',\r\n addressLine1: ''\r\n });\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n DataService.getCountries(culture)\r\n .then(response => {\r\n if (response) {\r\n setCountries(response)\r\n } else {\r\n console.error(\"Unable to get countries\")\r\n }\r\n }).catch(console.error);\r\n }, []);\r\n\r\n useEffect(() => {\r\n props.handleUpdate(model);\r\n }, [model]);\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleInput = (event: React.ChangeEvent) => {\r\n const { name, value } = event.target;\r\n\r\n if (hasXSSCharacters(value)) {\r\n event.preventDefault();\r\n }\r\n\r\n let errMsg = '';\r\n\r\n if (name === 'fullName') {\r\n if (!value || !value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Full name\");\r\n } else if (!isFullNameValid(value.trim())) {\r\n errMsg = \"Invalid full name\";\r\n }\r\n } else if (name === 'email') {\r\n if (!value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Email\");\r\n } else if (!isEmail(value)) {\r\n errMsg = labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.Email.ErrorMessage\");\r\n }\r\n } else if (name === 'companyName' && !value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Company name\");\r\n } else if (name === 'country' && !value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Country\");\r\n } else if (name === 'city' && !value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"City\");\r\n } else if (name === 'addressLine1' && !value.trim()) {\r\n errMsg = formatStringWithPlaceholders(labels.get(\"GiftCard.App.V2.Shared.ErrorMessages.FieldRequired\"), \"Address line 1\");\r\n } else if (name === 'postcode' && value && value.trim() && value.trim().length < 3) {\r\n errMsg = \"Invalid postcode\";\r\n }\r\n\r\n setModelErrors({\r\n ...modelErrors,\r\n [name]: errMsg\r\n });\r\n\r\n setModel({\r\n ...model,\r\n [name]: value\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n
\r\n
{labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Title\")}
\r\n
\r\n
\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.FullName.Placeholder\")}\r\n />\r\n\r\n {modelErrors.fullName && (\r\n \r\n {modelErrors.fullName}\r\n \r\n )}\r\n
\r\n {/*
*/}\r\n {/* */}\r\n {/* handleInput(event)}*/}\r\n {/* placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.FirstName.Placeholder\")}*/}\r\n {/* />*/}\r\n {/*
*/}\r\n {/*
*/}\r\n {/* */}\r\n {/* handleInput(event)}*/}\r\n {/* placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.LastName.Placeholder\")}*/}\r\n {/* />*/}\r\n {/*
*/}\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.Email.Placeholder\")}\r\n />\r\n\r\n {modelErrors.email && (\r\n \r\n {modelErrors.email}\r\n \r\n )}\r\n
\r\n {props.isBusinessPurchase && (\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.CompanyName.Placeholder\")}\r\n />\r\n\r\n {modelErrors.companyName && (\r\n \r\n {modelErrors.companyName}\r\n \r\n )}\r\n
\r\n )}\r\n
\r\n \r\n \r\n\r\n {modelErrors.country && (\r\n \r\n {modelErrors.country}\r\n \r\n )}\r\n
\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.County.Placeholder\")}\r\n />\r\n
\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.City.Placeholder\")}\r\n />\r\n\r\n {modelErrors.city && (\r\n \r\n {modelErrors.city}\r\n \r\n )}\r\n
\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.PostCode.Placeholder\")}\r\n />\r\n\r\n {modelErrors.postcode && (\r\n \r\n {modelErrors.postcode}\r\n \r\n )}\r\n
\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.AddressLine1.Placeholder\")}\r\n />\r\n\r\n {modelErrors.addressLine1 && (\r\n \r\n {modelErrors.addressLine1}\r\n \r\n )}\r\n
\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.AddressLine2.Placeholder\")}\r\n />\r\n
\r\n
\r\n \r\n handleInput(event)}\r\n placeholder={labels.get(\"GiftCard.App.Steps.PreviewAndPay.Invoice.Labels.AddressLine3.Placeholder\")}\r\n />\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default InvoiceDetails;","import Cropper from \"cropperjs\";\r\nimport React, { useContext, useState } from \"react\";\r\nimport { isVideoFile } from \"../../../helpers/Utils\";\r\nimport { BuyGiftCardContext } from \"../../../pages/BuyGiftCardPageNew\";\r\nimport DataService from \"../../../services/DataService.service\";\r\nimport { AppSettingContext } from \"../../Application\";\r\nimport LoadingComponent from \"../../shared/LoadingComponent\";\r\n\r\ninterface IMediaUploaderProps {\r\n uploaderId: number;\r\n selectedMediaUrl: string;\r\n lastUploadedTemplate: string;\r\n isVideoAllowed: boolean;\r\n imageCropperAspectRatio: number;\r\n\r\n setLastUploadedTemplate: (url: string) => void;\r\n handleMediaChange: (mediaUrl: string) => void;\r\n}\r\n\r\nconst MediaUploader = (props: IMediaUploaderProps) => {\r\n const { id } = useContext(BuyGiftCardContext);\r\n const { labels, cardSettings } = useContext(AppSettingContext);\r\n const culture = document.documentElement.lang;\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [isMediaLoading, setIsMediaLoading] = useState();\r\n const [dragging, setDragging] = useState(false);\r\n const [isMediaDropping, setIsMediaDropping] = useState(false);\r\n const [fileUploadError, setFileUploadError] = useState(\"\");\r\n\r\n //#endregion\r\n\r\n //#region HANDLERS\r\n\r\n const handleDragOver = (event: React.DragEvent): void => {\r\n event.preventDefault();\r\n setDragging(true);\r\n };\r\n\r\n const handleDragLeave = (): void => {\r\n setDragging(false);\r\n };\r\n\r\n const handleDrop = async (event: React.DragEvent): Promise => {\r\n event.preventDefault();\r\n setDragging(false);\r\n\r\n const file = event.dataTransfer.files[0];\r\n if (!isMediaFileValid(file)) {\r\n return;\r\n }\r\n\r\n setIsMediaDropping(true);\r\n setTimeout(async () => {\r\n if (props.isVideoAllowed && isVideoFile(file.name)) {\r\n await processVideoFile(file);\r\n } else {\r\n initializeImageCropper(file);\r\n }\r\n\r\n setIsMediaDropping(false);\r\n }, 300);\r\n };\r\n\r\n const handleMediaUpload = async (e: React.ChangeEvent): Promise => {\r\n const file = e.target.files[0];\r\n if (!isMediaFileValid(file)) {\r\n return;\r\n }\r\n\r\n if (props.isVideoAllowed && isVideoFile(file.name)) {\r\n await processVideoFile(file);\r\n } else {\r\n initializeImageCropper(file);\r\n }\r\n };\r\n\r\n //#endregion\r\n\r\n //#region COMMON HELPERS\r\n\r\n const isMediaFileValid = (file: File): boolean => {\r\n if (!file) {\r\n return false;\r\n }\r\n\r\n if (!file.type.startsWith(\"image/\") && (!file.type.startsWith(\"video/\") || !props.isVideoAllowed)) {\r\n console.error(`File is not of an image${props.isVideoAllowed ? \"/video\" : \"\"} type. File type: ${file.type}`);\r\n setFileUploadError(`File is not of an image${props.isVideoAllowed ? \" / video\" : \"\"} type.`);\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n const initializeImageCropper = (file: File): void => {\r\n const reader = new FileReader();\r\n\r\n reader.onload = (event) => {\r\n const image = event.target.result as string;\r\n let cropper: Cropper;\r\n\r\n if (image) {\r\n const cropperModal = document.getElementById(`template-cropper-modal-${props.uploaderId}`);\r\n cropperModal.style.display = 'flex';\r\n\r\n const cropperImage = document.getElementById(`template-cropper-img-${props.uploaderId}`) as HTMLImageElement;\r\n cropperImage.src = image;\r\n\r\n cropper = new Cropper(cropperImage, {\r\n aspectRatio: props.imageCropperAspectRatio,\r\n viewMode: 2\r\n });\r\n }\r\n\r\n const btnCancel = document.getElementById(`cancel-btn-${props.uploaderId}`);\r\n if (btnCancel) {\r\n btnCancel.addEventListener('click', function () {\r\n if (cropper) {\r\n try {\r\n cropper.getCroppedCanvas().toDataURL('image/jpeg');\r\n (document.getElementById(`add-multimedia__upload-${props.uploaderId}`) as HTMLInputElement).value = '';\r\n (document.getElementById(`template-cropper-img-${props.uploaderId}`) as HTMLImageElement).src = '';\r\n document.getElementById(`template-cropper-modal-${props.uploaderId}`).style.display = 'none';\r\n cropper.destroy();\r\n } catch (error) {\r\n console.error(error);\r\n }\r\n }\r\n });\r\n }\r\n\r\n const btnCrop = document.getElementById(`crop-btn-${props.uploaderId}`);\r\n if (btnCrop) {\r\n btnCrop.addEventListener('click', function () {\r\n if (cropper) {\r\n try {\r\n const croppedImageCanvas = cropper.getCroppedCanvas();\r\n\r\n croppedImageCanvas.toBlob((blob) => {\r\n const croppedImage = new File([blob], 'cropped-image.jpg', {\r\n type: 'image/jpeg'\r\n })\r\n\r\n processImageFile(croppedImage);\r\n\r\n (document.getElementById(`add-multimedia__upload-${props.uploaderId}`) as HTMLInputElement).value = '';\r\n (document.getElementById(`template-cropper-img-${props.uploaderId}`) as HTMLImageElement).src = '';\r\n document.getElementById(`template-cropper-modal-${props.uploaderId}`).style.display = 'none';\r\n cropper.destroy();\r\n }, 'image/jpeg');\r\n } catch (error) {\r\n console.error(error);\r\n }\r\n }\r\n });\r\n }\r\n };\r\n\r\n reader.readAsDataURL(file);\r\n };\r\n\r\n const processImageFile = (file: File): void => {\r\n file.arrayBuffer()\r\n .then(async (arrayBuffer) => {\r\n const byteArray = new Uint8Array(arrayBuffer);\r\n const blob = new Blob([byteArray], { type: file.type });\r\n const sizeInKb = blob.size / 1024;\r\n\r\n if (sizeInKb > cardSettings.mediaSizeMax) {\r\n console.error(`The uploaded image exceeds the maximum size. File size: ${sizeInKb}kb`);\r\n setFileUploadError(\"The uploaded image exceeds the maximum size.\");\r\n return;\r\n }\r\n\r\n const formData = new FormData();\r\n formData.append('file', blob, file.name);\r\n uploadTemplateFile(formData);\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n };\r\n\r\n const processVideoFile = async (file: File): Promise => {\r\n const videoElement = document.createElement(\"video\");\r\n const reader = new FileReader();\r\n\r\n reader.onload = (event) => {\r\n videoElement.src = event.target.result as string;\r\n };\r\n\r\n videoElement.onloadedmetadata = () => {\r\n if (videoElement.duration > cardSettings.mediaDurationMax) {\r\n console.error(`The uploaded video exceeds the maximum duration. Video duration: ${videoElement.duration}s`);\r\n setFileUploadError(\"The uploaded video exceeds the maximum duration.\");\r\n }\r\n };\r\n\r\n // throwing error\r\n //const duration = await getVideoDuration(file);\r\n //if (duration > cardSettings.mediaDurationMax) {\r\n // console.error(`The uploaded video exceeds the maximum duration. Video duration: ${duration}s`);\r\n // setFileUploadError(\"The uploaded video exceeds the maximum duration.\");\r\n //}\r\n\r\n file.arrayBuffer()\r\n .then(async (arrayBuffer) => {\r\n const byteArray = new Uint8Array(arrayBuffer);\r\n const blob = new Blob([byteArray], { type: file.type });\r\n const sizeInKb = blob.size / 1024;\r\n\r\n if (sizeInKb > cardSettings.mediaSizeMax) {\r\n console.error(`The uploaded video exceeds the maximum size. File size: ${sizeInKb}kb`);\r\n setFileUploadError(\"The uploaded video exceeds the maximum size.\");\r\n return;\r\n }\r\n\r\n const formData = new FormData();\r\n formData.append('file', blob, file.name);\r\n uploadTemplateFile(formData);\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n };\r\n\r\n const uploadTemplateFile = (formData: FormData): void => {\r\n if (formData) {\r\n setIsMediaLoading(true);\r\n\r\n DataService.uploadGiftCardTemplate(culture, id, formData)\r\n .then((response) => {\r\n if (response && response.url.trim()) {\r\n props.handleMediaChange(response.url);\r\n props.setLastUploadedTemplate(response.url);\r\n setFileUploadError(\"\");\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n }).finally(() => {\r\n setTimeout(() => {\r\n setIsMediaLoading(false);\r\n }, 300);\r\n });\r\n }\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n <>\r\n
\r\n {isMediaLoading ? (\r\n \r\n ) : (\r\n <>\r\n \r\n {\r\n handleMediaUpload(e);\r\n e.target.value = '';\r\n }}\r\n />\r\n \"Upload\"\r\n\r\n {isMediaDropping ? (\r\n \r\n ) : (\r\n
\r\n )}\r\n\r\n \r\n \r\n {props.isVideoAllowed && isVideoFile(props.lastUploadedTemplate) ? (\r\n {\r\n if (props.lastUploadedTemplate) {\r\n props.handleMediaChange(props.lastUploadedTemplate);\r\n }\r\n }}\r\n hidden={!props.lastUploadedTemplate}\r\n >\r\n ) : (\r\n {\r\n if (props.lastUploadedTemplate) {\r\n props.handleMediaChange(props.lastUploadedTemplate);\r\n }\r\n }}\r\n hidden={!props.lastUploadedTemplate}\r\n />\r\n )}\r\n
\r\n
\r\n
\r\n
\r\n \"Crop\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n \r\n )}\r\n
\r\n\r\n {fileUploadError && (\r\n \r\n {fileUploadError}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default MediaUploader;","import React, { useEffect, useRef, useState } from \"react\";\r\nimport { AppSettingContext } from \"../../Application\";\r\n\r\nimport { IRecipientsStepProps } from \"@src/models/props/RecipientsStepProps\";\r\nimport { IRecipientDetails } from \"../../../models/RecipientDetails.model\";\r\nimport { IRecipientsStep, RecipientsStepModel } from \"../../../models/RecipientsStep.model\";\r\nimport { ISenderDetails } from \"../../../models/SenderDetails.model\";\r\nimport LoadingComponent from \"../../shared/LoadingComponent\";\r\nimport RecipientsStepHowToSend from \"./RecipientsStepHowToSend\";\r\nimport RecipientsStepRecipientsDetails from \"./RecipientsStepRecipientsDetails\";\r\nimport RecipientsStepSenderDetails from \"./RecipientsStepSenderDetails\";\r\nimport IScheduleSendDetails from \"../../../models/interfaces/ScheduleSendDetails.interface\";\r\nimport { WorkflowTypeEnum } from \"../../../models/enums/WorkflowTypeEnum\";\r\nimport ScheduleSendDetailsModel from \"../../../models/ScheduleSendDetails.model\";\r\nimport { GiftCardSendTypeEnum } from \"../../../models/enums/GiftCardSendTypeEnum\";\r\n\r\nconst RecipientsStep = (props: IRecipientsStepProps) => {\r\n\r\n //global context\r\n const { debugMode, labels } = React.useContext(AppSettingContext);\r\n\r\n const [pageModel, setPageModel] = useState(undefined);\r\n const [recipients, setRecipients] = useState(Array);\r\n const [sender, setSender] = useState({ ...props.model.sender });\r\n const [isDirty, setIsDirty] = useState(false);\r\n\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState(null);\r\n\r\n //this should be call always\r\n const checkboxEditRef = useRef(null);\r\n useEffect(() => {\r\n checkboxEditRef.current.checked = props.expanded;\r\n });\r\n\r\n // Init\r\n useEffect(() => {\r\n //console.debug('useEffect - init');\r\n if (pageModel && pageModel.recipients) {\r\n //in case the user change Qty on Step 1\r\n if (props.model.recipients.length != pageModel.recipients.length) {\r\n propsModelUpdating();\r\n return;\r\n }\r\n //below code is not needeed as the model is fixed by propsModelUpdating\r\n //if (props.model.recipients.length != recipients.length) {\r\n // tryToFixTotalRecipients(props.model.recipients.length);\r\n // return; //to skip code below. This method will fire again as tryToFixTotalRecipients update recipients\r\n //}\r\n }\r\n\r\n }, []);\r\n\r\n useEffect(() => {\r\n //console.log('useEffect - props.model');\r\n propsModelUpdating();\r\n }, [props.model]);\r\n\r\n useEffect(() => {\r\n setIsLoading(false);\r\n const result = checkIfModelIsDirty();\r\n setIsDirty(result);\r\n props.handleDirtyState(result);\r\n\r\n }, [pageModel, sender, recipients]);\r\n\r\n useEffect(() => {\r\n //console.debug('useEffect - pageModel');\r\n\r\n if (pageModel && pageModel.recipients) {\r\n //in case the user change Qty on Step 1\r\n if (props.model.recipients.length != pageModel.recipients.length) {\r\n propsModelUpdating();\r\n }\r\n else if (props.model.recipients.length != recipients.length) {\r\n tryToFixTotalRecipients(props.model.recipients.length);\r\n }\r\n }\r\n }, [pageModel]);\r\n\r\n const isValid = () => {\r\n //VALIDATE object before SAVE\r\n let copyPageModel = { ...pageModel };\r\n copyPageModel.sender = { ...sender };\r\n copyPageModel.recipients = [...recipients];\r\n return RecipientsStepModel.validateModel(copyPageModel, props.workflowType);\r\n };\r\n\r\n const checkIfModelIsDirty = (): boolean => {\r\n if (!pageModel) return false;\r\n if (!sender) return false;\r\n if (!recipients) return false;\r\n\r\n //model input:text fields are same like props input:text\r\n //model.sender.firstName == props.model.sender.firstName\r\n //model.recipients[i].firstName == props.model.recipients[i].firstName\r\n\r\n // check\r\n if (pageModel.sendBy != props.model.sendBy) {\r\n return true;\r\n }\r\n if (pageModel.senderSameAsRecipient != props.model.senderSameAsRecipient) {\r\n return true;\r\n }\r\n if (pageModel.sendIndividually != props.model.sendIndividually) {\r\n return true;\r\n }\r\n if (pageModel.sendItLater != props.model.sendItLater) {\r\n return true;\r\n }\r\n\r\n //sender\r\n //Regift - no sender details \r\n if (props.workflowType == WorkflowTypeEnum.BUY_GIFT_CARD) {\r\n if ((sender.firstName != props.model.sender.firstName) ||\r\n (sender.lastName != props.model.sender.lastName) ||\r\n (sender.email != props.model.sender.email) ||\r\n (sender.phone != props.model.sender.phone) ||\r\n (sender.company != props.model.sender.company)) {\r\n return true;\r\n }\r\n }\r\n\r\n // scheduled details\r\n if ((pageModel.scheduleSendDetails.date != props.model.scheduleSendDetails.date) ||\r\n (pageModel.scheduleSendDetails.hour != props.model.scheduleSendDetails.hour) ||\r\n (pageModel.scheduleSendDetails.minute != props.model.scheduleSendDetails.minute)) {\r\n return true;\r\n }\r\n\r\n //recipients\r\n if (recipients.length != props.model.recipients.length) {\r\n //debugger;\r\n\r\n return true;\r\n } else {\r\n for (var i = 0; i < recipients.length; i++) {\r\n if ((recipients[i].firstName != props.model.recipients[i].firstName) ||\r\n (recipients[i].lastName != props.model.recipients[i].lastName) ||\r\n (recipients[i].email != props.model.recipients[i].email) ||\r\n (recipients[i].phone != props.model.recipients[i].phone)) {\r\n //debugger;\r\n\r\n return true;\r\n }\r\n }\r\n\r\n }\r\n\r\n return false;\r\n }\r\n\r\n const propsModelUpdating = () => {\r\n setIsLoading(true);\r\n //setRecipients(props.model.recipients);\r\n setPageModel(props.model);\r\n setRecipients(cloneRecipients());\r\n };\r\n\r\n const cloneRecipients = (): IRecipientDetails[] => {\r\n //TODO: in case of length >0 and send individual:false, we can update all records from first one\r\n\r\n // Recipients clone\r\n const recipientsClone = [] as Array;\r\n if (props.model.recipients) {\r\n for (let i = 0; i < props.model.recipients.length; i++) {\r\n const recipient = {\r\n firstName: props.model.recipients[i].firstName,\r\n firstNameIsValid: props.model.recipients[i].firstNameIsValid,\r\n lastName: props.model.recipients[i].lastName,\r\n lastNameIsValid: props.model.recipients[i].lastNameIsValid,\r\n email: props.model.recipients[i].email,\r\n emailIsValid: props.model.recipients[i].emailIsValid,\r\n phone: props.model.recipients[i].phone,\r\n };\r\n\r\n recipientsClone.push(recipient);\r\n }\r\n }\r\n\r\n return recipientsClone;\r\n }\r\n\r\n const tryToFixTotalRecipients = (sourceLength: number) => {\r\n let copyRecipients = Object.assign([], recipients);\r\n let difference = sourceLength - recipients.length;\r\n if (difference > 0) {\r\n //Add items\r\n for (var i = 0; i < difference; i++) {\r\n copyRecipients.push({\r\n firstName: '', lastName: '', email: '', phone: ''\r\n });\r\n }\r\n } else if (difference < 0) {\r\n //remove items\r\n difference *= -1;\r\n for (var i = 0; i < difference; i++) {\r\n copyRecipients.pop();\r\n }\r\n }\r\n\r\n setRecipients(copyRecipients);\r\n }\r\n\r\n //Edit/Close\r\n const handleExpandCheck = (e: React.ChangeEvent) => {\r\n if (checkboxEditRef.current.checked) {\r\n props.handleBeginEdit();\r\n }\r\n }\r\n\r\n // RECIPIENTS\r\n const handleRecipientUpdate = (recipientModel: IRecipientDetails, index: number): void => {\r\n //console.debug(\"handleRecipientUpdate\", recipientModel, recipients);\r\n\r\n const copyArr = [...recipients];\r\n copyArr[index].firstName = recipientModel.firstName;\r\n copyArr[index].lastName = recipientModel.lastName;\r\n copyArr[index].email = recipientModel.email;\r\n copyArr[index].phone = recipientModel.phone;\r\n setRecipients(copyArr);\r\n };\r\n\r\n // SEND NOW / LATER\r\n const handleSendItLaterUpdate = (model: IScheduleSendDetails): void => {\r\n //console.debug(\"handleSendItLaterUpdate\", model);\r\n let copyPageModel = { ...pageModel };\r\n copyPageModel.scheduleSendDetails.date = model.date;\r\n copyPageModel.scheduleSendDetails.hour = model.hour;\r\n copyPageModel.scheduleSendDetails.minute = model.minute;\r\n\r\n setPageModel(copyPageModel);\r\n };\r\n\r\n // SENDER\r\n const handleSenderModelUpdate = (senderModel: ISenderDetails): void => {\r\n setSender({\r\n firstName: senderModel.firstName,\r\n firstNameIsValid: senderModel.firstNameIsValid,\r\n lastName: senderModel.lastName,\r\n lastNameIsValid: senderModel.lastNameIsValid,\r\n email: senderModel.email,\r\n emailIsValid: senderModel.emailIsValid,\r\n phone: senderModel.phone,\r\n company: senderModel.company,\r\n fullName: `${senderModel.firstName} ${senderModel.lastName}`\r\n });\r\n };\r\n\r\n const handleSenderSameAsRecipientChange = (checked: boolean): void => {\r\n setIsLoading(true);\r\n\r\n //should exists at least one recipient\r\n setPageModel({ ...pageModel, senderSameAsRecipient: checked });\r\n\r\n if (checked) {\r\n handleSenderModelUpdate({\r\n firstName: recipients[0].firstName,\r\n firstNameIsValid: recipients[0].firstNameIsValid,\r\n lastName: recipients[0].lastName,\r\n lastNameIsValid: recipients[0].lastNameIsValid,\r\n email: recipients[0].email,\r\n emailIsValid: recipients[0].emailIsValid,\r\n phone: recipients[0].phone,\r\n company: \"\",\r\n fullName: `${recipients[0].firstName} ${recipients[0].lastName}`\r\n });\r\n } else {\r\n handleSenderModelUpdate({\r\n firstName: \"\",\r\n firstNameIsValid: pageModel.sender.firstNameIsValid,\r\n lastName: \"\",\r\n lastNameIsValid: pageModel.sender.lastNameIsValid,\r\n email: \"\",\r\n emailIsValid: pageModel.sender.emailIsValid,\r\n phone: \"\",\r\n company: \"\",\r\n fullName: \"\"\r\n });\r\n }\r\n }\r\n\r\n const handleSaveAndContinue = (event: React.MouseEvent) => {\r\n event.preventDefault();\r\n\r\n let copyPageModel = { ...pageModel };\r\n copyPageModel.sender = { ...sender };\r\n copyPageModel.recipients = [...recipients];\r\n\r\n props.handleSubmit(copyPageModel);\r\n setIsDirty(false);\r\n };\r\n\r\n if (error) throw error;\r\n return (\r\n
\r\n {/* By default the input is set to checked=false so the show div is hidden */}\r\n \r\n\r\n
\r\n

{labels.get(\"GiftCard.App.Steps.Recepients\")}

\r\n\r\n
\r\n {(!props.isSaving && props.isActive) &&\r\n }\r\n
\r\n\r\n
\r\n {(props.isSaving) && }\r\n\r\n {(!isLoading && !props.isSaving) &&\r\n
\r\n {debugMode &&\r\n
\r\n

total: {pageModel.recipients.length} : {recipients.length}

\r\n

sendBy: {pageModel.sendBy}

\r\n

sendIndividually: {String(pageModel.sendIndividually)}

\r\n

senderSameAsRecipient: {String(pageModel.senderSameAsRecipient)}

\r\n

sender: {`${sender.firstName} ${sender.lastName} (${sender.email}, ${sender.company})`}

\r\n

Send It Later: {String(pageModel.sendItLater)}, date:\r\n {`${pageModel.scheduleSendDetails.date} ${pageModel.scheduleSendDetails.hour}:${pageModel.scheduleSendDetails.minute}`}

\r\n
\r\n {recipients.length > 0 && <>\r\n

RECEPIENT 1:

\r\n

{`${recipients[0].firstName} ${recipients[0].lastName} (${pageModel.recipients[0].email})`}

\r\n
\r\n }\r\n\r\n

Is dirty: {String(isDirty)}

\r\n

Is valid: {String(isValid())}

\r\n
}\r\n\r\n {\r\n if (sendBy === GiftCardSendTypeEnum.BY_PDF) {\r\n setPageModel({\r\n ...pageModel,\r\n sendBy: sendBy,\r\n sendItLater: false,\r\n scheduleSendDetails: new ScheduleSendDetailsModel()\r\n });\r\n } else {\r\n setPageModel({\r\n ...pageModel,\r\n sendBy: sendBy,\r\n });\r\n }\r\n }}\r\n />\r\n\r\n
\r\n setPageModel({ ...pageModel, sendIndividually: checked })}\r\n handleChangeSendItLater={(checked) => setPageModel({ ...pageModel, sendItLater: checked })}\r\n handleRecipientUpdate={(recipient, index) => handleRecipientUpdate(recipient, index)}\r\n\r\n handleSendItLaterUpdate={(model) => handleSendItLaterUpdate(model)}\r\n />\r\n\r\n {/* Manage recipients only in Buy gift workflow \r\n {props.workflowType == WorkflowTypeEnum.BUY_GIFT_CARD &&} */}\r\n handleSenderSameAsRecipientChange(checked)}\r\n handleModelUpdate={(senderModel) => handleSenderModelUpdate(senderModel)}\r\n />\r\n
\r\n\r\n \r\n\r\n
}\r\n
\r\n
\r\n
\r\n )\r\n}\r\n\r\nexport default RecipientsStep;","import React, { useState, useEffect, useRef } from \"react\";\r\nimport { AppSettingContext } from \"@src/components/Application\";\r\nimport { IRecipientsStepProps } from \"../../../models/props/RecipientsStepProps\";\r\nimport { IRecipientsStep } from \"../../../models/RecipientsStep.model\";\r\nimport { GiftCardSendTypeEnum } from \"../../../models/enums/GiftCardSendTypeEnum\";\r\nimport LabeledCheckbox from \"../../atoms/LabeledCheckbox\";\r\n\r\ninterface IRecipientsStepHowToSendProps {\r\n sendBy: GiftCardSendTypeEnum;\r\n handleSendByChange(sendBy: GiftCardSendTypeEnum): void;\r\n}\r\n\r\nconst RecipientsStepHowToSend = (props: IRecipientsStepHowToSendProps) => {\r\n //Page translation\r\n const { labels } = React.useContext(AppSettingContext);\r\n\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n useEffect(() => {\r\n\r\n }, []);\r\n\r\n if (error) throw error;\r\n return (\r\n <>\r\n
{labels.get(\"GiftCard.App.Steps.Recepients.Fields.HowToSend\")}
\r\n\r\n
\r\n
\r\n props.handleSendByChange(GiftCardSendTypeEnum.BY_EMAIL)}\r\n labelCssClass=\"label-fs\"\r\n lableTitle={labels.get(\"GiftCard.App.Steps.Recepients.Fields.HowToSend.ByEmail\")}\r\n />\r\n
\r\n\r\n
\r\n props.handleSendByChange(GiftCardSendTypeEnum.BY_SMS)}\r\n labelCssClass=\"label-fs\"\r\n lableTitle={labels.get(\"GiftCard.App.Steps.Recepients.Fields.HowToSend.BySMS\")}\r\n />\r\n
\r\n\r\n
\r\n props.handleSendByChange(GiftCardSendTypeEnum.BY_PDF)}\r\n labelCssClass=\"label-fs\"\r\n lableTitle={labels.get(\"GiftCard.App.Steps.Recepients.Fields.HowToSend.ByPDF\")}\r\n />\r\n
\r\n
\r\n \r\n )\r\n}\r\n\r\nexport default RecipientsStepHowToSend;","import React, { useState, useEffect, useRef } from \"react\";\r\nimport { AppSettingContext } from \"@src/components/Application\";\r\nimport RecipientDetails from \"../RecipientDetails\";\r\nimport RecipientsStepWhenToSend from \"./RecipientsStepWhenToSend\";\r\nimport LabeledCheckbox from \"../../atoms/LabeledCheckbox\";\r\nimport { IRecipientDetails } from \"../../../models/RecipientDetails.model\";\r\nimport { GiftCardSendTypeEnum } from \"../../../models/enums/GiftCardSendTypeEnum\";\r\nimport IScheduleSendDetails from \"../../../models/interfaces/ScheduleSendDetails.interface\";\r\n\r\ninterface IRecipientsStepRecipientsDetailsProps {\r\n recipients: IRecipientDetails[];\r\n sendIndividually: boolean;\r\n sendBy: GiftCardSendTypeEnum;\r\n sendItLater: boolean;\r\n scheduleSendDetails: IScheduleSendDetails;\r\n\r\n handleSendIndividualyChange(sendIndividualy: boolean): void;\r\n handleChangeSendItLater(sendItLater: boolean): void;\r\n handleRecipientUpdate(model: IRecipientDetails, index: number): void;\r\n handleSendItLaterUpdate(model: IScheduleSendDetails): void;\r\n}\r\n\r\nconst RecipientsStepRecipientsDetails = (props: IRecipientsStepRecipientsDetailsProps) => {\r\n\r\n //Page translation\r\n const { labels } = React.useContext(AppSettingContext);\r\n\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState(null);\r\n\r\n // Init\r\n useEffect(() => {\r\n //local model initialization\r\n setIsLoading(true);\r\n }, []);\r\n\r\n //useEffect(() => {\r\n // if (props.recipients.length === 1) {\r\n // props.handleSendIndividualyChange(false);\r\n // } else if (props.recipients.length > 1) {\r\n // if (props.sendIndividually == false) {\r\n // props.handleSendIndividualyChange(true);\r\n // }\r\n // }\r\n //}, [props.recipients])\r\n\r\n const getRecipients = (): IRecipientDetails[] => {\r\n\r\n const recipients = [] as IRecipientDetails[];\r\n if (props.recipients.length == 0) return recipients\r\n\r\n if (props.sendIndividually == false) {\r\n //then show only the first recipient\r\n if (props.recipients.length) {\r\n recipients.push(props.recipients[0]);\r\n }\r\n\r\n } else {\r\n //show all\r\n return props.recipients;\r\n }\r\n\r\n return recipients;\r\n }\r\n const recipients = getRecipients();\r\n\r\n if (error) throw error;\r\n return (\r\n <>\r\n
\r\n
{labels.get(\"GiftCard.App.Steps.Recepients.RecipientDetails.Title\")}
\r\n\r\n {/*show only of there are more than 1 recipients*/}\r\n {(props.recipients && props.recipients.length > 1) &&\r\n <>\r\n
\r\n props.handleSendIndividualyChange(checked)}\r\n labelCssClass=\"label-fs\"\r\n lableTitle={labels.get(\"GiftCard.App.Steps.Recepients.Fields.SendIndividually\")}\r\n />\r\n
\r\n }\r\n
\r\n\r\n {(props.recipients && props.recipients.length > 0) &&\r\n
\r\n {recipients.map((recipient, index) => (\r\n props.handleRecipientUpdate(model, index)} />\r\n ))}\r\n\r\n {props.sendBy !== GiftCardSendTypeEnum.BY_PDF &&\r\n props.handleChangeSendItLater(sendItLater)}\r\n handleModelUpdate={(model) => props.handleSendItLaterUpdate(model)} />\r\n }\r\n
}\r\n\r\n \r\n )\r\n}\r\n\r\nexport default RecipientsStepRecipientsDetails;","import { AppSettingContext } from \"@src/components/Application\";\r\nimport React, { useEffect, useRef, useState } from \"react\";\r\nimport { ISenderDetails } from \"../../../models/SenderDetails.model\";\r\nimport LabeledCheckbox from \"../../atoms/LabeledCheckbox\";\r\nimport { hasXSSCharacters, isEmail } from \"../../../helpers/Utils\";\r\n\r\ninterface IRecipientsStepSenderDetailsProps {\r\n //model: IRecipientsStep;\r\n sender: ISenderDetails;\r\n hasToShowSameAsRecipientToggle: boolean;\r\n senderSameAsRecipient: boolean;\r\n handleSenderSameAsRecipientChange(checked: boolean): void;\r\n handleModelUpdate(sender: ISenderDetails): void;\r\n}\r\n\r\nconst RecipientsStepSenderDetails = (props: IRecipientsStepSenderDetailsProps) => {\r\n const ref = useRef(true);\r\n\r\n //Page translation\r\n const { labels } = React.useContext(AppSettingContext);\r\n\r\n const [firstName, setFirstName] = useState(props.sender.firstName || \"\");\r\n const [lastName, setLastName] = useState(props.sender.lastName || \"\");\r\n const [email, setEmail] = useState(props.sender.email || \"\");\r\n const [phone, setPhone] = useState(props.sender.phone || \"\");\r\n const [company, setCompany] = useState(props.sender.company || \"\");\r\n\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n const firstRender = useRef(true);\r\n\r\n useEffect(() => {\r\n const firstRender = ref.current;\r\n if (firstRender) {\r\n ref.current = false;\r\n }\r\n\r\n }, [])\r\n\r\n useEffect(() => {\r\n const firstRender = ref.current;\r\n if (firstRender == false) {\r\n propagateChanges();\r\n }\r\n }, [firstName, lastName, email, company]);\r\n\r\n const propagateChanges = () => {\r\n if (firstRender.current) {\r\n props.handleModelUpdate({\r\n firstName: firstName,\r\n firstNameIsValid: true,\r\n lastName: lastName,\r\n lastNameIsValid: true,\r\n email: email,\r\n emailIsValid: true,\r\n phone: phone,\r\n company: company\r\n } as ISenderDetails);\r\n\r\n //because this function is being called multiple times, wait 0.1 seconds before setting the firstRender to false\r\n setTimeout(() => {\r\n firstRender.current = false;\r\n }, 100);\r\n\r\n return;\r\n }\r\n\r\n props.handleModelUpdate({\r\n firstName: firstName,\r\n firstNameIsValid: props.sender.firstNameIsValid,\r\n lastName: lastName,\r\n lastNameIsValid: props.sender.lastNameIsValid,\r\n email: email,\r\n emailIsValid: props.sender.emailIsValid,\r\n phone: phone,\r\n company: company\r\n } as ISenderDetails);\r\n };\r\n\r\n if (error) throw error;\r\n return (\r\n
\r\n
\r\n
\r\n
{labels.get(\"GiftCard.App.Steps.Recepients.Fields.Sender.Title\")}
\r\n\r\n {/*show only of there are only 1 recipient*/}\r\n {props.hasToShowSameAsRecipientToggle &&\r\n
\r\n props.handleSenderSameAsRecipientChange(result)}\r\n labelCssClass=\"label-fs\"\r\n lableTitle={labels.get(\"GiftCard.App.Steps.Recepients.Fields.Sender.SameAsRecipient\")}\r\n />\r\n
}\r\n
\r\n\r\n
\r\n
\r\n \r\n {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n } else {\r\n if (!event.target.value.trim()) {\r\n props.sender.firstNameIsValid = false;\r\n } else {\r\n props.sender.firstNameIsValid = true;\r\n }\r\n\r\n setFirstName(event.target.value);\r\n }\r\n }}\r\n className={props.sender.firstNameIsValid === false ? \"react-input-error\" : \"\"}\r\n />\r\n {props.sender.firstNameIsValid === false &&\r\n
\r\n Please enter sender first name\r\n
\r\n }\r\n
\r\n
\r\n \r\n {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n } else {\r\n if (!event.target.value.trim()) {\r\n props.sender.lastNameIsValid = false;\r\n } else {\r\n props.sender.lastNameIsValid = true;\r\n }\r\n\r\n setLastName(event.target.value);\r\n }\r\n }}\r\n className={props.sender.lastNameIsValid === false ? \"react-input-error\" : \"\"}\r\n />\r\n {props.sender.lastNameIsValid === false &&\r\n
\r\n Please enter sender last name\r\n
\r\n }\r\n
\r\n
\r\n \r\n {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n } else {\r\n if (!isEmail(event.target.value)) {\r\n props.sender.emailIsValid = false;\r\n } else {\r\n props.sender.emailIsValid = true;\r\n }\r\n\r\n setEmail(event.target.value);\r\n }\r\n }}\r\n className={props.sender.emailIsValid === false ? \"react-input-error\" : \"\"}\r\n />\r\n {props.sender.emailIsValid === false &&\r\n
\r\n Please enter sender email address\r\n
\r\n }\r\n
\r\n\r\n
\r\n \r\n {\r\n if (hasXSSCharacters(event.target.value)) {\r\n event.preventDefault();\r\n } else {\r\n setCompany(event.target.value);\r\n }\r\n }}\r\n />\r\n
\r\n
\r\n\r\n
\r\n )\r\n}\r\n\r\nexport default RecipientsStepSenderDetails;","import { AppSettingContext } from \"@src/components/Application\";\r\nimport React, { useEffect, useRef, useState } from \"react\";\r\nimport IScheduleSendDetails from \"../../../models/interfaces/ScheduleSendDetails.interface\";\r\n\r\nimport DatePicker from \"react-datepicker\";\r\nimport \"react-datepicker/dist/react-datepicker.css\";\r\n//https://reactdatepicker.com/#example-calendar-icon\r\n//https://www.npmjs.com/package/react-datepicker\r\n\r\ninterface IRecipientsStepWhenToSendProps {\r\n model: IScheduleSendDetails;\r\n sendItLater: boolean;\r\n handleChangeSendItLater(sendItLater: boolean): void;\r\n handleModelUpdate(sender: IScheduleSendDetails): void;\r\n}\r\n\r\nconst RecipientsStepWhenToSend = (props: IRecipientsStepWhenToSendProps) => {\r\n const ref = useRef(true);\r\n\r\n //Page translation\r\n const { labels } = React.useContext(AppSettingContext);\r\n\r\n const [date, setDate] = useState(props.model.date);\r\n const [hour, setHour] = useState(props.model.hour == 0 ? 1 : props.model.hour);\r\n const [minute, setMinute] = useState(props.model.minute);\r\n\r\n const [formattedDate, setFormattedDate] = useState(\"\");\r\n\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n useEffect(() => {\r\n\r\n //const date: Date = new Date();\r\n //date.setDate(date.getDate() + 1); //add 1 day\r\n //setFormattedDate(formatDate(date, 'dd/mm/yyyy'));\r\n\r\n //setDate(date);\r\n\r\n //setTimeout(() => {\r\n // initDatePicker();\r\n //}, 3000);\r\n\r\n //setTimeout(() => {\r\n // props.handleModelUpdate({\r\n // date: date,\r\n // hour: hour,\r\n // minute: minute\r\n // } as IScheduleSendDetails);\r\n //}, 2000);\r\n\r\n }, []);\r\n\r\n useEffect(() => {\r\n propagateChanges();\r\n //const firstRender = ref.current;\r\n //if (firstRender == false) {\r\n // propagateChanges();\r\n //}\r\n }, [date, hour, minute]);\r\n\r\n const propagateChanges = () => {\r\n //only on change\r\n\r\n props.handleModelUpdate({\r\n date: date,\r\n hour: hour,\r\n minute: minute\r\n } as IScheduleSendDetails);\r\n };\r\n\r\n const handleHourChange = (event: React.ChangeEvent) => {\r\n //console.debug(\"handleHourChange\", event.target.value);\r\n setHour(parseInt(event.target.value));\r\n };\r\n\r\n const handleMinuteChange = (event: React.ChangeEvent) => {\r\n //console.debug(\"handleMinuteChange\", event.target.value);\r\n setMinute(parseInt(event.target.value));\r\n };\r\n\r\n //const handleSendNow = (event: React.MouseEvent) => {\r\n // props.handleChangeSendItLater(false);\r\n //};\r\n\r\n //const handleSendLater = (event: React.MouseEvent) => {\r\n // props.handleChangeSendItLater(true);\r\n //};\r\n\r\n //const initDatePicker = () => {\r\n // //if (document.querySelector('.send-it')) {\r\n\r\n // // const firstRender = ref.current;\r\n // // if (firstRender) {\r\n // // ref.current = false;\r\n // // //console.debug('init .swiper-upload');\r\n // // setIsLoading(false);\r\n\r\n // // setTimeout(() => {\r\n // // if (document.querySelector('input[name=\"send-it__date\"]')) {\r\n\r\n // // const elem = document.querySelector('input[name=\"send-it__date\"]');\r\n // // const minDate = document.querySelector('input[name=\"send-it__date\"]').getAttribute('data-mindate')\r\n // // const datepicker = new Datepicker(elem, {\r\n // // format: 'dd MM yyyy',\r\n // // minDate: minDate,\r\n // // prevArrow: '',\r\n // // nextArrow: '',\r\n // // });\r\n\r\n\r\n // // }\r\n // // }, 100);\r\n\r\n // // }\r\n // //}\r\n //};\r\n\r\n const addDays = (date: Date, days: number) => {\r\n if (date) {\r\n date.setDate(date.getDate() + days);\r\n }\r\n return date;\r\n }\r\n\r\n const subDays = (date: Date, days: number) => {\r\n if (date) {\r\n date.setDate(date.getDate() - days);\r\n }\r\n return date;\r\n }\r\n\r\n const isDateSame = (date: Date) => {\r\n const today = new Date();\r\n if (date) {\r\n return date.getDate() == today.getDate()\r\n && date.getMonth() == today.getMonth()\r\n && date.getFullYear() == today.getFullYear();\r\n }\r\n\r\n return false;\r\n }\r\n\r\n if (error) throw error;\r\n return (\r\n
\r\n\r\n {/* */}\r\n\r\n
\r\n
{labels.get(\"GiftCard.App.Steps.Recepients.Fields.WhenToSend.Title\")}
\r\n
\r\n \r\n \r\n\r\n {/**/}\r\n
\r\n\r\n
\r\n
\r\n \r\n
\r\n e.target === document}\r\n selected={date}\r\n onChange={(d) => setDate(d)}\r\n calendarStartDay={1}\r\n />\r\n\r\n \"Date\"\r\n \"Select\"\r\n
\r\n
\r\n\r\n\r\n {/*
*/}\r\n {/* */}\r\n {/*
*/}\r\n {/* */}\r\n\r\n {/* \"\"*/}\r\n {/* \"\"*/}\r\n {/*
*/}\r\n {/*
*/}\r\n
\r\n \r\n
\r\n \r\n \"Select\"\r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n \"Select\"\r\n
\r\n
\r\n
\r\n
\r\n )\r\n}\r\n\r\nexport default RecipientsStepWhenToSend;","import React from \"react\";\r\n\r\ninterface IStepsProgressBarProps {\r\n stepsCount: number;\r\n currentStep: number;\r\n}\r\n\r\nconst StepsProgressBar = (props: IStepsProgressBarProps) => {\r\n return (\r\n
\r\n
\r\n
\r\n {Array.from({ length: props.stepsCount }, (_, index) => (\r\n \r\n
props.currentStep ? \"step-inactive\" : \"\"}`}>\r\n {(index + 1 === props.currentStep) && (\r\n
\r\n ·\r\n
\r\n )}\r\n\r\n {(index + 1 < props.currentStep) && (\r\n
\r\n ✔\r\n
\r\n )}\r\n
\r\n {(index < props.stepsCount - 1) && (\r\n
index + 1 ? \"line-active\" : \"\"}`}>
\r\n )}\r\n
\r\n ))}\r\n
\r\n {/* add another div below .progress-bar -

tags with space between each other (the same space as the width of the horizontal line) */}\r\n

\r\n
\r\n );\r\n};\r\n\r\nexport default StepsProgressBar;","import React, { Component, ReactNode, ErrorInfo } from \"react\";\r\nimport ErrorComponent from \"./ErrorComponent\";\r\n\r\ninterface ErrorBoundaryProps {\r\n children: ReactNode;\r\n\r\n onCriticalError?: (error: Error, errorInfo: ErrorInfo) => void;\r\n}\r\n\r\ninterface ErrorBoundaryState {\r\n hasError: boolean;\r\n}\r\n\r\n/*This doesn't catch errors from: event handlers, async code, server-side rendering*/\r\nclass ErrorBoundary extends Component {\r\n constructor(props: ErrorBoundaryProps) {\r\n super(props);\r\n\r\n this.state = {\r\n hasError: false\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(_: Error): ErrorBoundaryState {\r\n // Update state to indicate an error occurred\r\n return {\r\n hasError: true\r\n };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n // Log error to the console\r\n console.error(\"Unhandled error caught in ErrorBoundary: \", error, errorInfo);\r\n\r\n // Call the critical error handler if provided\r\n if (this.props.onCriticalError) {\r\n this.props.onCriticalError(error, errorInfo);\r\n }\r\n }\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n return (\r\n \r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\nexport default ErrorBoundary;","//@ts-nocheck\r\n\r\nimport React from \"react\";\r\n\r\nconst ErrorComponent = () => {\r\n return (\r\n
\r\n
\r\n
\r\n \"Error\r\n
\r\n
\r\n ERROR\r\n

Oh no! Please refresh the page

\r\n {/*

Luckily there's always more Options.

*/}\r\n location.reload()} className=\"btn btn__large btn__primary large-fs\" title=\"Refresh\">Page refresh\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ErrorComponent;","import React from \"react\";\r\n\r\ninterface ILoadingComponentProps {\r\n large?: boolean;\r\n extraSmall?: boolean;\r\n}\r\n\r\nconst LoadingComponent = (props: ILoadingComponentProps) => {\r\n\r\n return (\r\n <>\r\n {props.extraSmall ? (\r\n \r\n \r\n \r\n ) : (\r\n
\r\n {props.large ? (\r\n
\r\n ) : (\r\n
\r\n )}\r\n
\r\n )}\r\n \r\n );\r\n};\r\nexport default LoadingComponent;","\r\n//API Endpoints\r\nexport const API_URL = \"/giftcard/v1/\";\r\n\r\n// Local storage\r\nexport const LOCALSTORAGE_KEY_BASKET_ID = \"giftcard-basket-id\";\r\n\r\nexport const LOCALSTORAGE_KEY_ACTIVATE_BASKET_ID = \"activate-basket-id\";\r\n\r\nexport const PERSONAL_MESSAGE_MAX_LENGTH = 1000;\r\n\r\n// Page Links aliases\r\nexport const PAGE_LINKS = {\r\n BENEFITS: \"benefits-page\",\r\n BUY_GIFT_CARD: \"buy-gift-card-page\",\r\n BUY_GIFT_CARD_CONFIRMATION: \"buy-gift-card-confirmation-page\",\r\n CATALOGUE: \"catalogue-page\",\r\n CONTACT: \"contact-page\",\r\n PRIVACY: \"privacy-page\",\r\n REGIFT: \"regift-page\",\r\n REGIFT_CONFIRMATION: \"regift-confirmation-page\",\r\n TERMS: \"terms-page\",\r\n REDEEM_CODE: \"redeem-code\"\r\n};\r\n\r\nexport type PhoneValidationRegexKeys = keyof typeof PHONE_NUMBER.VALIDATIONS.REGEX;\r\nexport type PhoneCountryCodeKeys = keyof typeof PHONE_NUMBER.COUNTRIES;\r\nexport const PHONE_NUMBER = {\r\n VALIDATIONS: {\r\n MAXLENGTH: 16,\r\n REGEX: {\r\n IE: /^\\+3538\\d{8}$/,\r\n GB: /^\\+447\\d{9}$/\r\n }\r\n },\r\n COUNTRIES: {\r\n IE: \"+353\",\r\n GB: \"+44\"\r\n },\r\n DEFAULT_COUNTRY: \"IE\"\r\n};","export function debounce(\r\n fn: (args: A) => R,\r\n ms: number\r\n): [(args: A) => Promise, () => void] {\r\n let timer: NodeJS.Timeout;\r\n\r\n const debouncedFunc = (args: A): Promise =>\r\n new Promise((resolve) => {\r\n if (timer) {\r\n clearTimeout(timer);\r\n }\r\n\r\n timer = setTimeout(() => {\r\n resolve(fn(args));\r\n }, ms);\r\n });\r\n\r\n const teardown = () => clearTimeout(timer);\r\n\r\n return [debouncedFunc, teardown];\r\n}\r\n","export { debounce } from \"./debounce\";\r\nexport { useDebounce } from \"./use-debounce\";","import { useEffect } from \"react\";\r\n\r\nimport { debounce } from \"./debounce\";\r\n\r\nexport const useDebounce = (\r\n fn: (args: A) => R,\r\n ms: number\r\n): ((args: A) => Promise) => {\r\n const [debouncedFun, teardown] = debounce(fn, ms);\r\n\r\n useEffect(() => () => teardown(), []);\r\n\r\n return debouncedFun;\r\n};\r\n","import { IBuyGiftCardOld } from \"../models/BuyGiftCard.model\";\r\nimport { RecipientDetailsModel } from \"../models/RecipientDetails.model\";\r\nimport { IRecipientsStep } from \"../models/RecipientsStep.model\";\r\nimport { IRegiftCard } from \"../models/RegiftCard.model\";\r\nimport { IChooseRecipientsStepModel, RecipientDetailsModel as RecipientDetailsModelNew } from \"../models/buy-giftcard/choose-card/ChooseRecipientsStep.model\";\r\nimport ILink from \"../models/core/Link.interface\";\r\n\r\nexport function findLinkByAlias(alias: string, links: Array): ILink | null {\r\n\r\n const link = links.find((el) => el.alias == alias);\r\n //console.debug('findLinkByAlias', links, alias, link);\r\n if(link) return link;\r\n\r\n return { alias: '', title: '', url: '', targetBlank: false } as ILink;\r\n}\r\n\r\nexport function resetRecipientsCountOnRecipientStep(quantity: number, stepModel: IRecipientsStep | IChooseRecipientsStepModel): IRecipientsStep | IChooseRecipientsStepModel {\r\n if (quantity == 1) {\r\n stepModel.sendIndividually = false;\r\n } else if (quantity > 1) {\r\n stepModel.sendIndividually = true;\r\n }\r\n\r\n const recipientsCount = stepModel.recipients.length;\r\n let hasToAddRecipients = recipientsCount == 0; // if there are not yet recipients.\r\n\r\n // check if there are already some recipients records\r\n if (recipientsCount > 0) {\r\n if (quantity > recipientsCount) {\r\n hasToAddRecipients = true;\r\n quantity = quantity - recipientsCount; // remaining records\r\n } else if (quantity < recipientsCount) {\r\n hasToAddRecipients = false; // no need to add recipients, we need to remove\r\n let recordsToRemove = recipientsCount - quantity;\r\n if (recordsToRemove > 0) {\r\n let recipients = [...stepModel.recipients] as typeof stepModel.recipients;\r\n\r\n while (recordsToRemove > 0) {\r\n recipients = recipients.slice(0, recipients.length - 1);\r\n recordsToRemove = recordsToRemove - 1;\r\n }\r\n\r\n stepModel.recipients = recipients;\r\n }\r\n }\r\n }\r\n\r\n if (hasToAddRecipients) {\r\n for (let i = 0; i < quantity; i++) {\r\n if (\"sender\" in stepModel) {\r\n // the model type is the old one\r\n stepModel.recipients.push(new RecipientDetailsModel());\r\n } else {\r\n stepModel.recipients.push(new RecipientDetailsModelNew());\r\n }\r\n }\r\n }\r\n\r\n return stepModel;\r\n}\r\n\r\nexport function isAnBuyGiftCard(obj: any): obj is IBuyGiftCardOld {\r\n //console.debug('isAnBuyGiftCard', obj, 'chooseCard' in obj);\r\n return 'chooseCard' in obj;\r\n //return 'type' in obj && obj.type === 'IBuyGiftCard';\r\n}\r\n\r\nexport function isAnRegiftCard(obj: any): obj is IRegiftCard {\r\n return 'type' in obj && obj.type === 'IRegiftCard';\r\n}\r\n\r\nexport function fixPreviewDetails() {\r\n\r\n setTimeout(() => {\r\n //hide image\r\n const previewImageEl = document.getElementById(\"cardDetailsDefaultTemplateId\");\r\n if (previewImageEl) {\r\n //previewImageEl.style.opacity = \"0\";\r\n previewImageEl.style.display = \"none\";\r\n }\r\n }, 6000);\r\n\r\n \r\n}\r\n//export function validateRecepientsStep(viewModel: IRecipientsStep): boolean {\r\n \r\n// var model = RecipientsStepModel.parseModel(viewModel);\r\n// if (model) {\r\n// //console.debug('validateRecepientsStep', model.isValid());\r\n// return model.isValid() ;\r\n// }\r\n\r\n// return false;\r\n//}\r\n\r\n","export function isNullOrUndefined(value: any):boolean {\r\n return value === null || value === undefined;\r\n}\r\n\r\nexport function isNotNullOrEmpty(value: string | null | undefined): boolean {\r\n return value !== null && value !== undefined && value.trim().length > 0;\r\n}\r\n\r\nexport function isNullOrWhiteSpace(value: string | null | undefined): boolean {\r\n if (!value || value === null || value === undefined) {\r\n return true;\r\n }\r\n\r\n if (!value.trim() || value.trim().length === 0) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function isEmail(email: string): boolean {\r\n return /^[a-zA-Z0-9]+([._+-][a-zA-Z0-9]+)*@[a-zA-Z0-9]+(-?[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z]{2,}$/i.test(email);\r\n}\r\n\r\nexport function isPhone(phone: string): boolean {\r\n if (!phone.trim()) return false;\r\n\r\n //https://stackabuse.com/validate-phone-numbers-in-javascript-with-regular-expressions/\r\n const iePattern = new RegExp(\"\\\\+353\\\\(0\\\\)\\\\s\\\\d\\\\s\\\\d{3}\\\\s\\\\d{4}\");\r\n //const ukPattern = new RegExp(\"\\\\+353\\\\(0\\\\)\\\\s\\\\d\\\\s\\\\d{3}\\\\s\\\\d{4}\");\r\n if (iePattern.test(phone)) { //|| ukPattern.test(phone)) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n\r\n //return /^(\\d{3}[-]?){1,2}(\\d{4})$/.test(phone);\r\n //const pattern = new RegExp(\"^[+]{1}(?:[0-9\\\\-\\\\(\\\\)\\\\/\\\\.]\\\\s?){6, 15}[0-9]{1}$\");\r\n //return pattern.test(phone);\r\n}\r\n\r\nexport function hasXSSCharacters(input:string):boolean {\r\n const xssPattern = /[<>&]/;\r\n return xssPattern.test(input);\r\n}\r\n\r\nexport function generate_uuidv4():string {\r\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,\r\n function (c) {\r\n var uuid = Math.random() * 16 | 0, v = c == 'x' ? uuid : (uuid & 0x3 | 0x8);\r\n return uuid.toString(16);\r\n });\r\n}\r\n\r\nexport function isVideoFile(filePath: string) {\r\n\r\n // Extract the file extension from the URL\r\n const fileExtension = filePath.split('.').pop().toLowerCase();\r\n\r\n if (['mp4', 'webm', 'ogg'].includes(fileExtension)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function isImageFile(filePath: string) {\r\n // Extract the file extension from the URL\r\n const fileExtension = filePath.split('.').pop().toLowerCase();\r\n\r\n if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(fileExtension)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function getVideoDuration(file: File): Promise {\r\n if (file) {\r\n console.debug(\"getVideoDuration\");\r\n const url = URL.createObjectURL(file);\r\n console.debug(\"url: \", url);\r\n\r\n return new Promise((resolve) => {\r\n const audio = document.createElement(\"audio\");\r\n audio.muted = true;\r\n const source = document.createElement(\"source\");\r\n source.src = url; //--> blob URL\r\n audio.preload = \"metadata\";\r\n audio.appendChild(source);\r\n audio.onloadedmetadata = function () {\r\n resolve(audio.duration)\r\n };\r\n });\r\n }\r\n}\r\n\r\nexport function formatStringWithPlaceholders(text: string, ...values: string[]): string {\r\n if (!text) {\r\n return \"\";\r\n }\r\n\r\n return text.replace(/{(\\d+)}/g, (match, index) => {\r\n return typeof values[index] !== 'undefined' ? values[index] : match;\r\n });\r\n}\r\n\r\nexport function isFullNameValid(fullName: string): boolean {\r\n if (!fullName || !fullName.trim()) {\r\n return false;\r\n }\r\n\r\n const regex = /^([\\p{L}][\\p{L}'-]{0,49}( [\\p{L}][\\p{L}'-]{0,49}){1,})?$/u;\r\n return regex.test(fullName);\r\n}","import React, { ErrorInfo } from 'react';\r\nimport { createRoot } from 'react-dom/client';\r\nimport Application from './components/Application';\r\nimport ErrorBoundary from './components/shared/ErrorBoundary';\r\n\r\n// Say something\r\nconsole.log('[Ovation] : Renderer execution started');\r\n\r\nconst handleCriticalError = (error: Error, errorInfo: ErrorInfo) => {\r\n console.error(\"Critical error caught:\", error, errorInfo);\r\n};\r\n\r\nif (document.getElementById('app')) {\r\n // Wrap Application in ErrorBoundary\r\n const app = (\r\n \r\n \r\n \r\n );\r\n\r\n // Render application in DOM\r\n createRoot(document.getElementById('app')).render(app);\r\n}\r\n","import IBaseStepModel from \"./interfaces/BaseStepModel.interface\";\r\n\r\nexport interface ICheckBalanceStep extends IBaseStepModel {\r\n giftCardCode: string;\r\n remainingBalance: number;\r\n redeemCode: string;\r\n currencySymbol: string;\r\n}\r\n\r\nexport class CheckBalanceStepModel implements ICheckBalanceStep, IBaseStepModel {\r\n giftCardCode: string;\r\n remainingBalance: number;\r\n currencySymbol: string;\r\n redeemCode: string;\r\n isDirty: boolean;\r\n\r\n constructor(\r\n ) {\r\n this.giftCardCode = \"\";\r\n this.remainingBalance = 0;\r\n this.currencySymbol = \"\";\r\n this.redeemCode = \"\";\r\n }\r\n\r\n static validateModel(model: ICheckBalanceStep): boolean {\r\n\r\n if (!model) return false;\r\n\r\n if (!model.giftCardCode.trim() || model.giftCardCode.length < 5) return false;\r\n\r\n return true;\r\n }\r\n}","import IBaseStepModel from \"./interfaces/BaseStepModel.interface\";\r\n\r\nexport interface ICustomizeStep extends IBaseStepModel {\r\n\r\n giftCardUrl: string;\r\n mediaUrl:string;\r\n personalMessage: string;\r\n\r\n userGiftCards: Array;\r\n userMedias: Array;\r\n\r\n\r\n// isDirty: boolean;\r\n// isValid(): boolean;\r\n}\r\n\r\nexport class CustomizeStepModel implements ICustomizeStep {\r\n\r\n giftCardUrl: string;\r\n mediaUrl:string;\r\n personalMessage: string;\r\n\r\n userGiftCards: Array;\r\n userMedias: Array;\r\n\r\n isDirty: boolean;\r\n\r\n static validateModel(model: ICustomizeStep): boolean {\r\n if (!model) return false;\r\n\r\n //if (model.giftCardUrl?.trim()\r\n // && (model.personalMessage?.trim())) {\r\n\r\n // return true;\r\n //}\r\n\r\n if (model.giftCardUrl?.trim()) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n //isValid(): boolean {\r\n // return CustomizeStepModel.validateModel(this);\r\n // ////this.mediaUrl?.trim()\r\n // //if (this.giftCardUrl?.trim()\r\n // // && (this.personalMessage?.trim())) {\r\n\r\n // // return true;\r\n // //}\r\n\r\n // //return false;\r\n //}\r\n}","\r\nexport enum CheckoutStatusEnum {\r\n Pending = -1,\r\n Success = 0,\r\n Failed = 1,\r\n Rejected = 2,\r\n Secure3DAuth = 3\r\n}\r\n\r\nexport interface IGiftCardCheckoutResult {\r\n checkoutStatus: CheckoutStatusEnum;\r\n statusMessage: string;\r\n thankYouPageUrl: string;\r\n secure3DAuth: ICheckout3DAuth;\r\n}\r\n\r\nexport interface ICheckout3DAuth {\r\n acsUrl: string;\r\n creq: string;\r\n transactionid: string;\r\n}","import { hasXSSCharacters, isEmail, isFullNameValid } from \"../helpers/Utils\";\r\nimport IBaseStepModel from \"./interfaces/BaseStepModel.interface\";\r\n\r\nexport interface IInvoiceDetails extends IBaseStepModel {\r\n fullName: string;\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n companyName: string;\r\n\r\n country: string;\r\n county: string;\r\n city: string;\r\n postcode: string;\r\n\r\n addressLine1: string;\r\n addressLine2: string;\r\n addressLine3: string;\r\n}\r\n\r\nexport class InvoiceDetailsModel implements IInvoiceDetails {\r\n fullName: string;\r\n firstName: string;\r\n lastName: string;\r\n email: string;\r\n companyName: string;\r\n\r\n country: string;\r\n county: string;\r\n city: string;\r\n postcode: string;\r\n\r\n addressLine1: string;\r\n addressLine2: string;\r\n addressLine3: string;\r\n\r\n isDirty: boolean;\r\n\r\n constructor() {\r\n this.fullName = \"\";\r\n this.firstName = \"\";\r\n this.lastName = \"\";\r\n this.email = \"\";\r\n this.companyName = \"\";\r\n\r\n this.country = \"\";\r\n this.county = \"\";\r\n this.city = \"\";\r\n this.postcode = \"\";\r\n\r\n this.addressLine1 = \"\";\r\n this.addressLine2 = \"\";\r\n this.addressLine3 = \"\";\r\n }\r\n\r\n static validateModel = (model: IInvoiceDetails): boolean => {\r\n if (!model) {\r\n return false;\r\n }\r\n\r\n if (!model.email) {\r\n return false;\r\n }\r\n\r\n if (!isEmail(model.email)) {\r\n return false;\r\n }\r\n\r\n // in case old version of invoice component is used (for example in regift page)\r\n if (!model.fullName || !model.fullName.trim()) {\r\n if (model.firstName && model.firstName.trim() &&\r\n model.lastName && model.lastName.trim()) {\r\n model.fullName = `${model.firstName} ${model.lastName}`;\r\n }\r\n }\r\n\r\n if (!model.fullName || !model.fullName.trim() ||\r\n //!model.companyName || !model.companyName.trim() ||\r\n !model.country || !model.country.trim() ||\r\n !model.city || !model.city.trim() ||\r\n !model.addressLine1 || !model.addressLine1.trim()\r\n ) {\r\n return false;\r\n }\r\n\r\n if (model.postcode && model.postcode.trim() && model.postcode.trim().length < 3) {\r\n return false;\r\n }\r\n\r\n if (hasXSSCharacters(model.fullName) ||\r\n hasXSSCharacters(model.companyName) ||\r\n hasXSSCharacters(model.country) ||\r\n hasXSSCharacters(model.county) ||\r\n hasXSSCharacters(model.city) ||\r\n hasXSSCharacters(model.postcode) ||\r\n hasXSSCharacters(model.addressLine1) ||\r\n hasXSSCharacters(model.addressLine2) ||\r\n hasXSSCharacters(model.addressLine3)\r\n ) {\r\n return false;\r\n }\r\n\r\n if (!isFullNameValid(model.fullName)) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}","import { isEmail, isNullOrUndefined, isPhone } from \"../helpers/Utils\";\r\n\r\nexport interface IRecipientDetails {\r\n firstName: string;\r\n firstNameIsValid: boolean;\r\n lastName: string;\r\n lastNameIsValid: boolean;\r\n email: string;\r\n emailIsValid: boolean;\r\n phone: string;\r\n\r\n //isValid(): boolean;\r\n}\r\n\r\nexport class RecipientDetailsModel implements IRecipientDetails {\r\n firstName: string;\r\n firstNameIsValid: boolean;\r\n lastName: string;\r\n lastNameIsValid: boolean;\r\n email: string;\r\n emailIsValid: boolean;\r\n phone: string;\r\n\r\n constructor(\r\n ) {\r\n this.firstNameIsValid = true;\r\n this.lastNameIsValid = true;\r\n this.emailIsValid = true;\r\n }\r\n\r\n static validateModel(\r\n model: IRecipientDetails,\r\n emailIsRequired: boolean,\r\n phoneIsRequired: boolean): boolean {\r\n\r\n if (!model) return false;\r\n\r\n let emailIsValid = !emailIsRequired;\r\n if (emailIsRequired) {\r\n emailIsValid = (model.email?.trim() && isEmail(model.email));\r\n model.emailIsValid = emailIsValid;\r\n }\r\n\r\n if (phoneIsRequired) {\r\n if (!model.phone) {\r\n return false;\r\n }\r\n\r\n let phoneNumberRegex;\r\n\r\n if (model.phone.startsWith(\"+44\")) {\r\n phoneNumberRegex = /^\\+447\\d{9}$/;\r\n } else if (model.phone.startsWith(\"+353\")) {\r\n phoneNumberRegex = /^\\+3538\\d{8}$/;\r\n } else {\r\n return false;\r\n }\r\n\r\n if (phoneNumberRegex.test(model.phone) === false) {\r\n return false;\r\n }\r\n }\r\n\r\n if (model.firstName?.trim()\r\n && model.lastName?.trim()\r\n && emailIsValid) {\r\n model.firstNameIsValid = true;\r\n model.lastNameIsValid = true;\r\n model.emailIsValid = true;\r\n return true;\r\n }\r\n\r\n if (!model.firstName?.trim()) {\r\n model.firstNameIsValid = false;\r\n } else {\r\n model.firstNameIsValid = true;\r\n }\r\n\r\n if (!model.lastName?.trim()) {\r\n model.lastNameIsValid = false;\r\n } else {\r\n model.lastNameIsValid = true;\r\n }\r\n\r\n if (!emailIsValid) {\r\n model.emailIsValid = false;\r\n } else {\r\n model.emailIsValid = true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n //[obsolete: use static validateModel instead]\r\n isValid():boolean {\r\n return (\r\n false\r\n );\r\n }\r\n}","import IScheduleSendDetails from \"./interfaces/ScheduleSendDetails.interface\";\r\n\r\nimport { GiftCardSendTypeEnum } from \"./enums/GiftCardSendTypeEnum\";\r\nimport IBaseStepModel from \"./interfaces/BaseStepModel.interface\";\r\nimport {IRecipientDetails, RecipientDetailsModel} from \"./RecipientDetails.model\";\r\nimport {ISenderDetails, SenderDetailsModel } from \"./SenderDetails.model\";\r\nimport ScheduleSendDetailsModel from \"./ScheduleSendDetails.model\";\r\nimport { WorkflowTypeEnum } from \"./enums/WorkflowTypeEnum\";\r\n\r\nexport interface IRecipientsStep extends IBaseStepModel {\r\n sendBy: GiftCardSendTypeEnum;\r\n \r\n sendIndividually: boolean;\r\n senderSameAsRecipient: boolean; //visible only if recipients.length=1\r\n sendItLater: boolean;\r\n\r\n recipients: IRecipientDetails[];\r\n sender: ISenderDetails;\r\n scheduleSendDetails: IScheduleSendDetails; \r\n}\r\n\r\nexport class RecipientsStepModel implements IRecipientsStep, IBaseStepModel {\r\n sendBy: GiftCardSendTypeEnum;\r\n \r\n sendIndividually: boolean;\r\n senderSameAsRecipient: boolean; //visible only if recipients.length=1\r\n sendItLater: boolean;\r\n\r\n recipients: Array\r\n sender: ISenderDetails;\r\n scheduleSendDetails: IScheduleSendDetails; \r\n \r\n isDirty: boolean;\r\n\r\n constructor(\r\n ) {\r\n //default by email\r\n this.sendBy = GiftCardSendTypeEnum.BY_EMAIL;\r\n this.sendIndividually = false;\r\n this.sendItLater = false;\r\n this.senderSameAsRecipient = false;\r\n\r\n this.recipients = new Array(0);\r\n this.sender = new SenderDetailsModel();\r\n\r\n //will be set later\r\n this.scheduleSendDetails = new ScheduleSendDetailsModel();\r\n }\r\n\r\n static parseModel(viewModel: IRecipientsStep): RecipientsStepModel {\r\n const model = new RecipientsStepModel();\r\n\r\n model.sendBy = viewModel.sendBy;\r\n model.senderSameAsRecipient = viewModel.senderSameAsRecipient;\r\n model.sendIndividually = viewModel.sendIndividually;\r\n model.sendItLater = viewModel.sendItLater;\r\n\r\n //objects\r\n model.recipients = [...viewModel.recipients];\r\n model.scheduleSendDetails = { ...viewModel.scheduleSendDetails };\r\n model.sender = { ...viewModel.sender };\r\n\r\n //sender\r\n //const sender = new SenderDetailsModel();\r\n //model.sender = new SenderDetailsModel();\r\n //model.sender.firstName = viewModel.sender.firstName;\r\n //model.sender.lastName = viewModel.sender.lastName;\r\n //model.sender.email = viewModel.sender.email;\r\n //model.sender.phone = viewModel.sender.phone;\r\n return model;\r\n }\r\n\r\n static validateModel(model: IRecipientsStep, workflowType: WorkflowTypeEnum): boolean {\r\n\r\n const emailIsRequired = model.sendBy == GiftCardSendTypeEnum.BY_EMAIL;\r\n const phoneIsRequired = model.sendBy == GiftCardSendTypeEnum.BY_SMS;\r\n\r\n // Sender\r\n if (!SenderDetailsModel.validateModel(model.sender)) return false;\r\n //if (workflowType == WorkflowTypeEnum.BUY_GIFT_CARD) {\r\n // if (!SenderDetailsModel.validateModel(model.sender)) return false;\r\n //}\r\n\r\n // Scheduled Sending\r\n if (model.sendItLater) {\r\n if (!ScheduleSendDetailsModel.validateModel(model.scheduleSendDetails)) return false;\r\n }\r\n\r\n // Recipients\r\n if (!model.recipients || model.recipients.length == 0) return false;\r\n let length = model.recipients.length;\r\n if (model.sendIndividually == false) length = 1; //validate only first recipient\r\n\r\n for (var i = 0; i < length; i++) {\r\n\r\n if (!RecipientDetailsModel.validateModel(model.recipients[i], emailIsRequired, phoneIsRequired)) {\r\n return false;\r\n }\r\n }\r\n\r\n //else\r\n return true;\r\n }\r\n\r\n ////USED\r\n //isValid(): boolean {\r\n // console.error(\"RecipientsStepModel.IsValid() - should not be used!\");\r\n\r\n // let emailIsRequired = this.sendBy == GiftCardSendTypeEnum.BY_EMAIL;\r\n // let phoneIsRequired = this.sendBy == GiftCardSendTypeEnum.BY_SMS;\r\n\r\n // // Sender\r\n // if (!SenderDetailsModel.validateModel(this.sender)) return false;\r\n\r\n // // Scheduled Sending\r\n // if (this.sendItLater) {\r\n // if (!ScheduleSendDetailsModel.validateModel(this.scheduleSendDetails)) return false;\r\n // }\r\n\r\n // // Recipients\r\n // if (!this.recipients || this.recipients.length == 0) return false;\r\n // for (var i = 0; i < this.recipients.length; i++) {\r\n // if (!RecipientDetailsModel.validateModel(this.recipients[i], emailIsRequired, phoneIsRequired)) {\r\n // return false;\r\n // }\r\n // }\r\n\r\n // //else\r\n // return true;\r\n //}\r\n}","import { CheckBalanceStepModel, ICheckBalanceStep } from \"./CheckBalanceStep.model\";\r\nimport { CustomizeStepModel, ICustomizeStep } from \"./CustomizeStep.model\";\r\nimport { RegiftCardStateEnum } from \"./enums/RegiftCardStateEnum\";\r\nimport { WorkflowTypeEnum } from \"./enums/WorkflowTypeEnum\";\r\nimport { IRecipientsStep, RecipientsStepModel } from \"./RecipientsStep.model\";\r\nimport { IRegiftCardStep, RegiftCardStepModel } from \"./RegiftCardStep.model\";\r\nimport { IRegiftPaymentStep, RegiftPaymentStepModel } from \"./RegiftPaymentStep.model\";\r\n\r\nexport interface IRegiftCard {\r\n id: string;\r\n currentState: RegiftCardStateEnum;\r\n\r\n checkBalanceStep: ICheckBalanceStep;\r\n regiftCardStep: IRegiftCardStep;\r\n recipientsStep: IRecipientsStep;\r\n customizeStep: ICustomizeStep;\r\n paymentStep: IRegiftPaymentStep;\r\n type: 'IRegiftCard';\r\n\r\n\r\n isValid(): boolean;\r\n}\r\n\r\nexport class RegiftCardModel implements IRegiftCard {\r\n id = \"\";\r\n currentState: RegiftCardStateEnum = RegiftCardStateEnum.CHECK_BALANCE;\r\n\r\n checkBalanceStep: ICheckBalanceStep;\r\n regiftCardStep: IRegiftCardStep;\r\n recipientsStep: IRecipientsStep\r\n customizeStep: ICustomizeStep;\r\n paymentStep: IRegiftPaymentStep;\r\n type: 'IRegiftCard';\r\n\r\n constructor(\r\n ) {\r\n this.id = \"\";\r\n\r\n this.checkBalanceStep = new CheckBalanceStepModel();\r\n this.regiftCardStep = new RegiftCardStepModel();\r\n this.recipientsStep = new RecipientsStepModel();\r\n this.customizeStep = new CustomizeStepModel();\r\n this.paymentStep = new RegiftPaymentStepModel();\r\n }\r\n\r\n //USED\r\n isValid(): boolean {\r\n return (\r\n CheckBalanceStepModel.validateModel(this.checkBalanceStep)\r\n && RegiftCardStepModel.validateModel(this.regiftCardStep, this.checkBalanceStep.remainingBalance)\r\n && RecipientsStepModel.validateModel(this.recipientsStep, WorkflowTypeEnum.REGIFT_CARD)\r\n && CustomizeStepModel.validateModel(this.customizeStep)\r\n && RegiftPaymentStepModel.validateModel(this.paymentStep)\r\n );\r\n }\r\n\r\n static MapModel(mapFrom: IRegiftCard): RegiftCardModel {\r\n var mapTo = new RegiftCardModel();\r\n\r\n mapTo.id = mapFrom.id;\r\n mapTo.currentState = mapFrom.currentState;\r\n\r\n // check balance\r\n mapTo.checkBalanceStep.giftCardCode = mapFrom.checkBalanceStep.giftCardCode;\r\n mapTo.checkBalanceStep.remainingBalance = mapFrom.checkBalanceStep.remainingBalance;\r\n\r\n // regift card\r\n mapTo.regiftCardStep.value = mapFrom.regiftCardStep.value;\r\n\r\n // Recipients\r\n var recipientsStep = new RecipientsStepModel();\r\n recipientsStep.isDirty = false;\r\n recipientsStep.sendBy = mapFrom.recipientsStep.sendBy;\r\n recipientsStep.senderSameAsRecipient = mapFrom.recipientsStep.senderSameAsRecipient;\r\n recipientsStep.sendIndividually = mapFrom.recipientsStep.sendIndividually;\r\n recipientsStep.sendItLater = mapFrom.recipientsStep.sendItLater;\r\n //recipientsStep.scheduleSendDetails = { ...mapFrom.recipientsStep.scheduleSendDetails };\r\n recipientsStep.sender = { ...mapFrom.recipientsStep.sender };\r\n recipientsStep.recipients = [...mapFrom.recipientsStep.recipients];\r\n mapTo.recipientsStep = { ...recipientsStep };\r\n\r\n if (mapFrom.recipientsStep.scheduleSendDetails.date != null) {\r\n const timestamp = Date.parse(mapFrom.recipientsStep.scheduleSendDetails.date.toString());\r\n mapTo.recipientsStep.scheduleSendDetails.date = new Date(timestamp);\r\n }\r\n mapTo.recipientsStep.scheduleSendDetails.hour = mapFrom.recipientsStep.scheduleSendDetails.hour;\r\n mapTo.recipientsStep.scheduleSendDetails.minute = mapFrom.recipientsStep.scheduleSendDetails.minute;\r\n\r\n //mapTo.recipientsStep.isDirty = false;\r\n //mapTo.recipientsStep.sendBy = mapFrom.recipientsStep.sendBy;\r\n //mapTo.recipientsStep.senderSameAsRecipient = mapFrom.recipientsStep.senderSameAsRecipient;\r\n //mapTo.recipientsStep.sendIndividually = mapFrom.recipientsStep.sendIndividually;\r\n //mapTo.recipientsStep.sendIndividually = mapFrom.recipientsStep.sendIndividually;\r\n //mapTo.recipientsStep.recipients = [...mapFrom.recipientsStep.recipients];\r\n //mapTo.recipientsStep.scheduleSendDetails = { ...mapFrom.recipientsStep.scheduleSendDetails };\r\n //mapTo.recipientsStep.sender = { ...mapFrom.recipientsStep.sender };\r\n\r\n // Customize\r\n mapTo.customizeStep.isDirty = false;\r\n mapTo.customizeStep.giftCardUrl = mapFrom.customizeStep.giftCardUrl ?? \"\";\r\n mapTo.customizeStep.mediaUrl = mapFrom.customizeStep.mediaUrl ?? \"\";\r\n mapTo.customizeStep.personalMessage = mapFrom.customizeStep.personalMessage ?? \"\";\r\n\r\n // Preview and Pay\r\n mapTo.paymentStep.isDirty = false;\r\n mapTo.paymentStep.termsAccepted = false;\r\n mapTo.paymentStep.paymentDetails.currency = mapFrom.paymentStep.paymentDetails.currency;\r\n mapTo.paymentStep.paymentDetails.stripeKey = mapFrom.paymentStep.paymentDetails.stripeKey;\r\n mapTo.paymentStep.paymentDetails.cardAmount = mapFrom.paymentStep.paymentDetails.cardAmount;\r\n mapTo.paymentStep.paymentDetails.totalAmount = mapFrom.paymentStep.paymentDetails.totalAmount;\r\n mapTo.paymentStep.paymentDetails.totalFees = mapFrom.paymentStep.paymentDetails.totalFees;\r\n\r\n //console.debug(\"MapTo Regift\", mapTo);\r\n return mapTo;\r\n }\r\n\r\n}","import IBaseStepModel from \"./interfaces/BaseStepModel.interface\";\r\n\r\nexport interface IRegiftCardStep extends IBaseStepModel {\r\n value: number;\r\n}\r\n\r\nexport class RegiftCardStepModel implements IRegiftCardStep, IBaseStepModel {\r\n value: number;\r\n isDirty: boolean;\r\n\r\n constructor(\r\n ) {\r\n this.value = 0;\r\n }\r\n\r\n static validateModel(model: IRegiftCardStep, cardBalance:number) {\r\n\r\n if (!model) return false;\r\n\r\n return model.value > 0 && model.value <= cardBalance;\r\n }\r\n}","import IPaymentDetails from \"./PaymentDetails.interface\";\r\nimport IBaseStepModel from \"./interfaces/BaseStepModel.interface\";\r\n\r\nexport interface IRegiftPaymentStep extends IBaseStepModel {\r\n paymentDetails: IPaymentDetails;\r\n termsAccepted: boolean;\r\n}\r\n\r\nexport class RegiftPaymentStepModel implements IRegiftPaymentStep, IBaseStepModel {\r\n paymentDetails: IPaymentDetails;\r\n\r\n termsAccepted: boolean;\r\n isDirty: boolean;\r\n\r\n constructor(\r\n ) {\r\n this.termsAccepted = false;\r\n this.paymentDetails = {\r\n currency: \"euro\",\r\n cardAmount: 0,\r\n totalAmount: 0,\r\n totalFees: 0\r\n } as IPaymentDetails;\r\n }\r\n\r\n static validateModel(model: IRegiftPaymentStep) {\r\n\r\n if (!model) return false;\r\n\r\n return model.termsAccepted;\r\n }\r\n}","import IScheduleSendDetails from \"./interfaces/ScheduleSendDetails.interface\";\r\n\r\nexport default class ScheduleSendDetailsModel implements IScheduleSendDetails {\r\n date: Date;\r\n hour: number;\r\n minute: number;\r\n\r\n constructor(\r\n ) {\r\n const tomorrow = new Date();\r\n //tomorrow.setDate(tomorrow.getDate() + 1); //add 1 day\r\n\r\n this.date = tomorrow;// new Date(currentDate.setDate(currentDate.getDate()+1));\r\n this.hour = 23;//currentDate.getHours();\r\n this.minute = 59;//currentDate.getMinutes();\r\n }\r\n\r\n static validateModel(model: IScheduleSendDetails) {\r\n if (!model) return false;\r\n\r\n if (!model.date) return false;\r\n\r\n const today = new Date();\r\n //const compareDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59);\r\n //const modelDate = new Date(model.date.getFullYear(), model.date.getMonth(), model.date.getDate(), model.hour, model.minute);\r\n //console.debug('selected', modelDate);\r\n //console.debug('today', today);\r\n //const todayDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 1);\r\n //const compareDate = new Date(model.date.getFullYear(), model.date.getMonth(), model.date.getDate(), model.hour, model.minute);\r\n const yesterday = new Date();\r\n yesterday.setDate(yesterday.getDate() -1); \r\n\r\n if (model.hour >= 0 && model.hour <= 23 &&\r\n model.minute >= 0 && model.minute <= 59\r\n && model.date > yesterday\r\n ) {\r\n return true;\r\n }\r\n\r\n //if (model.hour >= 0 && model.hour <= 23 &&\r\n // model.minute >= 0 && model.minute <= 59\r\n // && modelDate.getTime() > today.getTime()\r\n //) {\r\n // return true;\r\n //}\r\n\r\n //if (model.hour >= 0 && model.hour <= 23 &&\r\n // model.minute >= 0 && model.minute <= 59\r\n // && model.date.getTime() > today.getTime()\r\n //) {\r\n // return true;\r\n //}\r\n\r\n return false;\r\n }\r\n\r\n //[obsolete: use static validateModel instead]\r\n isValid(): boolean {\r\n return ScheduleSendDetailsModel.validateModel(this);\r\n }\r\n}","import { isEmail } from \"../helpers/Utils\";\r\n\r\nexport interface ISenderDetails {\r\n firstName: string;\r\n firstNameIsValid: boolean,\r\n lastName: string;\r\n lastNameIsValid: boolean,\r\n email: string;\r\n emailIsValid: boolean,\r\n phone: string;\r\n company: string;\r\n\r\n fullName: string;\r\n //isValid: () => boolean;\r\n //isValid(): boolean;\r\n}\r\n\r\nexport class SenderDetailsModel implements ISenderDetails {\r\n firstName: string;\r\n firstNameIsValid: boolean;\r\n lastName: string;\r\n lastNameIsValid: boolean;\r\n email: string;\r\n emailIsValid: boolean;\r\n phone: string;\r\n company: string;\r\n\r\n fullName: string;\r\n\r\n constructor(\r\n ) {\r\n this.firstName = \"\";\r\n this.lastName = \"\";\r\n this.email = \"\";\r\n this.phone = \"\";\r\n this.company = \"\";\r\n this.firstNameIsValid = true;\r\n this.lastNameIsValid = true;\r\n this.emailIsValid = true;\r\n\r\n this.fullName = \"\";\r\n }\r\n\r\n static validateModel(model: ISenderDetails): boolean {\r\n\r\n if (!model) return false;\r\n\r\n if (model.firstName?.trim()\r\n && model.lastName?.trim()\r\n && (model.email?.trim() && isEmail(model.email))) {\r\n model.firstNameIsValid = true;\r\n model.lastNameIsValid = true;\r\n model.emailIsValid = true;\r\n return true;\r\n }\r\n\r\n if (!model.firstName?.trim()) {\r\n model.firstNameIsValid = false;\r\n } else {\r\n model.firstNameIsValid = true;\r\n }\r\n\r\n if (!model.lastName?.trim()) {\r\n model.lastNameIsValid = false;\r\n } else {\r\n model.lastNameIsValid = true;\r\n }\r\n\r\n if (!model.email?.trim() || !isEmail(model.email)) {\r\n model.emailIsValid = false;\r\n } else {\r\n model.emailIsValid = true;\r\n }\r\n\r\n return false;\r\n } \r\n\r\n //[obsolete: use static validateModel instead]\r\n isValid(): boolean {\r\n return SenderDetailsModel.validateModel(this);\r\n }\r\n}","import { BuyGiftCardStateEnum } from \"../enums/BuyGiftCardStateEnum\";\r\nimport { BuyGiftCardSubpageEnum } from \"../enums/BuyGiftCardSubpageEnum\";\r\nimport { ChooseCardSubpageModel, IChooseCardSubpageModel } from \"./choose-card/ChooseCardSubpage.model\";\r\nimport { CustomiseCardSubpageModel, ICustomiseCardSubpageModel } from \"./customise-card/CustomiseCardSubpage.model\";\r\nimport { IReviewAndPaySubpageModel, ReviewAndPaySubpageModel } from \"./review-pay/ReviewAndPaySubpage.model\";\r\n\r\nexport interface IBuyGiftCardModel {\r\n id: string;\r\n\r\n currentSubpage: BuyGiftCardSubpageEnum;\r\n currentState: BuyGiftCardStateEnum;\r\n\r\n chooseCardSubpage: IChooseCardSubpageModel;\r\n customiseCardSubpage: ICustomiseCardSubpageModel;\r\n reviewAndPaySubpage: IReviewAndPaySubpageModel;\r\n}\r\n\r\nexport class BuyGiftCardModel implements IBuyGiftCardModel {\r\n id = \"\";\r\n\r\n currentSubpage: BuyGiftCardSubpageEnum = BuyGiftCardSubpageEnum.CHOOSE_CARD;\r\n currentState: BuyGiftCardStateEnum = BuyGiftCardStateEnum.CHOOSE_CARD_DETAILS;\r\n\r\n chooseCardSubpage: IChooseCardSubpageModel;\r\n customiseCardSubpage: ICustomiseCardSubpageModel;\r\n reviewAndPaySubpage: IReviewAndPaySubpageModel;\r\n\r\n constructor() {\r\n this.id = \"\";\r\n this.currentSubpage = BuyGiftCardSubpageEnum.CHOOSE_CARD;\r\n this.currentState = BuyGiftCardStateEnum.CHOOSE_CARD_DETAILS;\r\n\r\n this.chooseCardSubpage = new ChooseCardSubpageModel();\r\n this.customiseCardSubpage = new CustomiseCardSubpageModel();\r\n this.reviewAndPaySubpage = new ReviewAndPaySubpageModel();\r\n }\r\n \r\n static isValid(model: IBuyGiftCardModel): boolean {\r\n return ChooseCardSubpageModel.isValid(model.chooseCardSubpage) &&\r\n CustomiseCardSubpageModel.isValid(model.customiseCardSubpage) &&\r\n ReviewAndPaySubpageModel.isValid(model.reviewAndPaySubpage);\r\n }\r\n\r\n static MapModel(mapFrom: IBuyGiftCardModel): IBuyGiftCardModel {\r\n const mapTo = new BuyGiftCardModel();\r\n\r\n mapTo.id = mapFrom.id;\r\n mapTo.currentSubpage = mapFrom.currentSubpage ?? BuyGiftCardSubpageEnum.CHOOSE_CARD;\r\n mapTo.currentState = mapFrom.currentState ?? BuyGiftCardStateEnum.CHOOSE_CARD_DETAILS;\r\n\r\n // ChooseCard subpage\r\n mapTo.chooseCardSubpage.chooseCardDetails.quantity = mapFrom.chooseCardSubpage.chooseCardDetails.quantity;\r\n mapTo.chooseCardSubpage.chooseCardDetails.value = mapFrom.chooseCardSubpage.chooseCardDetails.value;\r\n\r\n mapTo.chooseCardSubpage.chooseRecipients.sendIndividually = mapFrom.chooseCardSubpage.chooseRecipients.sendIndividually;\r\n mapTo.chooseCardSubpage.chooseRecipients.sendBy = mapFrom.chooseCardSubpage.chooseRecipients.sendBy;\r\n mapTo.chooseCardSubpage.chooseRecipients.recipients = [...mapFrom.chooseCardSubpage.chooseRecipients.recipients];\r\n\r\n mapTo.chooseCardSubpage.chooseSender.fullName = mapFrom.chooseCardSubpage.chooseSender.fullName.trim();\r\n\r\n // CustomiseCard subpage\r\n mapTo.customiseCardSubpage.customiseCard.giftCardUrl = mapFrom.customiseCardSubpage.customiseCard.giftCardUrl;\r\n mapTo.customiseCardSubpage.customiseCard.useCardTemplate = mapFrom.customiseCardSubpage.customiseCard.useCardTemplate ?? true;\r\n\r\n mapTo.customiseCardSubpage.customiseMail.personalMessage = mapFrom.customiseCardSubpage.customiseMail.personalMessage;\r\n mapTo.customiseCardSubpage.customiseMail.mediaUrl = mapFrom.customiseCardSubpage.customiseMail.mediaUrl;\r\n\r\n // ReviewAndPay subpage\r\n mapTo.reviewAndPaySubpage.reviewAndPaySenderInfo.useBusinessDetails = mapFrom.reviewAndPaySubpage.reviewAndPaySenderInfo.useBusinessDetails;\r\n mapTo.reviewAndPaySubpage.reviewAndPaySenderInfo.usePersonalDetails = mapFrom.reviewAndPaySubpage.reviewAndPaySenderInfo.usePersonalDetails;\r\n mapTo.reviewAndPaySubpage.reviewAndPaySenderInfo.personDetails = mapFrom.reviewAndPaySubpage.reviewAndPaySenderInfo.personDetails;\r\n mapTo.reviewAndPaySubpage.reviewAndPaySenderInfo.businessDetails = mapFrom.reviewAndPaySubpage.reviewAndPaySenderInfo.businessDetails;\r\n\r\n mapTo.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails = { ...mapFrom.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails };\r\n\r\n if (mapFrom.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails.date != null) {\r\n const timestamp = Date.parse(mapFrom.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails.date.toString());\r\n mapTo.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails.date = new Date(timestamp);\r\n }\r\n\r\n mapTo.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails.hour = mapFrom.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails.hour;\r\n mapTo.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails.minute = mapFrom.reviewAndPaySubpage.reviewAndPayWhenToSend.scheduleSendDetails.minute;\r\n\r\n mapTo.reviewAndPaySubpage.reviewAndPayPayment.paymentType = mapFrom.reviewAndPaySubpage.reviewAndPayPayment.paymentType;\r\n mapTo.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.checkoutKey = mapFrom.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.checkoutKey;\r\n mapTo.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.checkoutExpiry = mapFrom.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.checkoutExpiry;\r\n mapTo.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.cardAmount = mapFrom.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.cardAmount;\r\n mapTo.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.totalAmount = mapFrom.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.totalAmount;\r\n mapTo.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.totalFees = mapFrom.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.totalFees;\r\n mapTo.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.currency = mapFrom.reviewAndPaySubpage.reviewAndPayPayment.paymentDetails.currency;\r\n mapTo.reviewAndPaySubpage.reviewAndPayPayment.invoiceDetails = mapFrom.reviewAndPaySubpage.reviewAndPayPayment.invoiceDetails;\r\n\r\n return mapTo;\r\n }\r\n}","import { ChooseCardStepModel, IChooseCardStepModel } from \"./ChooseCardsStep.model\";\r\nimport { ChooseRecipientsStepModel, IChooseRecipientsStepModel } from \"./ChooseRecipientsStep.model\";\r\nimport { ChooseSenderStepModel, IChooseSenderStepModel } from \"./ChooseSenderStep.model\";\r\n\r\nexport interface IChooseCardSubpageModel {\r\n chooseCardDetails: IChooseCardStepModel;\r\n chooseRecipients: IChooseRecipientsStepModel;\r\n chooseSender: IChooseSenderStepModel;\r\n}\r\n\r\nexport class ChooseCardSubpageModel implements IChooseCardSubpageModel {\r\n chooseCardDetails: IChooseCardStepModel;\r\n chooseRecipients: IChooseRecipientsStepModel;\r\n chooseSender: IChooseSenderStepModel;\r\n\r\n constructor() {\r\n this.chooseCardDetails = new ChooseCardStepModel();\r\n this.chooseRecipients = new ChooseRecipientsStepModel();\r\n this.chooseSender = new ChooseSenderStepModel();\r\n }\r\n\r\n static isValid(model: IChooseCardSubpageModel): boolean {\r\n return ChooseCardStepModel.isValid(model.chooseCardDetails, null) &&\r\n ChooseRecipientsStepModel.isValid(model.chooseRecipients) &&\r\n ChooseSenderStepModel.isValid(model.chooseSender);\r\n }\r\n}","import { ICardSettings } from \"../../interfaces/AppSettings.interface\";\r\n\r\nexport interface IChooseCardStepModel {\r\n quantity: number;\r\n value: number;\r\n}\r\n\r\nexport class ChooseCardStepModel implements IChooseCardStepModel {\r\n quantity: number;\r\n value: number;\r\n\r\n constructor() {\r\n this.quantity = 1;\r\n this.value = 0;\r\n }\r\n \r\n static isValid(model: IChooseCardStepModel, cardSettings: ICardSettings) {\r\n if (cardSettings) {\r\n if (model.quantity < cardSettings.quantityMin || model.quantity > cardSettings.quantityMax) {\r\n return false;\r\n }\r\n\r\n if (model.value < cardSettings.valueMin || model.value > cardSettings.valueMax) {\r\n return false;\r\n }\r\n\r\n const cardTotal = model.quantity * model.value;\r\n if (cardTotal <= 0 || cardTotal > cardSettings.totalValueMax) {\r\n return false;\r\n }\r\n } else {\r\n if (model.quantity <= 0 || model.value <= 0) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n}","import { PHONE_NUMBER } from \"../../../constants/global\";\r\nimport { hasXSSCharacters, isEmail, isFullNameValid } from \"../../../helpers/Utils\";\r\nimport { GiftCardSendTypeEnum } from \"../../enums/GiftCardSendTypeEnum\";\r\n\r\nexport interface IChooseRecipientsStepModel {\r\n sendIndividually: boolean;\r\n sendBy: GiftCardSendTypeEnum;\r\n recipients: Array;\r\n}\r\n\r\nexport class ChooseRecipientsStepModel implements IChooseRecipientsStepModel {\r\n sendIndividually: boolean;\r\n sendBy: GiftCardSendTypeEnum;\r\n recipients: Array;\r\n \r\n constructor() {\r\n this.sendIndividually = true;\r\n this.sendBy = GiftCardSendTypeEnum.BY_EMAIL;\r\n this.recipients = new Array();\r\n }\r\n\r\n static isValid(model: IChooseRecipientsStepModel): boolean {\r\n if (!model.recipients || model.recipients.length == 0) {\r\n return false;\r\n }\r\n\r\n let isValid = true;\r\n\r\n model.recipients.forEach(r => {\r\n if (!r.fullName || !isFullNameValid(r.fullName.trim())) {\r\n isValid = false;\r\n }\r\n\r\n if (model.sendBy === GiftCardSendTypeEnum.BY_EMAIL) {\r\n if (!isEmail(r.email)) {\r\n isValid = false;\r\n }\r\n\r\n if (r.phone && hasXSSCharacters(r.phone)) {\r\n isValid = false;\r\n }\r\n } else if (model.sendBy === GiftCardSendTypeEnum.BY_SMS) {\r\n const ieRegex = PHONE_NUMBER.VALIDATIONS.REGEX.IE;\r\n const ukRegex = PHONE_NUMBER.VALIDATIONS.REGEX.GB;\r\n\r\n if (!ieRegex.test(r.phone) && !ukRegex.test(r.phone)) {\r\n isValid = false;\r\n }\r\n\r\n if (r.email && !isEmail(r.email)) {\r\n isValid = false;\r\n }\r\n }\r\n });\r\n\r\n return isValid;\r\n }\r\n}\r\n\r\nexport interface IRecipientDetails {\r\n fullName: string;\r\n email: string;\r\n phone: string;\r\n}\r\n\r\nexport class RecipientDetailsModel implements IRecipientDetails {\r\n fullName: string;\r\n email: string;\r\n phone: string;\r\n\r\n constructor() {\r\n this.fullName = '';\r\n this.email = '';\r\n this.phone = '';\r\n }\r\n}","export interface IChooseSenderStepModel {\r\n fullName: string;\r\n}\r\n\r\nexport class ChooseSenderStepModel implements IChooseSenderStepModel {\r\n fullName: string;\r\n\r\n constructor() {\r\n this.fullName = \"\";\r\n }\r\n\r\n static isValid(model: IChooseSenderStepModel): boolean {\r\n if (!model.fullName || !model.fullName.trim()) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}","export interface ICustomiseCardStepModel {\r\n giftCardUrl: string;\r\n userGiftCards: Array;\r\n useCardTemplate: boolean;\r\n}\r\n\r\nexport class CustomiseCardStepModel implements ICustomiseCardStepModel {\r\n giftCardUrl: string;\r\n userGiftCards: Array;\r\n useCardTemplate: boolean;\r\n\r\n constructor() {\r\n this.giftCardUrl = \"\";\r\n this.userGiftCards = new Array();\r\n this.useCardTemplate = true;\r\n }\r\n\r\n static isValid(model: ICustomiseCardStepModel): boolean {\r\n if (!model.giftCardUrl.trim()) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}","import { CustomiseCardStepModel, ICustomiseCardStepModel } from \"./CustomiseCardStep.model\";\r\nimport { CustomiseMailStepModel, ICustomiseMailStepModel } from \"./CustomiseMailStep.model\";\r\n\r\nexport interface ICustomiseCardSubpageModel {\r\n customiseCard: ICustomiseCardStepModel;\r\n customiseMail: ICustomiseMailStepModel;\r\n}\r\n\r\nexport class CustomiseCardSubpageModel implements ICustomiseCardSubpageModel {\r\n customiseCard: ICustomiseCardStepModel;\r\n customiseMail: ICustomiseMailStepModel;\r\n\r\n constructor() {\r\n this.customiseCard = new CustomiseCardStepModel();\r\n this.customiseMail = new CustomiseMailStepModel();\r\n }\r\n\r\n static isValid(model: ICustomiseCardSubpageModel): boolean {\r\n return CustomiseCardStepModel.isValid(model.customiseCard) &&\r\n CustomiseMailStepModel.isValid(model.customiseMail);\r\n }\r\n}","export interface ICustomiseMailStepModel {\r\n writePersonalMessage: boolean;\r\n personalMessage: string;\r\n addMedia: boolean;\r\n useGif: boolean;\r\n mediaUrl: string;\r\n userMedias: Array;\r\n}\r\n\r\nexport class CustomiseMailStepModel implements ICustomiseMailStepModel {\r\n writePersonalMessage: boolean;\r\n personalMessage: string;\r\n addMedia: boolean;\r\n useGif: boolean;\r\n mediaUrl: string;\r\n userMedias: Array;\r\n\r\n constructor() {\r\n this.writePersonalMessage = true;\r\n this.personalMessage = \"\";\r\n this.addMedia = false;\r\n this.useGif = true;\r\n this.mediaUrl = \"\";\r\n this.userMedias = new Array();\r\n }\r\n\r\n static isValid(model: ICustomiseMailStepModel): boolean {\r\n if (model.writePersonalMessage && !model.personalMessage.trim()) {\r\n return false;\r\n }\r\n\r\n if (model.addMedia && !model.mediaUrl.trim()) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}","import { IInvoiceDetails, InvoiceDetailsModel } from \"../../InvoiceDetails.model\";\r\nimport IPaymentDetails from \"../../PaymentDetails.interface\";\r\nimport { PaymentTypeEnum } from \"../../enums/PaymentTypeEnum\";\r\n\r\nexport interface IReviewAndPayPaymentStepModel {\r\n paymentType: PaymentTypeEnum;\r\n paymentDetails: IPaymentDetails;\r\n invoiceDetails: IInvoiceDetails;\r\n termsAccepted: boolean;\r\n paymentCompleted: boolean;\r\n}\r\n\r\nexport class ReviewAndPayPaymentStepModel implements IReviewAndPayPaymentStepModel {\r\n paymentType: PaymentTypeEnum;\r\n paymentDetails: IPaymentDetails;\r\n invoiceDetails: IInvoiceDetails;\r\n termsAccepted: boolean;\r\n paymentCompleted: boolean;\r\n\r\n constructor() {\r\n this.paymentType = PaymentTypeEnum.NONE;\r\n this.paymentDetails = new PaymentDetails();\r\n this.invoiceDetails = new InvoiceDetailsModel();\r\n this.termsAccepted = false;\r\n this.paymentCompleted = false;\r\n }\r\n \r\n static isValid(model: IReviewAndPayPaymentStepModel): boolean {\r\n if (!model.termsAccepted) {\r\n return false;\r\n }\r\n\r\n if (model.paymentType === PaymentTypeEnum.CREDIT_CARD) {\r\n return model.paymentCompleted;\r\n } else if (model.paymentType === PaymentTypeEnum.BANK) {\r\n return InvoiceDetailsModel.validateModel(model.invoiceDetails);\r\n } else {\r\n return false;\r\n }\r\n }\r\n}\r\n\r\nexport class PaymentDetails implements IPaymentDetails {\r\n checkoutKey: string;\r\n checkoutExpiry: Date;\r\n stripeKey: string;\r\n cardAmount: number;\r\n totalAmount: number;\r\n totalFees: number;\r\n currency: string;\r\n\r\n constructor() {\r\n this.checkoutKey = \"\";\r\n this.checkoutExpiry = new Date();\r\n this.stripeKey = \"\";\r\n this.cardAmount = 0;\r\n this.totalAmount = 0;\r\n this.totalFees = 0;\r\n this.currency = \"EUR\";\r\n }\r\n}","import { hasXSSCharacters, isEmail, isFullNameValid } from \"../../../helpers/Utils\";\r\nimport ICountry from \"../../Country.interface\";\r\n\r\nexport interface IReviewAndPaySenderInfoStepModel {\r\n usePersonalDetails: boolean;\r\n useBusinessDetails: boolean;\r\n personDetails: IReviewAndPaySenderInfoPersonDetails;\r\n businessDetails: IReviewAndPaySenderInfoBusinessDetails;\r\n}\r\n\r\nexport class ReviewAndPaySenderInfoStepModel implements IReviewAndPaySenderInfoStepModel {\r\n usePersonalDetails: boolean;\r\n useBusinessDetails: boolean;\r\n personDetails: IReviewAndPaySenderInfoPersonDetails;\r\n businessDetails: IReviewAndPaySenderInfoBusinessDetails;\r\n\r\n constructor() {\r\n this.usePersonalDetails = false;\r\n this.useBusinessDetails = false;\r\n this.personDetails = new ReviewAndPaySenderInfoPersonDetails();\r\n this.businessDetails = new ReviewAndPaySenderInfoBusinessDetails();\r\n }\r\n\r\n static isValid(model: IReviewAndPaySenderInfoStepModel, countries: ICountry[]): boolean {\r\n if (model.usePersonalDetails) {\r\n return ReviewAndPaySenderInfoPersonDetails.isValid(model.personDetails);\r\n }\r\n\r\n if (model.useBusinessDetails) {\r\n return ReviewAndPaySenderInfoBusinessDetails.isValid(model.businessDetails, countries);\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\ninterface IReviewAndPaySenderInfoPersonDetails {\r\n fullName: string;\r\n email: string;\r\n}\r\n\r\nclass ReviewAndPaySenderInfoPersonDetails implements IReviewAndPaySenderInfoPersonDetails {\r\n fullName: string;\r\n email: string;\r\n\r\n constructor() {\r\n this.fullName = \"\";\r\n this.email = \"\";\r\n }\r\n\r\n static isValid(model: IReviewAndPaySenderInfoPersonDetails): boolean {\r\n if (!model.fullName || !model.fullName.trim() || hasXSSCharacters(model.fullName)) {\r\n return false;\r\n }\r\n\r\n if (!isFullNameValid(model.fullName.trim())) {\r\n return false;\r\n }\r\n\r\n if (!model.email || !model.email.trim() || !isEmail(model.email)) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n\r\ninterface IReviewAndPaySenderInfoBusinessDetails {\r\n fullName: string;\r\n email: string;\r\n companyName: string;\r\n tradingAs: string;\r\n businessType: string;\r\n vat: string;\r\n cro: string;\r\n businessAddress: IReviewAndPaySenderInfoBusinessAddress;\r\n}\r\n\r\nclass ReviewAndPaySenderInfoBusinessDetails implements IReviewAndPaySenderInfoBusinessDetails {\r\n fullName: string;\r\n email: string;\r\n companyName: string;\r\n tradingAs: string;\r\n businessType: string;\r\n vat: string;\r\n cro: string;\r\n businessAddress: IReviewAndPaySenderInfoBusinessAddress;\r\n\r\n constructor() {\r\n this.fullName = \"\";\r\n this.email = \"\";\r\n this.companyName = \"\";\r\n this.tradingAs = \"\";\r\n this.businessType = \"\";\r\n this.vat = \"\";\r\n this.cro = \"\";\r\n this.businessAddress = new ReviewAndPaySenderInfoBusinessAddress();\r\n }\r\n\r\n static isValid(model: IReviewAndPaySenderInfoBusinessDetails, countries: ICountry[]): boolean {\r\n if (!model.fullName || !model.fullName.trim() || hasXSSCharacters(model.fullName)) {\r\n return false;\r\n }\r\n\r\n if (!isFullNameValid(model.fullName)) {\r\n return false;\r\n }\r\n\r\n if (!model.email || !model.email.trim() || !isEmail(model.email)) {\r\n return false;\r\n }\r\n\r\n if (!model.companyName || !model.companyName.trim() || hasXSSCharacters(model.companyName)) {\r\n return false;\r\n }\r\n\r\n if (!model.businessType || !model.businessType.trim() || hasXSSCharacters(model.businessType)) {\r\n return false;\r\n }\r\n\r\n if (hasXSSCharacters(model.tradingAs) || hasXSSCharacters(model.vat) || hasXSSCharacters(model.cro)) {\r\n return false;\r\n }\r\n\r\n if (!model.businessAddress) {\r\n return false;\r\n }\r\n\r\n const isBusinessAddressValid = ReviewAndPaySenderInfoBusinessAddress.isValid(model.businessAddress, countries);\r\n if (!isBusinessAddressValid) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n\r\ninterface IReviewAndPaySenderInfoBusinessAddress {\r\n country: string;\r\n county: string;\r\n city: string;\r\n postcode: string;\r\n addressLine1: string;\r\n addressLine2: string;\r\n addressLine3: string;\r\n}\r\n\r\nclass ReviewAndPaySenderInfoBusinessAddress implements IReviewAndPaySenderInfoBusinessAddress {\r\n country: string;\r\n county: string;\r\n city: string;\r\n postcode: string;\r\n addressLine1: string;\r\n addressLine2: string;\r\n addressLine3: string;\r\n\r\n constructor() {\r\n this.country = '';\r\n this.county = '';\r\n this.city = '';\r\n this.postcode = '';\r\n this.addressLine1 = '';\r\n this.addressLine2 = '';\r\n this.addressLine3 = '';\r\n }\r\n\r\n static isValid(model: IReviewAndPaySenderInfoBusinessAddress, countries: ICountry[]): boolean {\r\n if (!model.country || !model.country.trim() || hasXSSCharacters(model.country)) {\r\n return false;\r\n }\r\n\r\n if (!model.city || !model.city.trim() || hasXSSCharacters(model.city)) {\r\n return false;\r\n }\r\n\r\n if (!model.addressLine1 || !model.addressLine1.trim() || hasXSSCharacters(model.addressLine1)) {\r\n return false;\r\n }\r\n\r\n if (model.postcode && model.postcode.trim() && model.postcode.trim().length < 3) {\r\n return false;\r\n }\r\n\r\n if (hasXSSCharacters(model.county) ||\r\n hasXSSCharacters(model.postcode) ||\r\n hasXSSCharacters(model.addressLine2) ||\r\n hasXSSCharacters(model.addressLine3)\r\n ) {\r\n return false;\r\n }\r\n\r\n if (countries && !countries.map(c => c.code).includes(model.country)) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}","import { IReviewAndPayPaymentStepModel, ReviewAndPayPaymentStepModel } from \"./ReviewAndPayPaymentStep.model\";\r\nimport { IReviewAndPaySenderInfoStepModel, ReviewAndPaySenderInfoStepModel } from \"./ReviewAndPaySenderInfoStep.model\";\r\nimport { IReviewAndPayWhenToSendStepModel, ReviewAndPayWhenToSendStepModel } from \"./ReviewAndPayWhenToSendStep.model\";\r\n\r\nexport interface IReviewAndPaySubpageModel {\r\n reviewAndPaySenderInfo: IReviewAndPaySenderInfoStepModel;\r\n reviewAndPayWhenToSend: IReviewAndPayWhenToSendStepModel;\r\n reviewAndPayPayment: IReviewAndPayPaymentStepModel;\r\n}\r\n\r\nexport class ReviewAndPaySubpageModel implements IReviewAndPaySubpageModel {\r\n reviewAndPaySenderInfo: IReviewAndPaySenderInfoStepModel;\r\n reviewAndPayWhenToSend: IReviewAndPayWhenToSendStepModel;\r\n reviewAndPayPayment: IReviewAndPayPaymentStepModel;\r\n\r\n constructor() {\r\n this.reviewAndPaySenderInfo = new ReviewAndPaySenderInfoStepModel();\r\n this.reviewAndPayWhenToSend = new ReviewAndPayWhenToSendStepModel();\r\n this.reviewAndPayPayment = new ReviewAndPayPaymentStepModel();\r\n }\r\n\r\n static isValid(model: IReviewAndPaySubpageModel): boolean {\r\n return ReviewAndPaySenderInfoStepModel.isValid(model.reviewAndPaySenderInfo, null) &&\r\n ReviewAndPayWhenToSendStepModel.isValid(model.reviewAndPayWhenToSend) &&\r\n ReviewAndPayPaymentStepModel.isValid(model.reviewAndPayPayment);\r\n }\r\n}","import ScheduleSendDetailsModel from \"../../ScheduleSendDetails.model\";\r\nimport IScheduleSendDetails from \"../../interfaces/ScheduleSendDetails.interface\";\r\n\r\nexport interface IReviewAndPayWhenToSendStepModel {\r\n sendLater: boolean;\r\n scheduleSendDetails: IScheduleSendDetails;\r\n}\r\n\r\nexport class ReviewAndPayWhenToSendStepModel implements IReviewAndPayWhenToSendStepModel {\r\n sendLater: boolean;\r\n scheduleSendDetails: IScheduleSendDetails;\r\n\r\n constructor() {\r\n this.sendLater = false;\r\n this.scheduleSendDetails = new ScheduleSendDetailsModel();\r\n }\r\n\r\n static isValid(model: IReviewAndPayWhenToSendStepModel): boolean {\r\n if (model.sendLater && !ScheduleSendDetailsModel.validateModel(model.scheduleSendDetails)) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}","export enum BuyGiftCardStateEnum {\r\n CHOOSE_CARD_DETAILS =\"CHOOSE_CARD_DETAILS\",\r\n CHOOSE_RECIPIENTS = \"CHOOSE_RECIPIENTS\",\r\n CHOOSE_SENDER = \"CHOOSE_SENDER\",\r\n\r\n CUSTOMISE_CARD = \"CUSTOMISE_CARD\",\r\n CUSTOMISE_MAIL = \"CUSTOMISE_MAIL\",\r\n\r\n REVIEW_PAY_REVIEW = \"REVIEW_PAY_REVIEW\", \r\n REVIEW_PAY_SENDER_INFO = \"REVIEW_PAY_SENDER_INFO\", \r\n REVIEW_PAY_WHEN_TO_SEND = \"REVIEW_PAY_WHEN_TO_SEND\", \r\n REVIEW_PAY_PAYMENT = \"REVIEW_PAY_PAYMENT\", \r\n}","export enum BuyGiftCardSubpageEnum {\r\n CHOOSE_CARD = \"CHOOSE_CARD\",\r\n CUSTOMISE_CARD = \"CUSTOMISE_CARD\",\r\n REVIEW_PAY = \"REVIEW_PAY\",\r\n}","export enum GiftCardSendTypeEnum {\r\n BY_EMAIL = \"BY_EMAIL\",\r\n BY_SMS = \"BY_SMS\",\r\n BY_PDF = \"BY_PDF\"\r\n}","export enum PaymentTypeEnum {\r\n CREDIT_CARD=\"CREDIT_CARD\",\r\n //GOOGLE_PAY =\"GOOGLE_PAY\",\r\n //APLLE_PAY =\"APLLE_PAY\",\r\n BANK = \"BANK\",\r\n NONE= \"NONE\"\r\n}","export enum RegiftCardStateEnum {\r\n CHECK_BALANCE =\"CHECK_BALANCE\",\r\n REGIFT_CARD =\"REGIFT_CARD\",\r\n ENTER_RECEPIENTS =\"ENTER_RECEPIENTS\",\r\n CUSTOMIZE_CARD=\"CUSTOMIZE_CARD\",\r\n REVIEW_PAY = \"REVIEW_PAY\" \r\n}","export enum WorkflowTypeEnum {\r\n BUY_GIFT_CARD = \"BUY_GIFT_CARD\",\r\n REGIFT_CARD = \"REGIFT_CARD\",\r\n ACTIVATE_GIFTCARD = \"ACTIVATE_GIFTCARD\"\r\n}","import React, { useContext, useEffect, useState } from \"react\";\r\nimport ActivateGiftCardForm from \"../components/giftCard/activate-giftcard/ActivateGiftCardForm\";\r\nimport LoadGiftCardForm from \"../components/giftCard/activate-giftcard/LoadGiftCardForm\";\r\nimport StepsProgressBar from \"../components/giftCard/shared/StepsProgressBar\";\r\nimport { AppSettingContext } from \"../components/Application\";\r\nimport DataService from \"../services/DataService.service\";\r\nimport * as GlobalConstants from \"../constants/global\";\r\nimport { IActivateBasketFullModel } from \"../models/ActivateGiftCard.model\";\r\nimport LoadingComponent from \"../components/shared/LoadingComponent\";\r\nimport LoadAndPayForm from \"../components/giftCard/activate-giftcard/LoadAndPayForm\";\r\n\r\nconst ActivateGiftCardPage = () => {\r\n const { labels } = useContext(AppSettingContext);\r\n\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [currentStep, setCurrentStep] = useState(\"activate\");\r\n const [basketData, setBasketData] = useState();\r\n const [actNumber, setActNumber] = useState(\"\");\r\n\r\n useEffect(() => {\r\n setIsLoading(true);\r\n\r\n const checkBasketCache = async (basketId: string) => {\r\n const response = await DataService.getActivateGiftCardBasket(basketId);\r\n\r\n if (response && response.activationNo) {\r\n setActNumber(response.activationNo);\r\n }\r\n\r\n setBasketData(response);\r\n setIsLoading(false);\r\n };\r\n\r\n const basketId = localStorage.getItem(GlobalConstants.LOCALSTORAGE_KEY_ACTIVATE_BASKET_ID);\r\n if (basketId) {\r\n checkBasketCache(basketId);\r\n } else {\r\n setIsLoading(false);\r\n }\r\n }, []);\r\n\r\n const appElement = document.getElementById('app');\r\n const sideBarImgSrc = appElement?.getAttribute(\"data-sidebar-img-src\");\r\n const sideBarImgName = appElement?.getAttribute(\"data-sidebar-img-name\");\r\n\r\n return (\r\n <>\r\n {isLoading ? (\r\n \r\n ) : (\r\n <>\r\n
\r\n \r\n\r\n
\r\n
\r\n

{labels.get(\"GiftCard.App.ActivateLoadCard.Title\")}

\r\n\r\n {\r\n setCurrentStep(\"load\");\r\n\r\n if (basketData && basketData.activationNo !== actNumber) {\r\n setBasketData(null);\r\n DataService.clearBasketCache(basketData.basketId);\r\n }\r\n }}\r\n handleActNumberUpdate={(actNumber) => {\r\n setCurrentStep(\"activate\");\r\n setActNumber(actNumber);\r\n }}\r\n />\r\n\r\n setBasketData(basketData)}\r\n proceedToNextStep={() => setCurrentStep(\"pay\")}\r\n handleSetCurrentStep={() => setCurrentStep(\"load\")}\r\n />\r\n\r\n \r\n\r\n {currentStep === 'activate' && (\r\n <>\r\n
\r\n
{labels.get(\"GiftCard.App.ActivateLoadCard.Tips.HowToActivateQuestion\")}
\r\n

{labels.get(\"GiftCard.App.ActivateLoadCard.Tips.HowToActivateAnswer\")}

\r\n
\r\n \r\n )}\r\n
\r\n\r\n\r\n
\r\n {sideBarImgSrc && (\r\n <>\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n )}\r\n
\r\n
\r\n
\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default ActivateGiftCardPage;\r\n","import React, { createContext, useEffect, useRef, useState } from 'react';\r\nimport { AppSettingContext } from '../components/Application';\r\nimport GiftCardDetails from '../components/giftCard/GiftCardDetails';\r\nimport StepsProgressBar from '../components/giftCard/buy-giftcard/shared/StepsProgressBar';\r\nimport SummarySection from '../components/giftCard/buy-giftcard/shared/SummarySection';\r\nimport ChooseCardSubpage from '../components/giftCard/buy-giftcard/subpages/ChooseCardSubpage';\r\nimport CustomiseCardSubpage from '../components/giftCard/buy-giftcard/subpages/CustomiseCardSubpage';\r\nimport ReviewAndPaySubpage from '../components/giftCard/buy-giftcard/subpages/ReviewAndPaySubpage';\r\nimport ErrorComponent from '../components/shared/ErrorComponent';\r\nimport LoadingComponent from '../components/shared/LoadingComponent';\r\nimport * as GlobalConstants from \"../constants/global\";\r\nimport { findLinkByAlias } from '../helpers/GiftCardHelper';\r\nimport { isNullOrWhiteSpace } from '../helpers/Utils';\r\nimport { BuyGiftCardModel, IBuyGiftCardModel } from '../models/buy-giftcard/BuyGiftCard.model';\r\nimport { IChooseCardSubpageModel } from '../models/buy-giftcard/choose-card/ChooseCardSubpage.model';\r\nimport { IChooseCardStepModel } from '../models/buy-giftcard/choose-card/ChooseCardsStep.model';\r\nimport { IChooseRecipientsStepModel } from '../models/buy-giftcard/choose-card/ChooseRecipientsStep.model';\r\nimport { ICustomiseCardStepModel } from '../models/buy-giftcard/customise-card/CustomiseCardStep.model';\r\nimport { ICustomiseCardSubpageModel } from '../models/buy-giftcard/customise-card/CustomiseCardSubpage.model';\r\nimport { IReviewAndPaySenderInfoStepModel } from '../models/buy-giftcard/review-pay/ReviewAndPaySenderInfoStep.model';\r\nimport { IReviewAndPaySubpageModel } from '../models/buy-giftcard/review-pay/ReviewAndPaySubpage.model';\r\nimport { IReviewAndPayWhenToSendStepModel } from '../models/buy-giftcard/review-pay/ReviewAndPayWhenToSendStep.model';\r\nimport { BuyGiftCardStateEnum } from '../models/enums/BuyGiftCardStateEnum';\r\nimport { BuyGiftCardSubpageEnum } from '../models/enums/BuyGiftCardSubpageEnum';\r\nimport DataService from '../services/DataService.service';\r\nimport './BuyGiftCardPage.scss';\r\n\r\nexport const BuyGiftCardContext = createContext({} as BuyGiftCardModel);\r\n\r\nconst BuyGiftCardPageNew = () => {\r\n const { labels, links } = React.useContext(AppSettingContext);\r\n const firstRenderRef = useRef(true);\r\n const pageRef = useRef(null);\r\n\r\n const defaultPersonalMessageText = labels.get(\"GiftCard.App.Steps.Customise.PersonalMessage.DefaultText\");\r\n\r\n //#region STATE PROPERTIES\r\n\r\n const [pageModel, setPageModel] = useState({} as IBuyGiftCardModel);\r\n const [culture, setCulture] = useState('en-GB');\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [error, setError] = useState(null);\r\n const [previewData, setPreviewData] = useState({\r\n initialTemplateUrl: '',\r\n templateUrl: '',\r\n mediaUrl: '',\r\n personalMessage: ''\r\n });\r\n const [finalAvailableSubpage, setFinalAvailableSubpage] = useState(BuyGiftCardSubpageEnum.CHOOSE_CARD);\r\n const [stateBeforeQuantityChange, setStateBeforeQuantityChange] = useState({\r\n wasAhead: false,\r\n subpage: BuyGiftCardSubpageEnum.CHOOSE_CARD\r\n });\r\n const [hasToSaveBasket, setHasToSaveBasket] = useState(true);\r\n\r\n //#endregion\r\n\r\n //#region USE EFFECT HOOKS\r\n\r\n useEffect(() => {\r\n if (firstRenderRef.current) {\r\n firstRenderRef.current = false;\r\n\r\n setIsLoading(true);\r\n setCulture(document.documentElement.lang);\r\n const basketId = localStorage.getItem(GlobalConstants.LOCALSTORAGE_KEY_BASKET_ID) ?? \"\";\r\n\r\n DataService.getBuyGiftCardBasket(culture, basketId, true)\r\n .then(response => {\r\n if (response && response.id && response.id.trim()) {\r\n localStorage.setItem(GlobalConstants.LOCALSTORAGE_KEY_BASKET_ID, response.id);\r\n const model = BuyGiftCardModel.MapModel(response as IBuyGiftCardModel);\r\n\r\n if (model.currentState === BuyGiftCardStateEnum.REVIEW_PAY_PAYMENT) {\r\n setHasToSaveBasket(false);\r\n }\r\n\r\n if (model.customiseCardSubpage.customiseCard.giftCardUrl) {\r\n setPreviewData({\r\n ...previewData,\r\n initialTemplateUrl: model.customiseCardSubpage.customiseCard.giftCardUrl,\r\n mediaUrl: model.customiseCardSubpage.customiseMail.mediaUrl ?? \"\"\r\n });\r\n setPageModel(model);\r\n setFinalAvailableSubpage(model.currentSubpage);\r\n } else {\r\n DataService.getGiftCardsTemplates(culture)\r\n .then(response => {\r\n if (response) {\r\n if (response && response.length > 0) {\r\n model.customiseCardSubpage.customiseCard.giftCardUrl = response[0]?.imageUrl ?? \"\";\r\n\r\n setPreviewData({\r\n ...previewData,\r\n initialTemplateUrl: response[0]?.imageUrl ?? \"\"\r\n });\r\n setPageModel(model);\r\n }\r\n }\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n }\r\n } else {\r\n setError(\"API response is an invalid buy gift card model\");\r\n }\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (pageModel && pageModel.id && pageModel.id.trim()) {\r\n //console.log('PAGE MODEL:');\r\n //console.log(pageModel);\r\n\r\n if (!previewData.templateUrl) {\r\n setPreviewData({\r\n ...previewData,\r\n templateUrl: pageModel?.customiseCardSubpage?.customiseCard?.giftCardUrl ?? \"\"\r\n });\r\n }\r\n\r\n if (!previewData.mediaUrl) {\r\n setPreviewData({\r\n ...previewData,\r\n mediaUrl: pageModel?.customiseCardSubpage?.customiseMail?.mediaUrl ?? \"\"\r\n });\r\n }\r\n\r\n if (!previewData.personalMessage) {\r\n setPreviewData({\r\n ...previewData,\r\n personalMessage: pageModel?.customiseCardSubpage?.customiseMail?.personalMessage ?? \"\"\r\n });\r\n }\r\n\r\n setIsLoading(false);\r\n setTimeout(() => {\r\n setIsSaving(false);\r\n }, 500);\r\n }\r\n }, [pageModel]);\r\n\r\n useEffect(() => {\r\n // if active subpage changes, scroll to the top\r\n scrollToTop();\r\n }, [pageModel.currentSubpage]);\r\n\r\n useEffect(() => {\r\n if (hasToSaveBasket && finalAvailableSubpage === BuyGiftCardSubpageEnum.REVIEW_PAY) {\r\n // the user was on review and pay page, but returned to change something\r\n // he has to post basket to UvServices again, send him directly to the step which posts basket\r\n setPageModel({\r\n ...pageModel,\r\n currentState: BuyGiftCardStateEnum.REVIEW_PAY_WHEN_TO_SEND\r\n });\r\n }\r\n }, [hasToSaveBasket]);\r\n\r\n //#endregion\r\n\r\n //#region COMMON\r\n\r\n const scrollToTop = (): void => {\r\n const element = pageRef.current;\r\n if (element) {\r\n const topPosition = element.getBoundingClientRect().top + window.pageYOffset;\r\n const offset = 150; // how many pixels from the top to scroll to\r\n\r\n setTimeout(() => {\r\n window.scrollTo({\r\n top: topPosition - offset,\r\n behavior: 'smooth'\r\n });\r\n }, 200);\r\n }\r\n };\r\n\r\n const handleUpdateState = (newSubpage: BuyGiftCardSubpageEnum, newState: BuyGiftCardStateEnum): void => {\r\n setPageModel({\r\n ...pageModel,\r\n currentSubpage: newSubpage,\r\n currentState: newState\r\n });\r\n };\r\n\r\n const handleProgressBarSubpageChange = (newSubpage: BuyGiftCardSubpageEnum): void => {\r\n if (pageModel.currentSubpage === newSubpage) {\r\n return;\r\n }\r\n\r\n handleUpdateState(newSubpage, pageModel.currentState);\r\n };\r\n\r\n const handleError = (message: string): void => {\r\n setError(message);\r\n };\r\n\r\n const postBasket = async (model: IBuyGiftCardModel): Promise => {\r\n if (model.customiseCardSubpage.customiseMail.personalMessage === defaultPersonalMessageText) {\r\n model.customiseCardSubpage.customiseMail.personalMessage = '';\r\n }\r\n\r\n const isUpdated = await DataService.updateBuyGiftCardBasket(culture, model.id, model, true)\r\n .then(response => {\r\n if (response && response.id && response.id.trim()) {\r\n //console.log(response);\r\n return true;\r\n }\r\n\r\n setError(\"Unable to do a post basket in UVServices\");\r\n return false;\r\n }).catch(error => {\r\n console.error(error);\r\n return false;\r\n });\r\n\r\n return isUpdated;\r\n };\r\n\r\n //#endregion\r\n\r\n //#region CHOOSE CARD SUBPAGE\r\n\r\n const handleCardDetailsChange = (model: IChooseCardStepModel): void => {\r\n if (model.quantity !== pageModel.chooseCardSubpage.chooseCardDetails.quantity &&\r\n finalAvailableSubpage !== BuyGiftCardSubpageEnum.CHOOSE_CARD\r\n ) {\r\n // the user was ahead in the process, but returned to change the cards quantity\r\n // meaning he also has to change details in recipients step\r\n setStateBeforeQuantityChange({\r\n wasAhead: true,\r\n subpage: finalAvailableSubpage\r\n });\r\n setFinalAvailableSubpage(BuyGiftCardSubpageEnum.CHOOSE_CARD);\r\n }\r\n\r\n if (!hasToSaveBasket) {\r\n // basket has to be posted to UvServices again\r\n setHasToSaveBasket(true);\r\n }\r\n\r\n setPageModel({\r\n ...pageModel,\r\n currentState: BuyGiftCardStateEnum.CHOOSE_RECIPIENTS,\r\n chooseCardSubpage: {\r\n ...pageModel.chooseCardSubpage,\r\n chooseCardDetails: model\r\n }\r\n });\r\n };\r\n\r\n const handleRecipientsChange = (model: IChooseRecipientsStepModel): void => {\r\n if (stateBeforeQuantityChange.wasAhead) {\r\n // if the user was ahead and returned to change cards quantity and recipients details\r\n // change subpage in progress bar to be the last step he was on\r\n setFinalAvailableSubpage(stateBeforeQuantityChange.subpage);\r\n setStateBeforeQuantityChange({\r\n wasAhead: false,\r\n subpage: BuyGiftCardSubpageEnum.CHOOSE_CARD\r\n });\r\n }\r\n\r\n if (!hasToSaveBasket) {\r\n // basket has to be posted to UvServices again\r\n setHasToSaveBasket(true);\r\n }\r\n\r\n setPageModel({\r\n ...pageModel,\r\n currentState: BuyGiftCardStateEnum.CHOOSE_SENDER,\r\n chooseCardSubpage: {\r\n ...pageModel.chooseCardSubpage,\r\n chooseRecipients: model\r\n }\r\n });\r\n };\r\n\r\n const handleChooseCardSubpageSubmit = async (model: IChooseCardSubpageModel): Promise => {\r\n const updatedPageModel = {\r\n ...pageModel,\r\n currentSubpage: BuyGiftCardSubpageEnum.CUSTOMISE_CARD,\r\n currentState: BuyGiftCardStateEnum.CUSTOMISE_CARD,\r\n chooseCardSubpage: model\r\n };\r\n\r\n if (!hasToSaveBasket) {\r\n // basket has to be posted to UvServices again\r\n setHasToSaveBasket(true);\r\n }\r\n\r\n setPageModel(updatedPageModel);\r\n\r\n // change subpage in progress bar\r\n if (finalAvailableSubpage === BuyGiftCardSubpageEnum.CHOOSE_CARD) {\r\n setFinalAvailableSubpage(BuyGiftCardSubpageEnum.CUSTOMISE_CARD);\r\n }\r\n\r\n await DataService.updateBuyGiftCardModelCache(updatedPageModel, culture);\r\n };\r\n\r\n //#endregion\r\n\r\n //#region CUSTOMISE CARD SUBPAGE\r\n\r\n const handleTemplateChange = (model: ICustomiseCardStepModel, isSubmit: boolean): void => {\r\n if (isSubmit && !hasToSaveBasket) {\r\n // basket has to be posted to UvServices again\r\n setHasToSaveBasket(true);\r\n }\r\n\r\n setPageModel({\r\n ...pageModel,\r\n currentState: isSubmit ? BuyGiftCardStateEnum.CUSTOMISE_MAIL : BuyGiftCardStateEnum.CUSTOMISE_CARD,\r\n customiseCardSubpage: {\r\n ...pageModel.customiseCardSubpage,\r\n customiseCard: model\r\n }\r\n });\r\n\r\n setPreviewData({\r\n ...previewData,\r\n templateUrl: model.giftCardUrl\r\n });\r\n };\r\n\r\n const handlePersonalMessageChange = (personalMessage: string): void => {\r\n setPageModel({\r\n ...pageModel,\r\n customiseCardSubpage: {\r\n ...pageModel.customiseCardSubpage,\r\n customiseMail: {\r\n ...pageModel.customiseCardSubpage.customiseMail,\r\n personalMessage: personalMessage\r\n }\r\n }\r\n });\r\n\r\n setPreviewData({\r\n ...previewData,\r\n personalMessage: personalMessage\r\n });\r\n };\r\n\r\n const handleMediaChange = (mediaUrl: string): void => {\r\n setPageModel({\r\n ...pageModel,\r\n customiseCardSubpage: {\r\n ...pageModel.customiseCardSubpage,\r\n customiseMail: {\r\n ...pageModel.customiseCardSubpage.customiseMail,\r\n mediaUrl: mediaUrl,\r\n addMedia: !isNullOrWhiteSpace(mediaUrl),\r\n useGif: isNullOrWhiteSpace(mediaUrl) || mediaUrl.includes(\"giphy.com\")\r\n }\r\n }\r\n });\r\n\r\n setPreviewData({\r\n ...previewData,\r\n mediaUrl: mediaUrl\r\n });\r\n };\r\n\r\n const handleCustomiseSubpageSubmit = async (model: ICustomiseCardSubpageModel): Promise => {\r\n const updatedPageModel = {\r\n ...pageModel,\r\n currentSubpage: BuyGiftCardSubpageEnum.REVIEW_PAY,\r\n currentState: BuyGiftCardStateEnum.REVIEW_PAY_SENDER_INFO,\r\n customiseCardSubpage: model\r\n };\r\n\r\n if (!hasToSaveBasket) {\r\n // basket has to be posted to UvServices again\r\n setHasToSaveBasket(true);\r\n }\r\n\r\n setPageModel(updatedPageModel);\r\n await DataService.updateBuyGiftCardModelCache(updatedPageModel, culture);\r\n\r\n // change subpage in progress bar\r\n setFinalAvailableSubpage(BuyGiftCardSubpageEnum.REVIEW_PAY);\r\n };\r\n\r\n //#endregion\r\n\r\n //#region REVIEW AND PAY SUBPAGE\r\n\r\n const handleReviewAndPaySenderInfoSubmit = (model: IReviewAndPaySenderInfoStepModel): void => {\r\n if (!hasToSaveBasket) {\r\n // basket has to be posted to UvServices again\r\n setHasToSaveBasket(true);\r\n }\r\n\r\n setPageModel({\r\n ...pageModel,\r\n currentState: BuyGiftCardStateEnum.REVIEW_PAY_WHEN_TO_SEND,\r\n reviewAndPaySubpage: {\r\n ...pageModel.reviewAndPaySubpage,\r\n reviewAndPaySenderInfo: model\r\n }\r\n });\r\n };\r\n\r\n const handleReviewAndPayWhenToSendSubmit = async (model: IReviewAndPayWhenToSendStepModel): Promise => {\r\n const updatedPageModel = {\r\n ...pageModel,\r\n currentState: BuyGiftCardStateEnum.REVIEW_PAY_PAYMENT,\r\n reviewAndPaySubpage: {\r\n ...pageModel.reviewAndPaySubpage,\r\n reviewAndPayWhenToSend: model\r\n }\r\n };\r\n\r\n setIsSaving(true);\r\n\r\n // post basket to UvServices; if it's successful, allow the user to continue\r\n const isUpdated = await postBasket(updatedPageModel);\r\n if (isUpdated) {\r\n setPageModel(updatedPageModel);\r\n await DataService.updateBuyGiftCardModelCache(updatedPageModel, culture);\r\n\r\n setHasToSaveBasket(false);\r\n }\r\n };\r\n\r\n const handleReviewAndPaySubpageSubmit = (model: IReviewAndPaySubpageModel): void => {\r\n setIsLoading(true);\r\n\r\n const copyModel = Object.assign({}, pageModel);\r\n copyModel.reviewAndPaySubpage = model;\r\n\r\n if (copyModel.customiseCardSubpage.customiseMail.personalMessage === defaultPersonalMessageText) {\r\n copyModel.customiseCardSubpage.customiseMail.personalMessage = '';\r\n }\r\n\r\n DataService.checkoutBuyGiftCard(culture, copyModel.id, copyModel, true)\r\n .then(response => {\r\n if (response && response.id && response.id.trim()) {\r\n localStorage.removeItem(GlobalConstants.LOCALSTORAGE_KEY_BASKET_ID);\r\n const pageLink = findLinkByAlias(GlobalConstants.PAGE_LINKS.BUY_GIFT_CARD_CONFIRMATION, links);\r\n\r\n if (pageLink && pageLink.url.trim()) {\r\n const queryString = {\r\n bid: copyModel.id\r\n };\r\n\r\n const url = pageLink.url + \"?\" + new URLSearchParams(queryString).toString();\r\n window.location.replace(url); //redirect to confirmation page\r\n }\r\n\r\n setTimeout(() => {\r\n setIsLoading(false);\r\n }, 5000);\r\n } else {\r\n handleError(\"Unable to checkout\");\r\n setIsLoading(false);\r\n }\r\n }).catch(err => {\r\n console.error(err)\r\n setIsLoading(false);\r\n });\r\n };\r\n\r\n //#endregion\r\n\r\n return (\r\n <>\r\n {error ? (\r\n \r\n ) : (\r\n <>\r\n {isLoading ? (\r\n \r\n ) : (\r\n \r\n
\r\n \r\n\r\n
\r\n
\r\n {pageModel.currentSubpage === BuyGiftCardSubpageEnum.CHOOSE_CARD &&\r\n \r\n }\r\n\r\n {pageModel.currentSubpage === BuyGiftCardSubpageEnum.CUSTOMISE_CARD &&\r\n \r\n }\r\n\r\n {pageModel.currentSubpage === BuyGiftCardSubpageEnum.REVIEW_PAY &&\r\n pageModel}\r\n handleError={handleError}\r\n handleStateChange={handleUpdateState}\r\n handleSenderInfoSubmit={handleReviewAndPaySenderInfoSubmit}\r\n handleWhenToSendSubmit={handleReviewAndPayWhenToSendSubmit}\r\n handleSubpageSubmit={handleReviewAndPaySubpageSubmit}\r\n />\r\n }\r\n
\r\n\r\n
\r\n \r\n\r\n \r\n
\r\n
\r\n
\r\n
\r\n )}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default BuyGiftCardPageNew;","import React, { useEffect, useRef, useState } from \"react\";\r\nimport { AppSettingContext } from '../components/Application';\r\nimport CheckMyBalanceStep from '../components/giftCard/CheckMyBalanceStep';\r\nimport GiftCardDetails from '../components/giftCard/GiftCardDetails';\r\nimport RegiftCardCustomizeStep from '../components/giftCard/RegiftCardCustomizeStep';\r\nimport RegiftCardPaymentStep from '../components/giftCard/RegiftCardPaymentStep';\r\nimport RegiftCardRecipientsStep from '../components/giftCard/RegiftCardRecipientsStep';\r\nimport RegiftCardStep from '../components/giftCard/RegiftCardStep';\r\nimport DebugRegiftDataPreivewComponent from '../components/giftCard/debug-mode/DebugRegiftDataPreivewComponent';\r\nimport ErrorComponent from '../components/shared/ErrorComponent';\r\nimport LoadingComponent from '../components/shared/LoadingComponent';\r\nimport * as GlobalConstants from \"../constants/global\";\r\nimport { fixPreviewDetails, resetRecipientsCountOnRecipientStep } from '../helpers/GiftCardHelper';\r\nimport { ICheckBalanceStep } from '../models/CheckBalanceStep.model';\r\nimport { ICustomizeStep } from '../models/CustomizeStep.model';\r\nimport { IRecipientsStep } from '../models/RecipientsStep.model';\r\nimport { IRegiftCard, RegiftCardModel } from '../models/RegiftCard.model';\r\nimport { IRegiftCardStep } from '../models/RegiftCardStep.model';\r\nimport { RegiftCardStateEnum } from '../models/enums/RegiftCardStateEnum';\r\nimport DataService from '../services/DataService.service';\r\nimport './RegiftCardPage.scss';\r\n\r\n\r\n// Global context of Buy Gift card step\r\nexport const RegiftCardContext = React.createContext({} as RegiftCardModel);\r\n\r\nconst RegiftCardPage = () => {\r\n const ref = useRef(true);\r\n const { debugMode, labels, cardSettings } = React.useContext(AppSettingContext);\r\n\r\n const [culture, setCulture] = useState('en-GB');\r\n const [pageModel, setPageModel] = useState({} as IRegiftCard);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [hasRequestToSaveBasket, setRequestHasToSaveBasket] = useState(false);\r\n const [error, setError] = useState(null);\r\n\r\n const [previewTemplateUrl, setPreviewTemplateUrl] = useState(\"\");\r\n const [previewMediaUrl, setPreviewMediaUrl] = useState(\"\");\r\n const [previewPersonalMessage, setPreviewPersonalMessage] = useState(\"\");\r\n const [hasToShowPreviewBox, setHasToShowPreviewBox] = useState(false);\r\n const [previewRegiftData, setPreviewRegiftData] = useState();\r\n\r\n const [firstTemplateUrl, setFirstTemplateUrl] = useState(\"\");\r\n const defaultPersonalMessageText = labels.get(\"GiftCard.App.Steps.Customise.PersonalMessage.DefaultText\");\r\n\r\n // INIT\r\n useEffect(() => {\r\n const firstRender = ref.current;\r\n if (firstRender) {\r\n ref.current = false;\r\n //console.debug(\"INIT (RegiftCardPage)\");\r\n setIsLoading(true);\r\n setCulture(document.documentElement.lang);\r\n\r\n // Get basket-id from local storage\r\n let baskedId = localStorage.getItem(GlobalConstants.LOCALSTORAGE_KEY_BASKET_ID);\r\n if (!baskedId) baskedId = \"\";\r\n //\r\n DataService.getRegiftCardBasket(culture, baskedId)\r\n .then(response => {\r\n if (response && response.id && response.id.trim()) {\r\n //Set basket-id back to local storage\r\n localStorage.setItem(GlobalConstants.LOCALSTORAGE_KEY_BASKET_ID, response.id);\r\n\r\n const model = RegiftCardModel.MapModel(response);\r\n\r\n if (model && model.customizeStep) {\r\n if (model.customizeStep.giftCardUrl && model.customizeStep.giftCardUrl.trim()) {\r\n setFirstTemplateUrl(model.customizeStep.giftCardUrl);\r\n }\r\n\r\n if (model.customizeStep.personalMessage && model.customizeStep.personalMessage.trim()) {\r\n setPreviewPersonalMessage(model.customizeStep.personalMessage);\r\n } else {\r\n model.customizeStep.personalMessage = \"\";\r\n }\r\n\r\n if (model.customizeStep.mediaUrl && model.customizeStep.mediaUrl.trim()) {\r\n setPreviewMediaUrl(model.customizeStep.mediaUrl);\r\n }\r\n }\r\n\r\n setPageModel(model);\r\n } else {\r\n setError(\"Api response is an invalid gift card model\")\r\n }\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n\r\n // Initialize state to store custom uploaded Templates and Medias\r\n // Load all templates; Then use first one as default selection when use save first step\r\n DataService.getGiftCardsTemplates(culture)\r\n .then(response => {\r\n if (response) {\r\n if (response && response.length > 0) {\r\n setFirstTemplateUrl(response[0].imageUrl);\r\n }\r\n }\r\n }).catch(error => {\r\n console.error(error);\r\n });\r\n }\r\n }, []);\r\n // *****\r\n\r\n useEffect(() => {\r\n if (pageModel.id && pageModel.id.trim()) {\r\n setIsLoading(false);\r\n setTimeout(() => {\r\n setIsSaving(false);\r\n }, 500);\r\n }\r\n }, [pageModel]);\r\n\r\n const handleUpdateState = (newState: RegiftCardStateEnum): void => {\r\n const pageModelCopy = Object.assign({}, pageModel);\r\n pageModelCopy.currentState = newState;\r\n setPageModel(pageModelCopy);\r\n };\r\n\r\n const handleModelState = (isDirty: boolean, step: RegiftCardStateEnum): void => {\r\n const pageModelCopy = Object.assign({}, pageModel);\r\n\r\n switch (step) {\r\n case RegiftCardStateEnum.CHECK_BALANCE:\r\n pageModelCopy.checkBalanceStep.isDirty = isDirty;\r\n break;\r\n case RegiftCardStateEnum.REGIFT_CARD:\r\n pageModelCopy.regiftCardStep.isDirty = isDirty;\r\n break;\r\n case RegiftCardStateEnum.ENTER_RECEPIENTS:\r\n pageModelCopy.recipientsStep.isDirty = isDirty;\r\n break;\r\n case RegiftCardStateEnum.CUSTOMIZE_CARD:\r\n pageModelCopy.customizeStep.isDirty = isDirty;\r\n break;\r\n case RegiftCardStateEnum.REVIEW_PAY:\r\n pageModelCopy.paymentStep.isDirty = isDirty;\r\n break;\r\n default: break;\r\n }\r\n\r\n setPageModel(pageModelCopy);\r\n };\r\n\r\n // ***\r\n // Check Balance Step\r\n const handleCheckBalanceSubmit = (model: ICheckBalanceStep): void => {\r\n\r\n if (model) {\r\n setIsSaving(true);\r\n const pageModelCopy = Object.assign({}, pageModel);\r\n\r\n pageModelCopy.checkBalanceStep.isDirty = false;\r\n pageModelCopy.checkBalanceStep.redeemCode = model.redeemCode;\r\n pageModelCopy.checkBalanceStep.giftCardCode = model.giftCardCode;\r\n pageModelCopy.checkBalanceStep.remainingBalance = model.remainingBalance;\r\n pageModelCopy.checkBalanceStep.currencySymbol = model.currencySymbol;\r\n\r\n // Update page state\r\n pageModelCopy.currentState = RegiftCardStateEnum.REGIFT_CARD;\r\n setPageModel(pageModelCopy);\r\n\r\n setPreviewRegiftData(null);\r\n }\r\n };\r\n\r\n // ***\r\n // Regift card Step\r\n const handleRegiftCardSubmit = (model: IRegiftCardStep): void => {\r\n if (model) {\r\n setIsSaving(true);\r\n\r\n const pageModelCopy = Object.assign({}, pageModel);\r\n\r\n pageModelCopy.regiftCardStep.isDirty = false;\r\n pageModelCopy.regiftCardStep.value = model.value;\r\n\r\n // Update Recipients\r\n //------------------------\r\n const responseModel = resetRecipientsCountOnRecipientStep(1, pageModelCopy.recipientsStep);\r\n pageModelCopy.recipientsStep.sendIndividually = responseModel.sendIndividually;\r\n pageModelCopy.recipientsStep.recipients = (responseModel as IRecipientsStep).recipients;\r\n\r\n // Customize\r\n if (!previewTemplateUrl.trim()) {\r\n setPreviewTemplateUrl(firstTemplateUrl);\r\n pageModelCopy.customizeStep.giftCardUrl = firstTemplateUrl;\r\n fixPreviewDetails();\r\n setRequestHasToSaveBasket(true);\r\n }\r\n\r\n // Update page state\r\n pageModelCopy.currentState = RegiftCardStateEnum.ENTER_RECEPIENTS;\r\n setPageModel(pageModelCopy);\r\n }\r\n }\r\n\r\n // ***\r\n // Recipients Step\r\n const handleRecipientsSubmit = (model: IRecipientsStep): void => {\r\n setIsSaving(true); //to refresh components\r\n\r\n //console.debug(\"handleRecipientsStepSubmit\", model);\r\n\r\n const pageModelCopy = Object.assign({}, pageModel);\r\n pageModelCopy.recipientsStep.isDirty = false;\r\n\r\n pageModelCopy.recipientsStep.sendBy = model.sendBy;\r\n pageModelCopy.recipientsStep.senderSameAsRecipient = model.senderSameAsRecipient;\r\n pageModelCopy.recipientsStep.sendIndividually = model.sendIndividually;\r\n pageModelCopy.recipientsStep.sendItLater = model.sendItLater;\r\n\r\n pageModelCopy.recipientsStep.sender = Object.assign({}, model.sender);\r\n pageModelCopy.recipientsStep.scheduleSendDetails = Object.assign({}, model.scheduleSendDetails);\r\n\r\n pageModelCopy.recipientsStep.recipients = [];\r\n for (let i = 0; i < model.recipients.length; i++) {\r\n pageModelCopy.recipientsStep.recipients.push({\r\n firstName: model.recipients[i].firstName,\r\n firstNameIsValid: model.recipients[i].firstNameIsValid,\r\n lastName: model.recipients[i].lastName,\r\n lastNameIsValid: model.recipients[i].lastNameIsValid,\r\n email: model.recipients[i].email,\r\n emailIsValid: model.recipients[i].emailIsValid,\r\n phone: model.recipients[i].phone,\r\n });\r\n }\r\n\r\n pageModelCopy.currentState = RegiftCardStateEnum.CUSTOMIZE_CARD;\r\n setPageModel(pageModelCopy);\r\n }\r\n // ***\r\n // Customize Card Step\r\n const handleTemplateChange = (templateUrl: string): void => {\r\n\r\n setPreviewTemplateUrl(templateUrl);\r\n //Do not update pageModelCopy - do that on Save\r\n //just create a temp state variable and pass it to details component\r\n //same like gif\r\n }\r\n\r\n const handleMediaChange = (mediaUrl: string): void => {\r\n setPreviewMediaUrl(mediaUrl);\r\n }\r\n\r\n const handlePreview = (draftPersonalMessage: string | null): void => {\r\n\r\n setPreviewPersonalMessage(\"\");//clear draft message, so the preview box should show ICustomizeStep based one\r\n if (draftPersonalMessage && draftPersonalMessage.trim()) {\r\n //set draft message only if passes\r\n setPreviewPersonalMessage(draftPersonalMessage);\r\n }\r\n\r\n setHasToShowPreviewBox(true);\r\n };\r\n\r\n const handleCustomizeSubmit = (model: ICustomizeStep): void => {\r\n if (model) {\r\n setIsSaving(true); //to refresh components\r\n\r\n // Update Page Model\r\n const pageModelCopy = Object.assign({}, pageModel);\r\n pageModelCopy.customizeStep.isDirty = false;\r\n pageModelCopy.customizeStep.giftCardUrl = model.giftCardUrl;\r\n pageModelCopy.customizeStep.mediaUrl = model.mediaUrl;\r\n pageModelCopy.customizeStep.personalMessage = model.personalMessage;\r\n\r\n setPreviewPersonalMessage(model.personalMessage);\r\n\r\n //Update BASKET CMS\r\n saveBasket(pageModelCopy);\r\n }\r\n }\r\n\r\n const saveBasket = (model: IRegiftCard): void => {\r\n if (!model) return;\r\n\r\n //Do not save default message\r\n if (model.customizeStep.personalMessage === defaultPersonalMessageText) {\r\n model.customizeStep.personalMessage = '';\r\n }\r\n\r\n DataService.updateRegiftCardBasket(culture, model.id, model)\r\n .then(response => {\r\n //console.debug(response);\r\n if (response && response.id && response.id.trim()) {\r\n\r\n //console.debug(\"updateBuyGiftCardBasket\", response);\r\n //debugger;\r\n\r\n setRequestHasToSaveBasket(false); //basket was updated\r\n setHasToShowPreviewBox(true);\r\n\r\n const model = RegiftCardModel.MapModel(response);\r\n model.currentState = RegiftCardStateEnum.REVIEW_PAY;\r\n setPageModel(model);\r\n\r\n } else {\r\n setError(\"Unable to update basket\")\r\n }\r\n })\r\n .catch(console.error)\r\n .finally(() => {\r\n //\r\n });\r\n }\r\n\r\n return (\r\n <>\r\n {error ? (\r\n \r\n ) : (\r\n \r\n {isLoading &&\r\n \r\n }\r\n {(!isLoading) &&\r\n
\r\n
\r\n
\r\n handleModelState(isDirty, RegiftCardStateEnum.CHECK_BALANCE)}\r\n handleBeginEdit={() => handleUpdateState(RegiftCardStateEnum.CHECK_BALANCE)}\r\n handleCheckBalance={setPreviewRegiftData}\r\n handleSubmit={handleCheckBalanceSubmit}\r\n />\r\n\r\n handleModelState(isDirty, RegiftCardStateEnum.REGIFT_CARD)}\r\n handleBeginEdit={() => handleUpdateState(RegiftCardStateEnum.REGIFT_CARD)}\r\n handleSubmit={(model) => handleRegiftCardSubmit(model)} />\r\n\r\n handleModelState(isDirty, RegiftCardStateEnum.ENTER_RECEPIENTS)}\r\n handleBeginEdit={() => handleUpdateState(RegiftCardStateEnum.ENTER_RECEPIENTS)}\r\n handleSubmit={(model) => handleRecipientsSubmit(model)} />\r\n\r\n handleUpdateState(RegiftCardStateEnum.CUSTOMIZE_CARD)}\r\n handleDirtyState={(isDirty) => handleModelState(isDirty, RegiftCardStateEnum.CUSTOMIZE_CARD)}\r\n handleTemplateChange={handleTemplateChange}\r\n handleMediaChange={handleMediaChange}\r\n handleSubmit={(model) => handleCustomizeSubmit(model)}\r\n handlePreview={handlePreview} />\r\n\r\n handleModelState(isDirty, RegiftCardStateEnum.REVIEW_PAY)}\r\n handleBeginEdit={() => handleUpdateState(RegiftCardStateEnum.REVIEW_PAY)}\r\n //handleSubmit={handlePaymentSubmit}\r\n handlePreview={() => handlePreview(null)}\r\n handleError={(message) => setError(message)}\r\n />\r\n\r\n
\r\n\r\n
\r\n \r\n\r\n {debugMode && }\r\n
\r\n
\r\n\r\n {/**/}\r\n
\r\n }\r\n
\r\n )}\r\n \r\n );\r\n};\r\nexport default RegiftCardPage;\r\n","import * as GlobalConstants from \"../constants/global\";\r\nimport { IActivateBasketFullModel } from \"../models/ActivateGiftCard.model\";\r\nimport { AssetUpload } from \"../models/AssetUpload.type\";\r\nimport { BuyGiftCardModelOld, IBuyGiftCardOld } from \"../models/BuyGiftCard.model\";\r\nimport ICountry from \"../models/Country.interface\";\r\nimport { CheckoutBillingAddressData } from \"../models/ElavonCheckoutModels\";\r\nimport { IGiftCardCheckoutResult } from \"../models/GiftCardCheckoutResult.model\";\r\nimport IGiftCardGif from \"../models/GiftCardGif.model\";\r\nimport IGiftCardTemplate from \"../models/GiftCardTemplate.model\";\r\nimport { ICheckoutSessionData, IPaymentStep } from \"../models/PaymentStep.model\";\r\nimport { IRegiftCard, RegiftCardModel } from \"../models/RegiftCard.model\";\r\nimport IState from \"../models/State.interface\";\r\nimport { ICheckBalanceResponse } from \"../models/api/CheckBalanceResponse.model\";\r\nimport { BuyGiftCardModel as BuyGiftCardModelNew, IBuyGiftCardModel as IBuyGiftCardNew } from \"../models/buy-giftcard/BuyGiftCard.model\";\r\nimport { IAppSettings } from \"../models/interfaces/AppSettings.interface\";\r\nimport jsonCountriesData from \"./static-data/countries.json\";\r\nimport jsonGifsData from \"./static-data/gift-card-gifs.json\";\r\nimport jsonTemplatesData from \"./static-data/gift-card-templates.data.json\";\r\nimport jsonUSAStatesData from \"./static-data/usa-states.json\";\r\n\r\nconst API_URL = GlobalConstants.API_URL;\r\nconst useStaticJson = false;\r\n\r\n//#region TEMPLATES & MEDIAS\r\n\r\nconst getGiftCardsTemplates = async (culture: string): Promise> => {\r\n try {\r\n if (useStaticJson) {\r\n return jsonTemplatesData;\r\n } else {\r\n //GET \r\n const response = await fetch(API_URL + `giftCards/${culture}`);\r\n if (response.ok) return response.json();\r\n }\r\n\r\n\r\n } catch {\r\n console.error(\"Cannot get gift card templates!\");\r\n return null;\r\n }\r\n};\r\n\r\nconst getGiftCardsGifsTemplates = async (culture: string, searchTerm: string): Promise> => {\r\n try {\r\n if (useStaticJson) {\r\n return jsonGifsData;\r\n } else {\r\n //GET\r\n const queryString = {\r\n s: searchTerm\r\n };\r\n\r\n const response = await fetch(API_URL + `gif/search?${new URLSearchParams(queryString).toString()}`);\r\n if (response.ok) return response.json();\r\n }\r\n } catch {\r\n console.error(\"Cannot get Gifs templates!\");\r\n return null;\r\n }\r\n};\r\n\r\nconst uploadGiftCardTemplate = async (culture: string, basketId: string, formData: FormData): Promise => {\r\n try {\r\n const uploadAssetUrl = API_URL + `assets/template/${culture}/${basketId}`;\r\n\r\n const requestOptions = {\r\n method: 'POST',\r\n body: formData\r\n };\r\n\r\n const response = await fetch(uploadAssetUrl, requestOptions);\r\n if (!response.ok) {\r\n throw Error(response.status.toString());\r\n }\r\n\r\n return await response.json();\r\n } catch {\r\n console.error(\"An error occurred while uploading gift card template!\");\r\n return null;\r\n }\r\n};\r\n\r\nconst uploadGiftCardMedia = async (culture: string, basketId: string, formData: FormData): Promise => {\r\n try {\r\n const uploadAssetUrl = API_URL + `assets/media/${culture}/${basketId}`;\r\n\r\n const requestOptions = {\r\n method: 'POST',\r\n body: formData\r\n };\r\n\r\n const response = await fetch(uploadAssetUrl, requestOptions);\r\n if (!response.ok) {\r\n throw Error(response.status.toString());\r\n }\r\n\r\n return await response.json();\r\n } catch {\r\n return null;\r\n }\r\n};\r\n\r\n//#endregion\r\n\r\n//#region BUY GIFTCARD\r\n\r\nconst getBuyGiftCardBasket = async (culture: string, basketId: string, isUsingNewDesign: boolean): Promise => {\r\n try {\r\n //GET\r\n const response = await fetch(API_URL + `buy/basket/${culture}/${basketId}?isUsingNewDesign=${isUsingNewDesign}`);\r\n\r\n if (response.ok) {\r\n const resObj = await response.json();\r\n return resObj;\r\n }\r\n } catch {\r\n console.error(\"Cannot initialize buy giftcard basket!\");\r\n return null;\r\n }\r\n};\r\n\r\nconst updateBuyGiftCardBasket = async (culture: string, basketId: string, model: BuyGiftCardModelOld | BuyGiftCardModelNew, isUsingNewDesign: boolean): Promise => {\r\n if (!model) {\r\n return Promise.resolve(null);\r\n }\r\n\r\n try {\r\n let apiUrl = API_URL + `buy/post-basket/${culture}`;\r\n if (!isUsingNewDesign) {\r\n apiUrl = API_URL + `buy/basket/${culture}/${basketId}`;\r\n }\r\n\r\n const requestOptions = {\r\n method: 'POST',\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(model),\r\n };\r\n\r\n const response = await fetch(apiUrl, requestOptions);\r\n if (!response.ok) {\r\n throw Error(response.status.toString());\r\n }\r\n\r\n return await response.json();\r\n } catch {\r\n console.error(\"An error occurred while updating basket!\");\r\n return Promise.resolve(null);\r\n }\r\n};\r\n\r\nconst checkoutBuyGiftCard = async (culture: string, basketId: string, model: BuyGiftCardModelOld | BuyGiftCardModelNew, isUsingNewDesign: boolean): Promise => {\r\n if (!model) {\r\n return Promise.resolve(null);\r\n }\r\n\r\n try {\r\n let apiUrl = API_URL + `buy/checkout-new/${culture}`;\r\n\r\n if (!isUsingNewDesign) {\r\n apiUrl = API_URL + `buy/checkout/${culture}/${basketId}`;\r\n }\r\n\r\n const requestOptions = {\r\n method: 'POST',\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(model),\r\n };\r\n\r\n const response = await fetch(apiUrl, requestOptions);\r\n if (!response.ok) {\r\n throw Error(response.status.toString());\r\n }\r\n\r\n return await response.json();\r\n } catch {\r\n return Promise.resolve(null);\r\n }\r\n};\r\n\r\nconst getCheckoutData = async (basketId: string, amount: number, currency: string): Promise => {\r\n try {\r\n const apiUrl = API_URL + `create-creditcard-checkout?bid=${basketId}&amount=${amount}&curr=${currency}`;\r\n const response = await fetch(apiUrl);\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n\r\n const errorMsg = await response.text();\r\n console.error(`Unable to get checkout session key. ${errorMsg}`);\r\n\r\n return null;\r\n } catch (err) {\r\n console.error(\"Unhandled exception was thrown while retrieving the checkout data\");\r\n return null;\r\n }\r\n};\r\n\r\n//#endregion\r\n\r\n//#region REGIFT CARD\r\n\r\nconst checkCardBalance = async (culture: string, basketId: string, cardCode: string, recaptchaToken: string): Promise => {\r\n try {\r\n //POST\r\n const requestOptions = {\r\n method: 'POST',\r\n headers: {\r\n 'Accept': 'application/json',\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify({\r\n cardCode: cardCode,\r\n recaptchaToken: recaptchaToken\r\n })\r\n };\r\n\r\n const response = await fetch(API_URL + `regift/balance/${culture}/${basketId}`, requestOptions);\r\n\r\n if (response.ok) {\r\n return response.json();\r\n } else if (response.status === 401) {\r\n const resJson = await response.json();\r\n\r\n const defaultErrorMessage = \"ReCaptcha verification failed.\";\r\n let errMsg = defaultErrorMessage;\r\n\r\n if (resJson && resJson.errorMessage) {\r\n errMsg = resJson.errorMessage;\r\n }\r\n\r\n console.error(errMsg);\r\n return defaultErrorMessage;\r\n }\r\n\r\n return null as ICheckBalanceResponse;\r\n } catch {\r\n console.error(\"Cannot check card balance\");\r\n return null as ICheckBalanceResponse;\r\n }\r\n};\r\n\r\nconst getRegiftCardBasket = async (culture: string, basketId: string): Promise => {\r\n try {\r\n //GET \r\n const response = await fetch(API_URL + `regift/basket/${culture}/${basketId}`);\r\n if (response.ok) {\r\n return response.json();\r\n }\r\n } catch {\r\n console.error(\"Cannot get regift card basket!\");\r\n return null;\r\n }\r\n};\r\n\r\nconst updateRegiftCardBasket = async (culture: string, basketId: string, model: RegiftCardModel): Promise => {\r\n if (!model) {\r\n return Promise.resolve(null);\r\n }\r\n\r\n try {\r\n const apiUrl = API_URL + `regift/basket/${culture}/${basketId}`;\r\n const requestOptions = {\r\n method: 'POST',\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(model),\r\n };\r\n\r\n const response = await fetch(apiUrl, requestOptions);\r\n if (!response.ok) {\r\n throw Error(response.status.toString());\r\n }\r\n\r\n return await response.json();\r\n } catch {\r\n console.error(\"An error occurred while updating basket!\");\r\n return Promise.resolve(null);\r\n }\r\n};\r\n\r\nconst checkoutRegiftCard = async (culture: string, basketId: string, model: RegiftCardModel): Promise => {\r\n if (!model) {\r\n return Promise.resolve(null);\r\n }\r\n\r\n try {\r\n\r\n const apiUrl = API_URL + `regift/checkout/${culture}/${basketId}`;\r\n\r\n const requestOptions = {\r\n method: 'POST',\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(model),\r\n };\r\n\r\n const response = await fetch(apiUrl, requestOptions);\r\n if (!response.ok) {\r\n throw Error(response.status.toString());\r\n }\r\n\r\n return await response.json();\r\n } catch {\r\n console.error(\"An error occurred while checking out regift basket!\");\r\n return Promise.resolve(null);\r\n }\r\n};\r\n\r\n//#endregion\r\n\r\n//#region ACTIVATE GIFTCARD\r\n\r\nconst checkLuhnPattern = async (activationNumber: string): Promise => {\r\n try {\r\n const apiUrl = API_URL + `check-luhn-pattern?actNum=${activationNumber}`;\r\n const response = await fetch(apiUrl);\r\n const resJson = await response.json();\r\n\r\n return resJson.IsValid;\r\n } catch (err) {\r\n console.error(`The activation number does not have valid luhn pattern.\\r\\n${err}`);\r\n return false;\r\n }\r\n}\r\n\r\nconst checkGiftCardCode = async (activationNumber: string): Promise<{ status: string, message: string }> => {\r\n try {\r\n const apiUrl = API_URL + `check?actNum=${activationNumber}`;\r\n const response = await fetch(apiUrl);\r\n const resJson = await response.json();\r\n\r\n return {\r\n status: resJson.Status,\r\n message: resJson.Message\r\n };\r\n } catch (err) {\r\n console.error(`An error occurred while checking giftcard code.\\r\\n${err}`);\r\n\r\n return {\r\n status: \"error\",\r\n message: err\r\n };\r\n }\r\n};\r\n\r\nconst updateGiftCardBasket = async (activationNumber: string, loadAmount: string): Promise => {\r\n try {\r\n const apiUrl = API_URL + `update-basket`;\r\n const data = {\r\n activationCode: activationNumber,\r\n unitPrice: loadAmount\r\n };\r\n\r\n const response = await fetch(apiUrl, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\"\r\n },\r\n body: JSON.stringify(data)\r\n });\r\n\r\n const responseJson = await response.json();\r\n if (response.ok && responseJson) {\r\n localStorage.setItem(GlobalConstants.LOCALSTORAGE_KEY_ACTIVATE_BASKET_ID, responseJson.basketId);\r\n\r\n return {\r\n basketId: responseJson.basketId,\r\n activationNo: responseJson.activationCode,\r\n amountNoFees: responseJson.amountNoFees,\r\n fees: responseJson.fees,\r\n totalAmount: responseJson.totalAmount,\r\n firstName: responseJson.firstName ?? \"\",\r\n lastName: responseJson.lastName ?? \"\",\r\n email: responseJson.email ?? \"\",\r\n phone: responseJson.phone ?? \"\"\r\n };\r\n }\r\n\r\n console.error(responseJson);\r\n throw Error(responseJson?.message ?? \"Cannot process response from the API in DataService.\");\r\n } catch (err) {\r\n console.error(\"An error occurred while updating giftcard basket\");\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst saveActivateGiftCardBasket = async (model: IActivateBasketFullModel, clearBasketQueryString: string): Promise<{ status: string, message: string }> => {\r\n try {\r\n let apiUrl = API_URL + `activate-basket-cache`;\r\n let data = {};\r\n\r\n if (model) {\r\n data = {\r\n basketId: model.basketId,\r\n activationCode: model.activationNo,\r\n amountInfo: {\r\n amountNoFees: model.amountNoFees ?? 0,\r\n fees: model.fees ?? 0,\r\n totalAmount: model.totalAmount\r\n },\r\n billingDetails: {\r\n firstName: model.firstName,\r\n lastName: model.lastName,\r\n email: model.email,\r\n phone: model.phone ?? \"\"\r\n },\r\n };\r\n } else if (clearBasketQueryString) {\r\n apiUrl += clearBasketQueryString;\r\n }\r\n\r\n const response = await fetch(apiUrl, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\"\r\n },\r\n body: JSON.stringify(data)\r\n });\r\n\r\n const responseJson = await response.json();\r\n if (response.ok && responseJson) {\r\n return {\r\n status: \"ok\",\r\n message: \"\"\r\n };\r\n }\r\n\r\n console.error(\"Could not save basket in cache. API returned invalid response.\");\r\n console.error(responseJson.message);\r\n\r\n return {\r\n status: \"error\",\r\n message: responseJson.message\r\n };\r\n } catch (err) {\r\n console.error(\"An exception was thrown while saving giftcard basket in cache.\");\r\n console.error(err);\r\n\r\n return {\r\n status: \"error\",\r\n message: err\r\n };\r\n }\r\n};\r\n\r\nconst clearBasketCache = async (basketId: string): Promise<{ status: string, message: string }> => {\r\n const clearBasketQueryString = `?basketId=${basketId}&clearBasketCache=true`;\r\n return await saveActivateGiftCardBasket(null, clearBasketQueryString);\r\n};\r\n\r\nconst getActivateGiftCardBasket = async (basketId: string): Promise => {\r\n try {\r\n const apiUrl = `${API_URL}activate-basket-cache?basketId=${basketId}`;\r\n\r\n const response = await fetch(apiUrl);\r\n\r\n if (response.status === 404) {\r\n console.warn(\"Basket does not exist in cache.\");\r\n return null;\r\n }\r\n\r\n const responseJson = await response.json();\r\n\r\n if (response.ok && responseJson) {\r\n return {\r\n basketId: responseJson.basketId,\r\n activationNo: responseJson.activationCode,\r\n amountNoFees: responseJson.amountInfo.amountNoFees,\r\n fees: responseJson.amountInfo.fees,\r\n totalAmount: responseJson.amountInfo.totalAmount,\r\n firstName: responseJson.billingDetails.firstName,\r\n lastName: responseJson.billingDetails.lastName,\r\n email: responseJson.billingDetails.email,\r\n phone: responseJson.billingDetails.phone\r\n };\r\n }\r\n\r\n return null;\r\n } catch (err) {\r\n console.error(\"An exception was thrown while getting giftcard basket from cache.\");\r\n console.error(err);\r\n return null;\r\n }\r\n}\r\n\r\n//#endregion\r\n\r\n//#region COMMON\r\n\r\nconst getAppSettings = async (culture: string, settingsNodeId: string): Promise => {\r\n try {\r\n const response = await fetch(API_URL + `settings/${settingsNodeId}/${culture}`);\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n\r\n const errRes = await response.text();\r\n console.error(errRes);\r\n } catch {\r\n console.error(\"Cannot get app settings!\");\r\n return null;\r\n }\r\n};\r\n\r\nconst getCountries = async (culture: string): Promise> => {\r\n try {\r\n return jsonCountriesData;\r\n } catch {\r\n console.error(\"Cannot get countries!\");\r\n return null;\r\n }\r\n};\r\n\r\nconst getUSAStates = async (): Promise> => {\r\n try {\r\n return jsonUSAStatesData;\r\n } catch {\r\n console.error(\"Cannot get USA states!\");\r\n return null;\r\n }\r\n};\r\n\r\nconst getTotalProcessingKey = async (basketId: string, amount: number, currency: string, workflow: string): Promise => {\r\n try {\r\n const apiUrl = API_URL + `create-creditcard-checkout?bid=${basketId}&workflow=${workflow}`;\r\n const response = await fetch(apiUrl);\r\n\r\n const resText = await response.text();\r\n\r\n if (response.ok) {\r\n return resText;\r\n }\r\n\r\n throw Error(resText);\r\n } catch (err) {\r\n console.error(\"An error occurred while retrieving the totalProcessing checkoutId\");\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst updateBasketPaymentStepCache = async (culture: string, basketId: string, model: IPaymentStep): Promise => {\r\n if (!model) {\r\n return Promise.resolve(null);\r\n }\r\n\r\n try {\r\n const apiUrl = API_URL + `buy/basket-cache/${culture}/${basketId}`;\r\n\r\n const requestOptions = {\r\n method: 'POST',\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(model),\r\n };\r\n\r\n const response = await fetch(apiUrl, requestOptions);\r\n if (!response.ok) {\r\n throw Error(response.status.toString());\r\n }\r\n\r\n return await response.json();\r\n } catch {\r\n console.error(\"An error occurred while updating basket cache!\");\r\n Promise.resolve(null);\r\n }\r\n\r\n return Promise.resolve(null);\r\n};\r\n\r\nconst updateBuyGiftCardModelCache = async (model: IBuyGiftCardNew, culture: string): Promise => {\r\n if (!model) {\r\n return Promise.resolve(null);\r\n }\r\n\r\n try {\r\n const apiUrl = API_URL + `buy/save-model-cache/${culture}/${model.id}`;\r\n\r\n const response = await fetch(apiUrl, {\r\n method: 'POST',\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(model),\r\n });\r\n\r\n if (!response.ok) {\r\n throw Error(response.status.toString());\r\n }\r\n\r\n const resObj = await response.json();\r\n\r\n if (!resObj) {\r\n throw Error('Empty model returned');\r\n }\r\n\r\n //console.log(resObj);\r\n return resObj;\r\n } catch (err) {\r\n console.error(`An error occurred while updating BuyGiftCard model cache! ${err}`);\r\n Promise.resolve(null);\r\n }\r\n};\r\n\r\nconst submitCreditCardPayment = async (workflow: string, basketId: string, sessionKey: string, cardId: string, billingAddress: CheckoutBillingAddressData): Promise => {\r\n const ipResponse = await fetch('https://api.ipify.org?format=json');\r\n const ipData = await ipResponse.json();\r\n const notificationUrl = `${window.location.origin}/giftcard/v1/${workflow.toLowerCase()}/3d-secure/${basketId}`;\r\n\r\n const model = {\r\n basketId: basketId,\r\n merchantKey: sessionKey,\r\n cardIdentifier: cardId,\r\n notificationUrl: notificationUrl,\r\n billingAddress: billingAddress,\r\n browserInformation: {\r\n ipAddress: ipData.ip,\r\n acceptHeader: navigator.userAgent,\r\n javascriptEnabled: true,\r\n javaEnabled: navigator.javaEnabled(),\r\n language: navigator.language,\r\n colourDepth: getBrowserColorDepth(screen.colorDepth),\r\n screenHeight: screen.height,\r\n screenWidth: screen.width,\r\n timeZone: new Date().getTimezoneOffset(),\r\n userAgent: navigator.userAgent,\r\n challengeWindowSize: calculateChallengeWindowSize()\r\n }\r\n };\r\n\r\n try {\r\n const response = await fetch(`${API_URL}creditcard/checkout?workflow=${workflow}`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify(model)\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n } else if (response.status === 400) {\r\n const resJson = await response.json();\r\n console.error('CreditCardCheckout returned BadRequest');\r\n console.error(resJson);\r\n return resJson;\r\n } else {\r\n console.log('Error: ', response.status, response.statusText);\r\n }\r\n } catch (err) {\r\n console.error(\"An unhandled error was thrown while sending CreditCardCheckout request.\");\r\n console.error(err);\r\n }\r\n};\r\n\r\n//#endregion\r\n\r\n//#region PRIVATE HELPERS\r\nfunction calculateChallengeWindowSize() {\r\n const width = window.innerWidth;\r\n const height = window.innerHeight;\r\n let challengeWindowSize = '';\r\n\r\n if (width <= 250 && height <= 400) {\r\n challengeWindowSize = 'FullScreen';\r\n } else if (width <= 390 && height <= 400) {\r\n challengeWindowSize = 'Small';\r\n } else if (width <= 500 && height <= 600) {\r\n challengeWindowSize = 'Medium';\r\n } else if (width <= 600 && height <= 400) {\r\n challengeWindowSize = 'Large';\r\n } else {\r\n challengeWindowSize = 'ExtraLarge';\r\n }\r\n\r\n return challengeWindowSize;\r\n}\r\n\r\nfunction getBrowserColorDepth(colorDepth: number) {\r\n const allowedColorDepths = [1, 4, 8, 15, 16, 24, 32, 48];\r\n\r\n if (!allowedColorDepths.includes(colorDepth)) {\r\n for (let i = allowedColorDepths.length - 1; i >= 0; i--) {\r\n if (allowedColorDepths[i] <= colorDepth) {\r\n return allowedColorDepths[i];\r\n }\r\n }\r\n }\r\n\r\n return colorDepth;\r\n}\r\n\r\n//#endregion\r\n\r\nconst DataService = {\r\n getGiftCardsTemplates,\r\n getGiftCardsGifsTemplates,\r\n uploadGiftCardTemplate,\r\n uploadGiftCardMedia,\r\n\r\n getBuyGiftCardBasket,\r\n updateBuyGiftCardBasket,\r\n checkoutBuyGiftCard,\r\n getCheckoutData,\r\n\r\n checkCardBalance,\r\n getRegiftCardBasket,\r\n updateRegiftCardBasket,\r\n checkoutRegiftCard,\r\n\r\n checkLuhnPattern,\r\n checkGiftCardCode,\r\n updateGiftCardBasket,\r\n saveActivateGiftCardBasket,\r\n clearBasketCache,\r\n getActivateGiftCardBasket,\r\n\r\n getAppSettings,\r\n getCountries,\r\n getUSAStates,\r\n getTotalProcessingKey,\r\n updateBasketPaymentStepCache,\r\n updateBuyGiftCardModelCache,\r\n submitCreditCardPayment\r\n};\r\n\r\nexport default DataService;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\tif (cachedModule.error !== undefined) throw cachedModule.error;\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\ttry {\n\t\tvar execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };\n\t\t__webpack_require__.i.forEach(function(handler) { handler(execOptions); });\n\t\tmodule = execOptions.module;\n\t\texecOptions.factory.call(module.exports, module, module.exports, execOptions.require);\n\t} catch(e) {\n\t\tmodule.error = e;\n\t\tthrow e;\n\t}\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n// expose the module cache\n__webpack_require__.c = __webpack_module_cache__;\n\n// expose the module execution interceptor\n__webpack_require__.i = [];\n\n","var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","// This function allow to reference all chunks\n__webpack_require__.hu = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".\" + __webpack_require__.h() + \".hot-update.js\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = (chunkId) => {\n\t// return url for filenames based on template\n\treturn undefined;\n};","__webpack_require__.hmrF = () => (\"main.\" + __webpack_require__.h() + \".hot-update.json\");","__webpack_require__.h = () => (\"4cba7eb1e1b5eccd6ab8\")","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var inProgress = {};\nvar dataWebpackPrefix = \"OptionsCard:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = (url, done, key, chunkId) => {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = (prev, event) => {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach((fn) => (fn(event)));\n\t\tif(prev) return prev(event);\n\t}\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = (module) => {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","var currentModuleData = {};\nvar installedModules = __webpack_require__.c;\n\n// module and require creation\nvar currentChildModule;\nvar currentParents = [];\n\n// status\nvar registeredStatusHandlers = [];\nvar currentStatus = \"idle\";\n\n// while downloading\nvar blockingPromises = 0;\nvar blockingPromisesWaiting = [];\n\n// The update info\nvar currentUpdateApplyHandlers;\nvar queuedInvalidatedModules;\n\n// eslint-disable-next-line no-unused-vars\n__webpack_require__.hmrD = currentModuleData;\n\n__webpack_require__.i.push(function (options) {\n\tvar module = options.module;\n\tvar require = createRequire(options.require, options.id);\n\tmodule.hot = createModuleHotObject(options.id, module);\n\tmodule.parents = currentParents;\n\tmodule.children = [];\n\tcurrentParents = [];\n\toptions.require = require;\n});\n\n__webpack_require__.hmrC = {};\n__webpack_require__.hmrI = {};\n\nfunction createRequire(require, moduleId) {\n\tvar me = installedModules[moduleId];\n\tif (!me) return require;\n\tvar fn = function (request) {\n\t\tif (me.hot.active) {\n\t\t\tif (installedModules[request]) {\n\t\t\t\tvar parents = installedModules[request].parents;\n\t\t\t\tif (parents.indexOf(moduleId) === -1) {\n\t\t\t\t\tparents.push(moduleId);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcurrentParents = [moduleId];\n\t\t\t\tcurrentChildModule = request;\n\t\t\t}\n\t\t\tif (me.children.indexOf(request) === -1) {\n\t\t\t\tme.children.push(request);\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t\"[HMR] unexpected require(\" +\n\t\t\t\t\trequest +\n\t\t\t\t\t\") from disposed module \" +\n\t\t\t\t\tmoduleId\n\t\t\t);\n\t\t\tcurrentParents = [];\n\t\t}\n\t\treturn require(request);\n\t};\n\tvar createPropertyDescriptor = function (name) {\n\t\treturn {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: true,\n\t\t\tget: function () {\n\t\t\t\treturn require[name];\n\t\t\t},\n\t\t\tset: function (value) {\n\t\t\t\trequire[name] = value;\n\t\t\t}\n\t\t};\n\t};\n\tfor (var name in require) {\n\t\tif (Object.prototype.hasOwnProperty.call(require, name) && name !== \"e\") {\n\t\t\tObject.defineProperty(fn, name, createPropertyDescriptor(name));\n\t\t}\n\t}\n\tfn.e = function (chunkId) {\n\t\treturn trackBlockingPromise(require.e(chunkId));\n\t};\n\treturn fn;\n}\n\nfunction createModuleHotObject(moduleId, me) {\n\tvar _main = currentChildModule !== moduleId;\n\tvar hot = {\n\t\t// private stuff\n\t\t_acceptedDependencies: {},\n\t\t_acceptedErrorHandlers: {},\n\t\t_declinedDependencies: {},\n\t\t_selfAccepted: false,\n\t\t_selfDeclined: false,\n\t\t_selfInvalidated: false,\n\t\t_disposeHandlers: [],\n\t\t_main: _main,\n\t\t_requireSelf: function () {\n\t\t\tcurrentParents = me.parents.slice();\n\t\t\tcurrentChildModule = _main ? undefined : moduleId;\n\t\t\t__webpack_require__(moduleId);\n\t\t},\n\n\t\t// Module API\n\t\tactive: true,\n\t\taccept: function (dep, callback, errorHandler) {\n\t\t\tif (dep === undefined) hot._selfAccepted = true;\n\t\t\telse if (typeof dep === \"function\") hot._selfAccepted = dep;\n\t\t\telse if (typeof dep === \"object\" && dep !== null) {\n\t\t\t\tfor (var i = 0; i < dep.length; i++) {\n\t\t\t\t\thot._acceptedDependencies[dep[i]] = callback || function () {};\n\t\t\t\t\thot._acceptedErrorHandlers[dep[i]] = errorHandler;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\thot._acceptedDependencies[dep] = callback || function () {};\n\t\t\t\thot._acceptedErrorHandlers[dep] = errorHandler;\n\t\t\t}\n\t\t},\n\t\tdecline: function (dep) {\n\t\t\tif (dep === undefined) hot._selfDeclined = true;\n\t\t\telse if (typeof dep === \"object\" && dep !== null)\n\t\t\t\tfor (var i = 0; i < dep.length; i++)\n\t\t\t\t\thot._declinedDependencies[dep[i]] = true;\n\t\t\telse hot._declinedDependencies[dep] = true;\n\t\t},\n\t\tdispose: function (callback) {\n\t\t\thot._disposeHandlers.push(callback);\n\t\t},\n\t\taddDisposeHandler: function (callback) {\n\t\t\thot._disposeHandlers.push(callback);\n\t\t},\n\t\tremoveDisposeHandler: function (callback) {\n\t\t\tvar idx = hot._disposeHandlers.indexOf(callback);\n\t\t\tif (idx >= 0) hot._disposeHandlers.splice(idx, 1);\n\t\t},\n\t\tinvalidate: function () {\n\t\t\tthis._selfInvalidated = true;\n\t\t\tswitch (currentStatus) {\n\t\t\t\tcase \"idle\":\n\t\t\t\t\tcurrentUpdateApplyHandlers = [];\n\t\t\t\t\tObject.keys(__webpack_require__.hmrI).forEach(function (key) {\n\t\t\t\t\t\t__webpack_require__.hmrI[key](\n\t\t\t\t\t\t\tmoduleId,\n\t\t\t\t\t\t\tcurrentUpdateApplyHandlers\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t\tsetStatus(\"ready\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"ready\":\n\t\t\t\t\tObject.keys(__webpack_require__.hmrI).forEach(function (key) {\n\t\t\t\t\t\t__webpack_require__.hmrI[key](\n\t\t\t\t\t\t\tmoduleId,\n\t\t\t\t\t\t\tcurrentUpdateApplyHandlers\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"prepare\":\n\t\t\t\tcase \"check\":\n\t\t\t\tcase \"dispose\":\n\t\t\t\tcase \"apply\":\n\t\t\t\t\t(queuedInvalidatedModules = queuedInvalidatedModules || []).push(\n\t\t\t\t\t\tmoduleId\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t// ignore requests in error states\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\n\t\t// Management API\n\t\tcheck: hotCheck,\n\t\tapply: hotApply,\n\t\tstatus: function (l) {\n\t\t\tif (!l) return currentStatus;\n\t\t\tregisteredStatusHandlers.push(l);\n\t\t},\n\t\taddStatusHandler: function (l) {\n\t\t\tregisteredStatusHandlers.push(l);\n\t\t},\n\t\tremoveStatusHandler: function (l) {\n\t\t\tvar idx = registeredStatusHandlers.indexOf(l);\n\t\t\tif (idx >= 0) registeredStatusHandlers.splice(idx, 1);\n\t\t},\n\n\t\t//inherit from previous dispose call\n\t\tdata: currentModuleData[moduleId]\n\t};\n\tcurrentChildModule = undefined;\n\treturn hot;\n}\n\nfunction setStatus(newStatus) {\n\tcurrentStatus = newStatus;\n\tvar results = [];\n\n\tfor (var i = 0; i < registeredStatusHandlers.length; i++)\n\t\tresults[i] = registeredStatusHandlers[i].call(null, newStatus);\n\n\treturn Promise.all(results);\n}\n\nfunction unblock() {\n\tif (--blockingPromises === 0) {\n\t\tsetStatus(\"ready\").then(function () {\n\t\t\tif (blockingPromises === 0) {\n\t\t\t\tvar list = blockingPromisesWaiting;\n\t\t\t\tblockingPromisesWaiting = [];\n\t\t\t\tfor (var i = 0; i < list.length; i++) {\n\t\t\t\t\tlist[i]();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n}\n\nfunction trackBlockingPromise(promise) {\n\tswitch (currentStatus) {\n\t\tcase \"ready\":\n\t\t\tsetStatus(\"prepare\");\n\t\t/* fallthrough */\n\t\tcase \"prepare\":\n\t\t\tblockingPromises++;\n\t\t\tpromise.then(unblock, unblock);\n\t\t\treturn promise;\n\t\tdefault:\n\t\t\treturn promise;\n\t}\n}\n\nfunction waitForBlockingPromises(fn) {\n\tif (blockingPromises === 0) return fn();\n\treturn new Promise(function (resolve) {\n\t\tblockingPromisesWaiting.push(function () {\n\t\t\tresolve(fn());\n\t\t});\n\t});\n}\n\nfunction hotCheck(applyOnUpdate) {\n\tif (currentStatus !== \"idle\") {\n\t\tthrow new Error(\"check() is only allowed in idle status\");\n\t}\n\treturn setStatus(\"check\")\n\t\t.then(__webpack_require__.hmrM)\n\t\t.then(function (update) {\n\t\t\tif (!update) {\n\t\t\t\treturn setStatus(applyInvalidatedModules() ? \"ready\" : \"idle\").then(\n\t\t\t\t\tfunction () {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn setStatus(\"prepare\").then(function () {\n\t\t\t\tvar updatedModules = [];\n\t\t\t\tcurrentUpdateApplyHandlers = [];\n\n\t\t\t\treturn Promise.all(\n\t\t\t\t\tObject.keys(__webpack_require__.hmrC).reduce(function (\n\t\t\t\t\t\tpromises,\n\t\t\t\t\t\tkey\n\t\t\t\t\t) {\n\t\t\t\t\t\t__webpack_require__.hmrC[key](\n\t\t\t\t\t\t\tupdate.c,\n\t\t\t\t\t\t\tupdate.r,\n\t\t\t\t\t\t\tupdate.m,\n\t\t\t\t\t\t\tpromises,\n\t\t\t\t\t\t\tcurrentUpdateApplyHandlers,\n\t\t\t\t\t\t\tupdatedModules\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn promises;\n\t\t\t\t\t},\n\t\t\t\t\t[])\n\t\t\t\t).then(function () {\n\t\t\t\t\treturn waitForBlockingPromises(function () {\n\t\t\t\t\t\tif (applyOnUpdate) {\n\t\t\t\t\t\t\treturn internalApply(applyOnUpdate);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn setStatus(\"ready\").then(function () {\n\t\t\t\t\t\t\t\treturn updatedModules;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t});\n}\n\nfunction hotApply(options) {\n\tif (currentStatus !== \"ready\") {\n\t\treturn Promise.resolve().then(function () {\n\t\t\tthrow new Error(\n\t\t\t\t\"apply() is only allowed in ready status (state: \" +\n\t\t\t\t\tcurrentStatus +\n\t\t\t\t\t\")\"\n\t\t\t);\n\t\t});\n\t}\n\treturn internalApply(options);\n}\n\nfunction internalApply(options) {\n\toptions = options || {};\n\n\tapplyInvalidatedModules();\n\n\tvar results = currentUpdateApplyHandlers.map(function (handler) {\n\t\treturn handler(options);\n\t});\n\tcurrentUpdateApplyHandlers = undefined;\n\n\tvar errors = results\n\t\t.map(function (r) {\n\t\t\treturn r.error;\n\t\t})\n\t\t.filter(Boolean);\n\n\tif (errors.length > 0) {\n\t\treturn setStatus(\"abort\").then(function () {\n\t\t\tthrow errors[0];\n\t\t});\n\t}\n\n\t// Now in \"dispose\" phase\n\tvar disposePromise = setStatus(\"dispose\");\n\n\tresults.forEach(function (result) {\n\t\tif (result.dispose) result.dispose();\n\t});\n\n\t// Now in \"apply\" phase\n\tvar applyPromise = setStatus(\"apply\");\n\n\tvar error;\n\tvar reportError = function (err) {\n\t\tif (!error) error = err;\n\t};\n\n\tvar outdatedModules = [];\n\tresults.forEach(function (result) {\n\t\tif (result.apply) {\n\t\t\tvar modules = result.apply(reportError);\n\t\t\tif (modules) {\n\t\t\t\tfor (var i = 0; i < modules.length; i++) {\n\t\t\t\t\toutdatedModules.push(modules[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\treturn Promise.all([disposePromise, applyPromise]).then(function () {\n\t\t// handle errors in accept handlers and self accepted module load\n\t\tif (error) {\n\t\t\treturn setStatus(\"fail\").then(function () {\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t}\n\n\t\tif (queuedInvalidatedModules) {\n\t\t\treturn internalApply(options).then(function (list) {\n\t\t\t\toutdatedModules.forEach(function (moduleId) {\n\t\t\t\t\tif (list.indexOf(moduleId) < 0) list.push(moduleId);\n\t\t\t\t});\n\t\t\t\treturn list;\n\t\t\t});\n\t\t}\n\n\t\treturn setStatus(\"idle\").then(function () {\n\t\t\treturn outdatedModules;\n\t\t});\n\t});\n}\n\nfunction applyInvalidatedModules() {\n\tif (queuedInvalidatedModules) {\n\t\tif (!currentUpdateApplyHandlers) currentUpdateApplyHandlers = [];\n\t\tObject.keys(__webpack_require__.hmrI).forEach(function (key) {\n\t\t\tqueuedInvalidatedModules.forEach(function (moduleId) {\n\t\t\t\t__webpack_require__.hmrI[key](\n\t\t\t\t\tmoduleId,\n\t\t\t\t\tcurrentUpdateApplyHandlers\n\t\t\t\t);\n\t\t\t});\n\t\t});\n\t\tqueuedInvalidatedModules = undefined;\n\t\treturn true;\n\t}\n}","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && !scriptUrl) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","__webpack_require__.i.push((options) => {\n\tconst originalFactory = options.factory;\n\toptions.factory = function (moduleObject, moduleExports, webpackRequire) {\n\t\t__webpack_require__.$Refresh$.setup(options.id);\n\t\ttry {\n\t\t\toriginalFactory.call(this, moduleObject, moduleExports, webpackRequire);\n\t\t} finally {\n\t\t\tif (typeof Promise !== 'undefined' && moduleObject.exports instanceof Promise) {\n\t\t\t\toptions.module.exports = options.module.exports.then(\n\t\t\t\t\t(result) => {\n\t\t\t\t\t\t__webpack_require__.$Refresh$.cleanup(options.id);\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t},\n\t\t\t\t\t(reason) => {\n\t\t\t\t\t\t__webpack_require__.$Refresh$.cleanup(options.id);\n\t\t\t\t\t\treturn Promise.reject(reason);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t__webpack_require__.$Refresh$.cleanup(options.id)\n\t\t\t}\n\t\t}\n\t};\n})\n\n__webpack_require__.$Refresh$ = {\n\tregister: () => (undefined),\n\tsignature: () => ((type) => (type)),\n\truntime: {\n\t\tcreateSignatureFunctionForTransform: () => ((type) => (type)),\n\t\tregister: () => (undefined)\n\t},\n\tsetup: (currentModuleId) => {\n\t\tconst prevModuleId = __webpack_require__.$Refresh$.moduleId;\n\t\tconst prevRegister = __webpack_require__.$Refresh$.register;\n\t\tconst prevSignature = __webpack_require__.$Refresh$.signature;\n\t\tconst prevCleanup = __webpack_require__.$Refresh$.cleanup;\n\n\t\t__webpack_require__.$Refresh$.moduleId = currentModuleId;\n\n\t\t__webpack_require__.$Refresh$.register = (type, id) => {\n\t\t\tconst typeId = currentModuleId + \" \" + id;\n\t\t\t__webpack_require__.$Refresh$.runtime.register(type, typeId);\n\t\t}\n\n\t\t__webpack_require__.$Refresh$.signature = () => (__webpack_require__.$Refresh$.runtime.createSignatureFunctionForTransform());\n\n\t\t__webpack_require__.$Refresh$.cleanup = (cleanupModuleId) => {\n\t\t\tif (currentModuleId === cleanupModuleId) {\n\t\t\t\t__webpack_require__.$Refresh$.moduleId = prevModuleId;\n\t\t\t\t__webpack_require__.$Refresh$.register = prevRegister;\n\t\t\t\t__webpack_require__.$Refresh$.signature = prevSignature;\n\t\t\t\t__webpack_require__.$Refresh$.cleanup = prevCleanup;\n\t\t\t}\n\t\t}\n\t}\n};","if (typeof document === \"undefined\") return;\nvar createStylesheet = (chunkId, fullhref, oldTag, resolve, reject) => {\n\tvar linkTag = document.createElement(\"link\");\n\n\tlinkTag.rel = \"stylesheet\";\n\tlinkTag.type = \"text/css\";\n\tvar onLinkComplete = (event) => {\n\t\t// avoid mem leaks.\n\t\tlinkTag.onerror = linkTag.onload = null;\n\t\tif (event.type === 'load') {\n\t\t\tresolve();\n\t\t} else {\n\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\tvar realHref = event && event.target && event.target.href || fullhref;\n\t\t\tvar err = new Error(\"Loading CSS chunk \" + chunkId + \" failed.\\n(\" + realHref + \")\");\n\t\t\terr.code = \"CSS_CHUNK_LOAD_FAILED\";\n\t\t\terr.type = errorType;\n\t\t\terr.request = realHref;\n\t\t\tif (linkTag.parentNode) linkTag.parentNode.removeChild(linkTag)\n\t\t\treject(err);\n\t\t}\n\t}\n\tlinkTag.onerror = linkTag.onload = onLinkComplete;\n\tlinkTag.href = fullhref;\n\n\tif (oldTag) {\n\t\toldTag.parentNode.insertBefore(linkTag, oldTag.nextSibling);\n\t} else {\n\t\tdocument.head.appendChild(linkTag);\n\t}\n\treturn linkTag;\n};\nvar findStylesheet = (href, fullhref) => {\n\tvar existingLinkTags = document.getElementsByTagName(\"link\");\n\tfor(var i = 0; i < existingLinkTags.length; i++) {\n\t\tvar tag = existingLinkTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\") || tag.getAttribute(\"href\");\n\t\tif(tag.rel === \"stylesheet\" && (dataHref === href || dataHref === fullhref)) return tag;\n\t}\n\tvar existingStyleTags = document.getElementsByTagName(\"style\");\n\tfor(var i = 0; i < existingStyleTags.length; i++) {\n\t\tvar tag = existingStyleTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\");\n\t\tif(dataHref === href || dataHref === fullhref) return tag;\n\t}\n};\nvar loadStylesheet = (chunkId) => {\n\treturn new Promise((resolve, reject) => {\n\t\tvar href = __webpack_require__.miniCssF(chunkId);\n\t\tvar fullhref = __webpack_require__.p + href;\n\t\tif(findStylesheet(href, fullhref)) return resolve();\n\t\tcreateStylesheet(chunkId, fullhref, null, resolve, reject);\n\t});\n}\n// no chunk loading\n\nvar oldTags = [];\nvar newTags = [];\nvar applyHandler = (options) => {\n\treturn { dispose: () => {\n\t\tfor(var i = 0; i < oldTags.length; i++) {\n\t\t\tvar oldTag = oldTags[i];\n\t\t\tif(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);\n\t\t}\n\t\toldTags.length = 0;\n\t}, apply: () => {\n\t\tfor(var i = 0; i < newTags.length; i++) newTags[i].rel = \"stylesheet\";\n\t\tnewTags.length = 0;\n\t} };\n}\n__webpack_require__.hmrC.miniCss = (chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList) => {\n\tapplyHandlers.push(applyHandler);\n\tchunkIds.forEach((chunkId) => {\n\t\tvar href = __webpack_require__.miniCssF(chunkId);\n\t\tvar fullhref = __webpack_require__.p + href;\n\t\tvar oldTag = findStylesheet(href, fullhref);\n\t\tif(!oldTag) return;\n\t\tpromises.push(new Promise((resolve, reject) => {\n\t\t\tvar tag = createStylesheet(chunkId, fullhref, oldTag, () => {\n\t\t\t\ttag.as = \"style\";\n\t\t\t\ttag.rel = \"preload\";\n\t\t\t\tresolve();\n\t\t\t}, reject);\n\t\t\toldTags.push(oldTag);\n\t\t\tnewTags.push(tag);\n\t\t}));\n\t});\n}","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = __webpack_require__.hmrS_jsonp = __webpack_require__.hmrS_jsonp || {\n\t\"main\": 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\nvar currentUpdatedModulesList;\nvar waitingUpdateResolves = {};\nfunction loadUpdateChunk(chunkId, updatedModulesList) {\n\tcurrentUpdatedModulesList = updatedModulesList;\n\treturn new Promise((resolve, reject) => {\n\t\twaitingUpdateResolves[chunkId] = resolve;\n\t\t// start update chunk loading\n\t\tvar url = __webpack_require__.p + __webpack_require__.hu(chunkId);\n\t\t// create error before stack unwound to get useful stacktrace later\n\t\tvar error = new Error();\n\t\tvar loadingEnded = (event) => {\n\t\t\tif(waitingUpdateResolves[chunkId]) {\n\t\t\t\twaitingUpdateResolves[chunkId] = undefined\n\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\terror.message = 'Loading hot update chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\terror.type = errorType;\n\t\t\t\terror.request = realSrc;\n\t\t\t\treject(error);\n\t\t\t}\n\t\t};\n\t\t__webpack_require__.l(url, loadingEnded);\n\t});\n}\n\nself[\"webpackHotUpdateOptionsCard\"] = (chunkId, moreModules, runtime) => {\n\tfor(var moduleId in moreModules) {\n\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\tcurrentUpdate[moduleId] = moreModules[moduleId];\n\t\t\tif(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);\n\t\t}\n\t}\n\tif(runtime) currentUpdateRuntime.push(runtime);\n\tif(waitingUpdateResolves[chunkId]) {\n\t\twaitingUpdateResolves[chunkId]();\n\t\twaitingUpdateResolves[chunkId] = undefined;\n\t}\n};\n\nvar currentUpdateChunks;\nvar currentUpdate;\nvar currentUpdateRemovedChunks;\nvar currentUpdateRuntime;\nfunction applyHandler(options) {\n\tif (__webpack_require__.f) delete __webpack_require__.f.jsonpHmr;\n\tcurrentUpdateChunks = undefined;\n\tfunction getAffectedModuleEffects(updateModuleId) {\n\t\tvar outdatedModules = [updateModuleId];\n\t\tvar outdatedDependencies = {};\n\n\t\tvar queue = outdatedModules.map(function (id) {\n\t\t\treturn {\n\t\t\t\tchain: [id],\n\t\t\t\tid: id\n\t\t\t};\n\t\t});\n\t\twhile (queue.length > 0) {\n\t\t\tvar queueItem = queue.pop();\n\t\t\tvar moduleId = queueItem.id;\n\t\t\tvar chain = queueItem.chain;\n\t\t\tvar module = __webpack_require__.c[moduleId];\n\t\t\tif (\n\t\t\t\t!module ||\n\t\t\t\t(module.hot._selfAccepted && !module.hot._selfInvalidated)\n\t\t\t)\n\t\t\t\tcontinue;\n\t\t\tif (module.hot._selfDeclined) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"self-declined\",\n\t\t\t\t\tchain: chain,\n\t\t\t\t\tmoduleId: moduleId\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (module.hot._main) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"unaccepted\",\n\t\t\t\t\tchain: chain,\n\t\t\t\t\tmoduleId: moduleId\n\t\t\t\t};\n\t\t\t}\n\t\t\tfor (var i = 0; i < module.parents.length; i++) {\n\t\t\t\tvar parentId = module.parents[i];\n\t\t\t\tvar parent = __webpack_require__.c[parentId];\n\t\t\t\tif (!parent) continue;\n\t\t\t\tif (parent.hot._declinedDependencies[moduleId]) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"declined\",\n\t\t\t\t\t\tchain: chain.concat([parentId]),\n\t\t\t\t\t\tmoduleId: moduleId,\n\t\t\t\t\t\tparentId: parentId\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (outdatedModules.indexOf(parentId) !== -1) continue;\n\t\t\t\tif (parent.hot._acceptedDependencies[moduleId]) {\n\t\t\t\t\tif (!outdatedDependencies[parentId])\n\t\t\t\t\t\toutdatedDependencies[parentId] = [];\n\t\t\t\t\taddAllToSet(outdatedDependencies[parentId], [moduleId]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdelete outdatedDependencies[parentId];\n\t\t\t\toutdatedModules.push(parentId);\n\t\t\t\tqueue.push({\n\t\t\t\t\tchain: chain.concat([parentId]),\n\t\t\t\t\tid: parentId\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\ttype: \"accepted\",\n\t\t\tmoduleId: updateModuleId,\n\t\t\toutdatedModules: outdatedModules,\n\t\t\toutdatedDependencies: outdatedDependencies\n\t\t};\n\t}\n\n\tfunction addAllToSet(a, b) {\n\t\tfor (var i = 0; i < b.length; i++) {\n\t\t\tvar item = b[i];\n\t\t\tif (a.indexOf(item) === -1) a.push(item);\n\t\t}\n\t}\n\n\t// at begin all updates modules are outdated\n\t// the \"outdated\" status can propagate to parents if they don't accept the children\n\tvar outdatedDependencies = {};\n\tvar outdatedModules = [];\n\tvar appliedUpdate = {};\n\n\tvar warnUnexpectedRequire = function warnUnexpectedRequire(module) {\n\t\tconsole.warn(\n\t\t\t\"[HMR] unexpected require(\" + module.id + \") to disposed module\"\n\t\t);\n\t};\n\n\tfor (var moduleId in currentUpdate) {\n\t\tif (__webpack_require__.o(currentUpdate, moduleId)) {\n\t\t\tvar newModuleFactory = currentUpdate[moduleId];\n\t\t\t/** @type {TODO} */\n\t\t\tvar result;\n\t\t\tif (newModuleFactory) {\n\t\t\t\tresult = getAffectedModuleEffects(moduleId);\n\t\t\t} else {\n\t\t\t\tresult = {\n\t\t\t\t\ttype: \"disposed\",\n\t\t\t\t\tmoduleId: moduleId\n\t\t\t\t};\n\t\t\t}\n\t\t\t/** @type {Error|false} */\n\t\t\tvar abortError = false;\n\t\t\tvar doApply = false;\n\t\t\tvar doDispose = false;\n\t\t\tvar chainInfo = \"\";\n\t\t\tif (result.chain) {\n\t\t\t\tchainInfo = \"\\nUpdate propagation: \" + result.chain.join(\" -> \");\n\t\t\t}\n\t\t\tswitch (result.type) {\n\t\t\t\tcase \"self-declined\":\n\t\t\t\t\tif (options.onDeclined) options.onDeclined(result);\n\t\t\t\t\tif (!options.ignoreDeclined)\n\t\t\t\t\t\tabortError = new Error(\n\t\t\t\t\t\t\t\"Aborted because of self decline: \" +\n\t\t\t\t\t\t\t\tresult.moduleId +\n\t\t\t\t\t\t\t\tchainInfo\n\t\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"declined\":\n\t\t\t\t\tif (options.onDeclined) options.onDeclined(result);\n\t\t\t\t\tif (!options.ignoreDeclined)\n\t\t\t\t\t\tabortError = new Error(\n\t\t\t\t\t\t\t\"Aborted because of declined dependency: \" +\n\t\t\t\t\t\t\t\tresult.moduleId +\n\t\t\t\t\t\t\t\t\" in \" +\n\t\t\t\t\t\t\t\tresult.parentId +\n\t\t\t\t\t\t\t\tchainInfo\n\t\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"unaccepted\":\n\t\t\t\t\tif (options.onUnaccepted) options.onUnaccepted(result);\n\t\t\t\t\tif (!options.ignoreUnaccepted)\n\t\t\t\t\t\tabortError = new Error(\n\t\t\t\t\t\t\t\"Aborted because \" + moduleId + \" is not accepted\" + chainInfo\n\t\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"accepted\":\n\t\t\t\t\tif (options.onAccepted) options.onAccepted(result);\n\t\t\t\t\tdoApply = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"disposed\":\n\t\t\t\t\tif (options.onDisposed) options.onDisposed(result);\n\t\t\t\t\tdoDispose = true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\"Unexception type \" + result.type);\n\t\t\t}\n\t\t\tif (abortError) {\n\t\t\t\treturn {\n\t\t\t\t\terror: abortError\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (doApply) {\n\t\t\t\tappliedUpdate[moduleId] = newModuleFactory;\n\t\t\t\taddAllToSet(outdatedModules, result.outdatedModules);\n\t\t\t\tfor (moduleId in result.outdatedDependencies) {\n\t\t\t\t\tif (__webpack_require__.o(result.outdatedDependencies, moduleId)) {\n\t\t\t\t\t\tif (!outdatedDependencies[moduleId])\n\t\t\t\t\t\t\toutdatedDependencies[moduleId] = [];\n\t\t\t\t\t\taddAllToSet(\n\t\t\t\t\t\t\toutdatedDependencies[moduleId],\n\t\t\t\t\t\t\tresult.outdatedDependencies[moduleId]\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (doDispose) {\n\t\t\t\taddAllToSet(outdatedModules, [result.moduleId]);\n\t\t\t\tappliedUpdate[moduleId] = warnUnexpectedRequire;\n\t\t\t}\n\t\t}\n\t}\n\tcurrentUpdate = undefined;\n\n\t// Store self accepted outdated modules to require them later by the module system\n\tvar outdatedSelfAcceptedModules = [];\n\tfor (var j = 0; j < outdatedModules.length; j++) {\n\t\tvar outdatedModuleId = outdatedModules[j];\n\t\tvar module = __webpack_require__.c[outdatedModuleId];\n\t\tif (\n\t\t\tmodule &&\n\t\t\t(module.hot._selfAccepted || module.hot._main) &&\n\t\t\t// removed self-accepted modules should not be required\n\t\t\tappliedUpdate[outdatedModuleId] !== warnUnexpectedRequire &&\n\t\t\t// when called invalidate self-accepting is not possible\n\t\t\t!module.hot._selfInvalidated\n\t\t) {\n\t\t\toutdatedSelfAcceptedModules.push({\n\t\t\t\tmodule: outdatedModuleId,\n\t\t\t\trequire: module.hot._requireSelf,\n\t\t\t\terrorHandler: module.hot._selfAccepted\n\t\t\t});\n\t\t}\n\t}\n\n\tvar moduleOutdatedDependencies;\n\n\treturn {\n\t\tdispose: function () {\n\t\t\tcurrentUpdateRemovedChunks.forEach(function (chunkId) {\n\t\t\t\tdelete installedChunks[chunkId];\n\t\t\t});\n\t\t\tcurrentUpdateRemovedChunks = undefined;\n\n\t\t\tvar idx;\n\t\t\tvar queue = outdatedModules.slice();\n\t\t\twhile (queue.length > 0) {\n\t\t\t\tvar moduleId = queue.pop();\n\t\t\t\tvar module = __webpack_require__.c[moduleId];\n\t\t\t\tif (!module) continue;\n\n\t\t\t\tvar data = {};\n\n\t\t\t\t// Call dispose handlers\n\t\t\t\tvar disposeHandlers = module.hot._disposeHandlers;\n\t\t\t\tfor (j = 0; j < disposeHandlers.length; j++) {\n\t\t\t\t\tdisposeHandlers[j].call(null, data);\n\t\t\t\t}\n\t\t\t\t__webpack_require__.hmrD[moduleId] = data;\n\n\t\t\t\t// disable module (this disables requires from this module)\n\t\t\t\tmodule.hot.active = false;\n\n\t\t\t\t// remove module from cache\n\t\t\t\tdelete __webpack_require__.c[moduleId];\n\n\t\t\t\t// when disposing there is no need to call dispose handler\n\t\t\t\tdelete outdatedDependencies[moduleId];\n\n\t\t\t\t// remove \"parents\" references from all children\n\t\t\t\tfor (j = 0; j < module.children.length; j++) {\n\t\t\t\t\tvar child = __webpack_require__.c[module.children[j]];\n\t\t\t\t\tif (!child) continue;\n\t\t\t\t\tidx = child.parents.indexOf(moduleId);\n\t\t\t\t\tif (idx >= 0) {\n\t\t\t\t\t\tchild.parents.splice(idx, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// remove outdated dependency from module children\n\t\t\tvar dependency;\n\t\t\tfor (var outdatedModuleId in outdatedDependencies) {\n\t\t\t\tif (__webpack_require__.o(outdatedDependencies, outdatedModuleId)) {\n\t\t\t\t\tmodule = __webpack_require__.c[outdatedModuleId];\n\t\t\t\t\tif (module) {\n\t\t\t\t\t\tmoduleOutdatedDependencies =\n\t\t\t\t\t\t\toutdatedDependencies[outdatedModuleId];\n\t\t\t\t\t\tfor (j = 0; j < moduleOutdatedDependencies.length; j++) {\n\t\t\t\t\t\t\tdependency = moduleOutdatedDependencies[j];\n\t\t\t\t\t\t\tidx = module.children.indexOf(dependency);\n\t\t\t\t\t\t\tif (idx >= 0) module.children.splice(idx, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tapply: function (reportError) {\n\t\t\t// insert new code\n\t\t\tfor (var updateModuleId in appliedUpdate) {\n\t\t\t\tif (__webpack_require__.o(appliedUpdate, updateModuleId)) {\n\t\t\t\t\t__webpack_require__.m[updateModuleId] = appliedUpdate[updateModuleId];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// run new runtime modules\n\t\t\tfor (var i = 0; i < currentUpdateRuntime.length; i++) {\n\t\t\t\tcurrentUpdateRuntime[i](__webpack_require__);\n\t\t\t}\n\n\t\t\t// call accept handlers\n\t\t\tfor (var outdatedModuleId in outdatedDependencies) {\n\t\t\t\tif (__webpack_require__.o(outdatedDependencies, outdatedModuleId)) {\n\t\t\t\t\tvar module = __webpack_require__.c[outdatedModuleId];\n\t\t\t\t\tif (module) {\n\t\t\t\t\t\tmoduleOutdatedDependencies =\n\t\t\t\t\t\t\toutdatedDependencies[outdatedModuleId];\n\t\t\t\t\t\tvar callbacks = [];\n\t\t\t\t\t\tvar errorHandlers = [];\n\t\t\t\t\t\tvar dependenciesForCallbacks = [];\n\t\t\t\t\t\tfor (var j = 0; j < moduleOutdatedDependencies.length; j++) {\n\t\t\t\t\t\t\tvar dependency = moduleOutdatedDependencies[j];\n\t\t\t\t\t\t\tvar acceptCallback =\n\t\t\t\t\t\t\t\tmodule.hot._acceptedDependencies[dependency];\n\t\t\t\t\t\t\tvar errorHandler =\n\t\t\t\t\t\t\t\tmodule.hot._acceptedErrorHandlers[dependency];\n\t\t\t\t\t\t\tif (acceptCallback) {\n\t\t\t\t\t\t\t\tif (callbacks.indexOf(acceptCallback) !== -1) continue;\n\t\t\t\t\t\t\t\tcallbacks.push(acceptCallback);\n\t\t\t\t\t\t\t\terrorHandlers.push(errorHandler);\n\t\t\t\t\t\t\t\tdependenciesForCallbacks.push(dependency);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (var k = 0; k < callbacks.length; k++) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tcallbacks[k].call(null, moduleOutdatedDependencies);\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\tif (typeof errorHandlers[k] === \"function\") {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\terrorHandlers[k](err, {\n\t\t\t\t\t\t\t\t\t\t\tmoduleId: outdatedModuleId,\n\t\t\t\t\t\t\t\t\t\t\tdependencyId: dependenciesForCallbacks[k]\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t} catch (err2) {\n\t\t\t\t\t\t\t\t\t\tif (options.onErrored) {\n\t\t\t\t\t\t\t\t\t\t\toptions.onErrored({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"accept-error-handler-errored\",\n\t\t\t\t\t\t\t\t\t\t\t\tmoduleId: outdatedModuleId,\n\t\t\t\t\t\t\t\t\t\t\t\tdependencyId: dependenciesForCallbacks[k],\n\t\t\t\t\t\t\t\t\t\t\t\terror: err2,\n\t\t\t\t\t\t\t\t\t\t\t\toriginalError: err\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (!options.ignoreErrored) {\n\t\t\t\t\t\t\t\t\t\t\treportError(err2);\n\t\t\t\t\t\t\t\t\t\t\treportError(err);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tif (options.onErrored) {\n\t\t\t\t\t\t\t\t\t\toptions.onErrored({\n\t\t\t\t\t\t\t\t\t\t\ttype: \"accept-errored\",\n\t\t\t\t\t\t\t\t\t\t\tmoduleId: outdatedModuleId,\n\t\t\t\t\t\t\t\t\t\t\tdependencyId: dependenciesForCallbacks[k],\n\t\t\t\t\t\t\t\t\t\t\terror: err\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (!options.ignoreErrored) {\n\t\t\t\t\t\t\t\t\t\treportError(err);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Load self accepted modules\n\t\t\tfor (var o = 0; o < outdatedSelfAcceptedModules.length; o++) {\n\t\t\t\tvar item = outdatedSelfAcceptedModules[o];\n\t\t\t\tvar moduleId = item.module;\n\t\t\t\ttry {\n\t\t\t\t\titem.require(moduleId);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (typeof item.errorHandler === \"function\") {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\titem.errorHandler(err, {\n\t\t\t\t\t\t\t\tmoduleId: moduleId,\n\t\t\t\t\t\t\t\tmodule: __webpack_require__.c[moduleId]\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} catch (err2) {\n\t\t\t\t\t\t\tif (options.onErrored) {\n\t\t\t\t\t\t\t\toptions.onErrored({\n\t\t\t\t\t\t\t\t\ttype: \"self-accept-error-handler-errored\",\n\t\t\t\t\t\t\t\t\tmoduleId: moduleId,\n\t\t\t\t\t\t\t\t\terror: err2,\n\t\t\t\t\t\t\t\t\toriginalError: err\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!options.ignoreErrored) {\n\t\t\t\t\t\t\t\treportError(err2);\n\t\t\t\t\t\t\t\treportError(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (options.onErrored) {\n\t\t\t\t\t\t\toptions.onErrored({\n\t\t\t\t\t\t\t\ttype: \"self-accept-errored\",\n\t\t\t\t\t\t\t\tmoduleId: moduleId,\n\t\t\t\t\t\t\t\terror: err\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!options.ignoreErrored) {\n\t\t\t\t\t\t\treportError(err);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn outdatedModules;\n\t\t}\n\t};\n}\n__webpack_require__.hmrI.jsonp = function (moduleId, applyHandlers) {\n\tif (!currentUpdate) {\n\t\tcurrentUpdate = {};\n\t\tcurrentUpdateRuntime = [];\n\t\tcurrentUpdateRemovedChunks = [];\n\t\tapplyHandlers.push(applyHandler);\n\t}\n\tif (!__webpack_require__.o(currentUpdate, moduleId)) {\n\t\tcurrentUpdate[moduleId] = __webpack_require__.m[moduleId];\n\t}\n};\n__webpack_require__.hmrC.jsonp = function (\n\tchunkIds,\n\tremovedChunks,\n\tremovedModules,\n\tpromises,\n\tapplyHandlers,\n\tupdatedModulesList\n) {\n\tapplyHandlers.push(applyHandler);\n\tcurrentUpdateChunks = {};\n\tcurrentUpdateRemovedChunks = removedChunks;\n\tcurrentUpdate = removedModules.reduce(function (obj, key) {\n\t\tobj[key] = false;\n\t\treturn obj;\n\t}, {});\n\tcurrentUpdateRuntime = [];\n\tchunkIds.forEach(function (chunkId) {\n\t\tif (\n\t\t\t__webpack_require__.o(installedChunks, chunkId) &&\n\t\t\tinstalledChunks[chunkId] !== undefined\n\t\t) {\n\t\t\tpromises.push(loadUpdateChunk(chunkId, updatedModulesList));\n\t\t\tcurrentUpdateChunks[chunkId] = true;\n\t\t} else {\n\t\t\tcurrentUpdateChunks[chunkId] = false;\n\t\t}\n\t});\n\tif (__webpack_require__.f) {\n\t\t__webpack_require__.f.jsonpHmr = function (chunkId, promises) {\n\t\t\tif (\n\t\t\t\tcurrentUpdateChunks &&\n\t\t\t\t__webpack_require__.o(currentUpdateChunks, chunkId) &&\n\t\t\t\t!currentUpdateChunks[chunkId]\n\t\t\t) {\n\t\t\t\tpromises.push(loadUpdateChunk(chunkId));\n\t\t\t\tcurrentUpdateChunks[chunkId] = true;\n\t\t\t}\n\t\t};\n\t}\n};\n\n__webpack_require__.hmrM = () => {\n\tif (typeof fetch === \"undefined\") throw new Error(\"No browser support: need fetch API\");\n\treturn fetch(__webpack_require__.p + __webpack_require__.hmrF()).then((response) => {\n\t\tif(response.status === 404) return; // no update available\n\t\tif(!response.ok) throw new Error(\"Failed to fetch update manifest \" + response.statusText);\n\t\treturn response.json();\n\t});\n};\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkOptionsCard\"] = self[\"webpackChunkOptionsCard\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","__webpack_require__.nc = undefined;","","// module cache are used so entry inlining is disabled\n// startup\n// Load entry module and return exports\n__webpack_require__.O(undefined, [\"vendors-node_modules_pmmmwh_react-refresh-webpack-plugin_lib_runtime_RefreshUtils_js-node_mod-2e02e2\"], () => (__webpack_require__(\"./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js\")))\n__webpack_require__.O(undefined, [\"vendors-node_modules_pmmmwh_react-refresh-webpack-plugin_lib_runtime_RefreshUtils_js-node_mod-2e02e2\"], () => (__webpack_require__(\"./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ErrorOverlayEntry.js?sockProtocol=http\")))\nvar __webpack_exports__ = __webpack_require__.O(undefined, [\"vendors-node_modules_pmmmwh_react-refresh-webpack-plugin_lib_runtime_RefreshUtils_js-node_mod-2e02e2\"], () => (__webpack_require__(\"./src/main.tsx\")))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n",""],"names":[],"sourceRoot":""}