@reportwright/viewer 0.11.0 → 0.12.0

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.
@@ -27,7 +27,7 @@ import {
27
27
  import "./chunk-OLLMACWA.js";
28
28
 
29
29
  // src/exporters/pdf.js
30
- import { PDFDocument, PDFName as PDFName3, PDFString as PDFString4, PDFHexString as PDFHexString4, PDFRawStream as PDFRawStream2, rgb as rgb2 } from "pdf-lib";
30
+ import { PDFDocument, PDFName as PDFName3, PDFString as PDFString4, PDFHexString as PDFHexString5, PDFRawStream as PDFRawStream2, rgb as rgb3 } from "pdf-lib";
31
31
  import fontkitModule from "@pdf-lib/fontkit";
32
32
 
33
33
  // src/exporters/pdfa.js
@@ -744,11 +744,8 @@ function pngProblem(b) {
744
744
  return null;
745
745
  }
746
746
 
747
- // src/exporters/pdf.js
748
- var fontkit = (
749
- /** @type {any} */
750
- fontkitModule.default || fontkitModule
751
- );
747
+ // src/exporters/pdfpaint.js
748
+ import { PDFHexString as PDFHexString4, rgb as rgb2 } from "pdf-lib";
752
749
  var colors = /* @__PURE__ */ new Map();
753
750
  var col = (c) => {
754
751
  if (colors.has(c)) return colors.get(c);
@@ -763,6 +760,321 @@ var n4 = (v) => Math.round(v * 1e4) / 1e4;
763
760
  var hex4 = (id) => id.toString(16).padStart(4, "0");
764
761
  var KAPPA = 4 * ((Math.SQRT2 - 1) / 3);
765
762
  var cleanText = (t) => t.replace(/\t|\u0085|\u2028|\u2029/g, " ").replace(/[\b\v]/g, "");
763
+ function drawRun(c, run, x, y, size, pf, color, spans, texts) {
764
+ const f = pf.embedder.font;
765
+ const per = 1e3 / size;
766
+ const span = (text) => `/Span <</ActualText ${PDFHexString4.fromText(text).toString()}>> BDC
767
+ `;
768
+ c.et();
769
+ c.paint(color, null);
770
+ c.font(pf, size);
771
+ if (!run.rtl) c.s += span(run.text);
772
+ c.s += `BT ${n2(x)} ${n2(y)} Td
773
+ `;
774
+ let arr = "";
775
+ let pen = 0, rise = 0;
776
+ const flush = () => {
777
+ if (arr) c.s += `[${arr}] TJ
778
+ `;
779
+ arr = "";
780
+ };
781
+ const all = run.glyphs;
782
+ const adv = (id) => f.getGlyph(id).advanceWidth;
783
+ let g = all, quietAt = -1;
784
+ if (run.rtl) {
785
+ const hasBase = /* @__PURE__ */ new Set();
786
+ for (let i = 0; i < all.length; i += 4) if (adv(all[i]) > 0) hasBase.add(all[i + 3]);
787
+ const quiet = (i) => spans?.has(all[i + 3]) ? adv(all[i]) === 0 && hasBase.has(all[i + 3]) : texts?.get(all[i]) === "";
788
+ g = [];
789
+ for (const late of [false, true]) {
790
+ if (late) quietAt = g.length;
791
+ for (let i = 0; i < all.length; i += 4) if (quiet(i) === late) g.push(all[i], all[i + 1], all[i + 2], all[i + 3]);
792
+ }
793
+ if (quietAt === g.length) quietAt = -1;
794
+ }
795
+ const starts = run.rtl ? [...new Set(all.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b) : [];
796
+ let inSpan = false;
797
+ for (let i = 0; i < g.length; i += 4) {
798
+ const id = g[i], gx = g[i + 1], gy = g[i + 2], cl = g[i + 3];
799
+ if (i === quietAt) {
800
+ flush();
801
+ c.s += span("");
802
+ inSpan = true;
803
+ } else if (run.rtl && spans?.has(cl) && (quietAt < 0 || i < quietAt) && (i === 0 || g[i - 1] !== cl)) {
804
+ flush();
805
+ c.s += span(run.text.slice(cl, starts[starts.indexOf(cl) + 1] ?? run.text.length));
806
+ inSpan = true;
807
+ }
808
+ if (gy !== rise) {
809
+ flush();
810
+ c.s += `${n4(gy)} Ts
811
+ `;
812
+ rise = gy;
813
+ }
814
+ const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
815
+ if (id === 0 && c.tagged) pen = gx;
816
+ else {
817
+ arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
818
+ pen = gx + adv(id) * size / f.unitsPerEm;
819
+ }
820
+ if (inSpan && (i + 4 >= g.length || (quietAt < 0 || i + 4 < quietAt) && g[i + 7] !== cl || i + 4 === quietAt)) {
821
+ flush();
822
+ c.s += "EMC\n";
823
+ inSpan = false;
824
+ }
825
+ }
826
+ flush();
827
+ if (rise) c.s += "0 Ts\n";
828
+ c.s += "ET\n";
829
+ if (!run.rtl) c.s += "EMC\n";
830
+ }
831
+ function glyphText(run, font, out, spans) {
832
+ const g = run.glyphs;
833
+ const starts = [...new Set(g.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b);
834
+ for (let k = 0; k < starts.length; k++) {
835
+ const chars = [...run.text.slice(starts[k], starts[k + 1] ?? run.text.length)];
836
+ const ids = [];
837
+ for (let i = 0; i < g.length; i += 4) if (g[i + 3] === starts[k]) ids.push(g[i]);
838
+ const own = new Map(chars.map((ch) => [font.glyphForCodePoint(ch.codePointAt(0)).id, ch]));
839
+ const rest = chars.filter((ch) => !ids.includes(font.glyphForCodePoint(ch.codePointAt(0)).id)).join("");
840
+ const carrier = rest ? ids.find((id) => !own.has(id) && font.getGlyph(id).advanceWidth > 0) ?? ids.find((id) => !own.has(id)) : void 0;
841
+ let ok = !rest || carrier !== void 0;
842
+ const want = /* @__PURE__ */ new Map();
843
+ for (const id of ids) {
844
+ const t = own.get(id) ?? (id === carrier ? rest : "");
845
+ if (want.has(id) && want.get(id) !== t) ok = false;
846
+ want.set(id, t);
847
+ }
848
+ for (const [id, t] of want) {
849
+ if (!out.has(id)) out.set(id, t);
850
+ else if (out.get(id) !== t) ok = false;
851
+ }
852
+ if (!ok && run.rtl && spans) {
853
+ let s = spans.get(run);
854
+ if (!s) spans.set(run, s = /* @__PURE__ */ new Set());
855
+ s.add(starts[k]);
856
+ }
857
+ }
858
+ }
859
+ function insideClip(it, m) {
860
+ const k = it.clip, asc = m.asc * it.size, desc = m.desc * it.size;
861
+ return it.lines.every((l) => l.w != null && !l.runs && l.x >= k.x && l.x + l.w <= k.x + k.w && l.y - asc >= k.y && l.y + desc <= k.y + k.h);
862
+ }
863
+ var Content = class {
864
+ constructor(shared) {
865
+ this.shared = shared;
866
+ this._s = "";
867
+ this.bt = false;
868
+ this.tx = 0;
869
+ this.ty = 0;
870
+ this.st = { fill: "0 0 0", stroke: "0 0 0", lw: 1, dash: "[] 0", ca: 1, CA: 1, font: "", size: 0 };
871
+ this.saved = [];
872
+ this.lines = null;
873
+ this.tagged = false;
874
+ }
875
+ /**
876
+ * The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
877
+ * of a table's cells stays in one text object (relative moves, which compress to little) instead of one per cell.
878
+ */
879
+ get s() {
880
+ this.flushLines();
881
+ return this._s;
882
+ }
883
+ set s(v) {
884
+ this._s = v;
885
+ }
886
+ /**
887
+ * A straight line. Untagged, it waits until something other than text is drawn (table borders between cell
888
+ * texts); collinear segments that touch, in the same stroke, become one (a row's border is one line).
889
+ * ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
890
+ */
891
+ line(stroke, w, dash, x1, y1, x2, y2) {
892
+ if (this.tagged) {
893
+ this.paint(null, stroke, w, dash);
894
+ this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
895
+ `;
896
+ return;
897
+ }
898
+ const key = `${stroke.rgb}|${stroke.opacity}|${w}|${(dash || []).join(" ")}`;
899
+ if (this.lines && this.lines.key !== key) this.flushLines();
900
+ this.lines || (this.lines = { key, stroke, w, dash, segs: [] });
901
+ const segs = this.lines.segs, last = segs[segs.length - 1];
902
+ const eq = (a, b) => Math.abs(a - b) < 5e-3;
903
+ if (last && eq(last[1], y1) && eq(last[3], y2) && eq(y1, y2) && eq(last[2], x1)) last[2] = x2;
904
+ else if (last && eq(last[0], x1) && eq(last[2], x2) && eq(x1, x2) && eq(last[3], y1)) last[3] = y2;
905
+ else segs.push([x1, y1, x2, y2]);
906
+ }
907
+ flushLines() {
908
+ const L = this.lines;
909
+ if (!L) return;
910
+ this.lines = null;
911
+ this.et();
912
+ this.paint(null, L.stroke, L.w, L.dash);
913
+ const g = L.segs;
914
+ const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
915
+ if (dy && g.every((q, i) => q[1] === q[3] && n2(q[0]) === n2(g[0][0]) && n2(q[2]) === n2(g[0][2]) && Math.abs(q[1] - (g[0][1] + i * dy / 100)) < 0.01)) {
916
+ const one = `${n2(g[0][0])} ${n2(g[0][1])} m ${n2(g[0][2])} ${n2(g[0][1])} l S
917
+ `;
918
+ this._s += `q
919
+ ${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
920
+ `;
921
+ return;
922
+ }
923
+ this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n";
924
+ }
925
+ q() {
926
+ this.et();
927
+ this._s += "q\n";
928
+ this.saved.push({ ...this.st });
929
+ }
930
+ Q() {
931
+ this.et();
932
+ this._s += "Q\n";
933
+ this.st = this.saved.pop();
934
+ }
935
+ /**
936
+ * A line of plain text at (x, y). Lines follow one another in one text object, each placed relative to the
937
+ * last (in whole hundredths, so nothing drifts): most of a table page is these.
938
+ * @param {string} str the glyphs, as a literal string's escaped body (array: a TJ array's body)
939
+ */
940
+ text(pf, size, color, x, y, str, array = false) {
941
+ this.setPaint(color, null);
942
+ this.setFont(pf, size);
943
+ const X = Math.round(x * 10) * 10, Y = Math.round(y * 10) * 10;
944
+ if (!this.bt) {
945
+ this._s += "BT\n";
946
+ this.bt = true;
947
+ this.tx = 0;
948
+ this.ty = 0;
949
+ }
950
+ this._s += array ? `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td [${str}] TJ
951
+ ` : `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td (${str}) Tj
952
+ `;
953
+ this.tx = X;
954
+ this.ty = Y;
955
+ }
956
+ /** end the open text object, if any: anything but text needs that (and draws the lines waiting) */
957
+ et() {
958
+ if (this.bt) {
959
+ this._s += "ET\n";
960
+ this.bt = false;
961
+ }
962
+ if (this.lines) this.flushLines();
963
+ }
964
+ lineWidth(w) {
965
+ if (this.lines) this.flushLines();
966
+ this.setLineWidth(w);
967
+ }
968
+ setLineWidth(w) {
969
+ if (this.st.lw !== w) {
970
+ this._s += `${n3(w)} w
971
+ `;
972
+ this.st.lw = w;
973
+ }
974
+ }
975
+ /** the graphics state that sets these opacities, or undefined when they are set already */
976
+ gsFor(ca, CA) {
977
+ return ca === this.st.ca && CA === this.st.CA ? void 0 : this.shared.gs(ca, CA);
978
+ }
979
+ alpha(ca, CA) {
980
+ if (this.lines) this.flushLines();
981
+ this.setAlpha(ca, CA);
982
+ }
983
+ setAlpha(ca, CA) {
984
+ const g = this.gsFor(ca, CA);
985
+ if (g) {
986
+ this._s += `/${g} gs
987
+ `;
988
+ this.st.ca = ca;
989
+ this.st.CA = CA;
990
+ }
991
+ }
992
+ /** set up to fill with fill and/or stroke with stroke (width w, dash); the lines waiting are drawn first */
993
+ paint(fill, stroke, w = 1, dash = null) {
994
+ if (this.lines) this.flushLines();
995
+ this.setPaint(fill, stroke, w, dash);
996
+ }
997
+ setPaint(fill, stroke, w = 1, dash = null) {
998
+ const st = this.st;
999
+ if (fill && fill.rgb !== st.fill) {
1000
+ this._s += `${fill.rgb} rg
1001
+ `;
1002
+ st.fill = fill.rgb;
1003
+ }
1004
+ if (stroke) {
1005
+ if (stroke.rgb !== st.stroke) {
1006
+ this._s += `${stroke.rgb} RG
1007
+ `;
1008
+ st.stroke = stroke.rgb;
1009
+ }
1010
+ this.setLineWidth(w);
1011
+ const d = `[${(dash || []).map(n3).join(" ")}] 0`;
1012
+ if (d !== st.dash) {
1013
+ this._s += `${d} d
1014
+ `;
1015
+ st.dash = d;
1016
+ }
1017
+ }
1018
+ this.setAlpha(fill ? fill.opacity : st.ca, stroke ? stroke.opacity : st.CA);
1019
+ }
1020
+ font(pf, size) {
1021
+ if (this.lines) this.flushLines();
1022
+ this.setFont(pf, size);
1023
+ }
1024
+ setFont(pf, size) {
1025
+ const name = this.shared.font(pf);
1026
+ if (name !== this.st.font || size !== this.st.size) {
1027
+ this._s += `/${name} ${n3(size)} Tf
1028
+ `;
1029
+ this.st.font = name;
1030
+ this.st.size = size;
1031
+ }
1032
+ }
1033
+ };
1034
+ function latin1(s) {
1035
+ const B = (
1036
+ /** @type {any} */
1037
+ globalThis.Buffer
1038
+ );
1039
+ if (B) return B.from(s, "latin1");
1040
+ const out = new Uint8Array(s.length);
1041
+ for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
1042
+ return out;
1043
+ }
1044
+ async function deflate(bytes) {
1045
+ if (zslots.free > 0) zslots.free--;
1046
+ else await new Promise((ok) => zslots.wait.push(
1047
+ /** @type {() => void} */
1048
+ ok
1049
+ ));
1050
+ try {
1051
+ return await deflateNow(bytes);
1052
+ } finally {
1053
+ const next = zslots.wait.shift();
1054
+ if (next) next();
1055
+ else zslots.free++;
1056
+ }
1057
+ }
1058
+ var zslots = { free: 4, wait: (
1059
+ /** @type {(() => void)[]} */
1060
+ []
1061
+ ) };
1062
+ var NODE_ZLIB = (
1063
+ /** @type {any} */
1064
+ globalThis.process?.getBuiltinModule?.("node:zlib")
1065
+ );
1066
+ async function deflateNow(bytes) {
1067
+ const zlib = NODE_ZLIB;
1068
+ if (zlib) return new Promise((ok, fail) => zlib.deflate(bytes, { level: 9 }, (e, z) => e ? fail(e) : ok(z)));
1069
+ if (typeof CompressionStream === "undefined") return (await import("fflate")).zlibSync(bytes);
1070
+ return new Uint8Array(await new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
1071
+ }
1072
+
1073
+ // src/exporters/pdf.js
1074
+ var fontkit = (
1075
+ /** @type {any} */
1076
+ fontkitModule.default || fontkitModule
1077
+ );
766
1078
  function exportPdf(model, fontStore, opt = {}) {
767
1079
  return withDeadline(
768
1080
  pdfOf(model, fontStore, opt),
@@ -781,7 +1093,7 @@ async function pdfOf(model, fontStore, opt) {
781
1093
  doc.setCreator("ReportWright");
782
1094
  if (opt.author) doc.setAuthor(opt.author);
783
1095
  setInfoDates(doc, when);
784
- if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString4.of(fileId), PDFHexString4.of(fileId)]);
1096
+ if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString5.of(fileId), PDFHexString5.of(fileId)]);
785
1097
  const used = /* @__PURE__ */ new Map();
786
1098
  const shaped = /* @__PURE__ */ new Map();
787
1099
  const spans = /* @__PURE__ */ new WeakMap();
@@ -1028,7 +1340,7 @@ async function pdfOf(model, fontStore, opt) {
1028
1340
  const form = doc.getForm();
1029
1341
  const f = await font(fieldFont(it));
1030
1342
  const name = uniqueName(it.name);
1031
- const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor: rgb2(0.61, 0.64, 0.69), borderWidth: 0.75, backgroundColor: rgb2(1, 1, 1) };
1343
+ const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor: rgb3(0.61, 0.64, 0.69), borderWidth: 0.75, backgroundColor: rgb3(1, 1, 1) };
1032
1344
  let field;
1033
1345
  if (it.kind === "checkbox") {
1034
1346
  field = form.createCheckBox(name);
@@ -1085,7 +1397,7 @@ async function pdfOf(model, fontStore, opt) {
1085
1397
  if (it.required) field.enableRequired();
1086
1398
  if (it.readOnly) field.enableReadOnly();
1087
1399
  if (tags) {
1088
- field.acroField.dict.set(PDFName3.of("TU"), PDFHexString4.fromText(it.label || it.name || name));
1400
+ field.acroField.dict.set(PDFName3.of("TU"), PDFHexString5.fromText(it.label || it.name || name));
1089
1401
  const w = field.acroField.getWidgets()[0];
1090
1402
  const ref2 = w && doc.context.getObjectRef(w.dict);
1091
1403
  if (ref2) tags.annot(pi, ii, ref2, "field");
@@ -1159,7 +1471,7 @@ async function pdfOf(model, fontStore, opt) {
1159
1471
  const to = l.href ? { A: { Type: "Action", S: "URI", URI: pdfLiteral(asciiUrl(l.href)) } } : { Dest: dest(l.to) };
1160
1472
  if (!l.href && !to.Dest) continue;
1161
1473
  const annot = doc.context.obj({ Type: "Annot", Subtype: "Link", F: 4, Rect: l.rect, Border: [0, 0, 0], ...to });
1162
- if (tags) annot.set(PDFName3.of("Contents"), PDFHexString4.fromText(String(l.text || l.tip || l.href || "Link")));
1474
+ if (tags) annot.set(PDFName3.of("Contents"), PDFHexString5.fromText(String(l.text || l.tip || l.href || "Link")));
1163
1475
  const ref = doc.context.register(annot);
1164
1476
  if (tags) tags.annot(l.pi, l.ii, ref, "link");
1165
1477
  const annots = l.page.node.lookup(PDFName3.of("Annots"));
@@ -1186,122 +1498,26 @@ function coveredText(items, box) {
1186
1498
  for (const t of items) if (t.t === "text" && t.lines) {
1187
1499
  for (const l of t.lines) if (l.text?.trim() && l.x >= box.x && l.x <= box.x + box.w && l.y >= box.y && l.y <= box.y + box.h) lines.push(l);
1188
1500
  }
1189
- return lines.sort((a, b) => a.y - b.y || a.x - b.x).map((l) => l.text.trim()).join(" ");
1190
- }
1191
- function fixedDate(opt) {
1192
- if (opt.creationDate !== void 0) {
1193
- if (!(opt.creationDate instanceof Date) || Number.isNaN(opt.creationDate.getTime())) throw Object.assign(new Error("creationDate must be a valid Date"), { status: 400 });
1194
- return opt.creationDate;
1195
- }
1196
- const epoch = globalThis.process?.env?.SOURCE_DATE_EPOCH;
1197
- return epoch && /^\d+$/.test(epoch) ? new Date(Number(epoch) * 1e3) : null;
1198
- }
1199
- async function contentId(model, opt, when) {
1200
- const bytes = new TextEncoder().encode(JSON.stringify([{ ...model, stats: void 0 }, opt.title || "Report", opt.author || "", when.toISOString()]));
1201
- const digest = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes));
1202
- return Array.from(digest.subarray(0, 16), (b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
1203
- }
1204
- function fieldFont(it) {
1205
- for (const d of it.draw) if (d.t === "text") {
1206
- for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return r.font;
1207
- }
1208
- return it.font;
1209
- }
1210
- function drawRun(c, run, x, y, size, pf, color, spans, texts) {
1211
- const f = pf.embedder.font;
1212
- const per = 1e3 / size;
1213
- const span = (text) => `/Span <</ActualText ${PDFHexString4.fromText(text).toString()}>> BDC
1214
- `;
1215
- c.et();
1216
- c.paint(color, null);
1217
- c.font(pf, size);
1218
- if (!run.rtl) c.s += span(run.text);
1219
- c.s += `BT ${n2(x)} ${n2(y)} Td
1220
- `;
1221
- let arr = "";
1222
- let pen = 0, rise = 0;
1223
- const flush = () => {
1224
- if (arr) c.s += `[${arr}] TJ
1225
- `;
1226
- arr = "";
1227
- };
1228
- const all = run.glyphs;
1229
- const adv = (id) => f.getGlyph(id).advanceWidth;
1230
- let g = all, quietAt = -1;
1231
- if (run.rtl) {
1232
- const hasBase = /* @__PURE__ */ new Set();
1233
- for (let i = 0; i < all.length; i += 4) if (adv(all[i]) > 0) hasBase.add(all[i + 3]);
1234
- const quiet = (i) => spans?.has(all[i + 3]) ? adv(all[i]) === 0 && hasBase.has(all[i + 3]) : texts?.get(all[i]) === "";
1235
- g = [];
1236
- for (const late of [false, true]) {
1237
- if (late) quietAt = g.length;
1238
- for (let i = 0; i < all.length; i += 4) if (quiet(i) === late) g.push(all[i], all[i + 1], all[i + 2], all[i + 3]);
1239
- }
1240
- if (quietAt === g.length) quietAt = -1;
1241
- }
1242
- const starts = run.rtl ? [...new Set(all.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b) : [];
1243
- let inSpan = false;
1244
- for (let i = 0; i < g.length; i += 4) {
1245
- const id = g[i], gx = g[i + 1], gy = g[i + 2], cl = g[i + 3];
1246
- if (i === quietAt) {
1247
- flush();
1248
- c.s += span("");
1249
- inSpan = true;
1250
- } else if (run.rtl && spans?.has(cl) && (quietAt < 0 || i < quietAt) && (i === 0 || g[i - 1] !== cl)) {
1251
- flush();
1252
- c.s += span(run.text.slice(cl, starts[starts.indexOf(cl) + 1] ?? run.text.length));
1253
- inSpan = true;
1254
- }
1255
- if (gy !== rise) {
1256
- flush();
1257
- c.s += `${n4(gy)} Ts
1258
- `;
1259
- rise = gy;
1260
- }
1261
- const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
1262
- if (id === 0 && c.tagged) pen = gx;
1263
- else {
1264
- arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
1265
- pen = gx + adv(id) * size / f.unitsPerEm;
1266
- }
1267
- if (inSpan && (i + 4 >= g.length || (quietAt < 0 || i + 4 < quietAt) && g[i + 7] !== cl || i + 4 === quietAt)) {
1268
- flush();
1269
- c.s += "EMC\n";
1270
- inSpan = false;
1271
- }
1501
+ return lines.sort((a, b) => a.y - b.y || a.x - b.x).map((l) => l.text.trim()).join(" ");
1502
+ }
1503
+ function fixedDate(opt) {
1504
+ if (opt.creationDate !== void 0) {
1505
+ if (!(opt.creationDate instanceof Date) || Number.isNaN(opt.creationDate.getTime())) throw Object.assign(new Error("creationDate must be a valid Date"), { status: 400 });
1506
+ return opt.creationDate;
1272
1507
  }
1273
- flush();
1274
- if (rise) c.s += "0 Ts\n";
1275
- c.s += "ET\n";
1276
- if (!run.rtl) c.s += "EMC\n";
1508
+ const epoch = globalThis.process?.env?.SOURCE_DATE_EPOCH;
1509
+ return epoch && /^\d+$/.test(epoch) ? new Date(Number(epoch) * 1e3) : null;
1277
1510
  }
1278
- function glyphText(run, font, out, spans) {
1279
- const g = run.glyphs;
1280
- const starts = [...new Set(g.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b);
1281
- for (let k = 0; k < starts.length; k++) {
1282
- const chars = [...run.text.slice(starts[k], starts[k + 1] ?? run.text.length)];
1283
- const ids = [];
1284
- for (let i = 0; i < g.length; i += 4) if (g[i + 3] === starts[k]) ids.push(g[i]);
1285
- const own = new Map(chars.map((ch) => [font.glyphForCodePoint(ch.codePointAt(0)).id, ch]));
1286
- const rest = chars.filter((ch) => !ids.includes(font.glyphForCodePoint(ch.codePointAt(0)).id)).join("");
1287
- const carrier = rest ? ids.find((id) => !own.has(id) && font.getGlyph(id).advanceWidth > 0) ?? ids.find((id) => !own.has(id)) : void 0;
1288
- let ok = !rest || carrier !== void 0;
1289
- const want = /* @__PURE__ */ new Map();
1290
- for (const id of ids) {
1291
- const t = own.get(id) ?? (id === carrier ? rest : "");
1292
- if (want.has(id) && want.get(id) !== t) ok = false;
1293
- want.set(id, t);
1294
- }
1295
- for (const [id, t] of want) {
1296
- if (!out.has(id)) out.set(id, t);
1297
- else if (out.get(id) !== t) ok = false;
1298
- }
1299
- if (!ok && run.rtl && spans) {
1300
- let s = spans.get(run);
1301
- if (!s) spans.set(run, s = /* @__PURE__ */ new Set());
1302
- s.add(starts[k]);
1303
- }
1511
+ async function contentId(model, opt, when) {
1512
+ const bytes = new TextEncoder().encode(JSON.stringify([{ ...model, stats: void 0 }, opt.title || "Report", opt.author || "", when.toISOString()]));
1513
+ const digest = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes));
1514
+ return Array.from(digest.subarray(0, 16), (b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
1515
+ }
1516
+ function fieldFont(it) {
1517
+ for (const d of it.draw) if (d.t === "text") {
1518
+ for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return r.font;
1304
1519
  }
1520
+ return it.font;
1305
1521
  }
1306
1522
  var pdfLiteral = (s) => PDFString4.of(String(s).replace(/[\\()]/g, "\\$&"));
1307
1523
  function plainEncoding(pf) {
@@ -1319,7 +1535,7 @@ function plainEncoding(pf) {
1319
1535
  }
1320
1536
  return hex2;
1321
1537
  };
1322
- e.encodeText = (text) => PDFHexString4.of(e.hexOf(text));
1538
+ e.encodeText = (text) => PDFHexString5.of(e.hexOf(text));
1323
1539
  e.widthOfTextAtSize = (text, size) => {
1324
1540
  let w = 0;
1325
1541
  for (const ch of text) w += f.glyphForCodePoint(
@@ -1410,7 +1626,7 @@ function addOutline(doc, bookmarks, dest) {
1410
1626
  if (!Dest) continue;
1411
1627
  const level = Math.max(0, Math.min(9, Number(b.level) || 0));
1412
1628
  while (stack[stack.length - 1].level >= level) stack.pop();
1413
- const node2 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString4.fromText(b.label), Dest };
1629
+ const node2 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString5.fromText(b.label), Dest };
1414
1630
  stack[stack.length - 1].kids.push(node2);
1415
1631
  stack.push(node2);
1416
1632
  }
@@ -1441,216 +1657,6 @@ function subsetTag(bytes) {
1441
1657
  }
1442
1658
  return tag;
1443
1659
  }
1444
- function insideClip(it, m) {
1445
- const k = it.clip, asc = m.asc * it.size, desc = m.desc * it.size;
1446
- return it.lines.every((l) => l.w != null && !l.runs && l.x >= k.x && l.x + l.w <= k.x + k.w && l.y - asc >= k.y && l.y + desc <= k.y + k.h);
1447
- }
1448
- var Content = class {
1449
- constructor(shared) {
1450
- this.shared = shared;
1451
- this._s = "";
1452
- this.bt = false;
1453
- this.tx = 0;
1454
- this.ty = 0;
1455
- this.st = { fill: "0 0 0", stroke: "0 0 0", lw: 1, dash: "[] 0", ca: 1, CA: 1, font: "", size: 0 };
1456
- this.saved = [];
1457
- this.lines = null;
1458
- this.tagged = false;
1459
- }
1460
- /**
1461
- * The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
1462
- * of a table's cells stays in one text object (relative moves, which compress to little) instead of one per cell.
1463
- */
1464
- get s() {
1465
- this.flushLines();
1466
- return this._s;
1467
- }
1468
- set s(v) {
1469
- this._s = v;
1470
- }
1471
- /**
1472
- * A straight line. Untagged, it waits until something other than text is drawn (table borders between cell
1473
- * texts); collinear segments that touch, in the same stroke, become one (a row's border is one line).
1474
- * ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
1475
- */
1476
- line(stroke, w, dash, x1, y1, x2, y2) {
1477
- if (this.tagged) {
1478
- this.paint(null, stroke, w, dash);
1479
- this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
1480
- `;
1481
- return;
1482
- }
1483
- const key = `${stroke.rgb}|${stroke.opacity}|${w}|${(dash || []).join(" ")}`;
1484
- if (this.lines && this.lines.key !== key) this.flushLines();
1485
- this.lines || (this.lines = { key, stroke, w, dash, segs: [] });
1486
- const segs = this.lines.segs, last = segs[segs.length - 1];
1487
- const eq = (a, b) => Math.abs(a - b) < 5e-3;
1488
- if (last && eq(last[1], y1) && eq(last[3], y2) && eq(y1, y2) && eq(last[2], x1)) last[2] = x2;
1489
- else if (last && eq(last[0], x1) && eq(last[2], x2) && eq(x1, x2) && eq(last[3], y1)) last[3] = y2;
1490
- else segs.push([x1, y1, x2, y2]);
1491
- }
1492
- flushLines() {
1493
- const L = this.lines;
1494
- if (!L) return;
1495
- this.lines = null;
1496
- this.et();
1497
- this.paint(null, L.stroke, L.w, L.dash);
1498
- const g = L.segs;
1499
- const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
1500
- if (dy && g.every((q, i) => q[1] === q[3] && n2(q[0]) === n2(g[0][0]) && n2(q[2]) === n2(g[0][2]) && Math.abs(q[1] - (g[0][1] + i * dy / 100)) < 0.01)) {
1501
- const one = `${n2(g[0][0])} ${n2(g[0][1])} m ${n2(g[0][2])} ${n2(g[0][1])} l S
1502
- `;
1503
- this._s += `q
1504
- ${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
1505
- `;
1506
- return;
1507
- }
1508
- this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n";
1509
- }
1510
- q() {
1511
- this.et();
1512
- this._s += "q\n";
1513
- this.saved.push({ ...this.st });
1514
- }
1515
- Q() {
1516
- this.et();
1517
- this._s += "Q\n";
1518
- this.st = this.saved.pop();
1519
- }
1520
- /**
1521
- * A line of plain text at (x, y). Lines follow one another in one text object, each placed relative to the
1522
- * last (in whole hundredths, so nothing drifts): most of a table page is these.
1523
- * @param {string} str the glyphs, as a literal string's escaped body (array: a TJ array's body)
1524
- */
1525
- text(pf, size, color, x, y, str, array = false) {
1526
- this.setPaint(color, null);
1527
- this.setFont(pf, size);
1528
- const X = Math.round(x * 10) * 10, Y = Math.round(y * 10) * 10;
1529
- if (!this.bt) {
1530
- this._s += "BT\n";
1531
- this.bt = true;
1532
- this.tx = 0;
1533
- this.ty = 0;
1534
- }
1535
- this._s += array ? `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td [${str}] TJ
1536
- ` : `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td (${str}) Tj
1537
- `;
1538
- this.tx = X;
1539
- this.ty = Y;
1540
- }
1541
- /** end the open text object, if any: anything but text needs that (and draws the lines waiting) */
1542
- et() {
1543
- if (this.bt) {
1544
- this._s += "ET\n";
1545
- this.bt = false;
1546
- }
1547
- if (this.lines) this.flushLines();
1548
- }
1549
- lineWidth(w) {
1550
- if (this.lines) this.flushLines();
1551
- this.setLineWidth(w);
1552
- }
1553
- setLineWidth(w) {
1554
- if (this.st.lw !== w) {
1555
- this._s += `${n3(w)} w
1556
- `;
1557
- this.st.lw = w;
1558
- }
1559
- }
1560
- /** the graphics state that sets these opacities, or undefined when they are set already */
1561
- gsFor(ca, CA) {
1562
- return ca === this.st.ca && CA === this.st.CA ? void 0 : this.shared.gs(ca, CA);
1563
- }
1564
- alpha(ca, CA) {
1565
- if (this.lines) this.flushLines();
1566
- this.setAlpha(ca, CA);
1567
- }
1568
- setAlpha(ca, CA) {
1569
- const g = this.gsFor(ca, CA);
1570
- if (g) {
1571
- this._s += `/${g} gs
1572
- `;
1573
- this.st.ca = ca;
1574
- this.st.CA = CA;
1575
- }
1576
- }
1577
- /** set up to fill with fill and/or stroke with stroke (width w, dash); the lines waiting are drawn first */
1578
- paint(fill, stroke, w = 1, dash = null) {
1579
- if (this.lines) this.flushLines();
1580
- this.setPaint(fill, stroke, w, dash);
1581
- }
1582
- setPaint(fill, stroke, w = 1, dash = null) {
1583
- const st = this.st;
1584
- if (fill && fill.rgb !== st.fill) {
1585
- this._s += `${fill.rgb} rg
1586
- `;
1587
- st.fill = fill.rgb;
1588
- }
1589
- if (stroke) {
1590
- if (stroke.rgb !== st.stroke) {
1591
- this._s += `${stroke.rgb} RG
1592
- `;
1593
- st.stroke = stroke.rgb;
1594
- }
1595
- this.setLineWidth(w);
1596
- const d = `[${(dash || []).map(n3).join(" ")}] 0`;
1597
- if (d !== st.dash) {
1598
- this._s += `${d} d
1599
- `;
1600
- st.dash = d;
1601
- }
1602
- }
1603
- this.setAlpha(fill ? fill.opacity : st.ca, stroke ? stroke.opacity : st.CA);
1604
- }
1605
- font(pf, size) {
1606
- if (this.lines) this.flushLines();
1607
- this.setFont(pf, size);
1608
- }
1609
- setFont(pf, size) {
1610
- const name = this.shared.font(pf);
1611
- if (name !== this.st.font || size !== this.st.size) {
1612
- this._s += `/${name} ${n3(size)} Tf
1613
- `;
1614
- this.st.font = name;
1615
- this.st.size = size;
1616
- }
1617
- }
1618
- };
1619
- function latin1(s) {
1620
- const B = (
1621
- /** @type {any} */
1622
- globalThis.Buffer
1623
- );
1624
- if (B) return B.from(s, "latin1");
1625
- const out = new Uint8Array(s.length);
1626
- for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
1627
- return out;
1628
- }
1629
- async function deflate(bytes) {
1630
- if (zslots.free > 0) zslots.free--;
1631
- else await new Promise((ok) => zslots.wait.push(ok));
1632
- try {
1633
- return await deflateNow(bytes);
1634
- } finally {
1635
- const next = zslots.wait.shift();
1636
- if (next) next();
1637
- else zslots.free++;
1638
- }
1639
- }
1640
- var zslots = { free: 4, wait: (
1641
- /** @type {(() => void)[]} */
1642
- []
1643
- ) };
1644
- var NODE_ZLIB = (
1645
- /** @type {any} */
1646
- globalThis.process?.getBuiltinModule?.("node:zlib")
1647
- );
1648
- async function deflateNow(bytes) {
1649
- const zlib = NODE_ZLIB;
1650
- if (zlib) return new Promise((ok, fail) => zlib.deflate(bytes, { level: 9 }, (e, z) => e ? fail(e) : ok(z)));
1651
- if (typeof CompressionStream === "undefined") return (await import("fflate")).zlibSync(bytes);
1652
- return new Uint8Array(await new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
1653
- }
1654
1660
  function roundRect(x, y, w, h, r) {
1655
1661
  r = Math.min(r, w / 2, h / 2);
1656
1662
  return `M ${x + r} ${y} H ${x + w - r} A ${r} ${r} 0 0 1 ${x + w} ${y + r} V ${y + h - r} A ${r} ${r} 0 0 1 ${x + w - r} ${y + h} H ${x + r} A ${r} ${r} 0 0 1 ${x} ${y + h - r} V ${y + r} A ${r} ${r} 0 0 1 ${x + r} ${y} Z`;
@@ -1658,4 +1664,4 @@ function roundRect(x, y, w, h, r) {
1658
1664
  export {
1659
1665
  exportPdf
1660
1666
  };
1661
- //# sourceMappingURL=chunk-66QZ3RDV.js.map
1667
+ //# sourceMappingURL=chunk-5N6OFCHJ.js.map