@medicus.ai/medicus-report-pdf-generator 1.3.13 → 1.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/HANDOVER.md +146 -0
  3. package/README.md +26 -26
  4. package/app/i18n.config.js +20 -20
  5. package/app/i18n_wellbeing.config.js +20 -20
  6. package/app/services/localeService.js +28 -28
  7. package/assets/Mediclinic/css/nasco_report.css +6297 -6297
  8. package/assets/Mediclinic/css/nasco_report_rtl.css +851 -851
  9. package/assets/Mediclinic/css/style.css +33 -33
  10. package/assets/Mediclinic/js/js.js +112 -112
  11. package/assets/Mediclinic/js/raphael.js +8437 -8437
  12. package/assets/arabic.css +275 -275
  13. package/assets/charts.min.js +7 -7
  14. package/assets/corporate_report/css/report.css +582 -582
  15. package/assets/corporate_report/css/report_rtl.css +144 -144
  16. package/assets/corporate_report/js/js.js +14 -14
  17. package/assets/data/data.json +124 -124
  18. package/assets/data/data2.json +675 -675
  19. package/assets/data/pdf_data_with_history.json +1255 -1255
  20. package/assets/doctor-note-insight-icon.svg +11 -11
  21. package/assets/imc/css/style.css +61 -61
  22. package/assets/jquery-1.4.min.js +151 -151
  23. package/assets/jquery-2.1.0.min.js +3 -3
  24. package/assets/js.js +201 -201
  25. package/assets/medicus_pdf/arabic.css +444 -444
  26. package/assets/medicus_pdf/styles.css +2427 -2427
  27. package/assets/print.css +4 -4
  28. package/assets/qr-code-style.css +68 -68
  29. package/assets/qrcode.min.js +3 -3
  30. package/assets/raphael-min.js +10 -10
  31. package/assets/sanusx/css/sanusx_report.css +707 -707
  32. package/assets/sizing.js +2 -2
  33. package/assets/styles.css +1545 -1545
  34. package/assets/styles.min.css +1358 -1358
  35. package/assets/translation.js +30 -30
  36. package/assets/wellbeing/css/nasco_report.css +3472 -3472
  37. package/assets/wellbeing/css/nasco_report_rtl.css +679 -679
  38. package/assets/wellbeing/js/js.js +111 -111
  39. package/assets/wellbeing/js/raphael.js +8437 -8437
  40. package/base64/cairo-font.js +2 -2
  41. package/config/Mediclinic.json +37 -37
  42. package/config/Najeeb.ai.json +35 -35
  43. package/config/Pha.json +64 -64
  44. package/config/bionext.json +37 -37
  45. package/config/default.json +35 -35
  46. package/config/diagnostikare.json +34 -34
  47. package/config/maisonsante.json +39 -39
  48. package/config/nasco.json +35 -35
  49. package/config/sanitas.json +35 -35
  50. package/config/sanusx.json +34 -34
  51. package/config/test.txt +4 -4
  52. package/data converter.js +53 -53
  53. package/docs/01-architecture-overview.md +149 -0
  54. package/docs/02-configuration-and-whitelabelling.md +111 -0
  55. package/docs/03-templating-and-rendering.md +71 -0
  56. package/docs/04-report-pipelines.md +128 -0
  57. package/docs/05-questions-and-data-model.md +67 -0
  58. package/docs/06-internationalization.md +59 -0
  59. package/docs/07-email-notifications.md +59 -0
  60. package/docs/08-known-issues-and-technical-debt.md +41 -0
  61. package/docs/README.md +22 -0
  62. package/downloadfile.js +6 -6
  63. package/example.txt +1188 -1188
  64. package/index.js +481 -480
  65. package/lib/big_integral_questionnaire.js +370 -298
  66. package/lib/corporate_report_generator.js +399 -399
  67. package/lib/pdf_generator.min.js +525 -525
  68. package/lib/sanusx_report_generator.js +533 -533
  69. package/lib/sendEmail.js +343 -343
  70. package/lib/template.js +2227 -2227
  71. package/lib/wellbeing_report_generator.js +2164 -2134
  72. package/locales/ar-AE.json +169 -169
  73. package/locales/ar-SA.json +169 -169
  74. package/locales/ar.json +397 -397
  75. package/locales/de.json +169 -169
  76. package/locales/en.json +229 -229
  77. package/locales/fr.json +168 -168
  78. package/locales/pt.json +165 -165
  79. package/locales/wellbeing/ar-AE.json +149 -149
  80. package/locales/wellbeing/ar-SA.json +257 -257
  81. package/locales/wellbeing/de.json +301 -301
  82. package/locales/wellbeing/en.json +423 -423
  83. package/locales/wellbeing/es.json +133 -133
  84. package/locales/wellbeing/fr.json +121 -121
  85. package/locales/wellbeing/it-IT.json +121 -121
  86. package/locales/wellbeing/pt.json +121 -121
  87. package/locales/wellbeing/tr.json +121 -121
  88. package/locales/wellbeing/zh-CN.json +121 -121
  89. package/locales/zh-CN.json +165 -165
  90. package/package.json +47 -47
  91. package/preview-big-integral.js +75 -75
  92. package/run.js +15 -15
  93. package/templates/Mediclinic/blocks/first-section.html +205 -205
  94. package/templates/Mediclinic/blocks/footer.html +7 -7
  95. package/templates/Mediclinic/blocks/header-template.html +5 -5
  96. package/templates/Mediclinic/blocks/header.html +20 -20
  97. package/templates/Mediclinic/blocks/patient-table.html +38 -38
  98. package/templates/Mediclinic/blocks/pdf-header.html +9 -9
  99. package/templates/Mediclinic/blocks/tips.html +8 -8
  100. package/templates/Mediclinic/ltr_no_pages.html +37 -37
  101. package/templates/Mediclinic/rtl_no_pages.html +42 -42
  102. package/templates/Mediclinic/wellbeing_template.html +41 -41
  103. package/templates/Pha/blocks/first-section.html +207 -207
  104. package/templates/Pha/blocks/footer.html +7 -7
  105. package/templates/Pha/blocks/header-template.html +5 -5
  106. package/templates/Pha/blocks/header.html +20 -20
  107. package/templates/Pha/blocks/patient-table.html +38 -38
  108. package/templates/Pha/blocks/pdf-header.html +8 -8
  109. package/templates/Pha/blocks/tips.html +8 -8
  110. package/templates/Pha/ltr_no_pages.html +37 -37
  111. package/templates/Pha/rtl_no_pages.html +42 -42
  112. package/templates/Pha/wellbeing_template.html +41 -41
  113. package/templates/base.html +23 -23
  114. package/templates/blocks/ar-first-page-header.html +68 -68
  115. package/templates/blocks/ar-footer.html +54 -54
  116. package/templates/blocks/ar-header.html +67 -67
  117. package/templates/blocks/biomarker-compact-ar.html +27 -27
  118. package/templates/blocks/biomarker-compact.html +27 -27
  119. package/templates/blocks/biomarker-details.html +41 -41
  120. package/templates/blocks/biomarker-insight.html +22 -22
  121. package/templates/blocks/biomarker-min.html +9 -9
  122. package/templates/blocks/doctor-note.html +11 -11
  123. package/templates/blocks/footer.html +35 -35
  124. package/templates/blocks/header-first-page.html +46 -46
  125. package/templates/blocks/header.html +49 -49
  126. package/templates/blocks/panel-compact.html +38 -38
  127. package/templates/blocks/panel-details.html +16 -16
  128. package/templates/blocks/report-summary.html +16 -16
  129. package/templates/blocks/section-title.html +4 -4
  130. package/templates/blocks/signature.html +16 -16
  131. package/templates/blocks/summary-insight.html +15 -15
  132. package/templates/blocks/summary.html +9 -9
  133. package/templates/corporate_report/cover_page.html +23 -23
  134. package/templates/corporate_report/footer.html +9 -9
  135. package/templates/corporate_report/ltr_no_pages.html +20 -20
  136. package/templates/corporate_report/page.html +24 -24
  137. package/templates/corporate_report/participant_analytics.html +5 -5
  138. package/templates/corporate_report/rtl_no_pages.html +20 -20
  139. package/templates/empty.html +10 -10
  140. package/templates/first_page_head.html +157 -157
  141. package/templates/imc/first-header-template.html +53 -53
  142. package/templates/ltr.html +1368 -1368
  143. package/templates/ltr_no_pages.html +89 -89
  144. package/templates/maisonsante/blocks/first-section.html +151 -207
  145. package/templates/maisonsante/blocks/footer.html +7 -7
  146. package/templates/maisonsante/blocks/header-template.html +5 -5
  147. package/templates/maisonsante/blocks/header.html +20 -20
  148. package/templates/maisonsante/blocks/patient-table.html +38 -38
  149. package/templates/maisonsante/blocks/pdf-header.html +8 -8
  150. package/templates/maisonsante/blocks/tips.html +8 -8
  151. package/templates/maisonsante/ltr_no_pages.html +38 -38
  152. package/templates/maisonsante/rtl_no_pages.html +43 -43
  153. package/templates/maisonsante/wellbeing_template.html +41 -41
  154. package/templates/no_pages.html +1224 -1224
  155. package/templates/popup/popup-template.html +129 -129
  156. package/templates/rtl_no_pages.html +92 -92
  157. package/templates/sanusx/blocks/footer.html +6 -6
  158. package/templates/sanusx/blocks/header.html +20 -20
  159. package/templates/sanusx/blocks/personal-details.html +123 -123
  160. package/templates/sanusx/blocks/predictions-section.html +57 -57
  161. package/templates/sanusx/blocks/recommendations-section.html +6 -6
  162. package/templates/sanusx/blocks/super-power-section.html +29 -29
  163. package/templates/sanusx/blocks/tips.html +8 -8
  164. package/templates/sanusx/ltr_no_pages.html +26 -26
  165. package/templates/sanusx/rtl_no_pages.html +36 -36
  166. package/templates/template.html +1377 -1377
  167. package/templates/wellbeing/blocks/first-section.html +106 -106
  168. package/templates/wellbeing/blocks/footer.html +7 -7
  169. package/templates/wellbeing/blocks/header.html +37 -37
  170. package/templates/wellbeing/blocks/tips.html +8 -8
  171. package/templates/wellbeing/ltr_no_pages.html +35 -35
  172. package/templates/wellbeing/rtl_no_pages.html +36 -36
  173. package/templates/wellbeing/wellbeing_template.html +43 -43
  174. package/test.js +74 -74
  175. package/testing-reports/mediclinic/arabic-data.js +0 -439
  176. package/testing-reports/mediclinic/doctor-data.js +0 -523
  177. package/testing-reports/mediclinic/with-wellbeing.js +0 -415
  178. package/testing-reports/pha/notes-example.js +0 -397
