{"version":3,"file":"app-21604579.9729664bca28a8e6916d.bundle.js","mappings":";;;;;;;;;;;;;;;AAAA;AACA;;AAEA;AACA;;AAEA;AAIA;AAAA;AAHA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAIA;AAHA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAGA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;;AAEA;AACA;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AAGA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;;AAEA;AACA;AAKA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAAA;AAGA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAIA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAGA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;;AAGA;AACA;AAGA;AACA;AACA;AACA;AAAA;AAAA;;AAGA;AACA;AAMA;AAJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAIA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAMA;AACA;;AAGA;AACA;;AAMA;AACA;AAGA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAKA;AAJA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AAEA;AACA;AACA;AAAA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;;AAGA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1oCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAmCA;AAAA;AAjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAMA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAIA;AAEA;AAAA;AAAA;AAAA;AAAA;AAMA;AACA;AAsIA;AACA;AApIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;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;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA5YA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;AC/CA;AACA;AAKA;AAAA;AAAA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAVA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;ACHA;AACA;AACA;AAEA;AAGA;AAAA;AAUA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AALA;AAEA;AAIA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAGA;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;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AA/EA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAeA;AAAA;AAbA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAhGA;;;;;;;;;;;;;;;;;;;;;;;ACRA;AACA;AACA;AACA;AACA;AAEA;AAWA;AAAA;AAAA;AAAA;AANA;AACA;AAEA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AApEA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AA+BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAjBA;AACA;AACA;AAGA;AAAA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAIA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AArGA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AAkCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AArBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;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;AApLA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;ACvCA;AAEA;AAKA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;AAAA;AAPA;AAAA;AAAA;AAAA;AAQA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAfA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;ACVA;AACA;AAEA;AASA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAFA;AA4CA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AArEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAiCA;AACA;AACA;AACA;AACA;AApFA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;ACRA;AACA;AAEA;AAIA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAzBA;;;;;;;;;;;;;;;;ACHA;AACA;AAEA;AAIA;AAAA;AAFA;AAGA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAhCA;;;;;;;;;;;;;;;;;;;ACHA;AAEA;AACA;AAAA;AADA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AALA;AAAA;;;;;;;;;;;;;;;;;;;ACHA;AAEA;AAAA;AAAA;AAAA;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;ACHA;AACA;AACA;AAEA;AAEA;AAAA;AAEA;AAAA;AAHA;AAIA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;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;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;ACzEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;;;;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACPA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA;;;;;;;;;;;ACHA;AACA;AACA;AACA","sources":["webpack://www.zeusteam.com/./src/resources/elements/team-chart/org-chart.js","webpack://www.zeusteam.com/./src/resources/elements/team-chart/team-chart.js","webpack://www.zeusteam.com/./src/resources/elements/three-dots/three-dots.js","webpack://www.zeusteam.com/./src/resources/elements/time-period-selector/time-period-selector.js","webpack://www.zeusteam.com/./src/resources/elements/to-dos/dialogs/edit-to-do.js","webpack://www.zeusteam.com/./src/resources/elements/to-dos/reminder-icon.js","webpack://www.zeusteam.com/./src/resources/elements/to-dos/to-do.js","webpack://www.zeusteam.com/./src/resources/elements/to-dos/to-dos.js","webpack://www.zeusteam.com/./src/resources/elements/toggle-switch/zeus-toggle-switch.js","webpack://www.zeusteam.com/./src/resources/elements/tooltip/tooltip.js","webpack://www.zeusteam.com/./src/resources/elements/ui-term/ui-term-editor-dialog.js","webpack://www.zeusteam.com/./src/resources/elements/ui-theme/ui-theme-mode-button.js","webpack://www.zeusteam.com/./src/resources/elements/ui/font-sizer.js","webpack://www.zeusteam.com/./src/resources/elements/working/working.js","webpack://www.zeusteam.com/./src/resources/elements/wysiwyg/wysiwyg.js","webpack://www.zeusteam.com/./src/resources/index.js","webpack://www.zeusteam.com/./src/resources/elements/team-chart/team-chart.scss","webpack://www.zeusteam.com/./src/resources/elements/three-dots/three-dots.scss","webpack://www.zeusteam.com/./src/resources/elements/to-dos/reminder-icon.scss","webpack://www.zeusteam.com/./src/resources/elements/to-dos/to-dos.scss","webpack://www.zeusteam.com/./src/resources/elements/toggle-switch/zeus-toggle-switch.scss","webpack://www.zeusteam.com/./src/resources/elements/tooltip/tooltip.scss","webpack://www.zeusteam.com/./src/resources/elements/ui/font-sizer.scss","webpack://www.zeusteam.com/./src/resources/elements/team-chart/team-chart.html","webpack://www.zeusteam.com/./src/resources/elements/three-dots/three-dots.html","webpack://www.zeusteam.com/./src/resources/elements/time-period-selector/time-period-selector.html","webpack://www.zeusteam.com/./src/resources/elements/to-dos/dialogs/edit-to-do.html","webpack://www.zeusteam.com/./src/resources/elements/to-dos/reminder-icon.html","webpack://www.zeusteam.com/./src/resources/elements/to-dos/to-do.html","webpack://www.zeusteam.com/./src/resources/elements/to-dos/to-dos.html","webpack://www.zeusteam.com/./src/resources/elements/toggle-switch/zeus-toggle-switch.html","webpack://www.zeusteam.com/./src/resources/elements/tooltip/tooltip.html","webpack://www.zeusteam.com/./src/resources/elements/ui-term/ui-term-editor-dialog.html","webpack://www.zeusteam.com/./src/resources/elements/ui-theme/ui-theme-mode-button.html","webpack://www.zeusteam.com/./src/resources/elements/ui/font-sizer.html","webpack://www.zeusteam.com/./src/resources/elements/working/working.html","webpack://www.zeusteam.com/./src/resources/elements/wysiwyg/wysiwyg.html"],"sourcesContent":["import * as d3 from 'd3';\r\nimport { siteUrlBase } from 'common/common';\r\n\r\n// https://github.com/bumbeishvili/d3-organization-chart/blob/master/index.js\r\n// 4/2/2021\r\n\r\nexport class OrgChart {\r\n mainSvg;\r\n _getNextLevel;\r\n\r\n constructor(getNextLevel) {\r\n this._getNextLevel = getNextLevel;\r\n // Exposed variables\r\n const attrs = {\r\n id: `ID${Math.floor(Math.random() * 1000000)}`, // Id for event handlings\r\n svgWidth: 800,\r\n svgHeight: 600,\r\n marginTop: 0,\r\n marginBottom: 0,\r\n marginRight: 0,\r\n marginLeft: 0,\r\n container: 'body',\r\n defaultTextFill: '#2C3E50',\r\n nodeTextFill: 'white',\r\n defaultFont: 'Helvetica',\r\n backgroundColor: '#fafafa',\r\n data: null,\r\n depth: 180,\r\n duration: 600,\r\n strokeWidth: 3,\r\n dropShadowId: null,\r\n initialZoom: 1,\r\n onNodeClick: d => d,\r\n };\r\n\r\n this.getChartState = () => attrs;\r\n\r\n // Dynamically set getter and setter functions for Chart class\r\n Object.keys(attrs).forEach((key) => {\r\n //@ts-ignore\r\n this[key] = function (_) {\r\n if (!arguments.length) {\r\n return attrs[key];\r\n } else {\r\n attrs[key] = _\r\n }\r\n return this;\r\n };\r\n });\r\n\r\n\r\n this.initializeEnterExitUpdatePattern();\r\n }\r\n\r\n initializeEnterExitUpdatePattern() {\r\n d3.selection.prototype.patternify = function (params) {\r\n var container = this;\r\n var selector = params.selector;\r\n var elementTag = params.tag;\r\n var data = params.data || [selector];\r\n\r\n // Pattern in action\r\n var selection = container.selectAll('.' + selector).data(data, (d, i) => {\r\n if (typeof d === 'object') {\r\n if (d.id) {\r\n return d.id;\r\n }\r\n }\r\n return i;\r\n });\r\n selection.exit().remove();\r\n selection = selection.enter().append(elementTag).merge(selection);\r\n selection.attr('class', selector);\r\n return selection;\r\n };\r\n }\r\n\r\n // This method retrieves passed node's children IDs (including node) \r\n getNodeChildrenIds({\r\n data,\r\n children,\r\n _children\r\n }, nodeIdsStore) {\r\n\r\n // Store current node ID\r\n nodeIdsStore.push(data.nodeId);\r\n\r\n // Loop over children and recursively store descendants id (expanded nodes)\r\n if (children) {\r\n children.forEach(d => {\r\n this.getNodeChildrenIds(d, nodeIdsStore)\r\n })\r\n }\r\n\r\n // Loop over _children and recursively store descendants id (collapsed nodes)\r\n if (_children) {\r\n _children.forEach(d => {\r\n this.getNodeChildrenIds(d, nodeIdsStore)\r\n })\r\n }\r\n\r\n // Return result\r\n return nodeIdsStore;\r\n }\r\n\r\n // This method can be invoked via chart.setZoomFactor API, it zooms to particulat scale\r\n setZoomFactor(zoomLevel) {\r\n const attrs = this.getChartState();\r\n const calc = attrs.calc;\r\n\r\n // Store passed zoom level\r\n attrs.initialZoom = zoomLevel;\r\n\r\n // Rescale container element accordingly\r\n attrs.centerG.attr('transform', ` translate(${calc.centerX}, ${calc.nodeMaxHeight / 2}) scale(${attrs.initialZoom})`)\r\n }\r\n\r\n render() {\r\n //InnerFunctions which will update visuals\r\n\r\n const attrs = this.getChartState();\r\n const thisObjRef = this;\r\n\r\n //Drawing containers\r\n const container = d3.select(attrs.container);\r\n const containerRect = container.node().getBoundingClientRect();\r\n if (containerRect.width > 0) attrs.svgWidth = containerRect.width;\r\n\r\n //Attach drop shadow id to attrs object\r\n this.setDropShadowId(attrs);\r\n\r\n //Calculated properties\r\n const calc = {\r\n id: null,\r\n chartTopMargin: null,\r\n chartLeftMargin: null,\r\n chartWidth: null,\r\n chartHeight: null\r\n };\r\n calc.id = `ID${Math.floor(Math.random() * 1000000)}`; // id for event handlings\r\n calc.chartLeftMargin = attrs.marginLeft;\r\n calc.chartTopMargin = attrs.marginTop;\r\n calc.chartWidth = attrs.svgWidth - attrs.marginRight - calc.chartLeftMargin;\r\n calc.chartHeight = attrs.svgHeight - attrs.marginBottom - calc.chartTopMargin;\r\n attrs.calc = calc;\r\n\r\n // Get maximum node width and height\r\n calc.nodeMaxWidth = d3.max(attrs.data || [], ({\r\n width\r\n }) => width);\r\n calc.nodeMaxHeight = d3.max(attrs.data || [], ({\r\n height\r\n }) => height);\r\n\r\n // Calculate max node depth (it's needed for layout heights calculation)\r\n attrs.depth = calc.nodeMaxHeight + 100;\r\n calc.centerX = calc.chartWidth / 2;\r\n\r\n //******************** LAYOUTS ***********************\r\n const layouts = {\r\n treemap: null\r\n }\r\n attrs.layouts = layouts;\r\n\r\n // Generate tree layout function\r\n layouts.treemap = d3.tree().size([calc.chartWidth, calc.chartHeight])\r\n .nodeSize([calc.nodeMaxWidth + 100, calc.nodeMaxHeight + attrs.depth])\r\n\r\n // ******************* BEHAVIORS . **********************\r\n const behaviors = {\r\n zoom: null\r\n }\r\n\r\n // Get zooming function \r\n behaviors.zoom = d3.zoom().on(\"zoom\", (event, d) => this.zoomed(event, d))\r\n\r\n //****************** ROOT node work ************************\r\n\r\n // Convert flat data to hierarchical\r\n attrs.root = d3.stratify()\r\n .id(({\r\n nodeId\r\n }) => nodeId)\r\n .parentId(({\r\n parentNodeId\r\n }) => parentNodeId)\r\n (attrs.data)\r\n\r\n // Set child nodes enter appearance positions\r\n attrs.root.x0 = 0;\r\n attrs.root.y0 = 0;\r\n\r\n /** Get all nodes as array (with extended parent & children properties set)\r\n This way we can access any node's parent directly using node.parent - pretty cool, huh?\r\n */\r\n attrs.allNodes = attrs.layouts.treemap(attrs.root).descendants()\r\n\r\n // Assign direct children and total subordinate children's cound\r\n attrs.allNodes.forEach(d => {\r\n const childrenLength = d.children ? d.children.length : 0;\r\n const directSubordinates = d.data.directSubordinates || childrenLength;\r\n Object.assign(d.data, {\r\n directSubordinates: directSubordinates,\r\n totalSubordinates: d.descendants().length - 1\r\n })\r\n })\r\n\r\n const children = attrs.root.children;\r\n\r\n if(children) {\r\n // Collapse all children at first\r\n children.forEach(d => this.collapse(d));\r\n\r\n // Then expand some nodes, which have `expanded` property set\r\n children.forEach(d => this.expandSomeNodes(d));\r\n }\r\n \r\n\r\n // ************************* DRAWING **************************\r\n //Add svg\r\n this.mainSvg = container\r\n .patternify({\r\n tag: 'svg',\r\n selector: 'svg-chart-container'\r\n })\r\n .attr('width', '100%') //attrs.svgWidth)\r\n .attr('height', attrs.svgHeight)\r\n .attr('font-family', attrs.defaultFont)\r\n .call(behaviors.zoom)\r\n .attr('cursor', 'move')\r\n .style('background-color', attrs.backgroundColor);\r\n attrs.svg = this.mainSvg;\r\n\r\n //Add container g element\r\n const chart = this.mainSvg\r\n .patternify({\r\n tag: 'g',\r\n selector: 'chart'\r\n })\r\n .attr('transform', `translate(${calc.chartLeftMargin},${calc.chartTopMargin})`);\r\n\r\n // Add one more container g element, for better positioning controls\r\n attrs.centerG = chart.patternify({\r\n tag: 'g',\r\n selector: 'center-group'\r\n })\r\n .attr('transform', `translate(${calc.centerX},${calc.nodeMaxHeight / 2}) scale(${attrs.initialZoom})`);\r\n\r\n attrs.chart = chart;\r\n\r\n // ************************** ROUNDED AND SHADOW IMAGE WORK USING SVG FILTERS **********************\r\n\r\n //Adding defs element for rounded image\r\n attrs.defs = this.mainSvg.patternify({\r\n tag: 'defs',\r\n selector: 'image-defs'\r\n });\r\n\r\n // Adding defs element for image's shadow\r\n const filterDefs = this.mainSvg.patternify({\r\n tag: 'defs',\r\n selector: 'filter-defs'\r\n });\r\n\r\n // Adding shadow element - (play with svg filter here - https://bit.ly/2HwnfyL)\r\n const filter = filterDefs.patternify({\r\n tag: 'filter',\r\n selector: 'shadow-filter-element'\r\n })\r\n .attr('id', attrs.dropShadowId)\r\n .attr('y', `${-50}%`)\r\n .attr('x', `${-50}%`)\r\n .attr('height', `${200}%`)\r\n .attr('width', `${200}%`);\r\n\r\n // Add gaussian blur element for shadows - we can control shadow length with this\r\n filter.patternify({\r\n tag: 'feGaussianBlur',\r\n selector: 'feGaussianBlur-element'\r\n })\r\n .attr('in', 'SourceAlpha')\r\n .attr('stdDeviation', 3.1)\r\n .attr('result', 'blur');\r\n\r\n // Add fe-offset element for shadows - we can control shadow positions with it\r\n filter.patternify({\r\n tag: 'feOffset',\r\n selector: 'feOffset-element'\r\n })\r\n .attr('in', 'blur')\r\n .attr('result', 'offsetBlur')\r\n .attr(\"dx\", 4.28)\r\n .attr(\"dy\", 4.48)\r\n .attr(\"x\", 8)\r\n .attr(\"y\", 8)\r\n\r\n // Add fe-flood element for shadows - we can control shadow color and opacity with this element\r\n filter.patternify({\r\n tag: 'feFlood',\r\n selector: 'feFlood-element'\r\n })\r\n .attr(\"in\", \"offsetBlur\")\r\n .attr(\"flood-color\", 'black')\r\n .attr(\"flood-opacity\", 0.3)\r\n .attr(\"result\", \"offsetColor\");\r\n\r\n // Add feComposite element for shadows\r\n filter.patternify({\r\n tag: 'feComposite',\r\n selector: 'feComposite-element'\r\n })\r\n .attr(\"in\", \"offsetColor\")\r\n .attr(\"in2\", \"offsetBlur\")\r\n .attr(\"operator\", \"in\")\r\n .attr(\"result\", \"offsetBlur\");\r\n\r\n // Add feMerge element for shadows\r\n const feMerge = filter.patternify({\r\n tag: 'feMerge',\r\n selector: 'feMerge-element'\r\n });\r\n\r\n // Add feMergeNode element for shadows\r\n feMerge.patternify({\r\n tag: 'feMergeNode',\r\n selector: 'feMergeNode-blur'\r\n })\r\n .attr('in', 'offsetBlur')\r\n\r\n // Add another feMergeNode element for shadows\r\n feMerge.patternify({\r\n tag: 'feMergeNode',\r\n selector: 'feMergeNode-graphic'\r\n })\r\n .attr('in', 'SourceGraphic')\r\n\r\n // Display tree contenrs\r\n this.update(attrs.root)\r\n\r\n //######################################### UTIL FUNCS ##################################\r\n // This function restyles foreign object elements ()\r\n d3.select(window).on(`resize.${attrs.id}`, () => {\r\n const containerRect = container.node().getBoundingClientRect();\r\n // if (containerRect.width > 0) attrs.svgWidth = containerRect.width;\r\n //\tmain();\r\n });\r\n\r\n\r\n return this;\r\n }\r\n\r\n // This function sets drop shadow ID to the passed object\r\n setDropShadowId(d) {\r\n\r\n // If it's already set, then return \r\n if (d.dropShadowId) return;\r\n\r\n // Generate drop shadow ID\r\n let id = `${d.id}-drop-shadow`;\r\n\r\n // If DOM object is available, then use UID method to generated shadow id\r\n //@ts-ignore\r\n if (typeof DOM != 'undefined') {\r\n //@ts-ignore\r\n id = DOM.uid(d.id).id;\r\n }\r\n\r\n // Extend passed object with drop shadow ID\r\n Object.assign(d, {\r\n dropShadowId: id\r\n })\r\n }\r\n\r\n // Add multiple nodes\r\n addNodes(nodes) {\r\n const attrs = this.getChartState();\r\n nodes.forEach(obj => attrs.data.push(obj));\r\n\r\n // Update state of nodes and redraw graph\r\n this.updateNodesState();\r\n return this;\r\n }\r\n\r\n // This function can be invoked via chart.addNode API, and it adds node in tree at runtime\r\n addNode(obj) {\r\n const attrs = this.getChartState();\r\n attrs.data.push(obj);\r\n\r\n // Update state of nodes and redraw graph\r\n this.updateNodesState();\r\n return this;\r\n }\r\n\r\n // This function can be invoked via chart.removeNode API, and it removes node from tree at runtime\r\n removeNode(nodeId) {\r\n const attrs = this.getChartState();\r\n const node = attrs.allNodes.filter(({\r\n data\r\n }) => data.nodeId == nodeId)[0];\r\n\r\n\r\n // Remove all node childs\r\n if (node) {\r\n // Retrieve all children nodes ids (including current node itself)\r\n const nodeChildrenIds = this.getNodeChildrenIds(node, []);\r\n\r\n // Filter out retrieved nodes and reassign data\r\n attrs.data = attrs.data.filter(d => !nodeChildrenIds.includes(d.nodeId))\r\n\r\n const updateNodesState = this.updateNodesState.bind(this);\r\n // Update state of nodes and redraw graph\r\n updateNodesState();\r\n }\r\n }\r\n\r\n // This function basically redraws visible graph, based on nodes state\r\n update({ x0, y0, x, y }) {\r\n\r\n const attrs = this.getChartState();\r\n const calc = attrs.calc;\r\n\r\n // Assigns the x and y position for the nodes\r\n const treeData = attrs.layouts.treemap(attrs.root);\r\n\r\n // Get tree nodes and links and attach some properties \r\n const nodes = treeData.descendants()\r\n .map(d => {\r\n // If at least one property is already set, then we don't want to reset other properties\r\n if (d.width) return d;\r\n\r\n // Declare properties with deffault values\r\n let imageWidth = 80;\r\n let imageHeight = 80;\r\n let imageBorderColor = 'steelblue';\r\n let imageBorderWidth = 0;\r\n let imageRx = 0;\r\n let imageCenterTopDistance = 0;\r\n let imageCenterLeftDistance = 0;\r\n let borderColor = 'steelblue';\r\n let backgroundColor = 'steelblue';\r\n let width = d.data.width;\r\n let height = d.data.height;\r\n let dropShadowId = `none`;\r\n\r\n // Override default values based on data\r\n if (d.data.nodeImage && d.data.nodeImage.shadow) {\r\n dropShadowId = `url(#${attrs.dropShadowId})`\r\n }\r\n if (d.data.nodeImage && d.data.nodeImage.width) {\r\n imageWidth = d.data.nodeImage.width\r\n };\r\n if (d.data.nodeImage && d.data.nodeImage.height) {\r\n imageHeight = d.data.nodeImage.height\r\n };\r\n if (d.data.nodeImage && d.data.nodeImage.borderColor) {\r\n imageBorderColor = this.rgbaObjToColor(d.data.nodeImage.borderColor)\r\n };\r\n if (d.data.nodeImage && d.data.nodeImage.borderWidth) {\r\n imageBorderWidth = d.data.nodeImage.borderWidth\r\n };\r\n if (d.data.nodeImage && d.data.nodeImage.centerTopDistance) {\r\n imageCenterTopDistance = d.data.nodeImage.centerTopDistance\r\n };\r\n if (d.data.nodeImage && d.data.nodeImage.centerLeftDistance) {\r\n imageCenterLeftDistance = d.data.nodeImage.centerLeftDistance\r\n };\r\n if (d.data.borderColor) {\r\n borderColor = this.rgbaObjToColor(d.data.borderColor);\r\n }\r\n if (d.data.backgroundColor) {\r\n backgroundColor = this.rgbaObjToColor(d.data.backgroundColor);\r\n }\r\n if (d.data.nodeImage &&\r\n d.data.nodeImage.cornerShape.toLowerCase() == \"circle\") {\r\n imageRx = Math.max(imageWidth, imageHeight);\r\n }\r\n if (d.data.nodeImage &&\r\n d.data.nodeImage.cornerShape.toLowerCase() == \"rounded\") {\r\n imageRx = Math.min(imageWidth, imageHeight) / 6;\r\n }\r\n\r\n // Extend node object with calculated properties\r\n return Object.assign(d, {\r\n imageWidth,\r\n imageHeight,\r\n imageBorderColor,\r\n imageBorderWidth,\r\n borderColor,\r\n backgroundColor,\r\n imageRx,\r\n width,\r\n height,\r\n imageCenterTopDistance,\r\n imageCenterLeftDistance,\r\n dropShadowId\r\n });\r\n });\r\n\r\n // Get all links\r\n const links = treeData.descendants().slice(1);\r\n\r\n // Set constant depth for each nodes\r\n nodes.forEach(d => d.y = d.depth * attrs.depth);\r\n\r\n // ------------------- FILTERS ---------------------\r\n\r\n // Add patterns for each node (it's needed for rounded image implementation)\r\n const patternsSelection = attrs.defs.selectAll('.pattern')\r\n .data(nodes, ({ id }) => id);\r\n\r\n // Define patterns enter selection\r\n const patternEnterSelection = patternsSelection.enter().append('pattern')\r\n\r\n // Patters update selection\r\n const patterns = patternEnterSelection\r\n .merge(patternsSelection)\r\n .attr('class', 'pattern')\r\n .attr('height', 1)\r\n .attr('width', 1)\r\n .attr('id', ({ id }) => id);\r\n\r\n // Add images to patterns\r\n const patternImages = patterns.patternify({ tag: 'image', selector: 'pattern-image', data: d => [d] })\r\n .attr('x', 0)\r\n .attr('y', 0)\r\n .attr('height', ({ imageWidth }) => imageWidth)\r\n .attr('width', ({ imageHeight }) => imageHeight)\r\n .attr('xlink:href', ({ data }) => data.nodeImage && data.nodeImage.url)\r\n .attr('src', () => `${siteUrlBase()}/memberzone/profile/default-profile.jpg`)\r\n .attr('viewbox', ({ imageWidth, imageHeight }) => `0 0 ${imageWidth * 2} ${imageHeight}`)\r\n .attr('preserveAspectRatio', 'xMidYMin slice');\r\n\r\n // Remove patterns exit selection after animation\r\n patternsSelection.exit().transition().duration(attrs.duration).remove();\r\n\r\n // -------------------------- LINKS ----------------------\r\n // Get links selection\r\n const linkSelection = attrs.centerG.selectAll('path.link')\r\n .data(links, ({ id }) => id);\r\n\r\n // Enter any new links at the parent's previous position.\r\n const linkEnter = linkSelection.enter()\r\n .insert('path', \"g\")\r\n .attr(\"class\", \"link\")\r\n .attr('d', d => {\r\n const o = {\r\n x: x0,\r\n y: y0\r\n };\r\n return this.diagonal(o, o)\r\n });\r\n\r\n // Get links update selection\r\n const linkUpdate = linkEnter.merge(linkSelection);\r\n\r\n // Styling links\r\n linkUpdate\r\n .attr(\"fill\", \"none\")\r\n .attr(\"stroke-width\", ({\r\n data\r\n }) => data.connectorLineWidth || 2)\r\n .attr('stroke', ({\r\n data\r\n }) => {\r\n if (data.connectorLineColor) {\r\n return this.rgbaObjToColor(data.connectorLineColor);\r\n }\r\n return 'green';\r\n })\r\n .attr('stroke-dasharray', ({\r\n data\r\n }) => {\r\n if (data.dashArray) {\r\n return data.dashArray;\r\n }\r\n return '';\r\n })\r\n\r\n // Transition back to the parent element position\r\n linkUpdate.transition()\r\n .duration(attrs.duration)\r\n .attr('d', d => this.diagonal(d, d.parent));\r\n\r\n // Remove any links which is exiting after animation\r\n const linkExit = linkSelection.exit().transition()\r\n .duration(attrs.duration)\r\n .attr('d', d => {\r\n const o = {\r\n x: x,\r\n y: y\r\n };\r\n return this.diagonal(o, o)\r\n })\r\n .remove();\r\n\r\n // -------------------------- NODES ----------------------\r\n // Get nodes selection\r\n const nodesSelection = attrs.centerG.selectAll('g.node')\r\n .data(nodes, ({\r\n id\r\n }) => id)\r\n\r\n // Enter any new nodes at the parent's previous position.\r\n const nodeEnter = nodesSelection.enter().append('g')\r\n .attr('class', 'node')\r\n .attr(\"transform\", d => `translate(${x0},${y0})`)\r\n .attr('cursor', 'pointer')\r\n .on('click', (event, d) => {\r\n if ([...event.srcElement.classList].includes('node-button-circle')) {\r\n return;\r\n }\r\n attrs.onNodeClick(d.data.nodeId);\r\n });\r\n\r\n // Add background rectangle for the nodes \r\n nodeEnter\r\n .patternify({\r\n tag: 'rect',\r\n selector: 'node-rect',\r\n data: d => [d]\r\n })\r\n .style(\"fill\", ({\r\n _children\r\n }) => _children ? \"lightsteelblue\" : \"#fff\")\r\n\r\n\r\n /*\r\n // Add node icon image inside node\r\n nodeEnter\r\n .patternify({\r\n tag: 'image',\r\n selector: 'node-icon-image',\r\n data: d => [d]\r\n })\r\n .attr('width', ({\r\n data\r\n }) => data.nodeIcon && data.nodeIcon.size)\r\n .attr('height', ({\r\n data\r\n }) => data.nodeIcon && data.nodeIcon.size)\r\n .attr(\"xlink:href\", ({\r\n data\r\n }) => data.nodeIcon && data.nodeIcon.icon)\r\n .attr('x', ({\r\n width\r\n }) => -width / 2 + 5)\r\n .attr('y', ({\r\n height,\r\n data\r\n }) => height / 2 - (data.nodeIcon && data.nodeIcon.size || 0) - 5)\r\n // Add total descendants text\r\n nodeEnter\r\n .patternify({\r\n tag: 'text',\r\n selector: 'node-icon-text-total',\r\n data: d => [d]\r\n })\r\n .text('test')\r\n .attr('x', ({\r\n width\r\n }) => -width / 2 + 7)\r\n .attr('y', ({\r\n height,\r\n data\r\n }) => height / 2 - (data.nodeIcon && data.nodeIcon.size) - 5)\r\n .text(({\r\n data\r\n }) => `${data.totalSubordinates} Subordinates`)\r\n .attr('fill', attrs.nodeTextFill)\r\n .attr('font-weight', 'bold')\r\n // Add direct descendants text\r\n nodeEnter\r\n .patternify({\r\n tag: 'text',\r\n selector: 'node-icon-text-direct',\r\n data: d => [d]\r\n })\r\n .text('test')\r\n .attr('x', ({\r\n width,\r\n data\r\n }) => -width / 2 + 10 + (data.nodeIcon && data.nodeIcon.size))\r\n .attr('y', ({\r\n height\r\n }) => height / 2 - 10)\r\n .text(({\r\n data\r\n }) => `${data.directSubordinates} Direct `)\r\n .attr('fill', attrs.nodeTextFill)\r\n .attr('font-weight', 'bold')\r\n */\r\n\r\n\r\n // Defined node images wrapper group\r\n const nodeImageGroups = nodeEnter.patternify({\r\n tag: 'g',\r\n selector: 'node-image-group',\r\n data: d => [d]\r\n })\r\n\r\n // Add background rectangle for node image\r\n nodeImageGroups\r\n .patternify({\r\n tag: 'rect',\r\n selector: 'node-image-rect',\r\n data: d => [d]\r\n })\r\n\r\n // Node update styles\r\n const nodeUpdate = nodeEnter.merge(nodesSelection)\r\n .style('font', '12px sans-serif');\r\n\r\n // Add foreignObject element inside rectangle\r\n const fo = nodeUpdate\r\n .patternify({\r\n tag: 'foreignObject',\r\n selector: 'node-foreign-object',\r\n data: d => [d]\r\n });\r\n\r\n // Add foreign object \r\n fo.patternify({\r\n tag: 'xhtml:div',\r\n selector: 'node-foreign-object-div',\r\n data: d => [d]\r\n });\r\n\r\n this.restyleForeignObjectElements();\r\n\r\n // Add Node button circle's group (expand-collapse button)\r\n const nodeButtonGroups = nodeEnter\r\n .patternify({\r\n tag: 'g',\r\n selector: 'node-button-g',\r\n data: d => [d]\r\n })\r\n .on('click', (event, d) => {\r\n event.stopPropagation();\r\n this.onButtonClick(event, d);\r\n });\r\n\r\n // Add expand collapse button circle \r\n nodeButtonGroups\r\n .patternify({\r\n tag: 'circle',\r\n selector: 'node-button-circle',\r\n data: d => [d]\r\n });\r\n\r\n // Add button text \r\n nodeButtonGroups\r\n .patternify({\r\n tag: 'text',\r\n selector: 'node-button-text',\r\n data: d => [d]\r\n })\r\n .attr('pointer-events', 'none');\r\n\r\n // Transition to the proper position for the node\r\n nodeUpdate.transition()\r\n .attr('opacity', 0)\r\n .duration(attrs.duration)\r\n .attr(\"transform\", ({\r\n x,\r\n y\r\n }) => `translate(${x},${y})`)\r\n .attr('opacity', 1);\r\n\r\n // Move images to desired positions\r\n nodeUpdate.selectAll('.node-image-group')\r\n .attr('transform', ({\r\n imageWidth,\r\n width,\r\n imageHeight,\r\n height\r\n }) => {\r\n let x = -imageWidth / 2 - width / 2;\r\n let y = -imageHeight / 2 - height / 2;\r\n return `translate(${x},${y})`\r\n });\r\n\r\n // Style node image rectangles\r\n nodeUpdate.select('.node-image-rect')\r\n .attr('fill', ({ id }) => `url(#${id})`)\r\n .attr('width', ({ imageWidth }) => imageWidth)\r\n .attr('height', ({ imageHeight }) => imageHeight)\r\n .attr('stroke', ({ imageBorderColor }) => imageBorderColor)\r\n .attr('stroke-width', ({ imageBorderWidth }) => imageBorderWidth)\r\n .attr('rx', ({ imageRx }) => imageRx)\r\n .attr('y', ({ imageCenterTopDistance }) => imageCenterTopDistance)\r\n .attr('x', ({ imageCenterLeftDistance }) => imageCenterLeftDistance)\r\n .attr('filter', ({ dropShadowId }) => dropShadowId);\r\n\r\n // Style node rectangles\r\n nodeUpdate.select('.node-rect')\r\n .attr('width', ({ data }) => data.width)\r\n .attr('height', ({ data }) => data.height)\r\n .attr('x', ({ data }) => -data.width / 2)\r\n .attr('y', ({ data }) => -data.height / 2)\r\n .attr('rx', ({ data }) => data.borderRadius || 0)\r\n .attr('stroke-width', ({ data }) => data.borderWidth || attrs.strokeWidth)\r\n .attr('cursor', 'pointer')\r\n .attr('stroke', ({ borderColor }) => borderColor)\r\n .style(\"fill\", ({ backgroundColor }) => backgroundColor);\r\n\r\n // Move node button group to the desired position\r\n nodeUpdate.select('.node-button-g')\r\n .attr('transform', ({ data }) => `translate(0,${data.height / 2})`)\r\n .attr('opacity', ({ children, _children, data }) => {\r\n if (children || _children || data.directSubordinates) {\r\n return 1;\r\n }\r\n return 0;\r\n });\r\n\r\n // Restyle node button circle\r\n nodeUpdate.select('.node-button-circle')\r\n .attr('r', 16)\r\n .attr('stroke-width', ({ data }) => data.borderWidth || attrs.strokeWidth)\r\n .attr('fill', attrs.backgroundColor)\r\n .attr('stroke', ({ borderColor }) => borderColor);\r\n\r\n // Restyle button texts\r\n nodeUpdate.select('.node-button-text')\r\n .attr('text-anchor', 'middle')\r\n .attr('alignment-baseline', 'middle')\r\n .attr('fill', attrs.defaultTextFill)\r\n .attr('font-size', ({ children }) => {\r\n if (children) return 40;\r\n return 26;\r\n })\r\n .text(({ children }) => {\r\n if (children) return '-';\r\n return '+';\r\n });\r\n\r\n // Align '+/-' text inside button\r\n const textNodes = nodeUpdate.select('.node-button-text');\r\n const textNodesGroups = textNodes && textNodes._groups;\r\n\r\n if (textNodesGroups && textNodesGroups.length) {\r\n textNodesGroups[0].forEach((el) => {\r\n if (this.isFirefox()) {\r\n el.setAttribute('y', el.textContent === '+' ? 8 : 11);\r\n } else if (this.isChrome()) {\r\n el.setAttribute('y', el.textContent === '+' ? 2 : 0);\r\n } else if (this.isEdge()) {\r\n el.setAttribute('y', 10);\r\n } else {\r\n el.setAttribute('y', 0);\r\n }\r\n });\r\n }\r\n\r\n // Remove any exiting nodes after transition\r\n const nodeExitTransition = nodesSelection.exit()\r\n .attr('opacity', 1)\r\n .transition()\r\n .duration(attrs.duration)\r\n .attr(\"transform\", d => `translate(${x},${y})`)\r\n .on('end', function () {\r\n d3.select(this).remove();\r\n })\r\n .attr('opacity', 0);\r\n\r\n // On exit reduce the node rects size to 0\r\n nodeExitTransition.selectAll('.node-rect')\r\n .attr('width', 10)\r\n .attr('height', 10)\r\n .attr('x', 0)\r\n .attr('y', 0);\r\n\r\n // On exit reduce the node image rects size to 0\r\n nodeExitTransition.selectAll('.node-image-rect')\r\n .attr('width', 10)\r\n .attr('height', 10)\r\n .attr('x', ({ width }) => width / 2)\r\n .attr('y', ({ height }) => height / 2);\r\n\r\n // Store the old positions for transition.\r\n nodes.forEach(d => {\r\n d.x0 = d.x;\r\n d.y0 = d.y;\r\n });\r\n }\r\n\r\n // This function detects whether current browser is edge\r\n isEdge() {\r\n return window.navigator.userAgent.includes(\"Edge\");\r\n }\r\n\r\n // This function detects whether current browser is firefox\r\n isFirefox() {\r\n return window.navigator.userAgent.includes(\"Firefox\");\r\n }\r\n\r\n // This function detects whether current browser is chrome\r\n isChrome() {\r\n return window.navigator.userAgent.includes(\"Chrome\");\r\n }\r\n\r\n /* Function converts rgba objects to rgba color string \r\n {red:110,green:150,blue:255,alpha:1} => rgba(110,150,255,1)\r\n */\r\n rgbaObjToColor({\r\n red,\r\n green,\r\n blue,\r\n alpha\r\n }) {\r\n return `rgba(${red},${green},${blue},${alpha})`;\r\n }\r\n\r\n // Generate custom diagonal - play with it here - https://observablehq.com/@bumbeishvili/curved-edges?collection=@bumbeishvili/work-components\r\n diagonal(s, t) {\r\n\r\n // Calculate some variables based on source and target (s,t) coordinates\r\n const x = s.x;\r\n const y = s.y;\r\n const ex = t.x;\r\n const ey = t.y;\r\n let xrvs = ex - x < 0 ? -1 : 1;\r\n let yrvs = ey - y < 0 ? -1 : 1;\r\n let rdef = 35;\r\n let rInitial = Math.abs(ex - x) / 2 < rdef ? Math.abs(ex - x) / 2 : rdef;\r\n let r = Math.abs(ey - y) / 2 < rInitial ? Math.abs(ey - y) / 2 : rInitial;\r\n let h = Math.abs(ey - y) / 2 - r;\r\n let w = Math.abs(ex - x) - r * 2;\r\n\r\n // Build the path\r\n const path = `\r\n M ${x} ${y}\r\n L ${x} ${y + h * yrvs}\r\n C ${x} ${y + h * yrvs + r * yrvs} ${x} ${y + h * yrvs + r * yrvs} ${x + r * xrvs} ${y + h * yrvs + r * yrvs}\r\n L ${x + w * xrvs + r * xrvs} ${y + h * yrvs + r * yrvs}\r\n C ${ex} ${y + h * yrvs + r * yrvs} ${ex} ${y + h * yrvs + r * yrvs} ${ex} ${ey - h * yrvs}\r\n L ${ex} ${ey}\r\n `\r\n // Return result\r\n return path;\r\n }\r\n\r\n restyleForeignObjectElements() {\r\n const attrs = this.getChartState();\r\n\r\n attrs.svg.selectAll('.node-foreign-object')\r\n .attr('width', ({\r\n width\r\n }) => width)\r\n .attr('height', ({\r\n height\r\n }) => height)\r\n .attr('x', ({\r\n width\r\n }) => -width / 2)\r\n .attr('y', ({\r\n height\r\n }) => -height / 2)\r\n attrs.svg.selectAll('.node-foreign-object-div')\r\n .style('width', ({\r\n width\r\n }) => `${width}px`)\r\n .style('height', ({\r\n height\r\n }) => `${height}px`)\r\n .style('color', 'white')\r\n .html(({\r\n data\r\n }) => data.template)\r\n }\r\n\r\n // Toggle children on click.\r\n async onButtonClick(event, d) {\r\n // If childrens are expanded\r\n if (d.children) {\r\n //Collapse them\r\n d._children = d.children;\r\n d.children = null;\r\n\r\n // Set descendants expanded property to false\r\n this.setExpansionFlagToChildren(d, false);\r\n } else {\r\n // Expand children\r\n d.children = d._children;\r\n d._children = null;\r\n\r\n if (!d.children) {\r\n // Need to load the next level dynamically\r\n const children = await this._getNextLevel(d.id);\r\n children.forEach(node => node.expanded = true);\r\n this.addNodes(children);\r\n } else {\r\n // Set each children as expanded\r\n d.children.forEach(({\r\n data\r\n }) => data.expanded = true)\r\n }\r\n }\r\n\r\n // Redraw Graph \r\n this.update(d);\r\n }\r\n\r\n // This function changes `expanded` property to descendants\r\n setExpansionFlagToChildren({ data, children, _children }, flag) { \r\n // Set flag to the current property\r\n data.expanded = flag;\r\n\r\n // Loop over and recursively update expanded children's descendants\r\n if (children) {\r\n children.forEach(d => {\r\n this.setExpansionFlagToChildren(d, flag)\r\n })\r\n }\r\n\r\n // Loop over and recursively update collapsed children's descendants\r\n if (_children) {\r\n _children.forEach(d => {\r\n this.setExpansionFlagToChildren(d, flag)\r\n })\r\n }\r\n }\r\n\r\n // This function can be invoked via chart.setExpanded API, it expands or collapses particular node\r\n setExpanded(id, expandedFlag) {\r\n const attrs = this.getChartState();\r\n // Retrieve node by node Id\r\n const node = attrs.allNodes.filter(({\r\n data\r\n }) => data.nodeId == id)[0]\r\n\r\n // If node exists, set expansion flag\r\n if (node) node.data.expanded = expandedFlag;\r\n\r\n // First expand all nodes\r\n attrs.root.children.forEach(d => this.expand(d));\r\n\r\n // Then collapse all nodes\r\n attrs.root.children.forEach(d => this.collapse(d));\r\n\r\n // Then expand only the nodes, which were previously expanded, or have an expand flag set\r\n attrs.root.children.forEach(d => this.expandSomeNodes(d));\r\n\r\n // Redraw graph\r\n this.update(attrs.root);\r\n }\r\n\r\n // Method which only expands nodes, which have property set \"expanded=true\"\r\n expandSomeNodes(d) {\r\n // If node has expanded property set\r\n if (d.data.expanded) {\r\n\r\n // Retrieve node's parent\r\n let parent = d.parent;\r\n\r\n // While we can go up \r\n while (parent) {\r\n\r\n // Expand all current parent's children\r\n if (parent._children) {\r\n parent.children = parent._children;\r\n }\r\n\r\n // Replace current parent holding object\r\n parent = parent.parent;\r\n }\r\n }\r\n\r\n // Recursivelly do the same for collapsed nodes\r\n if (d._children) {\r\n d._children.forEach(ch => this.expandSomeNodes(ch));\r\n }\r\n\r\n // Recursivelly do the same for expanded nodes \r\n if (d.children) {\r\n d.children.forEach(ch => this.expandSomeNodes(ch));\r\n }\r\n }\r\n\r\n\r\n // This function updates nodes state and redraws graph, usually after data change\r\n updateNodesState() {\r\n const attrs = this.getChartState();\r\n // Store new root by converting flat data to hierarchy\r\n attrs.root = d3.stratify()\r\n .id(({\r\n nodeId\r\n }) => nodeId)\r\n .parentId(({\r\n parentNodeId\r\n }) => parentNodeId)\r\n (attrs.data)\r\n\r\n // Store positions, where children appear during their enter animation\r\n attrs.root.x0 = 0;\r\n attrs.root.y0 = 0;\r\n\r\n // Store all nodes in flat format (although, now we can browse parent, see depth e.t.c. )\r\n attrs.allNodes = attrs.layouts.treemap(attrs.root).descendants()\r\n\r\n // Store direct and total descendants count\r\n attrs.allNodes.forEach(d => {\r\n const childrenLength = d.children ? d.children.length : 0;\r\n const directSubordinates = d.data.directSubordinates || childrenLength;\r\n Object.assign(d.data, {\r\n directSubordinates: directSubordinates,\r\n totalSubordinates: d.descendants().length - 1\r\n })\r\n })\r\n\r\n // Expand all nodes first\r\n attrs.root.children && attrs.root.children.forEach(this.expand);\r\n\r\n // Then collapse them all\r\n attrs.root.children && attrs.root.children.forEach(d => this.collapse(d));\r\n\r\n // Then only expand nodes, which have expanded proprty set to true\r\n attrs.root.children && attrs.root.children.forEach(ch => this.expandSomeNodes(ch));\r\n\r\n // Redraw Graphs\r\n this.update(attrs.root)\r\n }\r\n\r\n\r\n // Function which collapses passed node and it's descendants\r\n collapse(d) {\r\n if (d.children) {\r\n d._children = d.children;\r\n d._children.forEach(ch => this.collapse(ch));\r\n d.children = null;\r\n }\r\n }\r\n\r\n // Function which expands passed node and it's descendants \r\n expand(d) {\r\n if (d._children) {\r\n d.children = d._children;\r\n d.children.forEach(ch => this.expand(ch));\r\n d._children = null;\r\n }\r\n }\r\n\r\n // Zoom handler function\r\n zoomed(event, d) {\r\n const attrs = this.getChartState();\r\n const chart = attrs.chart;\r\n\r\n // Get d3 event's transform object\r\n const transform = event.transform;\r\n\r\n // Store it\r\n attrs.lastTransform = transform;\r\n\r\n // Reposition and rescale chart accordingly\r\n chart.attr('transform', transform);\r\n\r\n // Apply new styles to the foreign object element\r\n if (this.isEdge()) {\r\n this.restyleForeignObjectElements();\r\n }\r\n\r\n }\r\n}\r\n","import { bindable, observable } from 'aurelia-framework';\r\nimport { EventAggregator } from 'aurelia-event-aggregator';\r\nimport { Security } from 'common/security';\r\nimport { Api } from 'common/server';\r\nimport { OrgChart } from './org-chart';\r\nimport { Page } from 'common/ui';\r\nimport { I18n } from 'common/i18n';\r\nimport { ProductionService } from 'services/production-service';\r\nimport { Sites } from 'services/sites';\r\nimport { Config } from 'services/config';\r\nimport { c, siteUrlBase } from 'common/common';\r\nimport { FormatNumber2ValueConverter } from 'resources/value-converters/format-number2';\r\nimport { TIME_PERIOD } from 'common/constants';\r\nimport moment from 'moment';\r\nimport environment from '../../../../config/environment.json';\r\n\r\nexport class TeamChart {\r\n static inject = [EventAggregator, Security, Api, Page, I18n, ProductionService, Sites, Config, FormatNumber2ValueConverter];\r\n _ea;\r\n _security;\r\n _api;\r\n _page;\r\n _i18n;\r\n _production;\r\n _sites;\r\n _config;\r\n _formatNumber2ValueConverter;\r\n\r\n @bindable view = 'chart';\r\n @bindable id;\r\n @bindable load = false;\r\n @bindable allowMapView = false;\r\n teamChartEl;\r\n\r\n TIME_PERIOD = TIME_PERIOD;\r\n timePeriod = TIME_PERIOD.MTD;\r\n sortTypes = [];\r\n @observable sortType1;\r\n @observable sortType2;\r\n @observable sortType3;\r\n agentTypes = ['prospects', 'registered-reps', 'recruits'];\r\n\r\n agentDisplays = ['team-chart-producers', 'team-chart-all'];\r\n @observable agentDisplay = 'team-chart-producers';\r\n\r\n @observable onlyActive = true;\r\n @observable showLevel = true;\r\n @observable showImage = true;\r\n showExport = false;\r\n _handlers = [];\r\n\r\n constructor(ea, security, api, page, i18n, production, sites, config, formatNumber2ValueConverter) {\r\n this._ea = ea;\r\n this._security = security;\r\n this._api = api;\r\n this._page = page;\r\n this._i18n = i18n;\r\n this._production = production;\r\n this._formatNumber2ValueConverter = formatNumber2ValueConverter;\r\n this.canPrint = security.isAdmin;\r\n this._sites = sites;\r\n\r\n this.agentDisplay = config.value('myTeamDefaultMemberDisplayProducers') ? 'team-chart-producers' : 'team-chart-all';\r\n }\r\n\r\n bind() {\r\n if (!this.id) this.id = this._security.authenticatedMemberId;\r\n this.setShowExport();\r\n }\r\n\r\n showView(view) {\r\n this.view = view;\r\n if (this.view === 'map' && !this.loadMap) this.loadMap = true;\r\n }\r\n\r\n idChanged(newValue, oldValue) {\r\n if (!oldValue) return;\r\n this._initialize();\r\n this.setShowExport();\r\n }\r\n\r\n setShowExport() {\r\n this.showExport = false; // this._security.isAdmin;\r\n }\r\n\r\n loadChanged(newValue, oldValue) {\r\n if (oldValue === undefined && !newValue) return;\r\n if (!oldValue && newValue) {\r\n this._initialize();\r\n }\r\n }\r\n\r\n toggleSettings() {\r\n this.showSettingsDrawer = moment().format();\r\n }\r\n\r\n onlyActiveChanged(newValue, oldValue) {\r\n this._initialize(true);\r\n }\r\n\r\n showLevelChanged(newValue, oldValue) {\r\n this._initialize(true);\r\n }\r\n\r\n showImageChanged(newValue, oldValue) {\r\n this._initialize(true);\r\n }\r\n\r\n async attached() {\r\n await this._loadOptions();\r\n if (!this.id || !this.load) return;\r\n this._initialize();\r\n }\r\n\r\n selectTimePeriod(timePeriod) {\r\n this.timePeriod = timePeriod;\r\n this._initialize(true);\r\n }\r\n\r\n sortType1Changed(newValue, oldValue) {\r\n if (oldValue === undefined || oldValue === null) return;\r\n this._initialize(true);\r\n }\r\n\r\n sortType2Changed(newValue, oldValue) {\r\n if (oldValue === undefined || oldValue === null) return;\r\n this._initialize(true);\r\n }\r\n\r\n sortType3Changed(newValue, oldValue) {\r\n if (oldValue === undefined || oldValue === null) return;\r\n this._initialize(true);\r\n }\r\n\r\n agentDisplayChanged(newValue, oldValue) {\r\n if (oldValue === undefined || oldValue === null) return;\r\n this._initialize(true);\r\n }\r\n\r\n async _initialize(clear = false) {\r\n try {\r\n if (clear) {\r\n this.teamChartEl.innerHTML = '';\r\n this._orgChart = undefined;\r\n }\r\n this.theme = await this._sites.theme();\r\n const loadSingleLevel = this.agentDisplay !== 'team-chart-producers';\r\n const data = await this._getDownline(this.id, loadSingleLevel);\r\n this._orgChart = new OrgChart(this.getNodeChildren)\r\n .container(this.teamChartEl)\r\n .data(data)\r\n .svgWidth(700)\r\n .initialZoom(0.7)\r\n .onNodeClick(nodeId => {\r\n this._ea.publish(c.EventKeys.site.openProfile, { memberId: nodeId, tab: { key: 'chart' } });\r\n })\r\n .render();\r\n } catch (err) {\r\n console.log(err);\r\n }\r\n }\r\n\r\n async _loadOptions() {\r\n try {\r\n this.premiumTypes = await this._production.premiumTypes();\r\n this.sortTypes = [...this.premiumTypes, ...this.agentTypes];\r\n this.sortType1 = 'submitted-actual';\r\n this.sortType2 = 'issued-actual';\r\n this.sortType3 = '';\r\n } catch (err) {\r\n console.log(err);\r\n }\r\n }\r\n\r\n exportDownline() {\r\n if (this.id === this._security.authenticatedMemberId) {\r\n this._page.exportData(this._api, 'member/export-my-downline-key', '/api/member/export-my-downline');\r\n } else {\r\n this._page.exportData(this._api, `member/${encodeURIComponent(this.id)}/export-downline-key`, '/api/member/export-downline');\r\n }\r\n }\r\n\r\n getNodeChildren = async(id) => {\r\n return await this._getDownline(id, true, false);\r\n }\r\n\r\n async _getDownline(id, singleLevel = true, includeNode = true) {\r\n try {\r\n this.loading = true;\r\n let url = `member/chart/${singleLevel ? 'downline-level' : 'downline'}?memberId=${encodeURIComponent(id)}&includeNode=${includeNode ? 'true' : 'false'}&includeInactive=${this.onlyActive ? 'false' : 'true'}`;\r\n const qs = [];\r\n qs.push(`display=${encodeURIComponent(this.agentDisplay)}`);\r\n if (this.timePeriod) qs.push(`timePeriod=${encodeURIComponent(this.timePeriod)}`);\r\n if (this.sortType1) qs.push(`sortType1=${encodeURIComponent(this.sortType1)}`);\r\n if (this.sortType2) qs.push(`sortType2=${encodeURIComponent(this.sortType2)}`);\r\n if (this.sortType3) qs.push(`sortType3=${encodeURIComponent(this.sortType3)}`);\r\n if (qs.length) url += `&${qs.join('&')}`;\r\n const downline = await this._api.get(url);\r\n const data = await this._hydrateData(downline);\r\n return data;\r\n } catch (err) {\r\n console.log(err);\r\n } finally {\r\n this.loading = false;\r\n }\r\n }\r\n\r\n async _hydrateData(flattenedData) {\r\n const width = 350;\r\n const height = 160;\r\n const agencyHeight = 175;\r\n const masterAgencyHeight = 190;\r\n const cornerShape = 'CIRCLE'; //['ORIGINAL','ROUNDED','CIRCLE']\r\n const nodeImageWidth = 60;\r\n const nodeImageHeight = 60;\r\n const centerTopDistance = nodeImageWidth / 2 + 10;\r\n const centerLeftDistance = nodeImageWidth / 2 + 10;\r\n const expanded = this.agentDisplay === 'team-chart-producers';\r\n\r\n const activeBorderColor = {\r\n red: 0,\r\n green: 54,\r\n blue: 84,\r\n alpha: 0.7,\r\n };\r\n const activeBackgroundColor = {\r\n red: 255,\r\n green: 255,\r\n blue: 255,\r\n alpha: 1,\r\n };\r\n const inactiveBorderColor = {\r\n red: 255,\r\n green: 0,\r\n blue: 0,\r\n alpha: 1,\r\n };\r\n const inactiveBackgroundColor = {\r\n red: 255,\r\n green: 204,\r\n blue: 203,\r\n alpha: 1,\r\n };\r\n const masterAgencyBorderColor = {\r\n red: 118,\r\n green: 210,\r\n blue: 33,\r\n alpha: 1,\r\n };\r\n const masterAgencyBackgroundColor = {\r\n red: 132,\r\n green: 229,\r\n blue: 65,\r\n alpha: 1,\r\n };\r\n const agencyBorderColor = {\r\n red: 168,\r\n green: 210,\r\n blue: 116,\r\n alpha: 1,\r\n };\r\n const agencyBackgroundColor = {\r\n red: 204,\r\n green: 229,\r\n blue: 174,\r\n alpha: 1,\r\n };\r\n const teamBorderColor = {\r\n red: 0,\r\n green: 48,\r\n blue: 143,\r\n alpha: 1,\r\n };\r\n const teamBackgroundColor = {\r\n red: 114,\r\n green: 160,\r\n blue: 193,\r\n alpha: 1,\r\n };\r\n const prospectBorderColor = {\r\n red: 255,\r\n green: 165,\r\n blue: 0,\r\n alpha: 1,\r\n };\r\n const prospectBackgroundColor = {\r\n red: 255,\r\n green: 221,\r\n blue: 159,\r\n alpha: 1,\r\n };\r\n\r\n const titlePaddingLeft = this.showImage\r\n ? nodeImageWidth + 20 + 10 // additional 10px right of the image\r\n : 10;\r\n\r\n const treeData = [];\r\n await flattenedData.reduce(async (promise, d) => {\r\n await promise;\r\n let imgUrl = this.showImage ? `${environment.static}${d.imageUrl}` : undefined;\r\n if (imgUrl) {\r\n if (!await this._profileImageExists(imgUrl)) {\r\n // use the default profile image\r\n imgUrl = `${environment.static}/files/themes/${this.theme.key}/favicons/favicon-96x96.png`\r\n }\r\n }\r\n let cardHeight = height;\r\n let borderColor = d.active ? activeBorderColor : inactiveBorderColor;\r\n let backgroundColor = d.active ? activeBackgroundColor : inactiveBackgroundColor;\r\n if (d.active && d.isAgency) {\r\n borderColor = agencyBorderColor;\r\n backgroundColor = agencyBackgroundColor;\r\n cardHeight = agencyHeight;\r\n } else if (d.active && d.isTeam) {\r\n borderColor = teamBorderColor;\r\n backgroundColor = teamBackgroundColor;\r\n }\r\n if (d.isProspect) {\r\n borderColor = prospectBorderColor;\r\n backgroundColor = prospectBackgroundColor;\r\n }\r\n if (d.production.length && d.production[0].masterAgency !== null) {\r\n borderColor = masterAgencyBorderColor;\r\n backgroundColor = masterAgencyBackgroundColor;\r\n cardHeight = masterAgencyHeight;\r\n }\r\n\r\n let template = `
${instructionsKey&t}
\\r\\n \\r\\n