@@ -1,526 +1,526 @@
1
- "use strict";
2
- const fs = require("fs"), {promisify: promisify} = require("util"), {JSDOM: JSDOM} = require("jsdom"),
3
- fetch = require("node-fetch"), hummus = require("hummus"), memoryStreams = require("memory-streams"),
4
- path = require("path"), LocaleService = require("../app/services/localeService.js"),
5
- i18n = require("../app/i18n.config.js"), puppeteer = require("puppeteer");
6
- var Chart = require("chart.js"), QRCode = require("qrcode"), localeService = new LocaleService(i18n);
7
- let isRTL = !1, OUT_FILE = "output/report-pdf.html", Pdf_file = "";
8
- const appDir = path.dirname(require.main.filename), FROM_TO = 0, LESS_THAN = 1, LESS_THAN_OR_EQUAL = 2, MORE_THAN = 3,
9
- MORE_THAN_OR_EQUAL = 4;
10
- let $, debug = !0, debugLog = (e, t = "") => {
11
- debug && console.log(e, t)
12
- }, shouldRenderCustomHeader = !1, generateHTMLStaging = async (e, t) => {
13
- let a = Date.now();
14
- debug = t, OUT_FILE = path.resolve(__dirname + "/../output/report-pdf" + a + ".html"), Pdf_file = "/output/report-pdf" + a + ".html";
15
- let r = !1;
16
- -1 !== e.language.indexOf("ar") && (e.language = "ar-SA", r = !0), console.log("Took 1", Date.now() - a, " ms to finish");
17
- let o = e.labType && 9 === e.labType;
18
- shouldRenderCustomHeader = o && e.customHeader, localeService.setLocale(e.language), debugLog("pdf language:", e.language);
19
- let l = shouldRenderCustomHeader ? fs.readFileSync(path.resolve(__dirname + "/../templates/imc/first-header-template.html"), "utf8") : r ? fs.readFileSync(path.resolve(__dirname + "/../templates/rtl_no_pages.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/ltr_no_pages.html"), "utf8"),
20
- n = r ? fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/ar-first-page-header.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/header-first-page.html"), "utf8"),
21
- i = r ? fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/ar-header.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/header.html"), "utf8"),
22
- s = r ? fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/ar-footer.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/footer.html"), "utf8"),
23
- c = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/panel-compact.html"), "utf8"),
24
- d = r ? fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/biomarker-compact-ar.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/biomarker-compact.html"), "utf8"),
25
- p = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/panel-details.html"), "utf8"),
26
- m = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/biomarker-details.html"), "utf8"),
27
- u = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/biomarker-insight.html"), "utf8"),
28
- g = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/summary.html"), "utf8"),
29
- h = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/report-summary.html"), "utf8"),
30
- f = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/summary-insight.html"), "utf8"),
31
- b = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/signature.html"), "utf8"),
32
- v = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/section-title.html"), "utf8"),
33
- w = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/doctor-note.html"), "utf8");
34
- console.log("Took 2", Date.now() - a, " ms to finish");
35
- let y = e.labLogo.split(".").pop(), S = e.labLogo;
36
- e.labLogo.includes("http") && (S = e.labLogo + `?v=${(new Date).valueOf()}`);
37
- let x = "";
38
- try {
39
- x = await fetch(S).then(e => e.buffer()).then(e => `data:image/${y};base64,` + e.toString("base64"))
40
- } catch (e) {
41
- debugLog("Couldn't browse lab logo!: ", e)
42
- }
43
- console.log("Took 3", Date.now() - a, " ms to finish");
44
- let k = [];
45
- debugLog("templates loaded");
46
- let D = e.patientName, _ = e.timeZoneOffset ? e.timeZoneOffset : 0, C = new Date(1e3 * e.reportDate + 36e5 * _),
47
- R = C.getDate(), T = C.getMonth();
48
- T += 1;
49
- let E = C.getFullYear(), N = (C.getHours() < 10 ? "0" : "") + C.getHours(),
50
- F = (C.getMinutes() < 10 ? "0" : "") + C.getMinutes(), P = N > 12 ? N - 12 : N;
51
- P = 0 == P ? 12 : P;
52
- let L = N > 12 ? "pm" : "am", O = "";
53
- O = "fr" === localeService.getCurrentLocale() ? R + " " + T + " " + E + "<br/>" + P + ":" + F + " " + localeService.t(L) : "de" === localeService.getCurrentLocale() ? R + "." + T + (r ? "،" : ",") + E + "<br/>" + N + ":" + F : R + "." + T + "." + E + "<br/>" + P + ":" + F + " " + localeService.t(L), i = i.replace("{{logo}}", x).replace("{{patient_name}}", D).replace("{{report_ref}}", fitNumber(e.reportNumber)).replace("{{division_name}}", e.reportDivision).replace("{{report_date}}", O).replace("{{PREPARED_FOR_T}}", localeService.t("PREPARED FOR")).replace("{{REFERENCE_T}}", localeService.t("REFERENCE")).replace("{{REFERENCE_T}}", localeService.t("REFERENCE")).replace("{{DIVISION_T}}", localeService.t(o ? "hospital" : "BRANCH")).replace("{{REPORT_DATE_T}}", localeService.t("REPORT DATE")), console.log("Took 4", Date.now() - a, " ms to finish");
54
- let B = e.labName;
55
- e.labAddress = e.labAddress, B += e.labAddress ? "<br>" + e.labAddress.replace(/\n/g, "<br>") : "", B += e.labPhoneNumber ? "<br>" + e.labPhoneNumber : "", n = n.replace("{{logo}}", x).replace("{{lab_info}}", B).replace("{{report_ref}}", fitNumber(e.reportNumber)).replace("{{division_name}}", e.reportDivision).replace("{{report_date}}", O).replace("{{PREPARED_FOR_T}}", localeService.t("PREPARED FOR")).replace("{{REFERENCE_T}}", localeService.t("REFERENCE")).replace("{{DIVISION_T}}", localeService.t(o ? "hospital" : "BRANCH")).replace("{{REPORT_DATE_T}}", localeService.t("REPORT DATE")).replace("{{LAB_T}}", localeService.t("LAB")), console.log("Took 5", Date.now() - a, " ms to finish"), s = s.replace("{{smartService}}", localeService.t("smartReportBy")).replace("{{Page}}", localeService.t("Page")).replace("{{of}}", localeService.t("of")).replace("{{address}}", B.replace(/<br>/g, "\t")), console.log("Took 6", Date.now() - a, " ms to finish");
56
- let I = new JSDOM(i), M = new JSDOM(n), A = new JSDOM(s), q = require("jquery")(I.window),
57
- H = require("jquery")(M.window), V = require("jquery")(A.window);
58
- const z = q(".page-head .logo .header_logo").first();
59
- e.copyright && V(".footer .footer-content .pages-container").after(`<div style="padding-top: 4px;">${e.copyright}</div>`), o && (z.css({
60
- maxHeight: "100%",
61
- width: "auto",
62
- maxWidth: "20%"
63
- }), H(".logo-container").css({height: "140px"}), H(".logo-container .logo").css({height: "100%"}), H(".page-head .logo img").css({
64
- maxHeight: "50%",
65
- width: "auto",
66
- maxWidth: "50%"
67
- }), V(".footer #footer_logo_container").hide(), r ? V(".footer .footer-content").css({flexDirection: "row-reverse"}) : V(".footer .footer-content").css({flexDirection: "unset"}));
68
- const U = new JSDOM(l);
69
- ($ = require("jquery")(U.window))(".logo img").attr("src", x), $("#lab-info").html(B), $("#reference").text(e.reportNumber), $("#division").text(e.reportDivision), $("#report-date").text(O), $("#report-title").text(e.reportTitle), $("#report-title-header-ltr .heading").text(localeService.t("Laboratory Report")), $("#report-title-header .heading").text(localeService.t("Laboratory Report")), console.log("Took 7", Date.now() - a, " ms to finish"), renderProfileItems(e, B, shouldRenderCustomHeader), console.log("Took 8", Date.now() - a, " ms to finish");
70
- let j = localeService.t("Access a detailed report online or in our app.") + "\n<br>" + localeService.t("1) Visit") + " " + e.moreLink + "\n";
71
- e.patientPin && (j += "<br>" + localeService.t(e.showPIN ? "2) Enter this PIN code:" : "Log in with a myLAB account") + " \n"), $("#more-link").html(j), e.patientPin && $("#pin").text(e.patientPin), $("#more-link_header").text(localeService.t("There's more...")), $("#more-link_header-rtl").text(localeService.t("There's more..."));
72
- let J = e.patientName, G = (new Buffer.from(J).toString("base64"), e.patientPin);
73
- if (G) {
74
- new Buffer.from(G).toString("base64");
75
- let t = "v_" + D + "_!_" + G;
76
- $("#chartsData").append("<script> var qrCodeText = " + JSON.stringify(t) + "<\/script>"), $("#pin.pin").css("display", e.showPIN ? "block" : "none")
77
- } else $("#chartsData").append("<script> var qrCodeText = null <\/script>");
78
- if ($("#canvas.pin-qr").css("display", G ? "block" : "none"), G || $("#canvas.pin-qr").remove(), console.log("Took 9", Date.now() - a, " ms to finish"), e.showCompactView) {
79
- console.log("Took 10", Date.now() - a, " ms to finish");
80
- let t = 0;
81
- e.panels.forEach(e => {
82
- let a = "cpt-pnl-" + safeCssName("cp" + e.panelId), r = c.replace("{{panel-id}}", a);
83
- shouldShowPanel(e) && (t++, $("#content").append(r), $("#" + a).addClass("panel-with-table"), $("#" + a + " .panel-title").text(e.name), e.panelDetails && e.panelDetails.length > 1 ? ($("#" + a + " .panel-title").text(e.panelDetails[0].name), $("#" + a + " .panel-subtitle").html(e.panelDetails.slice(1).map((e, t) => `<div class="panel-subtitle-item" style="margin-left:${10 * (t + 1)}px">${e.name}</div>`))) : ($("#" + a + " .panel-title").text(e.panelDetails && e.panelDetails[0] && e.panelDetails[0].name ? e.panelDetails[0].name : e.name), $("#" + a + " .panel-subtitle").html("")), e.notes && e.notes.length && $("#" + a + " .panel-title").append(`<div style="line-height: 22px;font-size: 12px; color: #555555;">${e.notes.join("<br />")}</div>`), 1 === t && ($("#" + a + " .section-content-header .panels-header .biom-range").text(localeService.t("Reference range")), $("#" + a + " .section-content-header .panels-header .biom-last").text(localeService.t("Last reading")), $("#" + a + " .section-content-header .panels-header .biom-past").text(localeService.t("Last reading date")))), e.biomarkers.forEach(e => {
84
- if (!0 === e.showInCompactView) {
85
- let t = "cpt-bio-" + safeCssName("cb" + e.id) + Math.random().toString().substr(2),
86
- r = d.replace("{{biomarker-id}}", t);
87
- $("#" + a + " table.listing").append(r), e.color && !e.isNormal && ($("#" + t).addClass("risk"), $("#" + t + ".risk .biom-parent-value").css({color: e.color})), $("#" + t + " .biom-title").text(e.fullName ? e.fullName : " "), e.unit || 0 != e.ranges.length || e.history && 0 != e.history.length ? ($("#" + t + " .biom-value").attr("colspan", 1), $("#" + t + " .biom-value .biom-parent-value").text(e.formattedValue ? e.formattedValue : " ")) : ($("#" + t + " .biom-value").addClass("biom-value-custom"), $("#" + t + " .biom-value .biom-parent-value").text(e.formattedValue)), isNaN(e.formattedValue.replace(/,/g, ".")) && ($("#" + t + " .biom-value").addClass("biom-value-custom small-value-font-size"), $("#" + t + " .biom-cell .biom-parent-value").css("width", "140px"), $("#" + t + " .biom-cell .biom-row").css("margin-left", "0px")), e.formattedValue.length >= 125 && ($("#" + t).addClass("no-border-bottom"), $("#" + t + " .biom-parent-value").html(e.formattedValue.replace(/\r/g, "<br />")), $("#" + t + " .biom-bar").remove(), $("#" + t + " .biom-range").remove(), $("#" + t + " .biom-past").remove(), $("#" + t + " .biom-last").remove(), $("#" + t + " .biom-unit").css({width: "auto"}), $("#" + t + " .biom-value").attr("colspan", 5)), $("#" + t + " .biom-unit .biom-parent-unit").text(e.unit ? e.unit : " "), $("#" + t + " .biom-unit").attr("colspan", 1);
88
- let o = "", l = "";
89
- e.childrenBiomarkers && e.childrenBiomarkers.length && ($("#" + t).addClass("hide-flag"), e.childrenBiomarkers.reverse().forEach((a, r) => {
90
- const n = a.formattedValue, i = a.unit;
91
- if (r > 0 && ($("#" + t + " .biom-unit .biom-parent-unit").after("<br/>"), $("#" + t + " .biom-value .biom-parent-value").after("<br/>")), $("#" + t + " .biom-unit .biom-parent-unit").after(`<span>${i}</span>`), $("#" + t + " .biom-value .biom-parent-value").after(`<span class="word-break-normal">${n}</span>`), e.color && !e.isNormal && $("#" + t + " .biom-value .word-break-normal").css({color: e.color}), a.ranges.length > 1 && a.showScale && a.ranges.forEach(e => {
92
- e.isCurrent && (o = e.min + " - " + e.max), l += "\n" + color(e.color), l += "\n" + e.min + " - " + e.max, l += "\n" + e.name, l += e.isCurrent ? "\ncurrent" : "", l += e !== a.ranges[a.ranges.length - 1] ? "\n//" : ""
93
- }), r === e.childrenBiomarkers.length - 1) {
94
- let e = a.ranges.find(e => e.isNormal),
95
- r = a.formattedNormalRangeMin ? a.formattedNormalRangeMin : e ? e.formattedMin : "",
96
- o = a.formattedNormalRangeMax ? a.formattedNormalRangeMax : e ? e.formattedMax : "",
97
- l = getRange(r, o, a.normalRangeType);
98
- $("#" + t + " .biom-range .parent-reference-range").after(`<div class="child-referene-range">${l}</div>`)
99
- }
100
- }));
101
- let n = "", i = "";
102
- if (e.showScale) if (e.ranges.length > 1) {
103
- e.ranges.forEach(t => {
104
- t.isCurrent && (i = t.min + " - " + t.max), n += "\n" + color(t.color), n += "\n" + t.min + " - " + t.max, n += "\n" + t.name, n += t.isCurrent ? "\ncurrent" : "", n += t !== e.ranges[e.ranges.length - 1] ? "\n//" : ""
105
- });
106
- let a = e.ranges.find(e => e.isNormal),
107
- r = e.formattedNormalRangeMin ? e.formattedNormalRangeMin : a ? a.formattedMin : "",
108
- o = e.formattedNormalRangeMax ? e.formattedNormalRangeMax : a ? a.formattedMax : "",
109
- l = getRange(r, o, e.normalRangeType);
110
- $("#" + t + " .range-placeholder").text(n), $("#" + t + " .biom-range .parent-reference-range").text(l || " "), $("#" + t + " .biom-range").attr("colspan", 1)
111
- } else {
112
- let a;
113
- if (e.childrenBiomarkers.find((e, t) => {
114
- e.ranges.length > 1 && (a || (a = {index: t, item: e}))
115
- }), a) {
116
- a.item.ranges.forEach(t => {
117
- n += "\n" + color(t.color), n += "\n" + t.min + " - " + t.max, n += "\n" + t.name, n += t.isCurrent ? "\ncurrent" : "", n += t !== e.ranges[e.ranges.length - 1] ? "\n//" : ""
118
- });
119
- const r = 10 + 26 * (a.index % e.childrenBiomarkers.length);
120
- $("#" + t + " .range-placeholder").text(n), $("#" + t + " .range-placeholder").css({
121
- position: "absolute",
122
- bottom: `${r}px`
123
- }), $("#" + t + " .child-referene-range").css({position: "absolute", bottom: `${r - 6}px`})
124
- } else $("#" + t).addClass("hide-scale")
125
- }
126
- if (e.history && e.history.length > 1) {
127
- let a = e.history.length - 2;
128
- $("#" + t + " .biom-last").text(e.history[a].formattedValue ? e.history[a].formattedValue : " "), $("#" + t + " .biom-last").attr("colspan", 1), $("#" + t + " .biom-past").attr("colspan", 1);
129
- let r = e.history[a] && e.history[a].formattedDate;
130
- $("#" + t + " .biom-past").text(r || "")
131
- }
132
- }
133
- })
134
- }), console.log("Took 11", Date.now() - a, " ms to finish")
135
- }
136
- if (console.log("Took 12", Date.now() - a, " ms to finish"), e.showDetailsView) {
137
- console.log("Took 13", Date.now() - a, " ms to finish");
138
- let t = v.replace("{{title}}", localeService.t("Details")).replace("{{section-id}}", "details-section");
139
- $("#content").append(t);
140
- let o = 0, l = !1;
141
- e.panels.forEach(e => {
142
- let t = "dtl-pnl-" + safeCssName("dp" + e.panelId);
143
- if (e.biomarkers && e.biomarkers.filter(e => e.showInDetailsView).length) {
144
- let a = p.replace("{{panel-id}}", t);
145
- $("#content").append(a), $("#" + t).addClass("sectionPanel"), e.panelDetails && e.panelDetails.length > 1 ? ($("#" + t + " .panel-title").text(e.panelDetails[0].name), $("#" + t + " .panel-subtitle").html(e.panelDetails.slice(1).map((e, t) => `<div class="panel-subtitle-item" style="margin-left:${10 * (t + 1)}px">${e.name}</div>`))) : ($("#" + t + " .panel-title").text(e.panelDetails && e.panelDetails[0] && e.panelDetails[0].name ? e.panelDetails[0].name : e.name), $("#" + t + " .panel-subtitle").html("")), $("#" + t + " .section-content .biom-last").text("ttt"), l = !0
146
- }
147
- e.biomarkers.forEach(a => {
148
- if (!0 === a.showInDetailsView) {
149
- let s = "dtl-bio-" + safeCssName("db" + a.id), c = m.replace("{{biomarker-id}}", s), d = "";
150
- isNaN(a.formattedValue) && (d = "16px");
151
- let p = GetBiomarkerCircleStyle(a.color, a.name, a.status, a.insightsCount, e.name, !1);
152
- c = (c = c.replace("{{unit}}", `<span>${a.unit}</span>`)).replace("{{full_name}}", a.fullName), $("#" + t + " .panel-container").append(c), $("#" + s + " .biomarker .biom-circle").attr("style", p), $("#" + s + " .biom-circle").text(a.name), a.formattedValue.length >= 125 && ($("#" + s).addClass("large-value-class"), $("#" + s + " .grid-col:last-child").remove(), $("#" + s + " .grid-col").first().removeClass("size4").css("width", "100%")), $("#" + s + " .value-text").html(`<span style="font-size:${d}">${a.formattedValue.replace(/\r/g, "<br />")}</span>`), a.showScale || $("#" + s).addClass("hide-scale");
153
- let g = "", h = "", f = 50;
154
- a.ranges.length > 1 ? ($("#" + s + " .biomarker .title").addClass("has-ranges"), a.ranges.forEach(e => {
155
- e.isCurrent && (h = e.min + " - " + e.max, e.min && e.min.toString() && e.max && e.max.toString() && (f = r ? 100 - (a.value - e.min) / (e.max - e.min) * 100 : (parseFloat(a.value) - e.min) / (e.max - e.min) * 100)), g += "\n" + color(e.color), e.isNormal ? g += "\n" + getRange(e.formattedMin, e.formattedMax, a.normalRangeType) : g += "\n" + getRange(e.formattedMin, e.formattedMax), g += "\n" + e.name, g += e.isCurrent ? "\ncurrent\n" + f : "", g += e !== a.ranges[a.ranges.length - 1] ? "\n//" : ""
156
- })) : $("#" + s + " .biomarker .title").addClass("has-no-ranges");
157
- let b = "", v = "", w = 50, y = 1;
158
- if (a.childrenBiomarkers && a.childrenBiomarkers.length && a.childrenBiomarkers.forEach(e => {
159
- if (e.ranges.length > 1) {
160
- y++;
161
- let t = e.formattedValue.replace(/\r/g, "<br />"), a = e.unit;
162
- $("#" + s + " .biom-info .value").after(`\n <div class="colorable pair">\n <span class="biomarker-extra-value">${t}</span>\n <span class="biomarker-extra-unit">${a}</span>\n </div>\n `), b = "", v = "", e.ranges.forEach((t, a) => {
163
- t.isCurrent && (v = t.min + " - " + t.max, t.min && t.min.toString() && t.max && t.max.toString() && (w = r ? 100 - (e.value - t.min) / (t.max - t.min) * 100 : (parseFloat(e.value) - t.min) / (t.max - t.min) * 100)), b += "\n" + color(t.color), t.isNormal ? b += "\n" + getRange(t.formattedMin, t.formattedMax, e.normalRangeType) : b += "\n" + getRange(t.formattedMin, t.formattedMax), b += "\n" + t.name, b += t.isCurrent ? "\ncurrent\n" + w : "", b += t !== e.ranges[e.ranges.length - 1] ? "\n//" : ""
164
- }), b && $("#" + s + " .range-placeholder").after(`<div class="extra-range-placeholder">${b}</div>`), $("#" + s + " .biomarker .title").addClass("has-ranges")
165
- } else $("#" + s + " .biomarker .title").addClass("has-no-ranges")
166
- }), $("#" + s + " .range-placeholder").text(g), y > 1 && $("#" + s).addClass("hide-flag"), a.history.length > 1) {
167
- let e = "chart-bio-" + safeCssName("db" + a.id),
168
- t = "<canvas id=" + e + " width='100%' height='30' class='chart-canvas' ></canvas>";
169
- $("#" + s + " .chart").append(t);
170
- var l = [], n = [], i = [];
171
- a.history.forEach((e, t) => {
172
- l[t] = parseFloat(e.value), n[t] = e.color, i[t] = e.formattedDate
173
- });
174
- let r = {id: e, dataset: l, dataColor: n, dataLabel: i};
175
- k[o] = r, o++
176
- }
177
- renderDoctorNotes(a.doctorNotes, t);
178
- let S = 0;
179
- a.relatedInsights.forEach(e => {
180
- let t = "dtl-bio-" + a.id + "-insight" + S;
181
- S++;
182
- let r = u.replace("{{insight-id}}", t).replace("{{doctorContentHeader}}", localeService.t("doctorContent")).replace("{{doctorContentSubheader}}", localeService.t("mostCommonCausesOfTheObservedValue"));
183
- $("#" + s + " .biomarker-insights").append(r);
184
- let o = "", l = "", n = "";
185
- if (n = e.introductoryStatement ? e.introductoryStatement : e.content) {
186
- let e = "<span>", t = "</span>";
187
- n.includes(e) && (l = n.substring(n.indexOf(e) + e.length, n.indexOf(t)), n = (n = n.replace(/<(.|\n)*?>/g, "")).replace(l, ""))
188
- }
189
- if (e.introductoryStatement || e.summary || e.testExplained || e.suggestion ? (o += n ? "\n" + n.replace(/(\r\n|\n|\r)/gm, "<br/>") : "", o += e.summary ? e.summary : "", o += e.testExplained ? e.testExplained : "", o = (o += e.suggestion ? e.suggestion : "").replace("(", "&rlm;("), $("#" + t + " .text").prepend(o)) : (o = (o += n).replace("(", "&rlm; ("), $("#" + t + " .text").prepend(o)), e.detailedList) {
190
- const a = parseTable(e.detailedList), r = renderDetails(a);
191
- $("#" + t + "+ .detailed-list-wrapper .detailed-list").html(r), $("#" + t + "+ .detailed-list-wrapper .tolerance-text").html(l), $("#" + t + "+ .detailed-list-wrapper .doctor-only-content-container").removeClass("hide-me"), $("#" + t + "+ .detailed-list-wrapper .detailed-list ul").prev("li").addClass("arrow-icon")
192
- }
193
- e.isClinicalReading || ("" === e.color ? $("#" + t).addClass("tip") : $("#" + t).addClass(color(e.color))), "" !== e.icon && $("#" + t + " .icon img").attr("src", e.icon);
194
- let i = "";
195
- e.title && (i += "<div class='title'>" + e.title + "</div>")
196
- })
197
- }
198
- }), renderDoctorNotes(e.doctorNotes, t);
199
- let a = 0;
200
- e.insights.forEach(r => {
201
- let o = "dtl-pnl-insight-" + e.panelId + "-insight" + a;
202
- a++;
203
- let l = u.replace("{{insight-id}}", o).replace("{{doctorContentHeader}}", localeService.t("doctorContent")).replace("{{doctorContentSubheader}}", localeService.t("mostCommonCausesOfTheObservedValue"));
204
- $("#" + t).append(l);
205
- let n = "", i = "", s = "";
206
- if (s = r.introductoryStatement ? r.introductoryStatement : r.content) {
207
- let e = "<span>", t = "</span>";
208
- s.includes(e) && (i = s.substring(s.indexOf(e) + e.length, s.indexOf(t)), s = (s = s.replace(/<(.|\n)*?>/g, "")).replace(i, ""))
209
- }
210
- if (r.introductoryStatement || r.summary || r.testExplained || r.suggestion ? (n += s ? "\n" + s.replace(/(\r\n|\n|\r)/gm, "<br/>") : "", n += r.summary ? "<br/>" + r.summary : "", n += r.testExplained ? "<br/>" + r.testExplained : "", n = (n += r.suggestion ? "<br/>" + r.suggestion : "").replace("(", "&rlm; ("), $("#" + o + " .text").prepend(n)) : (n = (n += s).replace("(", "&rlm; ("), $("#" + o + " .text").prepend(n)), r.detailedList) {
211
- const e = parseTable(r.detailedList), t = renderDetails(e);
212
- $("#" + o + "+ .detailed-list-wrapper .detailed-list").html(t), $("#" + o + "+ .detailed-list-wrapper .tolerance-text").html(i), $("#" + o + "+ .detailed-list-wrapper .doctor-only-content-container").removeClass("hide-me"), $("#" + o + "+ .detailed-list-wrapper .detailed-list ul").prev("li").addClass("arrow-icon")
213
- }
214
- r.isClinicalReading || ("" === r.color ? $("#" + o).addClass("tip") : $("#" + o).addClass(color(r.color))), "" !== r.icon && $("#" + o + " .icon img").attr("src", r.icon);
215
- let c = "";
216
- if (r.title && (c += "<div class='title'>" + r.title + "</div>"), r.relatedBiomarkers && r.relatedBiomarkers.length > 0) {
217
- $("#" + o + " .text ").addClass("insight-text"), r.disclaimer && $("#" + o).append("<div class='insight-disclaimer'>" + r.disclaimer + "</div>");
218
- let t = "<div id='" + o + "' class='related-icons' />";
219
- $("#" + o).append(t), $("#" + o + " .related-icons").addClass("has-related").addClass(color(r.color)), r.relatedBiomarkers.forEach(t => {
220
- $("#" + o + " .related-icons").append(GetRelatedBiomarker(GetBiomarkerCircleStyle(t.color, t.name, t.status, t.insightsCount, e.name, !1), t.name, t.fullName))
221
- })
222
- } else $("#" + o + " .related-icons").remove()
223
- })
224
- }), l || $("#details-section").remove(), $("#chartsData").append("<script> var chartsData = " + JSON.stringify(k) + "<\/script>"), console.log("Took 14", Date.now() - a, " ms to finish")
225
- }
226
- if (console.log("Took 15", Date.now() - a, " ms to finish"), (e.summary && e.summary.length > 0 || e.doctorNote && e.doctorNote.length) && ($("#content").append(g), $("#summary .resume-title").text(localeService.t("Summary"))), console.log("Took 16", Date.now() - a, " ms to finish"), e.doctorNote && e.doctorNote.length > 0) {
227
- e.doctorNote.forEach((e, t) => {
228
- let a = "dtl-bio-" + e.id + "-insight" + t, r = w.replace("{{note-id}}", a);
229
- $("#summary .section-content").append(r), $("#" + a + " .text .from-doctor").append(localeService.t("noteFromDoctor") + " " + e.createdByName), $("#" + a + " .text .note-content").append(e.content)
230
- })
231
- }
232
- if (console.log("Took 17", Date.now() - a, " ms to finish"), e.summary && e.summary.length > 0) {
233
- let t = 0;
234
- setSummaryStatInsightText(e.summary).forEach(e => {
235
- let a = "smry-insight" + t;
236
- t++;
237
- let r = f.replace("{{insight-id}}", a);
238
- $("#summary .section-content").append(r), e.isClinicalReading ? $("#" + a).addClass("cr") : "" === e.color ? $("#" + a).addClass("tip") : $("#" + a).addClass(color(e.color)), "" !== e.icon && $("#" + a + " .icon img").attr("src", e.icon);
239
- let o = "";
240
- e.title && (o += "<div class='title'>" + e.title + "</div>"), o += e.content.replace(/(\r\n|\n|\r)/gm, "<br/>"), $("#" + a + " .text").html(o), e.relatedBiomarkers && e.relatedBiomarkers.length > 0 ? ($("#" + a).addClass("has-related").addClass(color(e.color)), e.relatedBiomarkers.forEach(e => {
241
- $("#" + a + " .related-icons").append(GetRelatedBiomarker(GetBiomarkerCircleStyle(e.color, e.name, e.status, e.insightsCount, "nothing", !0), e.name, e.fullName))
242
- })) : $("#" + a + " .related-icons").remove()
243
- }), console.log("Took 18", Date.now() - a, " ms to finish")
244
- }
245
- if (console.log("Took 19", Date.now() - a, " ms to finish"), (e.reportSummary || e.reportProperties && e.labType && "9" !== e.labType.toString()) && ($("#content").append("<br><br>"), $("#content").append(h)), console.log("Took 20", Date.now() - a, " ms to finish"), e.reportSummary ? ($("#report-summary .report-summary-title").text(localeService.t("reportSummary")), $("#report-summary .report-summary-content").append(e.reportSummary)) : ($("#report-summary .report-summary-title").remove(), $("#report-summary .report-summary-content").remove()), console.log("Took 21", Date.now() - a, " ms to finish"), e.reportProperties && e.labType && "9" !== e.labType.toString()) {
246
- $("#report-summary .report-properties-title").text(localeService.t("reportProperties"));
247
- let t = e.reportProperties;
248
- Object.keys(t).forEach(e => {
249
- $("#report-summary .report-properties-content").append("<p>" + e + ":" + t[e] + "</p>")
250
- })
251
- } else $("#report-summary .report-properties-title").remove(), $("#report-summary .report-properties-content").remove();
252
- console.log("Took 22", Date.now() - a, " ms to finish"), e.signatures && e.signatures.length > 0 && ($("#content").append("<br><br><br><br>"), e.signatures.forEach((t, a) => {
253
- let r = "sgtr-" + a, o = b.replace("{{signature-id}}", r);
254
- $("#content").append(o);
255
- let l = t.name;
256
- l += "" !== e.approvalDate ? "<br>" + e.approvalDate : "", $("#" + r + " .info-label").text(localeService.t("signedBy")), $("#" + r + " .info-value").html(l), $("#" + r + " .signature-image").attr("src", t.signatureURL), e.labStamp ? $("#" + r + " .stamp-image").attr("src", e.labStamp) : $("#" + r + " .stamp-image").remove()
257
- }), $("#content").append("<br>")), console.log("Took 23", Date.now() - a, " ms to finish"), $(".grid-row + .grid-row.biomarker-insights").each(function () {
258
- $(this).children().length || $(this).remove()
259
- }), $(".detailed-list").each(function () {
260
- $(this).children().length || $(this).remove()
261
- }), $(".section.new-page").first().addClass("first-new-page"), $(".text").each(function () {
262
- $(this).text().trim() || $(this).parent().remove()
263
- }), $(".extra-range-placeholder").each(function () {
264
- $(this).text().trim() || $(this).remove()
265
- }), $(".panel-title + .section-content .panel-container").each(function () {
266
- $(this).text().trim() || $(this).parent().siblings(".panel-title").remove()
267
- }), $(".section.new-page#details-section,.section.panel.sectionPanel").wrapAll('<div class="pdf-wrapper" />'), $(".section.new-page.first-new-page").prependTo($(".pdf-wrapper .sectionPanel:nth-child(2) .panel-wrapper")), $(".section-content .panel-container .biomarker-container:first-child").each(function () {
268
- let e = $(this).parent().parent().parent().find(".panel-wrapper");
269
- $(this).appendTo(e)
270
- }), debugLog("after signature"), console.log("Took 24", Date.now() - a, " ms to finish");
271
- let Q = path.resolve(`${__dirname}/../output`);
272
- return fs.existsSync(Q) || fs.mkdirSync(Q), await promisify(fs.writeFile)(OUT_FILE, U.serialize()), console.log("Took end of html", Date.now() - a, " ms to finish"), {
273
- html: U.serialize(),
274
- firstHeader: M.serialize(),
275
- outputFile: OUT_FILE,
276
- header: I.serialize(),
277
- footer: A.serialize(),
278
- historyData: k,
279
- labType: e.labType,
280
- dateNow: a
281
- }
282
- }, GetRelatedBiomarker = (e, t, a) => {
283
- let r = "";
284
- if (color && t && a) {
285
- return t.length >= 7 && (r = "small-fontSize-circle"), ('<div class="related">\n <div class="bicon ' + r + '" style="{{biomarkerstyle}}"><span class="bicon-inner">{{name}}</span></div>\n </div>').replace("{{biomarkerstyle}}", e).replace("{{name}}", t).replace("{{fullname}}", a)
286
- }
287
- return null
288
- }, GetBiomarkerCircleStyle = (e, t, a, r, o, l) => {
289
- let n = "";
290
- return n = l ? `\n background-color: ${e ? "transparent" : "#E05A5A30"};\n border: 2px solid ${e || "#E05A5A"};\n color: ${e || "#555555"};\n font-size: ${t && t.length > 6 ? "12px" : "14px"}\n ` : `\n background-color: transparent;\n border: 2px solid ${e || "#555555"};\n color: ${e || "#555555"};\n font-size: ${t && t.length > 6 ? "12px" : "14px"}\n `, void 0 !== r && void 0 !== typeof r && void 0 !== a && void 0 !== typeof a && (n = `\n background-color: ${r || "health risk calculators" === o.toLowerCase() ? e : "transparent"};\n border: ${r || o.toLowerCase(), `2px solid ${e}`};\n color: ${r ? "#ffffff" : e};\n font-size: ${t && t.length > 6 ? "12px" : "14px"}\n `, 1 == a && "1" == a || (n = `\n background-color: transparent;\n border: 2px solid rgba(0,0,0,.4);\n color: rgba(0,0,0,.4);\n font-size: ${t && t.length > 7 ? "12px" : "14px"}\n `)), n
291
- }, num = e => isNaN(e) ? parseFloat(e.replace(",", "")) : e, shouldShowPanel = e => {
292
- let t = e.biomarkers, a = t.length;
293
- return !(!t || t && !a) && t.filter(e => !e.showInCompactView).length !== a
294
- }, getRange = (e, t, a = null) => {
295
- let r = "";
296
- switch (null !== t && null !== e && (r = e + " - " + t), null !== t && null === e && (r = "< ".max), null !== e && null === t && (r = "> " + e), a) {
297
- case"0":
298
- null !== t && null !== e && (r = e + " - " + t), null !== t && null === e && (r = "<= " + t), null !== e && null === t && (r = ">= " + e);
299
- break;
300
- case"1":
301
- r = "< " + t;
302
- break;
303
- case"2":
304
- r = "<= " + t;
305
- break;
306
- case"3":
307
- r = "> " + e;
308
- break;
309
- case"4":
310
- r = ">= " + e
311
- }
312
- return r
313
- }, color = e => {
314
- switch (e) {
315
- case"#E05A5A":
316
- return "red";
317
- case"#EE734E":
318
- return "orange";
319
- case"#41B9D6":
320
- return "blue";
321
- case"#F7AA2E":
322
- return "yellow";
323
- case"#BC2828":
324
- return "dark-red";
325
- case"#02D9D1":
326
- case"#05B9AF":
327
- return "green";
328
- case"#0F0F0F":
329
- return "black";
330
- case"#87B7CE":
331
- return "lightblue";
332
- case"#FB7377":
333
- return "light-red";
334
- default:
335
- return e
336
- }
337
- }, fitNumber = e => e.length > 11 ? e.slice(0, 11) + "<br>" + e.slice(11) : e,
338
- safeCssName = e => encodeURIComponent(e.toLowerCase()).replace(/%[0-9A-F]{2}/gi, ""), generatePDF = async e => {
339
- console.log("Took generatePDF 1", Date.now() - e.dateNow, " ms to finish");
340
- try {
341
- e.html;
342
- let t = e.firstHeader, a = e.header, r = e.footer, o = e.labType, l = o && 9 === o;
343
- console.log("Took generatePDF 2", Date.now() - e.dateNow, " ms to finish"), OUT_FILE = e.outputFile;
344
- let n = await puppeteer.launch({
345
- args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"],
346
- headless: !0,
347
- defaultViewport: null
348
- });
349
- console.log("Took generatePDF 3", Date.now() - e.dateNow, " ms to finish");
350
- let i = await n.newPage();
351
- debugLog("page launched!"), await i.setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"), console.log("Took generatePDF 4", Date.now() - e.dateNow, " ms to finish"), await i.setViewport({
352
- width: 1366,
353
- height: 768
354
- }), await i.goto("file:///" + path.resolve(__dirname + `/../${Pdf_file}`), {waitUntil: "networkidle2"}).catch(e => {
355
- console.log("ERROR IS File path: " + e.message)
356
- }), console.log("Took generatePDF 5", Date.now() - e.dateNow, " ms to finish"), debugLog("page opened!");
357
- let s = await i.pdf({
358
- format: "A4",
359
- pageRanges: "1",
360
- printBackground: !0,
361
- displayHeaderFooter: !0,
362
- margin: {top: shouldRenderCustomHeader ? 0 : l ? 125 : 100, bottom: 100},
363
- headerTemplate: t,
364
- footerTemplate: r
365
- });
366
- console.log("Took generatePDF 6", Date.now() - e.dateNow, " ms to finish"), debugLog("Buffer1 loaded!");
367
- let c = null;
368
- try {
369
- c = await i.pdf({
370
- format: "A4",
371
- pageRanges: "2-",
372
- printBackground: !0,
373
- displayHeaderFooter: !0,
374
- margin: {top: l ? 125 : 100, bottom: l ? 100 : 125},
375
- headerTemplate: a,
376
- footerTemplate: r
377
- })
378
- } catch (e) {
379
- debugLog("ERROR!!: ", e), c = null
380
- }
381
- console.log("Took generatePDF 7", Date.now() - e.dateNow, " ms to finish"), debugLog("Buffer2 loaded!");
382
- let d = null != c ? await combinePDFBuffers(s, c) : s;
383
- return console.log("Took generatePDF 8", Date.now() - e.dateNow, " ms to finish"), await n.close(), d
384
- } catch (e) {
385
- return debugLog("ERROR!: ", e), ""
386
- }
387
- };
388
- const setSummaryStatInsightText = e => {
389
- let t = [], a = e;
390
- return e.forEach((r, o) => {
391
- if (null != r.stackedInsight) {
392
- let l = {};
393
- a.find((a, n) => {
394
- a && a.id == r.stackedInsight && (l.index = n, r.content += "<br><br>" + a.content, l.elm = r, t[o] = a, e[l.index] = l.elm, e.splice(n, 1))
395
- })
396
- }
397
- }), e
398
- }, combinePDFBuffers = (e, t) => {
399
- var a = new memoryStreams.WritableStream;
400
- try {
401
- var r = new hummus.PDFRStreamForBuffer(e), o = new hummus.PDFRStreamForBuffer(t),
402
- l = hummus.createWriterToModify(r, new hummus.PDFStreamForResponse(a));
403
- l.appendPDFPagesFromPDF(o), l.end();
404
- var n = a.toBuffer();
405
- return a.end(), n
406
- } catch (e) {
407
- throw a.end(), new Error("Error during PDF combination: " + e.message)
408
- }
409
- }, list_to_tree = (e, t) => {
410
- let a = [], r = e.filter(e => e.parent_id === t);
411
- return 0 === r.length ? [] : (r.map(t => {
412
- t.children = list_to_tree(e, t.id), a.push(t)
413
- }), a)
414
- }, findParentId = (e, t, a) => {
415
- for (let r = e; r > 0; r--) if (a[r].sepCount === t) return a[r].parent_id
416
- }, separtorsNumbers = e => {
417
- let t = e.lastIndexOf("#"), a = e.indexOf("#");
418
- if (-1 !== a && 0 !== a) return 0;
419
- let r = e.substring(a, t + 1).split(""), o = !0;
420
- return r.map(e => {
421
- if ("#" !== e) return o = !1, !1
422
- }), o ? r.length : separtorsNumbers(e.substring(a, t))
423
- }, parseTable = e => {
424
- let t = e.split("\n"), a = [];
425
- t.map(e => {
426
- let t = separtorsNumbers(e), r = {id: Math.random().toString().substr(2, 6), content: e, sepCount: t};
427
- r.id = Math.random().toString().substr(2, 6), a.push(r)
428
- });
429
- let r = a[0].sepCount;
430
- for (let e = 0; e < a.length; e++) 0 !== e && r !== a[e].sepCount ? isEmpty(a[e - 1]) || (a[e].sepCount > a[e - 1].sepCount && (a[e].parent_id = a[e - 1].id), a[e].sepCount === a[e - 1].sepCount && (a[e].parent_id = a[e - 1].parent_id), a[e].sepCount < a[e - 1].sepCount && (a[e].parent_id = findParentId(e - 1, a[e].sepCount, a))) : a[e].parent_id = "0";
431
- return list_to_tree(a, "0")
432
- }, isEmpty = e => {
433
- for (let t in e) if (e.hasOwnProperty(t)) return !1;
434
- return !0
435
- },
436
- empty = e => void 0 === e || void 0 === e || void 0 === typeof e || null === e || "" === e || "" === e || 0 === e.length || "undefined" === e,
437
- renderDetails = e => {
438
- if (1 === e.length && empty(e[0].children)) return `<li>${e[0].content.substring(e[0].sepCount, e[0].content.length + 1)}</li>`;
439
- let t = [], a = !1;
440
- e.map((e, r) => {
441
- "0" === e.parent_id && (a = !0);
442
- let o = "";
443
- o = empty(e.children) ? "<li>" + `${e.content.substring(e.sepCount, e.content.length + 1)}` + "</li>" : "<li>" + `${e.content.substring(e.sepCount, e.content.length + 1)}` + "</li><ul>" + `${renderDetails(e.children)}` + "</ul>", empty(o) || t.push(o)
444
- });
445
- let r = "";
446
- return t.map(e => {
447
- empty(e) || (r += e)
448
- }), empty(t) ? null : `${r}`
449
- }, generatePatientQR = async e => {
450
- try {
451
- const t = new JSDOM(e);
452
- let a = t.serialize(), r = path.resolve(`${__dirname}/../output`);
453
- fs.existsSync(r) || fs.mkdirSync(r);
454
- let o = path.resolve(__dirname + "/../output/report-pdf-QR" + Date.now() + ".html"),
455
- l = "/output/report-pdf-QR" + Date.now() + ".html";
456
- await promisify(fs.writeFile)(o, t.serialize());
457
- const n = await puppeteer.launch({args: ["--no-sandbox"]}), i = await n.newPage();
458
- debugLog("page launched!"), await i.setContent(a, {waitUntil: "networkidle2"}), debugLog("Content loaded"), await i.goto("file:///" + path.resolve(__dirname + `/../${l}`), {
459
- timeout: 3e7,
460
- waitUntil: "networkidle2"
461
- }).catch(e => {
462
- console.log("ERROR IS File path: " + e.message)
463
- }), debugLog("page opened!"), await i.evaluateHandle("document.fonts.ready"), debugLog("fonts loaded!");
464
- let s = await i.pdf({
465
- format: "letter",
466
- printBackground: !0,
467
- displayHeaderFooter: !1,
468
- margin: {top: 0, bottom: 0},
469
- headerTemplate: "",
470
- footerTemplate: ""
471
- });
472
- debugLog("Buffer1 loaded!"), debugLog("Buffer2 loaded!");
473
- let c = s;
474
- return debugLog("Buffers merged !"), await n.close(), c
475
- } catch (e) {
476
- return debugLog("ERROR! here 2: ", e), ""
477
- }
478
- }, renderDoctorNotes = (e, t) => {
479
- if (empty(e)) return null;
480
- let a = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/doctor-note.html"), "utf8");
481
- e.forEach(e => {
482
- let r = `doctor-note-${generateUniqueId()}`, o = a.replace("{{note-id}}", r);
483
- $("#" + t + " .biomarker-insights").append(o), $("#" + r + " .text .from-doctor").append(localeService.t("noteFromDoctor") + " " + e.createdByName), $("#" + r + " .text .note-content").append(e.content)
484
- })
485
- }, generateUniqueId = () => Date.now() + (100 * Math.random()).toString().substr(6),
486
- renderProfileItems = (e, t, a = !1) => {
487
- if (a) {
488
- $(".imc-header-address").html(t);
489
- const a = $("#patient-container");
490
- for (let t of e.profileItems) t && t.title && t.value && a.append(`\n <div class="profile-item-row">\n <div class="key">${t.title}:</div>\n <div class="value">${t.value}</div>\n </div>\n `)
491
- } else {
492
- if (e.labType && "9" === e.labType.toString()) {
493
- $(".profile-items-container").removeClass("size4").css("width", "100%"), $(".plus-info-container").remove(), $(".intro").css("width", "93%");
494
- let t = 100 / 3, a = e.profileItems;
495
- if (e.reportProperties) {
496
- let t = Object.keys(e.reportProperties).map(t => ({title: t, value: e.reportProperties[t]}));
497
- a.push(...t)
498
- }
499
- for (let a of e.profileItems) {
500
- let e = `<div style="width: ${t}%; padding: 10px 0" class='grid-col size2' >\n <div class='info-label'> ${a.title}</div>\n <div class='info-value'>${a.value}</div>\n </div>`;
501
- $("#patient-container").append(e)
502
- }
503
- return null
504
- }
505
- for (var r = 0; r < e.profileItems.length - 1;) {
506
- var o = "sub" + r, l = " <div id=" + o + " class='grid-row'> </div>";
507
- $("#patient-container").append(l);
508
- for (var n = 0; n < 2; n++) {
509
- let t = "<div id=" + (o + "-" + n) + " class='grid-col size2' >\n <div class='info-label'>" + e.profileItems[r].title + "</div>\n <div class='info-value'>" + e.profileItems[r].value + "</div>\n </div>";
510
- $("#" + o).append(t), r++
511
- }
512
- }
513
- if (e.profileItems.length % 2) {
514
- let t = "sub" + r;
515
- l = " <div id=" + t + " class='grid-row'> </div>";
516
- $("#patient-container").append(l);
517
- let a = "<div id=" + (t + "-0") + " class='grid-col size2' >\n <div class='info-label'>" + e.profileItems[r].title + "</div>\n <div class='info-value'>" + e.profileItems[r].value + "</div>\n </div>";
518
- $("#" + t).append(a)
519
- }
520
- }
521
- };
522
- module.exports = {
523
- generatePDF: generatePDF,
524
- generateHTMLStaging: generateHTMLStaging,
525
- generatePatientQR: generatePatientQR
1
+ "use strict";
2
+ const fs = require("fs"), {promisify: promisify} = require("util"), {JSDOM: JSDOM} = require("jsdom"),
3
+ fetch = require("node-fetch"), hummus = require("hummus"), memoryStreams = require("memory-streams"),
4
+ path = require("path"), LocaleService = require("../app/services/localeService.js"),
5
+ i18n = require("../app/i18n.config.js"), puppeteer = require("puppeteer");
6
+ var Chart = require("chart.js"), QRCode = require("qrcode"), localeService = new LocaleService(i18n);
7
+ let isRTL = !1, OUT_FILE = "output/report-pdf.html", Pdf_file = "";
8
+ const appDir = path.dirname(require.main.filename), FROM_TO = 0, LESS_THAN = 1, LESS_THAN_OR_EQUAL = 2, MORE_THAN = 3,
9
+ MORE_THAN_OR_EQUAL = 4;
10
+ let $, debug = !0, debugLog = (e, t = "") => {
11
+ debug && console.log(e, t)
12
+ }, shouldRenderCustomHeader = !1, generateHTMLStaging = async (e, t) => {
13
+ let a = Date.now();
14
+ debug = t, OUT_FILE = path.resolve(__dirname + "/../output/report-pdf" + a + ".html"), Pdf_file = "/output/report-pdf" + a + ".html";
15
+ let r = !1;
16
+ -1 !== e.language.indexOf("ar") && (e.language = "ar-SA", r = !0), console.log("Took 1", Date.now() - a, " ms to finish");
17
+ let o = e.labType && 9 === e.labType;
18
+ shouldRenderCustomHeader = o && e.customHeader, localeService.setLocale(e.language), debugLog("pdf language:", e.language);
19
+ let l = shouldRenderCustomHeader ? fs.readFileSync(path.resolve(__dirname + "/../templates/imc/first-header-template.html"), "utf8") : r ? fs.readFileSync(path.resolve(__dirname + "/../templates/rtl_no_pages.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/ltr_no_pages.html"), "utf8"),
20
+ n = r ? fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/ar-first-page-header.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/header-first-page.html"), "utf8"),
21
+ i = r ? fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/ar-header.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/header.html"), "utf8"),
22
+ s = r ? fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/ar-footer.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/footer.html"), "utf8"),
23
+ c = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/panel-compact.html"), "utf8"),
24
+ d = r ? fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/biomarker-compact-ar.html"), "utf8") : fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/biomarker-compact.html"), "utf8"),
25
+ p = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/panel-details.html"), "utf8"),
26
+ m = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/biomarker-details.html"), "utf8"),
27
+ u = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/biomarker-insight.html"), "utf8"),
28
+ g = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/summary.html"), "utf8"),
29
+ h = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/report-summary.html"), "utf8"),
30
+ f = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/summary-insight.html"), "utf8"),
31
+ b = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/signature.html"), "utf8"),
32
+ v = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/section-title.html"), "utf8"),
33
+ w = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/doctor-note.html"), "utf8");
34
+ console.log("Took 2", Date.now() - a, " ms to finish");
35
+ let y = e.labLogo.split(".").pop(), S = e.labLogo;
36
+ e.labLogo.includes("http") && (S = e.labLogo + `?v=${(new Date).valueOf()}`);
37
+ let x = "";
38
+ try {
39
+ x = await fetch(S).then(e => e.buffer()).then(e => `data:image/${y};base64,` + e.toString("base64"))
40
+ } catch (e) {
41
+ debugLog("Couldn't browse lab logo!: ", e)
42
+ }
43
+ console.log("Took 3", Date.now() - a, " ms to finish");
44
+ let k = [];
45
+ debugLog("templates loaded");
46
+ let D = e.patientName, _ = e.timeZoneOffset ? e.timeZoneOffset : 0, C = new Date(1e3 * e.reportDate + 36e5 * _),
47
+ R = C.getDate(), T = C.getMonth();
48
+ T += 1;
49
+ let E = C.getFullYear(), N = (C.getHours() < 10 ? "0" : "") + C.getHours(),
50
+ F = (C.getMinutes() < 10 ? "0" : "") + C.getMinutes(), P = N > 12 ? N - 12 : N;
51
+ P = 0 == P ? 12 : P;
52
+ let L = N > 12 ? "pm" : "am", O = "";
53
+ O = "fr" === localeService.getCurrentLocale() ? R + " " + T + " " + E + "<br/>" + P + ":" + F + " " + localeService.t(L) : "de" === localeService.getCurrentLocale() ? R + "." + T + (r ? "،" : ",") + E + "<br/>" + N + ":" + F : R + "." + T + "." + E + "<br/>" + P + ":" + F + " " + localeService.t(L), i = i.replace("{{logo}}", x).replace("{{patient_name}}", D).replace("{{report_ref}}", fitNumber(e.reportNumber)).replace("{{division_name}}", e.reportDivision).replace("{{report_date}}", O).replace("{{PREPARED_FOR_T}}", localeService.t("PREPARED FOR")).replace("{{REFERENCE_T}}", localeService.t("REFERENCE")).replace("{{REFERENCE_T}}", localeService.t("REFERENCE")).replace("{{DIVISION_T}}", localeService.t(o ? "hospital" : "BRANCH")).replace("{{REPORT_DATE_T}}", localeService.t("REPORT DATE")), console.log("Took 4", Date.now() - a, " ms to finish");
54
+ let B = e.labName;
55
+ e.labAddress = e.labAddress, B += e.labAddress ? "<br>" + e.labAddress.replace(/\n/g, "<br>") : "", B += e.labPhoneNumber ? "<br>" + e.labPhoneNumber : "", n = n.replace("{{logo}}", x).replace("{{lab_info}}", B).replace("{{report_ref}}", fitNumber(e.reportNumber)).replace("{{division_name}}", e.reportDivision).replace("{{report_date}}", O).replace("{{PREPARED_FOR_T}}", localeService.t("PREPARED FOR")).replace("{{REFERENCE_T}}", localeService.t("REFERENCE")).replace("{{DIVISION_T}}", localeService.t(o ? "hospital" : "BRANCH")).replace("{{REPORT_DATE_T}}", localeService.t("REPORT DATE")).replace("{{LAB_T}}", localeService.t("LAB")), console.log("Took 5", Date.now() - a, " ms to finish"), s = s.replace("{{smartService}}", localeService.t("smartReportBy")).replace("{{Page}}", localeService.t("Page")).replace("{{of}}", localeService.t("of")).replace("{{address}}", B.replace(/<br>/g, "\t")), console.log("Took 6", Date.now() - a, " ms to finish");
56
+ let I = new JSDOM(i), M = new JSDOM(n), A = new JSDOM(s), q = require("jquery")(I.window),
57
+ H = require("jquery")(M.window), V = require("jquery")(A.window);
58
+ const z = q(".page-head .logo .header_logo").first();
59
+ e.copyright && V(".footer .footer-content .pages-container").after(`<div style="padding-top: 4px;">${e.copyright}</div>`), o && (z.css({
60
+ maxHeight: "100%",
61
+ width: "auto",
62
+ maxWidth: "20%"
63
+ }), H(".logo-container").css({height: "140px"}), H(".logo-container .logo").css({height: "100%"}), H(".page-head .logo img").css({
64
+ maxHeight: "50%",
65
+ width: "auto",
66
+ maxWidth: "50%"
67
+ }), V(".footer #footer_logo_container").hide(), r ? V(".footer .footer-content").css({flexDirection: "row-reverse"}) : V(".footer .footer-content").css({flexDirection: "unset"}));
68
+ const U = new JSDOM(l);
69
+ ($ = require("jquery")(U.window))(".logo img").attr("src", x), $("#lab-info").html(B), $("#reference").text(e.reportNumber), $("#division").text(e.reportDivision), $("#report-date").text(O), $("#report-title").text(e.reportTitle), $("#report-title-header-ltr .heading").text(localeService.t("Laboratory Report")), $("#report-title-header .heading").text(localeService.t("Laboratory Report")), console.log("Took 7", Date.now() - a, " ms to finish"), renderProfileItems(e, B, shouldRenderCustomHeader), console.log("Took 8", Date.now() - a, " ms to finish");
70
+ let j = localeService.t("Access a detailed report online or in our app.") + "\n<br>" + localeService.t("1) Visit") + " " + e.moreLink + "\n";
71
+ e.patientPin && (j += "<br>" + localeService.t(e.showPIN ? "2) Enter this PIN code:" : "Log in with a myLAB account") + " \n"), $("#more-link").html(j), e.patientPin && $("#pin").text(e.patientPin), $("#more-link_header").text(localeService.t("There's more...")), $("#more-link_header-rtl").text(localeService.t("There's more..."));
72
+ let J = e.patientName, G = (new Buffer.from(J).toString("base64"), e.patientPin);
73
+ if (G) {
74
+ new Buffer.from(G).toString("base64");
75
+ let t = "v_" + D + "_!_" + G;
76
+ $("#chartsData").append("<script> var qrCodeText = " + JSON.stringify(t) + "<\/script>"), $("#pin.pin").css("display", e.showPIN ? "block" : "none")
77
+ } else $("#chartsData").append("<script> var qrCodeText = null <\/script>");
78
+ if ($("#canvas.pin-qr").css("display", G ? "block" : "none"), G || $("#canvas.pin-qr").remove(), console.log("Took 9", Date.now() - a, " ms to finish"), e.showCompactView) {
79
+ console.log("Took 10", Date.now() - a, " ms to finish");
80
+ let t = 0;
81
+ e.panels.forEach(e => {
82
+ let a = "cpt-pnl-" + safeCssName("cp" + e.panelId), r = c.replace("{{panel-id}}", a);
83
+ shouldShowPanel(e) && (t++, $("#content").append(r), $("#" + a).addClass("panel-with-table"), $("#" + a + " .panel-title").text(e.name), e.panelDetails && e.panelDetails.length > 1 ? ($("#" + a + " .panel-title").text(e.panelDetails[0].name), $("#" + a + " .panel-subtitle").html(e.panelDetails.slice(1).map((e, t) => `<div class="panel-subtitle-item" style="margin-left:${10 * (t + 1)}px">${e.name}</div>`))) : ($("#" + a + " .panel-title").text(e.panelDetails && e.panelDetails[0] && e.panelDetails[0].name ? e.panelDetails[0].name : e.name), $("#" + a + " .panel-subtitle").html("")), e.notes && e.notes.length && $("#" + a + " .panel-title").append(`<div style="line-height: 22px;font-size: 12px; color: #555555;">${e.notes.join("<br />")}</div>`), 1 === t && ($("#" + a + " .section-content-header .panels-header .biom-range").text(localeService.t("Reference range")), $("#" + a + " .section-content-header .panels-header .biom-last").text(localeService.t("Last reading")), $("#" + a + " .section-content-header .panels-header .biom-past").text(localeService.t("Last reading date")))), e.biomarkers.forEach(e => {
84
+ if (!0 === e.showInCompactView) {
85
+ let t = "cpt-bio-" + safeCssName("cb" + e.id) + Math.random().toString().substr(2),
86
+ r = d.replace("{{biomarker-id}}", t);
87
+ $("#" + a + " table.listing").append(r), e.color && !e.isNormal && ($("#" + t).addClass("risk"), $("#" + t + ".risk .biom-parent-value").css({color: e.color})), $("#" + t + " .biom-title").text(e.fullName ? e.fullName : " "), e.unit || 0 != e.ranges.length || e.history && 0 != e.history.length ? ($("#" + t + " .biom-value").attr("colspan", 1), $("#" + t + " .biom-value .biom-parent-value").text(e.formattedValue ? e.formattedValue : " ")) : ($("#" + t + " .biom-value").addClass("biom-value-custom"), $("#" + t + " .biom-value .biom-parent-value").text(e.formattedValue)), isNaN(e.formattedValue.replace(/,/g, ".")) && ($("#" + t + " .biom-value").addClass("biom-value-custom small-value-font-size"), $("#" + t + " .biom-cell .biom-parent-value").css("width", "140px"), $("#" + t + " .biom-cell .biom-row").css("margin-left", "0px")), e.formattedValue.length >= 125 && ($("#" + t).addClass("no-border-bottom"), $("#" + t + " .biom-parent-value").html(e.formattedValue.replace(/\r/g, "<br />")), $("#" + t + " .biom-bar").remove(), $("#" + t + " .biom-range").remove(), $("#" + t + " .biom-past").remove(), $("#" + t + " .biom-last").remove(), $("#" + t + " .biom-unit").css({width: "auto"}), $("#" + t + " .biom-value").attr("colspan", 5)), $("#" + t + " .biom-unit .biom-parent-unit").text(e.unit ? e.unit : " "), $("#" + t + " .biom-unit").attr("colspan", 1);
88
+ let o = "", l = "";
89
+ e.childrenBiomarkers && e.childrenBiomarkers.length && ($("#" + t).addClass("hide-flag"), e.childrenBiomarkers.reverse().forEach((a, r) => {
90
+ const n = a.formattedValue, i = a.unit;
91
+ if (r > 0 && ($("#" + t + " .biom-unit .biom-parent-unit").after("<br/>"), $("#" + t + " .biom-value .biom-parent-value").after("<br/>")), $("#" + t + " .biom-unit .biom-parent-unit").after(`<span>${i}</span>`), $("#" + t + " .biom-value .biom-parent-value").after(`<span class="word-break-normal">${n}</span>`), e.color && !e.isNormal && $("#" + t + " .biom-value .word-break-normal").css({color: e.color}), a.ranges.length > 1 && a.showScale && a.ranges.forEach(e => {
92
+ e.isCurrent && (o = e.min + " - " + e.max), l += "\n" + color(e.color), l += "\n" + e.min + " - " + e.max, l += "\n" + e.name, l += e.isCurrent ? "\ncurrent" : "", l += e !== a.ranges[a.ranges.length - 1] ? "\n//" : ""
93
+ }), r === e.childrenBiomarkers.length - 1) {
94
+ let e = a.ranges.find(e => e.isNormal),
95
+ r = a.formattedNormalRangeMin ? a.formattedNormalRangeMin : e ? e.formattedMin : "",
96
+ o = a.formattedNormalRangeMax ? a.formattedNormalRangeMax : e ? e.formattedMax : "",
97
+ l = getRange(r, o, a.normalRangeType);
98
+ $("#" + t + " .biom-range .parent-reference-range").after(`<div class="child-referene-range">${l}</div>`)
99
+ }
100
+ }));
101
+ let n = "", i = "";
102
+ if (e.showScale) if (e.ranges.length > 1) {
103
+ e.ranges.forEach(t => {
104
+ t.isCurrent && (i = t.min + " - " + t.max), n += "\n" + color(t.color), n += "\n" + t.min + " - " + t.max, n += "\n" + t.name, n += t.isCurrent ? "\ncurrent" : "", n += t !== e.ranges[e.ranges.length - 1] ? "\n//" : ""
105
+ });
106
+ let a = e.ranges.find(e => e.isNormal),
107
+ r = e.formattedNormalRangeMin ? e.formattedNormalRangeMin : a ? a.formattedMin : "",
108
+ o = e.formattedNormalRangeMax ? e.formattedNormalRangeMax : a ? a.formattedMax : "",
109
+ l = getRange(r, o, e.normalRangeType);
110
+ $("#" + t + " .range-placeholder").text(n), $("#" + t + " .biom-range .parent-reference-range").text(l || " "), $("#" + t + " .biom-range").attr("colspan", 1)
111
+ } else {
112
+ let a;
113
+ if (e.childrenBiomarkers.find((e, t) => {
114
+ e.ranges.length > 1 && (a || (a = {index: t, item: e}))
115
+ }), a) {
116
+ a.item.ranges.forEach(t => {
117
+ n += "\n" + color(t.color), n += "\n" + t.min + " - " + t.max, n += "\n" + t.name, n += t.isCurrent ? "\ncurrent" : "", n += t !== e.ranges[e.ranges.length - 1] ? "\n//" : ""
118
+ });
119
+ const r = 10 + 26 * (a.index % e.childrenBiomarkers.length);
120
+ $("#" + t + " .range-placeholder").text(n), $("#" + t + " .range-placeholder").css({
121
+ position: "absolute",
122
+ bottom: `${r}px`
123
+ }), $("#" + t + " .child-referene-range").css({position: "absolute", bottom: `${r - 6}px`})
124
+ } else $("#" + t).addClass("hide-scale")
125
+ }
126
+ if (e.history && e.history.length > 1) {
127
+ let a = e.history.length - 2;
128
+ $("#" + t + " .biom-last").text(e.history[a].formattedValue ? e.history[a].formattedValue : " "), $("#" + t + " .biom-last").attr("colspan", 1), $("#" + t + " .biom-past").attr("colspan", 1);
129
+ let r = e.history[a] && e.history[a].formattedDate;
130
+ $("#" + t + " .biom-past").text(r || "")
131
+ }
132
+ }
133
+ })
134
+ }), console.log("Took 11", Date.now() - a, " ms to finish")
135
+ }
136
+ if (console.log("Took 12", Date.now() - a, " ms to finish"), e.showDetailsView) {
137
+ console.log("Took 13", Date.now() - a, " ms to finish");
138
+ let t = v.replace("{{title}}", localeService.t("Details")).replace("{{section-id}}", "details-section");
139
+ $("#content").append(t);
140
+ let o = 0, l = !1;
141
+ e.panels.forEach(e => {
142
+ let t = "dtl-pnl-" + safeCssName("dp" + e.panelId);
143
+ if (e.biomarkers && e.biomarkers.filter(e => e.showInDetailsView).length) {
144
+ let a = p.replace("{{panel-id}}", t);
145
+ $("#content").append(a), $("#" + t).addClass("sectionPanel"), e.panelDetails && e.panelDetails.length > 1 ? ($("#" + t + " .panel-title").text(e.panelDetails[0].name), $("#" + t + " .panel-subtitle").html(e.panelDetails.slice(1).map((e, t) => `<div class="panel-subtitle-item" style="margin-left:${10 * (t + 1)}px">${e.name}</div>`))) : ($("#" + t + " .panel-title").text(e.panelDetails && e.panelDetails[0] && e.panelDetails[0].name ? e.panelDetails[0].name : e.name), $("#" + t + " .panel-subtitle").html("")), $("#" + t + " .section-content .biom-last").text("ttt"), l = !0
146
+ }
147
+ e.biomarkers.forEach(a => {
148
+ if (!0 === a.showInDetailsView) {
149
+ let s = "dtl-bio-" + safeCssName("db" + a.id), c = m.replace("{{biomarker-id}}", s), d = "";
150
+ isNaN(a.formattedValue) && (d = "16px");
151
+ let p = GetBiomarkerCircleStyle(a.color, a.name, a.status, a.insightsCount, e.name, !1);
152
+ c = (c = c.replace("{{unit}}", `<span>${a.unit}</span>`)).replace("{{full_name}}", a.fullName), $("#" + t + " .panel-container").append(c), $("#" + s + " .biomarker .biom-circle").attr("style", p), $("#" + s + " .biom-circle").text(a.name), a.formattedValue.length >= 125 && ($("#" + s).addClass("large-value-class"), $("#" + s + " .grid-col:last-child").remove(), $("#" + s + " .grid-col").first().removeClass("size4").css("width", "100%")), $("#" + s + " .value-text").html(`<span style="font-size:${d}">${a.formattedValue.replace(/\r/g, "<br />")}</span>`), a.showScale || $("#" + s).addClass("hide-scale");
153
+ let g = "", h = "", f = 50;
154
+ a.ranges.length > 1 ? ($("#" + s + " .biomarker .title").addClass("has-ranges"), a.ranges.forEach(e => {
155
+ e.isCurrent && (h = e.min + " - " + e.max, e.min && e.min.toString() && e.max && e.max.toString() && (f = r ? 100 - (a.value - e.min) / (e.max - e.min) * 100 : (parseFloat(a.value) - e.min) / (e.max - e.min) * 100)), g += "\n" + color(e.color), e.isNormal ? g += "\n" + getRange(e.formattedMin, e.formattedMax, a.normalRangeType) : g += "\n" + getRange(e.formattedMin, e.formattedMax), g += "\n" + e.name, g += e.isCurrent ? "\ncurrent\n" + f : "", g += e !== a.ranges[a.ranges.length - 1] ? "\n//" : ""
156
+ })) : $("#" + s + " .biomarker .title").addClass("has-no-ranges");
157
+ let b = "", v = "", w = 50, y = 1;
158
+ if (a.childrenBiomarkers && a.childrenBiomarkers.length && a.childrenBiomarkers.forEach(e => {
159
+ if (e.ranges.length > 1) {
160
+ y++;
161
+ let t = e.formattedValue.replace(/\r/g, "<br />"), a = e.unit;
162
+ $("#" + s + " .biom-info .value").after(`\n <div class="colorable pair">\n <span class="biomarker-extra-value">${t}</span>\n <span class="biomarker-extra-unit">${a}</span>\n </div>\n `), b = "", v = "", e.ranges.forEach((t, a) => {
163
+ t.isCurrent && (v = t.min + " - " + t.max, t.min && t.min.toString() && t.max && t.max.toString() && (w = r ? 100 - (e.value - t.min) / (t.max - t.min) * 100 : (parseFloat(e.value) - t.min) / (t.max - t.min) * 100)), b += "\n" + color(t.color), t.isNormal ? b += "\n" + getRange(t.formattedMin, t.formattedMax, e.normalRangeType) : b += "\n" + getRange(t.formattedMin, t.formattedMax), b += "\n" + t.name, b += t.isCurrent ? "\ncurrent\n" + w : "", b += t !== e.ranges[e.ranges.length - 1] ? "\n//" : ""
164
+ }), b && $("#" + s + " .range-placeholder").after(`<div class="extra-range-placeholder">${b}</div>`), $("#" + s + " .biomarker .title").addClass("has-ranges")
165
+ } else $("#" + s + " .biomarker .title").addClass("has-no-ranges")
166
+ }), $("#" + s + " .range-placeholder").text(g), y > 1 && $("#" + s).addClass("hide-flag"), a.history.length > 1) {
167
+ let e = "chart-bio-" + safeCssName("db" + a.id),
168
+ t = "<canvas id=" + e + " width='100%' height='30' class='chart-canvas' ></canvas>";
169
+ $("#" + s + " .chart").append(t);
170
+ var l = [], n = [], i = [];
171
+ a.history.forEach((e, t) => {
172
+ l[t] = parseFloat(e.value), n[t] = e.color, i[t] = e.formattedDate
173
+ });
174
+ let r = {id: e, dataset: l, dataColor: n, dataLabel: i};
175
+ k[o] = r, o++
176
+ }
177
+ renderDoctorNotes(a.doctorNotes, t);
178
+ let S = 0;
179
+ a.relatedInsights.forEach(e => {
180
+ let t = "dtl-bio-" + a.id + "-insight" + S;
181
+ S++;
182
+ let r = u.replace("{{insight-id}}", t).replace("{{doctorContentHeader}}", localeService.t("doctorContent")).replace("{{doctorContentSubheader}}", localeService.t("mostCommonCausesOfTheObservedValue"));
183
+ $("#" + s + " .biomarker-insights").append(r);
184
+ let o = "", l = "", n = "";
185
+ if (n = e.introductoryStatement ? e.introductoryStatement : e.content) {
186
+ let e = "<span>", t = "</span>";
187
+ n.includes(e) && (l = n.substring(n.indexOf(e) + e.length, n.indexOf(t)), n = (n = n.replace(/<(.|\n)*?>/g, "")).replace(l, ""))
188
+ }
189
+ if (e.introductoryStatement || e.summary || e.testExplained || e.suggestion ? (o += n ? "\n" + n.replace(/(\r\n|\n|\r)/gm, "<br/>") : "", o += e.summary ? e.summary : "", o += e.testExplained ? e.testExplained : "", o = (o += e.suggestion ? e.suggestion : "").replace("(", "&rlm;("), $("#" + t + " .text").prepend(o)) : (o = (o += n).replace("(", "&rlm; ("), $("#" + t + " .text").prepend(o)), e.detailedList) {
190
+ const a = parseTable(e.detailedList), r = renderDetails(a);
191
+ $("#" + t + "+ .detailed-list-wrapper .detailed-list").html(r), $("#" + t + "+ .detailed-list-wrapper .tolerance-text").html(l), $("#" + t + "+ .detailed-list-wrapper .doctor-only-content-container").removeClass("hide-me"), $("#" + t + "+ .detailed-list-wrapper .detailed-list ul").prev("li").addClass("arrow-icon")
192
+ }
193
+ e.isClinicalReading || ("" === e.color ? $("#" + t).addClass("tip") : $("#" + t).addClass(color(e.color))), "" !== e.icon && $("#" + t + " .icon img").attr("src", e.icon);
194
+ let i = "";
195
+ e.title && (i += "<div class='title'>" + e.title + "</div>")
196
+ })
197
+ }
198
+ }), renderDoctorNotes(e.doctorNotes, t);
199
+ let a = 0;
200
+ e.insights.forEach(r => {
201
+ let o = "dtl-pnl-insight-" + e.panelId + "-insight" + a;
202
+ a++;
203
+ let l = u.replace("{{insight-id}}", o).replace("{{doctorContentHeader}}", localeService.t("doctorContent")).replace("{{doctorContentSubheader}}", localeService.t("mostCommonCausesOfTheObservedValue"));
204
+ $("#" + t).append(l);
205
+ let n = "", i = "", s = "";
206
+ if (s = r.introductoryStatement ? r.introductoryStatement : r.content) {
207
+ let e = "<span>", t = "</span>";
208
+ s.includes(e) && (i = s.substring(s.indexOf(e) + e.length, s.indexOf(t)), s = (s = s.replace(/<(.|\n)*?>/g, "")).replace(i, ""))
209
+ }
210
+ if (r.introductoryStatement || r.summary || r.testExplained || r.suggestion ? (n += s ? "\n" + s.replace(/(\r\n|\n|\r)/gm, "<br/>") : "", n += r.summary ? "<br/>" + r.summary : "", n += r.testExplained ? "<br/>" + r.testExplained : "", n = (n += r.suggestion ? "<br/>" + r.suggestion : "").replace("(", "&rlm; ("), $("#" + o + " .text").prepend(n)) : (n = (n += s).replace("(", "&rlm; ("), $("#" + o + " .text").prepend(n)), r.detailedList) {
211
+ const e = parseTable(r.detailedList), t = renderDetails(e);
212
+ $("#" + o + "+ .detailed-list-wrapper .detailed-list").html(t), $("#" + o + "+ .detailed-list-wrapper .tolerance-text").html(i), $("#" + o + "+ .detailed-list-wrapper .doctor-only-content-container").removeClass("hide-me"), $("#" + o + "+ .detailed-list-wrapper .detailed-list ul").prev("li").addClass("arrow-icon")
213
+ }
214
+ r.isClinicalReading || ("" === r.color ? $("#" + o).addClass("tip") : $("#" + o).addClass(color(r.color))), "" !== r.icon && $("#" + o + " .icon img").attr("src", r.icon);
215
+ let c = "";
216
+ if (r.title && (c += "<div class='title'>" + r.title + "</div>"), r.relatedBiomarkers && r.relatedBiomarkers.length > 0) {
217
+ $("#" + o + " .text ").addClass("insight-text"), r.disclaimer && $("#" + o).append("<div class='insight-disclaimer'>" + r.disclaimer + "</div>");
218
+ let t = "<div id='" + o + "' class='related-icons' />";
219
+ $("#" + o).append(t), $("#" + o + " .related-icons").addClass("has-related").addClass(color(r.color)), r.relatedBiomarkers.forEach(t => {
220
+ $("#" + o + " .related-icons").append(GetRelatedBiomarker(GetBiomarkerCircleStyle(t.color, t.name, t.status, t.insightsCount, e.name, !1), t.name, t.fullName))
221
+ })
222
+ } else $("#" + o + " .related-icons").remove()
223
+ })
224
+ }), l || $("#details-section").remove(), $("#chartsData").append("<script> var chartsData = " + JSON.stringify(k) + "<\/script>"), console.log("Took 14", Date.now() - a, " ms to finish")
225
+ }
226
+ if (console.log("Took 15", Date.now() - a, " ms to finish"), (e.summary && e.summary.length > 0 || e.doctorNote && e.doctorNote.length) && ($("#content").append(g), $("#summary .resume-title").text(localeService.t("Summary"))), console.log("Took 16", Date.now() - a, " ms to finish"), e.doctorNote && e.doctorNote.length > 0) {
227
+ e.doctorNote.forEach((e, t) => {
228
+ let a = "dtl-bio-" + e.id + "-insight" + t, r = w.replace("{{note-id}}", a);
229
+ $("#summary .section-content").append(r), $("#" + a + " .text .from-doctor").append(localeService.t("noteFromDoctor") + " " + e.createdByName), $("#" + a + " .text .note-content").append(e.content)
230
+ })
231
+ }
232
+ if (console.log("Took 17", Date.now() - a, " ms to finish"), e.summary && e.summary.length > 0) {
233
+ let t = 0;
234
+ setSummaryStatInsightText(e.summary).forEach(e => {
235
+ let a = "smry-insight" + t;
236
+ t++;
237
+ let r = f.replace("{{insight-id}}", a);
238
+ $("#summary .section-content").append(r), e.isClinicalReading ? $("#" + a).addClass("cr") : "" === e.color ? $("#" + a).addClass("tip") : $("#" + a).addClass(color(e.color)), "" !== e.icon && $("#" + a + " .icon img").attr("src", e.icon);
239
+ let o = "";
240
+ e.title && (o += "<div class='title'>" + e.title + "</div>"), o += e.content.replace(/(\r\n|\n|\r)/gm, "<br/>"), $("#" + a + " .text").html(o), e.relatedBiomarkers && e.relatedBiomarkers.length > 0 ? ($("#" + a).addClass("has-related").addClass(color(e.color)), e.relatedBiomarkers.forEach(e => {
241
+ $("#" + a + " .related-icons").append(GetRelatedBiomarker(GetBiomarkerCircleStyle(e.color, e.name, e.status, e.insightsCount, "nothing", !0), e.name, e.fullName))
242
+ })) : $("#" + a + " .related-icons").remove()
243
+ }), console.log("Took 18", Date.now() - a, " ms to finish")
244
+ }
245
+ if (console.log("Took 19", Date.now() - a, " ms to finish"), (e.reportSummary || e.reportProperties && e.labType && "9" !== e.labType.toString()) && ($("#content").append("<br><br>"), $("#content").append(h)), console.log("Took 20", Date.now() - a, " ms to finish"), e.reportSummary ? ($("#report-summary .report-summary-title").text(localeService.t("reportSummary")), $("#report-summary .report-summary-content").append(e.reportSummary)) : ($("#report-summary .report-summary-title").remove(), $("#report-summary .report-summary-content").remove()), console.log("Took 21", Date.now() - a, " ms to finish"), e.reportProperties && e.labType && "9" !== e.labType.toString()) {
246
+ $("#report-summary .report-properties-title").text(localeService.t("reportProperties"));
247
+ let t = e.reportProperties;
248
+ Object.keys(t).forEach(e => {
249
+ $("#report-summary .report-properties-content").append("<p>" + e + ":" + t[e] + "</p>")
250
+ })
251
+ } else $("#report-summary .report-properties-title").remove(), $("#report-summary .report-properties-content").remove();
252
+ console.log("Took 22", Date.now() - a, " ms to finish"), e.signatures && e.signatures.length > 0 && ($("#content").append("<br><br><br><br>"), e.signatures.forEach((t, a) => {
253
+ let r = "sgtr-" + a, o = b.replace("{{signature-id}}", r);
254
+ $("#content").append(o);
255
+ let l = t.name;
256
+ l += "" !== e.approvalDate ? "<br>" + e.approvalDate : "", $("#" + r + " .info-label").text(localeService.t("signedBy")), $("#" + r + " .info-value").html(l), $("#" + r + " .signature-image").attr("src", t.signatureURL), e.labStamp ? $("#" + r + " .stamp-image").attr("src", e.labStamp) : $("#" + r + " .stamp-image").remove()
257
+ }), $("#content").append("<br>")), console.log("Took 23", Date.now() - a, " ms to finish"), $(".grid-row + .grid-row.biomarker-insights").each(function () {
258
+ $(this).children().length || $(this).remove()
259
+ }), $(".detailed-list").each(function () {
260
+ $(this).children().length || $(this).remove()
261
+ }), $(".section.new-page").first().addClass("first-new-page"), $(".text").each(function () {
262
+ $(this).text().trim() || $(this).parent().remove()
263
+ }), $(".extra-range-placeholder").each(function () {
264
+ $(this).text().trim() || $(this).remove()
265
+ }), $(".panel-title + .section-content .panel-container").each(function () {
266
+ $(this).text().trim() || $(this).parent().siblings(".panel-title").remove()
267
+ }), $(".section.new-page#details-section,.section.panel.sectionPanel").wrapAll('<div class="pdf-wrapper" />'), $(".section.new-page.first-new-page").prependTo($(".pdf-wrapper .sectionPanel:nth-child(2) .panel-wrapper")), $(".section-content .panel-container .biomarker-container:first-child").each(function () {
268
+ let e = $(this).parent().parent().parent().find(".panel-wrapper");
269
+ $(this).appendTo(e)
270
+ }), debugLog("after signature"), console.log("Took 24", Date.now() - a, " ms to finish");
271
+ let Q = path.resolve(`${__dirname}/../output`);
272
+ return fs.existsSync(Q) || fs.mkdirSync(Q), await promisify(fs.writeFile)(OUT_FILE, U.serialize()), console.log("Took end of html", Date.now() - a, " ms to finish"), {
273
+ html: U.serialize(),
274
+ firstHeader: M.serialize(),
275
+ outputFile: OUT_FILE,
276
+ header: I.serialize(),
277
+ footer: A.serialize(),
278
+ historyData: k,
279
+ labType: e.labType,
280
+ dateNow: a
281
+ }
282
+ }, GetRelatedBiomarker = (e, t, a) => {
283
+ let r = "";
284
+ if (color && t && a) {
285
+ return t.length >= 7 && (r = "small-fontSize-circle"), ('<div class="related">\n <div class="bicon ' + r + '" style="{{biomarkerstyle}}"><span class="bicon-inner">{{name}}</span></div>\n </div>').replace("{{biomarkerstyle}}", e).replace("{{name}}", t).replace("{{fullname}}", a)
286
+ }
287
+ return null
288
+ }, GetBiomarkerCircleStyle = (e, t, a, r, o, l) => {
289
+ let n = "";
290
+ return n = l ? `\n background-color: ${e ? "transparent" : "#E05A5A30"};\n border: 2px solid ${e || "#E05A5A"};\n color: ${e || "#555555"};\n font-size: ${t && t.length > 6 ? "12px" : "14px"}\n ` : `\n background-color: transparent;\n border: 2px solid ${e || "#555555"};\n color: ${e || "#555555"};\n font-size: ${t && t.length > 6 ? "12px" : "14px"}\n `, void 0 !== r && void 0 !== typeof r && void 0 !== a && void 0 !== typeof a && (n = `\n background-color: ${r || "health risk calculators" === o.toLowerCase() ? e : "transparent"};\n border: ${r || o.toLowerCase(), `2px solid ${e}`};\n color: ${r ? "#ffffff" : e};\n font-size: ${t && t.length > 6 ? "12px" : "14px"}\n `, 1 == a && "1" == a || (n = `\n background-color: transparent;\n border: 2px solid rgba(0,0,0,.4);\n color: rgba(0,0,0,.4);\n font-size: ${t && t.length > 7 ? "12px" : "14px"}\n `)), n
291
+ }, num = e => isNaN(e) ? parseFloat(e.replace(",", "")) : e, shouldShowPanel = e => {
292
+ let t = e.biomarkers, a = t.length;
293
+ return !(!t || t && !a) && t.filter(e => !e.showInCompactView).length !== a
294
+ }, getRange = (e, t, a = null) => {
295
+ let r = "";
296
+ switch (null !== t && null !== e && (r = e + " - " + t), null !== t && null === e && (r = "< ".max), null !== e && null === t && (r = "> " + e), a) {
297
+ case"0":
298
+ null !== t && null !== e && (r = e + " - " + t), null !== t && null === e && (r = "<= " + t), null !== e && null === t && (r = ">= " + e);
299
+ break;
300
+ case"1":
301
+ r = "< " + t;
302
+ break;
303
+ case"2":
304
+ r = "<= " + t;
305
+ break;
306
+ case"3":
307
+ r = "> " + e;
308
+ break;
309
+ case"4":
310
+ r = ">= " + e
311
+ }
312
+ return r
313
+ }, color = e => {
314
+ switch (e) {
315
+ case"#E05A5A":
316
+ return "red";
317
+ case"#EE734E":
318
+ return "orange";
319
+ case"#41B9D6":
320
+ return "blue";
321
+ case"#F7AA2E":
322
+ return "yellow";
323
+ case"#BC2828":
324
+ return "dark-red";
325
+ case"#02D9D1":
326
+ case"#05B9AF":
327
+ return "green";
328
+ case"#0F0F0F":
329
+ return "black";
330
+ case"#87B7CE":
331
+ return "lightblue";
332
+ case"#FB7377":
333
+ return "light-red";
334
+ default:
335
+ return e
336
+ }
337
+ }, fitNumber = e => e.length > 11 ? e.slice(0, 11) + "<br>" + e.slice(11) : e,
338
+ safeCssName = e => encodeURIComponent(e.toLowerCase()).replace(/%[0-9A-F]{2}/gi, ""), generatePDF = async e => {
339
+ console.log("Took generatePDF 1", Date.now() - e.dateNow, " ms to finish");
340
+ try {
341
+ e.html;
342
+ let t = e.firstHeader, a = e.header, r = e.footer, o = e.labType, l = o && 9 === o;
343
+ console.log("Took generatePDF 2", Date.now() - e.dateNow, " ms to finish"), OUT_FILE = e.outputFile;
344
+ let n = await puppeteer.launch({
345
+ args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"],
346
+ headless: !0,
347
+ defaultViewport: null
348
+ });
349
+ console.log("Took generatePDF 3", Date.now() - e.dateNow, " ms to finish");
350
+ let i = await n.newPage();
351
+ debugLog("page launched!"), await i.setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"), console.log("Took generatePDF 4", Date.now() - e.dateNow, " ms to finish"), await i.setViewport({
352
+ width: 1366,
353
+ height: 768
354
+ }), await i.goto("file:///" + path.resolve(__dirname + `/../${Pdf_file}`), {waitUntil: "networkidle2"}).catch(e => {
355
+ console.log("ERROR IS File path: " + e.message)
356
+ }), console.log("Took generatePDF 5", Date.now() - e.dateNow, " ms to finish"), debugLog("page opened!");
357
+ let s = await i.pdf({
358
+ format: "A4",
359
+ pageRanges: "1",
360
+ printBackground: !0,
361
+ displayHeaderFooter: !0,
362
+ margin: {top: shouldRenderCustomHeader ? 0 : l ? 125 : 100, bottom: 100},
363
+ headerTemplate: t,
364
+ footerTemplate: r
365
+ });
366
+ console.log("Took generatePDF 6", Date.now() - e.dateNow, " ms to finish"), debugLog("Buffer1 loaded!");
367
+ let c = null;
368
+ try {
369
+ c = await i.pdf({
370
+ format: "A4",
371
+ pageRanges: "2-",
372
+ printBackground: !0,
373
+ displayHeaderFooter: !0,
374
+ margin: {top: l ? 125 : 100, bottom: l ? 100 : 125},
375
+ headerTemplate: a,
376
+ footerTemplate: r
377
+ })
378
+ } catch (e) {
379
+ debugLog("ERROR!!: ", e), c = null
380
+ }
381
+ console.log("Took generatePDF 7", Date.now() - e.dateNow, " ms to finish"), debugLog("Buffer2 loaded!");
382
+ let d = null != c ? await combinePDFBuffers(s, c) : s;
383
+ return console.log("Took generatePDF 8", Date.now() - e.dateNow, " ms to finish"), await n.close(), d
384
+ } catch (e) {
385
+ return debugLog("ERROR!: ", e), ""
386
+ }
387
+ };
388
+ const setSummaryStatInsightText = e => {
389
+ let t = [], a = e;
390
+ return e.forEach((r, o) => {
391
+ if (null != r.stackedInsight) {
392
+ let l = {};
393
+ a.find((a, n) => {
394
+ a && a.id == r.stackedInsight && (l.index = n, r.content += "<br><br>" + a.content, l.elm = r, t[o] = a, e[l.index] = l.elm, e.splice(n, 1))
395
+ })
396
+ }
397
+ }), e
398
+ }, combinePDFBuffers = (e, t) => {
399
+ var a = new memoryStreams.WritableStream;
400
+ try {
401
+ var r = new hummus.PDFRStreamForBuffer(e), o = new hummus.PDFRStreamForBuffer(t),
402
+ l = hummus.createWriterToModify(r, new hummus.PDFStreamForResponse(a));
403
+ l.appendPDFPagesFromPDF(o), l.end();
404
+ var n = a.toBuffer();
405
+ return a.end(), n
406
+ } catch (e) {
407
+ throw a.end(), new Error("Error during PDF combination: " + e.message)
408
+ }
409
+ }, list_to_tree = (e, t) => {
410
+ let a = [], r = e.filter(e => e.parent_id === t);
411
+ return 0 === r.length ? [] : (r.map(t => {
412
+ t.children = list_to_tree(e, t.id), a.push(t)
413
+ }), a)
414
+ }, findParentId = (e, t, a) => {
415
+ for (let r = e; r > 0; r--) if (a[r].sepCount === t) return a[r].parent_id
416
+ }, separtorsNumbers = e => {
417
+ let t = e.lastIndexOf("#"), a = e.indexOf("#");
418
+ if (-1 !== a && 0 !== a) return 0;
419
+ let r = e.substring(a, t + 1).split(""), o = !0;
420
+ return r.map(e => {
421
+ if ("#" !== e) return o = !1, !1
422
+ }), o ? r.length : separtorsNumbers(e.substring(a, t))
423
+ }, parseTable = e => {
424
+ let t = e.split("\n"), a = [];
425
+ t.map(e => {
426
+ let t = separtorsNumbers(e), r = {id: Math.random().toString().substr(2, 6), content: e, sepCount: t};
427
+ r.id = Math.random().toString().substr(2, 6), a.push(r)
428
+ });
429
+ let r = a[0].sepCount;
430
+ for (let e = 0; e < a.length; e++) 0 !== e && r !== a[e].sepCount ? isEmpty(a[e - 1]) || (a[e].sepCount > a[e - 1].sepCount && (a[e].parent_id = a[e - 1].id), a[e].sepCount === a[e - 1].sepCount && (a[e].parent_id = a[e - 1].parent_id), a[e].sepCount < a[e - 1].sepCount && (a[e].parent_id = findParentId(e - 1, a[e].sepCount, a))) : a[e].parent_id = "0";
431
+ return list_to_tree(a, "0")
432
+ }, isEmpty = e => {
433
+ for (let t in e) if (e.hasOwnProperty(t)) return !1;
434
+ return !0
435
+ },
436
+ empty = e => void 0 === e || void 0 === e || void 0 === typeof e || null === e || "" === e || "" === e || 0 === e.length || "undefined" === e,
437
+ renderDetails = e => {
438
+ if (1 === e.length && empty(e[0].children)) return `<li>${e[0].content.substring(e[0].sepCount, e[0].content.length + 1)}</li>`;
439
+ let t = [], a = !1;
440
+ e.map((e, r) => {
441
+ "0" === e.parent_id && (a = !0);
442
+ let o = "";
443
+ o = empty(e.children) ? "<li>" + `${e.content.substring(e.sepCount, e.content.length + 1)}` + "</li>" : "<li>" + `${e.content.substring(e.sepCount, e.content.length + 1)}` + "</li><ul>" + `${renderDetails(e.children)}` + "</ul>", empty(o) || t.push(o)
444
+ });
445
+ let r = "";
446
+ return t.map(e => {
447
+ empty(e) || (r += e)
448
+ }), empty(t) ? null : `${r}`
449
+ }, generatePatientQR = async e => {
450
+ try {
451
+ const t = new JSDOM(e);
452
+ let a = t.serialize(), r = path.resolve(`${__dirname}/../output`);
453
+ fs.existsSync(r) || fs.mkdirSync(r);
454
+ let o = path.resolve(__dirname + "/../output/report-pdf-QR" + Date.now() + ".html"),
455
+ l = "/output/report-pdf-QR" + Date.now() + ".html";
456
+ await promisify(fs.writeFile)(o, t.serialize());
457
+ const n = await puppeteer.launch({args: ["--no-sandbox"]}), i = await n.newPage();
458
+ debugLog("page launched!"), await i.setContent(a, {waitUntil: "networkidle2"}), debugLog("Content loaded"), await i.goto("file:///" + path.resolve(__dirname + `/../${l}`), {
459
+ timeout: 3e7,
460
+ waitUntil: "networkidle2"
461
+ }).catch(e => {
462
+ console.log("ERROR IS File path: " + e.message)
463
+ }), debugLog("page opened!"), await i.evaluateHandle("document.fonts.ready"), debugLog("fonts loaded!");
464
+ let s = await i.pdf({
465
+ format: "letter",
466
+ printBackground: !0,
467
+ displayHeaderFooter: !1,
468
+ margin: {top: 0, bottom: 0},
469
+ headerTemplate: "",
470
+ footerTemplate: ""
471
+ });
472
+ debugLog("Buffer1 loaded!"), debugLog("Buffer2 loaded!");
473
+ let c = s;
474
+ return debugLog("Buffers merged !"), await n.close(), c
475
+ } catch (e) {
476
+ return debugLog("ERROR! here 2: ", e), ""
477
+ }
478
+ }, renderDoctorNotes = (e, t) => {
479
+ if (empty(e)) return null;
480
+ let a = fs.readFileSync(path.resolve(__dirname + "/../templates/blocks/doctor-note.html"), "utf8");
481
+ e.forEach(e => {
482
+ let r = `doctor-note-${generateUniqueId()}`, o = a.replace("{{note-id}}", r);
483
+ $("#" + t + " .biomarker-insights").append(o), $("#" + r + " .text .from-doctor").append(localeService.t("noteFromDoctor") + " " + e.createdByName), $("#" + r + " .text .note-content").append(e.content)
484
+ })
485
+ }, generateUniqueId = () => Date.now() + (100 * Math.random()).toString().substr(6),
486
+ renderProfileItems = (e, t, a = !1) => {
487
+ if (a) {
488
+ $(".imc-header-address").html(t);
489
+ const a = $("#patient-container");
490
+ for (let t of e.profileItems) t && t.title && t.value && a.append(`\n <div class="profile-item-row">\n <div class="key">${t.title}:</div>\n <div class="value">${t.value}</div>\n </div>\n `)
491
+ } else {
492
+ if (e.labType && "9" === e.labType.toString()) {
493
+ $(".profile-items-container").removeClass("size4").css("width", "100%"), $(".plus-info-container").remove(), $(".intro").css("width", "93%");
494
+ let t = 100 / 3, a = e.profileItems;
495
+ if (e.reportProperties) {
496
+ let t = Object.keys(e.reportProperties).map(t => ({title: t, value: e.reportProperties[t]}));
497
+ a.push(...t)
498
+ }
499
+ for (let a of e.profileItems) {
500
+ let e = `<div style="width: ${t}%; padding: 10px 0" class='grid-col size2' >\n <div class='info-label'> ${a.title}</div>\n <div class='info-value'>${a.value}</div>\n </div>`;
501
+ $("#patient-container").append(e)
502
+ }
503
+ return null
504
+ }
505
+ for (var r = 0; r < e.profileItems.length - 1;) {
506
+ var o = "sub" + r, l = " <div id=" + o + " class='grid-row'> </div>";
507
+ $("#patient-container").append(l);
508
+ for (var n = 0; n < 2; n++) {
509
+ let t = "<div id=" + (o + "-" + n) + " class='grid-col size2' >\n <div class='info-label'>" + e.profileItems[r].title + "</div>\n <div class='info-value'>" + e.profileItems[r].value + "</div>\n </div>";
510
+ $("#" + o).append(t), r++
511
+ }
512
+ }
513
+ if (e.profileItems.length % 2) {
514
+ let t = "sub" + r;
515
+ l = " <div id=" + t + " class='grid-row'> </div>";
516
+ $("#patient-container").append(l);
517
+ let a = "<div id=" + (t + "-0") + " class='grid-col size2' >\n <div class='info-label'>" + e.profileItems[r].title + "</div>\n <div class='info-value'>" + e.profileItems[r].value + "</div>\n </div>";
518
+ $("#" + t).append(a)
519
+ }
520
+ }
521
+ };
522
+ module.exports = {
523
+ generatePDF: generatePDF,
524
+ generateHTMLStaging: generateHTMLStaging,
525
+ generatePatientQR: generatePatientQR
526
526
  };