@formfeed/engine 0.3.12 → 0.3.14
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.
- package/index.cjs +694 -275
- package/index.js +694 -275
- package/package.json +1 -1
- package/types/frame/audit.d.cts +15 -0
- package/types/frame/audit.d.ts +15 -0
- package/types/frame/audit.entry.d.cts +1 -0
- package/types/frame/audit.entry.d.ts +1 -0
- package/types/index.d.cts +5 -0
- package/types/index.d.ts +5 -0
- package/types/lib/accessibility/index.d.cts +201 -0
- package/types/lib/accessibility/index.d.ts +201 -0
- package/types/lib/accessibility/static.d.cts +40 -0
- package/types/lib/accessibility/static.d.ts +40 -0
- package/types/lib/assemble.d.cts +8 -0
- package/types/lib/assemble.d.ts +8 -0
- package/types/lib/generated/frames.d.cts +2 -0
- package/types/lib/generated/frames.d.ts +2 -0
- package/types/lib/helpers/document.d.cts +5 -0
- package/types/lib/helpers/document.d.ts +5 -0
- package/types/lib/preview.d.cts +5 -0
- package/types/lib/preview.d.ts +5 -0
package/index.js
CHANGED
|
@@ -182,11 +182,11 @@ function validateEpc(input) {
|
|
|
182
182
|
const purpose = String(input.purpose ?? "");
|
|
183
183
|
if (purpose.length > 4) problems.push({ field: "purpose", code: "too_long", max: 4, actual: purpose.length });
|
|
184
184
|
const reference = String(input.reference ?? "").trim();
|
|
185
|
-
const
|
|
186
|
-
if (reference &&
|
|
185
|
+
const text4 = String(input.text ?? "").trim();
|
|
186
|
+
if (reference && text4) problems.push({ field: "reference", code: "reference_or_text" });
|
|
187
187
|
if (reference.length > 35)
|
|
188
188
|
problems.push({ field: "reference", code: "too_long", max: 35, actual: reference.length });
|
|
189
|
-
if (
|
|
189
|
+
if (text4.length > 140) problems.push({ field: "text", code: "too_long", max: 140, actual: text4.length });
|
|
190
190
|
const bytes = byteLength(epcPayload(input));
|
|
191
191
|
if (bytes > EPC_MAX_BYTES)
|
|
192
192
|
problems.push({ field: "payload", code: "too_long", max: EPC_MAX_BYTES, actual: bytes });
|
|
@@ -224,9 +224,12 @@ var barcodeTypes = {
|
|
|
224
224
|
};
|
|
225
225
|
var ownTextLayout = /* @__PURE__ */ new Set(["ean13", "ean8", "upca"]);
|
|
226
226
|
function codeText(helper, value) {
|
|
227
|
-
const
|
|
228
|
-
if (
|
|
229
|
-
|
|
227
|
+
const text4 = value === void 0 || value === null ? "" : String(value);
|
|
228
|
+
if (text4 === "")
|
|
229
|
+
throw new Error(
|
|
230
|
+
`${helper}: nothing to encode, the value is empty or missing from the data`
|
|
231
|
+
);
|
|
232
|
+
return text4;
|
|
230
233
|
}
|
|
231
234
|
var codeHelpers = [
|
|
232
235
|
{
|
|
@@ -234,18 +237,25 @@ var codeHelpers = [
|
|
|
234
237
|
aliases: ["qr"],
|
|
235
238
|
doc: {
|
|
236
239
|
signature: "qrcode(value, { size = 160, ecc = 'M', margin = 1, color, background })",
|
|
237
|
-
description: "QR code as an SVG data URI for an <img> src.",
|
|
240
|
+
description: "QR code as an SVG data URI for an <img> src. Give the image an `alt` that says where the code leads: a screen reader cannot scan it.",
|
|
238
241
|
examples: {
|
|
239
|
-
jinja2: '<img src="{{ qrcode(order.url, { size: 120 }) }}">',
|
|
240
|
-
liquid: '<img src="{{ order.url | qrcode: size: 120 }}">',
|
|
241
|
-
handlebars: '<img src="{{qrcode order.url size=120}}">'
|
|
242
|
+
jinja2: '<img src="{{ qrcode(order.url, { size: 120 }) }}" alt="QR code: {{ order.url }}">',
|
|
243
|
+
liquid: '<img src="{{ order.url | qrcode: size: 120 }}" alt="QR code: {{ order.url }}">',
|
|
244
|
+
handlebars: '<img src="{{qrcode order.url size=120}}" alt="QR code: {{order.url}}">'
|
|
242
245
|
},
|
|
243
246
|
category: "code"
|
|
244
247
|
},
|
|
245
248
|
fn: (ctx, value, options) => {
|
|
246
249
|
const o = options ?? {};
|
|
247
250
|
const svg = qrSvg(codeText("qrcode", value), o);
|
|
248
|
-
if (ctx.drawing)
|
|
251
|
+
if (ctx.drawing)
|
|
252
|
+
return ctx.drawing({
|
|
253
|
+
kind: "svg",
|
|
254
|
+
svg,
|
|
255
|
+
width: o.size,
|
|
256
|
+
height: o.size,
|
|
257
|
+
alt: "QR code"
|
|
258
|
+
});
|
|
249
259
|
return svgDataUri(svg);
|
|
250
260
|
}
|
|
251
261
|
},
|
|
@@ -253,28 +263,29 @@ var codeHelpers = [
|
|
|
253
263
|
name: "barcode",
|
|
254
264
|
doc: {
|
|
255
265
|
signature: "barcode(value, { type = 'code128', height = 12, width, text = true, scale = 2 })",
|
|
256
|
-
description: "Barcode (code128, ean13, ean8, upc, itf14, code39, datamatrix, pdf417) as an SVG data URI.",
|
|
266
|
+
description: "Barcode (code128, ean13, ean8, upc, itf14, code39, datamatrix, pdf417) as an SVG data URI. Give the image an `alt` with the value it encodes.",
|
|
257
267
|
examples: {
|
|
258
|
-
jinja2: `<img src="{{ barcode(item.sku, { type: 'code128' }) }}">`,
|
|
259
|
-
liquid: `<img src="{{ item.sku | barcode: type: 'code128' }}">`,
|
|
260
|
-
handlebars: `<img src="{{barcode item.sku type='code128'}}">`
|
|
268
|
+
jinja2: `<img src="{{ barcode(item.sku, { type: 'code128' }) }}" alt="Barcode {{ item.sku }}">`,
|
|
269
|
+
liquid: `<img src="{{ item.sku | barcode: type: 'code128' }}" alt="Barcode {{ item.sku }}">`,
|
|
270
|
+
handlebars: `<img src="{{barcode item.sku type='code128'}}" alt="Barcode {{item.sku}}">`
|
|
261
271
|
},
|
|
262
272
|
category: "code"
|
|
263
273
|
},
|
|
264
274
|
fn: (ctx, value, options) => {
|
|
265
275
|
const o = options ?? {};
|
|
266
276
|
const bcid = barcodeTypes[String(o.type ?? "code128").toLowerCase()] ?? "code128";
|
|
267
|
-
const
|
|
277
|
+
const text4 = codeText("barcode", value);
|
|
268
278
|
const svg = toSVG({
|
|
269
279
|
bcid,
|
|
270
|
-
text:
|
|
280
|
+
text: text4,
|
|
271
281
|
height: o.height ?? 12,
|
|
272
282
|
...o.width === void 0 ? {} : { width: o.width },
|
|
273
283
|
scale: o.scale ?? 2,
|
|
274
284
|
includetext: o.text !== false,
|
|
275
285
|
...ownTextLayout.has(bcid) ? {} : { textxalign: "center" }
|
|
276
286
|
});
|
|
277
|
-
if (ctx.drawing)
|
|
287
|
+
if (ctx.drawing)
|
|
288
|
+
return ctx.drawing({ kind: "svg", svg, alt: `Barcode ${text4}` });
|
|
278
289
|
return svgDataUri(svg);
|
|
279
290
|
}
|
|
280
291
|
},
|
|
@@ -283,11 +294,11 @@ var codeHelpers = [
|
|
|
283
294
|
aliases: ["epc_qr", "girocode"],
|
|
284
295
|
doc: {
|
|
285
296
|
signature: "epcQr({ name, iban, bic?, amount?, reference?, text? }, { size })",
|
|
286
|
-
description: "SEPA credit transfer QR code (EPC069-12 / GiroCode) that banking apps scan to prefill a payment.",
|
|
297
|
+
description: "SEPA credit transfer QR code (EPC069-12 / GiroCode) that banking apps scan to prefill a payment. Give the image an `alt`, and print the bank details as text as well: the code is a picture.",
|
|
287
298
|
examples: {
|
|
288
|
-
jinja2: '<img src="{{ epcQr({ name: company.name, iban: company.iban, amount: invoice.total, reference: invoice.number }) }}">',
|
|
289
|
-
liquid: '<img src="{{ company.iban | epcQr: name: company.name, amount: invoice.total, reference: invoice.number }}">',
|
|
290
|
-
handlebars: '<img src="{{epcQr name=company.name iban=company.iban amount=invoice.total reference=invoice.number}}">'
|
|
299
|
+
jinja2: '<img src="{{ epcQr({ name: company.name, iban: company.iban, amount: invoice.total, reference: invoice.number }) }}" alt="QR code to pay invoice {{ invoice.number }}">',
|
|
300
|
+
liquid: '<img src="{{ company.iban | epcQr: name: company.name, amount: invoice.total, reference: invoice.number }}" alt="QR code to pay invoice {{ invoice.number }}">',
|
|
301
|
+
handlebars: '<img src="{{epcQr name=company.name iban=company.iban amount=invoice.total reference=invoice.number}}" alt="QR code to pay invoice {{invoice.number}}">'
|
|
291
302
|
},
|
|
292
303
|
category: "code"
|
|
293
304
|
},
|
|
@@ -306,12 +317,27 @@ var codeHelpers = [
|
|
|
306
317
|
(EPC_FIELDS.has(key) ? payment2 : qr)[key] = value;
|
|
307
318
|
const o = { ecc: "M", ...qr };
|
|
308
319
|
const svg = qrSvg(epcPayload(payment2), o);
|
|
309
|
-
if (ctx.drawing)
|
|
320
|
+
if (ctx.drawing)
|
|
321
|
+
return ctx.drawing({
|
|
322
|
+
kind: "svg",
|
|
323
|
+
svg,
|
|
324
|
+
width: o.size,
|
|
325
|
+
height: o.size,
|
|
326
|
+
alt: "GiroCode"
|
|
327
|
+
});
|
|
310
328
|
return svgDataUri(svg);
|
|
311
329
|
}
|
|
312
330
|
}
|
|
313
331
|
];
|
|
314
|
-
var EPC_FIELDS = /* @__PURE__ */ new Set([
|
|
332
|
+
var EPC_FIELDS = /* @__PURE__ */ new Set([
|
|
333
|
+
"name",
|
|
334
|
+
"iban",
|
|
335
|
+
"bic",
|
|
336
|
+
"amount",
|
|
337
|
+
"reference",
|
|
338
|
+
"text",
|
|
339
|
+
"purpose"
|
|
340
|
+
]);
|
|
315
341
|
|
|
316
342
|
// packages/engine/src/lib/helpers/format.ts
|
|
317
343
|
import { TZDate } from "@date-fns/tz";
|
|
@@ -329,8 +355,8 @@ import { toCardinal as nlWords } from "n2words/nl";
|
|
|
329
355
|
function resolveTranslation(dictionaries, locale, key) {
|
|
330
356
|
const lang = locale.split("-")[0] ?? locale;
|
|
331
357
|
for (const candidate of [locale, lang, "en"]) {
|
|
332
|
-
const
|
|
333
|
-
if (typeof
|
|
358
|
+
const text4 = dictionaries?.[candidate]?.[key];
|
|
359
|
+
if (typeof text4 === "string") return { text: text4, from: candidate };
|
|
334
360
|
}
|
|
335
361
|
return { text: key, from: null };
|
|
336
362
|
}
|
|
@@ -810,9 +836,9 @@ var formatHelpers = [
|
|
|
810
836
|
category: "text"
|
|
811
837
|
},
|
|
812
838
|
fn: (ctx, key, params) => {
|
|
813
|
-
const { text:
|
|
839
|
+
const { text: text4 } = resolveTranslation(ctx.i18n, ctx.locale, str(key));
|
|
814
840
|
const p = params ?? {};
|
|
815
|
-
return
|
|
841
|
+
return text4.replace(/\{(\w+)\}/g, (_, name) => str(p[name]));
|
|
816
842
|
}
|
|
817
843
|
},
|
|
818
844
|
{
|
|
@@ -1083,7 +1109,16 @@ var collectionHelpers = [
|
|
|
1083
1109
|
];
|
|
1084
1110
|
|
|
1085
1111
|
// packages/engine/src/lib/helpers/document.ts
|
|
1086
|
-
var CHART_PALETTE = [
|
|
1112
|
+
var CHART_PALETTE = [
|
|
1113
|
+
"#3E63DD",
|
|
1114
|
+
"#12A594",
|
|
1115
|
+
"#E5484D",
|
|
1116
|
+
"#F76B15",
|
|
1117
|
+
"#8E4EC6",
|
|
1118
|
+
"#FFC53D",
|
|
1119
|
+
"#0090FF",
|
|
1120
|
+
"#978365"
|
|
1121
|
+
];
|
|
1087
1122
|
var SLICED = /* @__PURE__ */ new Set(["pie", "doughnut", "polarArea"]);
|
|
1088
1123
|
var colour = (value) => typeof value === "string" && value ? value : Array.isArray(value) && value.length ? value.map(String) : void 0;
|
|
1089
1124
|
function chartDataFromPlain(spec) {
|
|
@@ -1097,8 +1132,13 @@ function chartDataFromPlain(spec) {
|
|
|
1097
1132
|
});
|
|
1098
1133
|
const own = colour(s.color);
|
|
1099
1134
|
const fill = SLICED.has(type) ? own ?? labels.map((_, i) => CHART_PALETTE[i % CHART_PALETTE.length]) : own ?? CHART_PALETTE[index % CHART_PALETTE.length];
|
|
1100
|
-
const dataset = {
|
|
1101
|
-
|
|
1135
|
+
const dataset = {
|
|
1136
|
+
data,
|
|
1137
|
+
backgroundColor: fill,
|
|
1138
|
+
borderColor: fill
|
|
1139
|
+
};
|
|
1140
|
+
if (s.label !== void 0 && s.label !== null && s.label !== "")
|
|
1141
|
+
dataset["label"] = String(s.label);
|
|
1102
1142
|
if (type === "line") dataset["fill"] = false;
|
|
1103
1143
|
return dataset;
|
|
1104
1144
|
});
|
|
@@ -1115,7 +1155,8 @@ function chartPayload(spec) {
|
|
|
1115
1155
|
const options = { ...spec.options ?? {} };
|
|
1116
1156
|
options["animation"] = false;
|
|
1117
1157
|
options["responsive"] = false;
|
|
1118
|
-
if (!isPlain(spec))
|
|
1158
|
+
if (!isPlain(spec))
|
|
1159
|
+
return { type: spec.type ?? "bar", data: spec.data ?? {}, options };
|
|
1119
1160
|
const data = chartDataFromPlain(spec);
|
|
1120
1161
|
const unnamed = data.datasets.length === 1 && data.datasets[0]?.["label"] === void 0;
|
|
1121
1162
|
const plugins = asObject(options["plugins"]);
|
|
@@ -1128,7 +1169,8 @@ function chartMarkup(spec, id) {
|
|
|
1128
1169
|
const height = toNumber(spec.height ?? 240) || 240;
|
|
1129
1170
|
const payload = escapeHtml(JSON.stringify(chartPayload(spec)));
|
|
1130
1171
|
const idAttr = id ? ` id="${escapeHtml(id)}"` : "";
|
|
1131
|
-
|
|
1172
|
+
const alt = typeof spec.alt === "string" && spec.alt.trim() ? ` role="img" aria-label="${escapeHtml(spec.alt.trim())}"` : "";
|
|
1173
|
+
return `<canvas class="ff-chart"${idAttr}${alt} width="${width}" height="${height}" style="width:${width}px;height:${height}px" data-ff-chart="${payload}"></canvas>`;
|
|
1132
1174
|
}
|
|
1133
1175
|
function imageMarkup(url, options = {}) {
|
|
1134
1176
|
const styles = [
|
|
@@ -1149,18 +1191,21 @@ var documentHelpers = [
|
|
|
1149
1191
|
name: "chart",
|
|
1150
1192
|
html: true,
|
|
1151
1193
|
doc: {
|
|
1152
|
-
signature: "chart({ type, labels, values, label, color } | { type, labels, series } | { type, data, options }, { width, height })",
|
|
1153
|
-
description: "Draws a Chart.js chart (bar, line, pie, doughnut, radar, \u2026) from plain data, `labels` with `values` or several `series` of `{ label, values, color }`, or from a full Chart.js `data` and `options`; animations are disabled so PDF and preview match.",
|
|
1194
|
+
signature: "chart({ type, labels, values, label, color } | { type, labels, series } | { type, data, options }, { width, height, alt })",
|
|
1195
|
+
description: "Draws a Chart.js chart (bar, line, pie, doughnut, radar, \u2026) from plain data, `labels` with `values` or several `series` of `{ label, values, color }`, or from a full Chart.js `data` and `options`; animations are disabled so PDF and preview match. `alt` says in words what the chart shows: a screen reader reads it in place of the picture, and a tagged PDF needs it.",
|
|
1154
1196
|
examples: {
|
|
1155
|
-
jinja2: "{{ chart({ type: 'line', labels: sales.labels, values: sales.quarters, width: 480 }) }}",
|
|
1156
|
-
liquid: "{{ '' | chart: type: 'line', labels: sales.labels, values: sales.quarters, width: 480 }}",
|
|
1157
|
-
handlebars: "{{chart type='line' labels=sales.labels values=sales.quarters width=480}}"
|
|
1197
|
+
jinja2: "{{ chart({ type: 'line', labels: sales.labels, values: sales.quarters, width: 480, alt: 'Sales by quarter' }) }}",
|
|
1198
|
+
liquid: "{{ '' | chart: type: 'line', labels: sales.labels, values: sales.quarters, width: 480, alt: 'Sales by quarter' }}",
|
|
1199
|
+
handlebars: "{{chart type='line' labels=sales.labels values=sales.quarters width=480 alt='Sales by quarter'}}"
|
|
1158
1200
|
},
|
|
1159
1201
|
category: "document"
|
|
1160
1202
|
},
|
|
1161
1203
|
fn: (ctx, spec, extra) => {
|
|
1162
1204
|
if (ctx.mode === "office") throw new Error(officeUnsupported("chart"));
|
|
1163
|
-
return chartMarkup({
|
|
1205
|
+
return chartMarkup({
|
|
1206
|
+
...asObject(spec),
|
|
1207
|
+
...asObject(extra)
|
|
1208
|
+
});
|
|
1164
1209
|
}
|
|
1165
1210
|
},
|
|
1166
1211
|
{
|
|
@@ -1168,18 +1213,24 @@ var documentHelpers = [
|
|
|
1168
1213
|
html: true,
|
|
1169
1214
|
doc: {
|
|
1170
1215
|
signature: "image(url, { width, height, fit, alt })",
|
|
1171
|
-
description: "Places an image with fixed size and crop mode (`cover`, `contain`, `fill`); the render-worker fetches it through its cache and blocks private hosts.",
|
|
1216
|
+
description: "Places an image with fixed size and crop mode (`cover`, `contain`, `fill`); the render-worker fetches it through its cache and blocks private hosts. `alt` says what it shows; without one the image counts as decoration and a screen reader passes over it.",
|
|
1172
1217
|
examples: {
|
|
1173
|
-
jinja2: "{{ image(product.photo, { width: 120, height: 80, fit: 'cover' }) }}",
|
|
1174
|
-
liquid: "{{ product.photo | image: width: 120, height: 80, fit: 'cover' }}",
|
|
1175
|
-
handlebars: "{{image product.photo width=120 height=80 fit='cover'}}"
|
|
1218
|
+
jinja2: "{{ image(product.photo, { width: 120, height: 80, fit: 'cover', alt: product.name }) }}",
|
|
1219
|
+
liquid: "{{ product.photo | image: width: 120, height: 80, fit: 'cover', alt: product.name }}",
|
|
1220
|
+
handlebars: "{{image product.photo width=120 height=80 fit='cover' alt=product.name}}"
|
|
1176
1221
|
},
|
|
1177
1222
|
category: "document"
|
|
1178
1223
|
},
|
|
1179
1224
|
fn: (ctx, url, options) => {
|
|
1180
1225
|
const o = asObject(options);
|
|
1181
1226
|
if (ctx.drawing)
|
|
1182
|
-
return ctx.drawing({
|
|
1227
|
+
return ctx.drawing({
|
|
1228
|
+
kind: "url",
|
|
1229
|
+
url: resolveAsset(ctx.assetBaseUrl, String(url ?? "")),
|
|
1230
|
+
width: o.width,
|
|
1231
|
+
height: o.height,
|
|
1232
|
+
alt: o.alt
|
|
1233
|
+
});
|
|
1183
1234
|
return imageMarkup(String(url ?? ""), o);
|
|
1184
1235
|
}
|
|
1185
1236
|
}
|
|
@@ -1919,8 +1970,8 @@ var SPEC = /^(?:([\s\S])?([<>=^]))?([+\- ])?(#)?(0)?(\d+)?([,_])?(?:\.(\d+))?([b
|
|
|
1919
1970
|
function group(digits, separator) {
|
|
1920
1971
|
return digits.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
|
|
1921
1972
|
}
|
|
1922
|
-
function pythonExponent(
|
|
1923
|
-
return
|
|
1973
|
+
function pythonExponent(text4) {
|
|
1974
|
+
return text4.replace(/e([+-])(\d)$/i, (m, sign, digit) => `${m[0]}${sign}0${digit}`);
|
|
1924
1975
|
}
|
|
1925
1976
|
function formatNumber(value, type, precision, alternate) {
|
|
1926
1977
|
if (!Number.isFinite(value)) return Number.isNaN(value) ? "nan" : "inf";
|
|
@@ -1933,20 +1984,20 @@ function formatNumber(value, type, precision, alternate) {
|
|
|
1933
1984
|
return `${(abs2 * 100).toFixed(precision ?? 6)}%`;
|
|
1934
1985
|
case "e":
|
|
1935
1986
|
case "E": {
|
|
1936
|
-
const
|
|
1937
|
-
return type === "E" ?
|
|
1987
|
+
const text4 = pythonExponent(abs2.toExponential(precision ?? 6));
|
|
1988
|
+
return type === "E" ? text4.toUpperCase() : text4;
|
|
1938
1989
|
}
|
|
1939
1990
|
case "g":
|
|
1940
1991
|
case "G": {
|
|
1941
1992
|
const p = precision === 0 ? 1 : precision ?? 6;
|
|
1942
1993
|
const exp = abs2 === 0 ? 0 : Math.floor(Math.log10(abs2));
|
|
1943
|
-
let
|
|
1994
|
+
let text4 = exp < -4 || exp >= p ? pythonExponent(abs2.toExponential(p - 1)) : abs2.toFixed(Math.max(0, p - 1 - exp));
|
|
1944
1995
|
if (!alternate) {
|
|
1945
|
-
const [mantissa = "", exponent] =
|
|
1996
|
+
const [mantissa = "", exponent] = text4.split("e");
|
|
1946
1997
|
const trimmed = mantissa.includes(".") ? mantissa.replace(/0+$/, "").replace(/\.$/, "") : mantissa;
|
|
1947
|
-
|
|
1998
|
+
text4 = exponent === void 0 ? trimmed : `${trimmed}e${exponent}`;
|
|
1948
1999
|
}
|
|
1949
|
-
return type === "G" ?
|
|
2000
|
+
return type === "G" ? text4.toUpperCase() : text4;
|
|
1950
2001
|
}
|
|
1951
2002
|
case "d":
|
|
1952
2003
|
case "n":
|
|
@@ -2015,35 +2066,35 @@ function lookupField(name, positional, named, next) {
|
|
|
2015
2066
|
function pythonFormat(template, positional, named = {}) {
|
|
2016
2067
|
let auto = 0;
|
|
2017
2068
|
const next = () => auto++;
|
|
2018
|
-
const render = (
|
|
2069
|
+
const render = (text4) => {
|
|
2019
2070
|
let out = "";
|
|
2020
|
-
for (let i = 0; i <
|
|
2021
|
-
const ch =
|
|
2071
|
+
for (let i = 0; i < text4.length; i++) {
|
|
2072
|
+
const ch = text4[i];
|
|
2022
2073
|
if (ch === "}") {
|
|
2023
2074
|
out += "}";
|
|
2024
|
-
if (
|
|
2075
|
+
if (text4[i + 1] === "}") i++;
|
|
2025
2076
|
continue;
|
|
2026
2077
|
}
|
|
2027
2078
|
if (ch !== "{") {
|
|
2028
2079
|
out += ch;
|
|
2029
2080
|
continue;
|
|
2030
2081
|
}
|
|
2031
|
-
if (
|
|
2082
|
+
if (text4[i + 1] === "{") {
|
|
2032
2083
|
out += "{";
|
|
2033
2084
|
i++;
|
|
2034
2085
|
continue;
|
|
2035
2086
|
}
|
|
2036
2087
|
let depth = 1;
|
|
2037
2088
|
let j = i + 1;
|
|
2038
|
-
for (; j <
|
|
2039
|
-
if (
|
|
2040
|
-
else if (
|
|
2089
|
+
for (; j < text4.length && depth > 0; j++) {
|
|
2090
|
+
if (text4[j] === "{") depth++;
|
|
2091
|
+
else if (text4[j] === "}") depth--;
|
|
2041
2092
|
}
|
|
2042
2093
|
if (depth > 0) {
|
|
2043
|
-
out +=
|
|
2094
|
+
out += text4.slice(i);
|
|
2044
2095
|
break;
|
|
2045
2096
|
}
|
|
2046
|
-
const field =
|
|
2097
|
+
const field = text4.slice(i + 1, j - 1);
|
|
2047
2098
|
const colon = field.indexOf(":");
|
|
2048
2099
|
const head = colon < 0 ? field : field.slice(0, colon);
|
|
2049
2100
|
const name = head.replace(/![rsa]$/, "");
|
|
@@ -4188,9 +4239,9 @@ function pick(input, ...keys) {
|
|
|
4188
4239
|
function toLength(value) {
|
|
4189
4240
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
4190
4241
|
if (typeof value === "number") return `${value}mm`;
|
|
4191
|
-
const
|
|
4192
|
-
if (/^-?\d+(\.\d+)?$/.test(
|
|
4193
|
-
if (/^-?\d+(\.\d+)?(mm|cm|in|px|pt)$/i.test(
|
|
4242
|
+
const text4 = String(value).trim();
|
|
4243
|
+
if (/^-?\d+(\.\d+)?$/.test(text4)) return `${text4}mm`;
|
|
4244
|
+
if (/^-?\d+(\.\d+)?(mm|cm|in|px|pt)$/i.test(text4)) return text4.toLowerCase();
|
|
4194
4245
|
return void 0;
|
|
4195
4246
|
}
|
|
4196
4247
|
function toMarginLength(value) {
|
|
@@ -4210,7 +4261,7 @@ function convertHeaderFooter(html) {
|
|
|
4210
4261
|
if (typeof html !== "string" || !html.trim()) return void 0;
|
|
4211
4262
|
return chromePlaceholders.reduce((out, [pattern, span]) => out.replace(pattern, span), html);
|
|
4212
4263
|
}
|
|
4213
|
-
var escapeText = (
|
|
4264
|
+
var escapeText = (text4) => text4.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
4214
4265
|
var visibleMarkup = (html) => html.replace(/<style[\s\S]*?<\/style>/gi, "").trim();
|
|
4215
4266
|
function apitemplateChrome(take, kind) {
|
|
4216
4267
|
const custom = take(`custom_${kind}`);
|
|
@@ -4224,7 +4275,7 @@ function apitemplateChrome(take, kind) {
|
|
|
4224
4275
|
if (!slots.some(Boolean)) return { fromSlots: false };
|
|
4225
4276
|
const sizeText = size === void 0 ? "" : String(size).trim();
|
|
4226
4277
|
const fontSize2 = /^\d+(\.\d+)?$/.test(sizeText) ? `${sizeText}px` : /^\d+(\.\d+)?(px|pt|mm)$/.test(sizeText) ? sizeText : "9px";
|
|
4227
|
-
const cells = slots.map((
|
|
4278
|
+
const cells = slots.map((text4, i) => `<span style="flex:1;text-align:${["left", "center", "right"][i]}">${escapeText(text4)}</span>`).join("");
|
|
4228
4279
|
const styles = customHtml.match(/<style[\s\S]*?<\/style>/gi)?.join("") ?? "";
|
|
4229
4280
|
return {
|
|
4230
4281
|
html: convertHeaderFooter(`${styles}<div style="display:flex;gap:4mm;font-size:${fontSize2}">${cells}</div>`),
|
|
@@ -4385,9 +4436,9 @@ function checkTemplate(engineId, html, sampleData, name, docs) {
|
|
|
4385
4436
|
function lengthMm(value) {
|
|
4386
4437
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
4387
4438
|
if (typeof value === "number" && Number.isFinite(value)) return `${value}mm`;
|
|
4388
|
-
const
|
|
4389
|
-
if (/^-?\d+(\.\d+)?$/.test(
|
|
4390
|
-
if (/^-?\d+(\.\d+)?(mm|cm|in|px|pt)$/i.test(
|
|
4439
|
+
const text4 = String(value).trim();
|
|
4440
|
+
if (/^-?\d+(\.\d+)?$/.test(text4)) return `${text4}mm`;
|
|
4441
|
+
if (/^-?\d+(\.\d+)?(mm|cm|in|px|pt)$/i.test(text4)) return text4.toLowerCase();
|
|
4391
4442
|
return void 0;
|
|
4392
4443
|
}
|
|
4393
4444
|
function toBase64(value) {
|
|
@@ -4904,11 +4955,11 @@ function inlineIncludes(source, blocks, errors, changes) {
|
|
|
4904
4955
|
}
|
|
4905
4956
|
var cssPaperFormats = { a3: "A3", a4: "A4", a5: "A5", letter: "Letter" };
|
|
4906
4957
|
var isoSizes = { a0: [841, 1189], a1: [594, 841], a2: [420, 594], a6: [105, 148] };
|
|
4907
|
-
var escapeHtml2 = (
|
|
4958
|
+
var escapeHtml2 = (text4) => text4.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
4908
4959
|
function simpleHeaderFooter(part, margin) {
|
|
4909
4960
|
const cells = ["left", "center", "right"].map((side) => part[side] ?? "");
|
|
4910
4961
|
if (!cells.some((c) => c.trim())) return void 0;
|
|
4911
|
-
const cell3 = (
|
|
4962
|
+
const cell3 = (text4, align) => `<div style="flex: 1; text-align: ${align}">${escapeHtml2(text4).replace(/\[page\]/g, '<span class="pageNumber"></span>').replace(/\[topage\]/g, '<span class="totalPages"></span>')}</div>`;
|
|
4912
4963
|
return `<div style="display: flex; width: 100%; font-size: 10px; padding: 0 ${margin.right} 0 ${margin.left}">${cell3(cells[0] ?? "", "left")}${cell3(cells[1] ?? "", "center")}${cell3(cells[2] ?? "", "right")}</div>`;
|
|
4913
4964
|
}
|
|
4914
4965
|
function mapSettings(input, kind, warnings, changes) {
|
|
@@ -5077,11 +5128,11 @@ var DOCS3 = "/migrate/jsreport";
|
|
|
5077
5128
|
var COLLECTIONS = ["templates", "data", "assets", "components", "scripts", "folders"];
|
|
5078
5129
|
function readJsreportExport(files) {
|
|
5079
5130
|
const bundle = { templates: [], data: [], assets: [], components: [], scripts: [], folders: [] };
|
|
5080
|
-
for (const [path,
|
|
5131
|
+
for (const [path, text4] of Object.entries(files)) {
|
|
5081
5132
|
const normalized = path.replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
5082
5133
|
if (normalized === "metadata.json") {
|
|
5083
5134
|
try {
|
|
5084
|
-
bundle.version = String(JSON.parse(
|
|
5135
|
+
bundle.version = String(JSON.parse(text4).reporterVersion ?? "");
|
|
5085
5136
|
} catch {
|
|
5086
5137
|
}
|
|
5087
5138
|
continue;
|
|
@@ -5089,7 +5140,7 @@ function readJsreportExport(files) {
|
|
|
5089
5140
|
const collection = normalized.split("/")[0];
|
|
5090
5141
|
if (!COLLECTIONS.includes(collection) || !normalized.endsWith(".json")) continue;
|
|
5091
5142
|
try {
|
|
5092
|
-
bundle[collection].push(JSON.parse(
|
|
5143
|
+
bundle[collection].push(JSON.parse(text4));
|
|
5093
5144
|
} catch {
|
|
5094
5145
|
}
|
|
5095
5146
|
}
|
|
@@ -5131,7 +5182,7 @@ function assetBase64(content) {
|
|
|
5131
5182
|
}
|
|
5132
5183
|
return toBase64(content);
|
|
5133
5184
|
}
|
|
5134
|
-
var escapeMustaches = (
|
|
5185
|
+
var escapeMustaches = (text4) => text4.replace(/\{\{/g, "\\{{");
|
|
5135
5186
|
function resolveAssets(source, bundle, options, warnings, changes) {
|
|
5136
5187
|
const v3 = /\{\{\{?\s*asset\s+(["'])([^"']+)\1(?:\s+(["'])([^"']+)\3)?\s*\}?\}\}/g;
|
|
5137
5188
|
const v2 = /\{#asset\s+([^\s}]+)(?:\s+@encoding=(\w+))?\s*\}/g;
|
|
@@ -5372,6 +5423,7 @@ function importJsreport(bundle, ref, options = {}) {
|
|
|
5372
5423
|
var textEditRuntime = '"use strict";(()=>{var O=`\nhtml.ff-edit-mode [data-ff-edit] { cursor: text; }\nhtml.ff-edit-mode [data-ff-edit]:hover { outline: 1px dashed rgba(37,99,235,.85); outline-offset: 2px; }\nhtml.ff-edit-mode [data-ff-edit="t"]:hover { outline-color: rgba(147,51,234,.9); }\n.ff-editing { outline: 2px solid #2563eb !important; outline-offset: 2px; cursor: text; }\n.ff-editing .ff-chip { background: rgba(37,99,235,.14) !important; box-shadow: inset 0 0 0 1px rgba(37,99,235,.45) !important; border-radius: 3px !important; padding: 0 1px !important; cursor: default; }\n.ff-edit-badge { position: absolute; z-index: 2147483647; font: 500 11px/1.4 system-ui, sans-serif !important; color: #fff !important; background: #2563eb !important; padding: 1px 6px !important; border-radius: 4px !important; pointer-events: none; white-space: nowrap; }\n`;function F(l,d={}){let m=d.clicks!==!1,g=d.live===!0,o=l.document,i=null,s=null,f=e=>{try{l.parent.postMessage(e,"*")}catch{}},v=m?o.querySelector(\'meta[name="formfeed:document"]\')?.getAttribute("content")??null:null,h=!1;l.addEventListener("blur",()=>{h=!0}),l.addEventListener("focus",()=>{h=!1});let y=o.createElement("style");y.setAttribute("data-formfeed","edit"),y.setAttribute("data-pagedjs-ignore",""),y.textContent=O,(o.head??o.documentElement).appendChild(y),m&&o.documentElement.classList.add("ff-edit-mode");let M=e=>(e&&typeof e.closest=="function"?e:null)?.closest("[data-ff-edit]")??null;o.addEventListener("click",e=>{if(!m)return;if(i&&!i.done&&i.element.contains(e.target)){e.stopImmediatePropagation();return}let t=M(e.target);t&&(e.preventDefault(),e.stopImmediatePropagation(),C(t,{x:e.clientX,y:e.clientY}))},!0);function C(e,t){i&&!i.done&&x();let n=e.getAttribute("data-ff-src")??"",r=e.getBoundingClientRect(),u=Array.from(o.querySelectorAll(`[data-ff-src="${n.replace(/"/g,"")}"]`));s={src:n,element:e,point:t},f({type:"formfeed:edit-request",src:n,doc:v,edit:e.getAttribute("data-ff-edit"),text:e.textContent??"",elements:e.childElementCount,count:u.length,index:Math.max(0,u.indexOf(e)),split:e.hasAttribute("data-split-from")||e.hasAttribute("data-split-to"),rect:{left:r.left,top:r.top,width:r.width,height:r.height}})}o.addEventListener("keydown",e=>{if(!m||i&&!i.done||!(e.ctrlKey||e.metaKey)||e.altKey)return;let t=e.key.toLowerCase();(t==="z"||t==="y")&&(e.preventDefault(),f({type:t==="y"||e.shiftKey?"formfeed:redo":"formfeed:undo"}))}),l.addEventListener("message",e=>{if(e.source!==l.parent)return;let t=e.data;!t||typeof t.type!="string"||(t.type==="formfeed:edit-begin"?P(t):t.type==="formfeed:edit-refuse"||t.type==="formfeed:edit-end"?(s=null,i&&!i.done&&E(!1)):t.type==="formfeed:edit-open"&&B(t))});function B(e){if(!m||typeof e.src!="string"||i&&!i.done)return;let t=Array.from(o.querySelectorAll(`[data-ff-src="${e.src.replace(/"/g,"")}"][data-ff-edit]`)),n=Number.isInteger(e.index)?Number(e.index):0,r=t[n]??t[0];r&&C(r,null)}if(m){let e=()=>f({type:"formfeed:edit-ready",doc:v}),t=l;t.PagedConfig?t.formfeedEditReady=e:o.readyState==="loading"?o.addEventListener("DOMContentLoaded",e):e()}function P(e){i&&!i.done&&E(!1);let t=e.layer?o.querySelector(`[data-ff-layer="${String(e.layer).replace(/"/g,"")}"] > .ff-text`):s&&s.src===e.src?s.element:o.querySelector(`[data-ff-src="${String(e.src).replace(/"/g,"")}"]`),n=e.at,r=e.layer?n&&Number.isFinite(n.x)&&Number.isFinite(n.y)?{x:Number(n.x),y:Number(n.y)}:null:s&&s.src===e.src?s.point:null;s=null;let u=h&&!o.hasFocus();if(!t||!Array.isArray(e.items)||u){f({type:"formfeed:edit-cancel",token:String(e.token)});return}let c=Array.from(t.childNodes),b=o.createDocumentFragment();for(let a of e.items)if(a.kind==="text")b.appendChild(o.createTextNode(String(a.text)));else if(a.kind==="break")b.appendChild(o.createElement("br"));else if(a.kind==="chip"){let p=o.createElement("span");p.className="ff-chip",p.setAttribute("data-ff-chip",String(a.index)),p.setAttribute("contenteditable","false"),a.title&&(p.title=String(a.title)),p.textContent=String(a.text),b.appendChild(p)}for(let a of c)t.removeChild(a);t.appendChild(b),t.contentEditable="true",t.classList.add("ff-editing"),t.setAttribute("role","textbox"),e.label&&t.setAttribute("aria-label",String(e.label)),t.spellcheck=!0,i={token:String(e.token),element:t,saved:c,allowBreaks:e.allowBreaks===!0,badge:e.note?H(t,String(e.note)):null,done:!1},t.addEventListener("keydown",A),t.addEventListener("beforeinput",T),t.addEventListener("paste",S),t.addEventListener("drop",N),t.addEventListener("focusout",R),g&&t.addEventListener("input",k),t.focus(),e.select==="all"?I(t):K(t,r),f({type:"formfeed:edit-started",token:i.token}),typeof e.insert=="string"&&e.insert&&L(e.insert.replace(/\\r\\n?|\\n/g," "))}function L(e){if(typeof o.execCommand=="function"&&o.execCommand("insertText",!1,e))return;let t=l.getSelection(),n=t&&t.rangeCount?t.getRangeAt(0):null;n&&(n.deleteContents(),n.insertNode(o.createTextNode(e)),n.collapse(!1),g&&k())}function k(){i&&!i.done&&f({type:"formfeed:edit-input",token:i.token,items:D(i.element)})}function H(e,t){let n=o.createElement("div");n.className="ff-edit-badge",n.textContent=t;let r=e.getBoundingClientRect();return n.style.left=`${r.left+l.scrollX}px`,n.style.top=`${Math.max(0,r.top+l.scrollY-22)}px`,o.body.appendChild(n),n}function I(e){let t=l.getSelection();if(!t)return;let n=o.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)}function K(e,t){let n=l.getSelection();if(!n)return;let r=null,u=o;if(t){if(u.caretRangeFromPoint)r=u.caretRangeFromPoint(t.x,t.y);else if(u.caretPositionFromPoint){let c=u.caretPositionFromPoint(t.x,t.y);c&&(r=o.createRange(),r.setStart(c.offsetNode,c.offset))}}if(!r||!e.contains(r.startContainer))r=o.createRange(),r.selectNodeContents(e),r.collapse(!1);else if(t){let c=r.startContainer,a=(c.nodeType===1?c:c.parentElement)?.closest("[data-ff-chip]")??null;if(a&&a!==e&&e.contains(a)){let p=a.getBoundingClientRect();r=o.createRange(),t.x<p.left+p.width/2?r.setStartBefore(a):r.setStartAfter(a),r.collapse(!0)}}n.removeAllRanges(),n.addRange(r)}function A(e){let t=e.key;t==="Escape"?(e.preventDefault(),E(!0)):t==="Enter"&&!e.shiftKey?(e.preventDefault(),x()):t==="Enter"?(e.preventDefault(),i?.allowBreaks&&q()):t==="Tab"?(e.preventDefault(),x()):(e.ctrlKey||e.metaKey)&&["b","i","u"].includes(t.toLowerCase())&&(e.preventDefault(),g&&i&&!e.altKey&&f({type:"formfeed:edit-style",token:i.token,key:t.toLowerCase()}))}function T(e){let t=e.inputType??"";(t.startsWith("format")||t==="insertFromDrop"||t==="insertParagraph"||t==="insertLineBreak")&&e.preventDefault()}function S(e){e.preventDefault(),L((e.clipboardData?.getData("text/plain")??"").replace(/\\r\\n?|\\n/g," "))}function N(e){e.preventDefault()}function R(){l.setTimeout(()=>{i&&!i.done&&(!o.hasFocus()||!i.element.contains(o.activeElement))&&x()},0)}function q(){let e=l.getSelection();if(!e||!e.rangeCount)return;let t=e.getRangeAt(0);t.deleteContents();let n=o.createElement("br");t.insertNode(n),n.nextSibling||n.parentNode?.appendChild(o.createElement("br"));let r=o.createRange();r.setStartAfter(n),r.collapse(!0),e.removeAllRanges(),e.addRange(r)}function w(e){e.done=!0;let t=e.element;t.removeEventListener("keydown",A),t.removeEventListener("beforeinput",T),t.removeEventListener("paste",S),t.removeEventListener("drop",N),t.removeEventListener("focusout",R),t.removeEventListener("input",k),t.removeAttribute("contenteditable"),t.removeAttribute("role"),t.removeAttribute("aria-label"),t.classList.remove("ff-editing"),e.badge?.remove(),i===e&&(i=null)}function x(){let e=i;if(!e||e.done)return;let t=D(e.element);w(e),f({type:"formfeed:edit-commit",token:e.token,items:t})}function E(e){let t=i;if(!t||t.done)return;let n=t.element;for(;n.firstChild;)n.removeChild(n.firstChild);for(let r of t.saved)n.appendChild(r);w(t),e&&f({type:"formfeed:edit-cancel",token:t.token})}}function D(l){let d=[],m=o=>{let i=d[d.length-1];i?.kind==="text"?i.text+=o:o&&d.push({kind:"text",text:o})},g=o=>{for(let i of Array.from(o.childNodes))if(i.nodeType===3)m(i.data);else if(i.nodeType===1){let s=i,f=s.getAttribute("data-ff-chip");f!==null?d.push({kind:"chip",index:Number(f)}):s.tagName==="BR"?d.push({kind:"break"}):((s.tagName==="DIV"||s.tagName==="P")&&d.length&&d.push({kind:"break"}),g(s))}};for(g(l);d[d.length-1]?.kind==="break";)d.pop();return d}F(window);})();';
|
|
5373
5424
|
var fitRuntime = '"use strict";(()=>{function a(t,e,n){if(e===t)return t.scrollHeight<=t.clientHeight+.5&&t.scrollWidth<=t.clientWidth+.5;let o=n.getComputedStyle(t),i=t.clientHeight-(parseFloat(o.paddingTop)||0)-(parseFloat(o.paddingBottom)||0);return e.scrollHeight<=i+.5&&e.scrollWidth<=e.clientWidth+.5}function m(t,e){let n=t.firstElementChild??t;n.style.fontSize="";let o=parseFloat(e.getComputedStyle(n).fontSize)||16,i=Math.min(o,parseFloat(t.getAttribute("data-ff-fit-min")??"")||o/2);if(a(t,n,e))return o;let l=i,s=o;for(let d=0;d<14;d++){let r=(l+s)/2;n.style.fontSize=`${r}px`,a(t,n,e)?l=r:s=r}let f=Math.floor(l*100)/100;return n.style.fontSize=`${f}px`,f}function c(t){let e=()=>{for(let o of Array.from(t.document.querySelectorAll(\'[data-ff-fit="shrink"]\')))m(o,t);t.document.documentElement.setAttribute("data-ff-fit","done")};t.formfeedFit=e;let n=t.document.fonts;n?n.ready.then(e):t.addEventListener("load",e)}c(window);})();';
|
|
5374
5425
|
var stageRuntime = '"use strict";(()=>{var W=`\nhtml.ff-edit-mode [data-ff-edit] { cursor: text; }\nhtml.ff-edit-mode [data-ff-edit]:hover { outline: 1px dashed rgba(37,99,235,.85); outline-offset: 2px; }\nhtml.ff-edit-mode [data-ff-edit="t"]:hover { outline-color: rgba(147,51,234,.9); }\n.ff-editing { outline: 2px solid #2563eb !important; outline-offset: 2px; cursor: text; }\n.ff-editing .ff-chip { background: rgba(37,99,235,.14) !important; box-shadow: inset 0 0 0 1px rgba(37,99,235,.45) !important; border-radius: 3px !important; padding: 0 1px !important; cursor: default; }\n.ff-edit-badge { position: absolute; z-index: 2147483647; font: 500 11px/1.4 system-ui, sans-serif !important; color: #fff !important; background: #2563eb !important; padding: 1px 6px !important; border-radius: 4px !important; pointer-events: none; white-space: nowrap; }\n`;function H(a,l={}){let f=l.clicks!==!1,p=l.live===!0,n=a.document,o=null,d=null,u=e=>{try{a.parent.postMessage(e,"*")}catch{}},m=f?n.querySelector(\'meta[name="formfeed:document"]\')?.getAttribute("content")??null:null,s=!1;a.addEventListener("blur",()=>{s=!0}),a.addEventListener("focus",()=>{s=!1});let g=n.createElement("style");g.setAttribute("data-formfeed","edit"),g.setAttribute("data-pagedjs-ignore",""),g.textContent=W,(n.head??n.documentElement).appendChild(g),f&&n.documentElement.classList.add("ff-edit-mode");let x=e=>(e&&typeof e.closest=="function"?e:null)?.closest("[data-ff-edit]")??null;n.addEventListener("click",e=>{if(!f)return;if(o&&!o.done&&o.element.contains(e.target)){e.stopImmediatePropagation();return}let t=x(e.target);t&&(e.preventDefault(),e.stopImmediatePropagation(),v(t,{x:e.clientX,y:e.clientY}))},!0);function v(e,t){o&&!o.done&&L();let r=e.getAttribute("data-ff-src")??"",i=e.getBoundingClientRect(),b=Array.from(n.querySelectorAll(`[data-ff-src="${r.replace(/"/g,"")}"]`));d={src:r,element:e,point:t},u({type:"formfeed:edit-request",src:r,doc:m,edit:e.getAttribute("data-ff-edit"),text:e.textContent??"",elements:e.childElementCount,count:b.length,index:Math.max(0,b.indexOf(e)),split:e.hasAttribute("data-split-from")||e.hasAttribute("data-split-to"),rect:{left:i.left,top:i.top,width:i.width,height:i.height}})}n.addEventListener("keydown",e=>{if(!f||o&&!o.done||!(e.ctrlKey||e.metaKey)||e.altKey)return;let t=e.key.toLowerCase();(t==="z"||t==="y")&&(e.preventDefault(),u({type:t==="y"||e.shiftKey?"formfeed:redo":"formfeed:undo"}))}),a.addEventListener("message",e=>{if(e.source!==a.parent)return;let t=e.data;!t||typeof t.type!="string"||(t.type==="formfeed:edit-begin"?B(t):t.type==="formfeed:edit-refuse"||t.type==="formfeed:edit-end"?(d=null,o&&!o.done&&S(!1)):t.type==="formfeed:edit-open"&&E(t))});function E(e){if(!f||typeof e.src!="string"||o&&!o.done)return;let t=Array.from(n.querySelectorAll(`[data-ff-src="${e.src.replace(/"/g,"")}"][data-ff-edit]`)),r=Number.isInteger(e.index)?Number(e.index):0,i=t[r]??t[0];i&&v(i,null)}if(f){let e=()=>u({type:"formfeed:edit-ready",doc:m}),t=a;t.PagedConfig?t.formfeedEditReady=e:n.readyState==="loading"?n.addEventListener("DOMContentLoaded",e):e()}function B(e){o&&!o.done&&S(!1);let t=e.layer?n.querySelector(`[data-ff-layer="${String(e.layer).replace(/"/g,"")}"] > .ff-text`):d&&d.src===e.src?d.element:n.querySelector(`[data-ff-src="${String(e.src).replace(/"/g,"")}"]`),r=e.at,i=e.layer?r&&Number.isFinite(r.x)&&Number.isFinite(r.y)?{x:Number(r.x),y:Number(r.y)}:null:d&&d.src===e.src?d.point:null;d=null;let b=s&&!n.hasFocus();if(!t||!Array.isArray(e.items)||b){u({type:"formfeed:edit-cancel",token:String(e.token)});return}let y=Array.from(t.childNodes),k=n.createDocumentFragment();for(let c of e.items)if(c.kind==="text")k.appendChild(n.createTextNode(String(c.text)));else if(c.kind==="break")k.appendChild(n.createElement("br"));else if(c.kind==="chip"){let h=n.createElement("span");h.className="ff-chip",h.setAttribute("data-ff-chip",String(c.index)),h.setAttribute("contenteditable","false"),c.title&&(h.title=String(c.title)),h.textContent=String(c.text),k.appendChild(h)}for(let c of y)t.removeChild(c);t.appendChild(k),t.contentEditable="true",t.classList.add("ff-editing"),t.setAttribute("role","textbox"),e.label&&t.setAttribute("aria-label",String(e.label)),t.spellcheck=!0,o={token:String(e.token),element:t,saved:y,allowBreaks:e.allowBreaks===!0,badge:e.note?I(t,String(e.note)):null,done:!1},t.addEventListener("keydown",T),t.addEventListener("beforeinput",N),t.addEventListener("paste",w),t.addEventListener("drop",R),t.addEventListener("focusout",F),p&&t.addEventListener("input",C),t.focus(),e.select==="all"?q(t):K(t,i),u({type:"formfeed:edit-started",token:o.token}),typeof e.insert=="string"&&e.insert&&A(e.insert.replace(/\\r\\n?|\\n/g," "))}function A(e){if(typeof n.execCommand=="function"&&n.execCommand("insertText",!1,e))return;let t=a.getSelection(),r=t&&t.rangeCount?t.getRangeAt(0):null;r&&(r.deleteContents(),r.insertNode(n.createTextNode(e)),r.collapse(!1),p&&C())}function C(){o&&!o.done&&u({type:"formfeed:edit-input",token:o.token,items:D(o.element)})}function I(e,t){let r=n.createElement("div");r.className="ff-edit-badge",r.textContent=t;let i=e.getBoundingClientRect();return r.style.left=`${i.left+a.scrollX}px`,r.style.top=`${Math.max(0,i.top+a.scrollY-22)}px`,n.body.appendChild(r),r}function q(e){let t=a.getSelection();if(!t)return;let r=n.createRange();r.selectNodeContents(e),t.removeAllRanges(),t.addRange(r)}function K(e,t){let r=a.getSelection();if(!r)return;let i=null,b=n;if(t){if(b.caretRangeFromPoint)i=b.caretRangeFromPoint(t.x,t.y);else if(b.caretPositionFromPoint){let y=b.caretPositionFromPoint(t.x,t.y);y&&(i=n.createRange(),i.setStart(y.offsetNode,y.offset))}}if(!i||!e.contains(i.startContainer))i=n.createRange(),i.selectNodeContents(e),i.collapse(!1);else if(t){let y=i.startContainer,c=(y.nodeType===1?y:y.parentElement)?.closest("[data-ff-chip]")??null;if(c&&c!==e&&e.contains(c)){let h=c.getBoundingClientRect();i=n.createRange(),t.x<h.left+h.width/2?i.setStartBefore(c):i.setStartAfter(c),i.collapse(!0)}}r.removeAllRanges(),r.addRange(i)}function T(e){let t=e.key;t==="Escape"?(e.preventDefault(),S(!0)):t==="Enter"&&!e.shiftKey?(e.preventDefault(),L()):t==="Enter"?(e.preventDefault(),o?.allowBreaks&&$()):t==="Tab"?(e.preventDefault(),L()):(e.ctrlKey||e.metaKey)&&["b","i","u"].includes(t.toLowerCase())&&(e.preventDefault(),p&&o&&!e.altKey&&u({type:"formfeed:edit-style",token:o.token,key:t.toLowerCase()}))}function N(e){let t=e.inputType??"";(t.startsWith("format")||t==="insertFromDrop"||t==="insertParagraph"||t==="insertLineBreak")&&e.preventDefault()}function w(e){e.preventDefault(),A((e.clipboardData?.getData("text/plain")??"").replace(/\\r\\n?|\\n/g," "))}function R(e){e.preventDefault()}function F(){a.setTimeout(()=>{o&&!o.done&&(!n.hasFocus()||!o.element.contains(n.activeElement))&&L()},0)}function $(){let e=a.getSelection();if(!e||!e.rangeCount)return;let t=e.getRangeAt(0);t.deleteContents();let r=n.createElement("br");t.insertNode(r),r.nextSibling||r.parentNode?.appendChild(n.createElement("br"));let i=n.createRange();i.setStartAfter(r),i.collapse(!0),e.removeAllRanges(),e.addRange(i)}function M(e){e.done=!0;let t=e.element;t.removeEventListener("keydown",T),t.removeEventListener("beforeinput",N),t.removeEventListener("paste",w),t.removeEventListener("drop",R),t.removeEventListener("focusout",F),t.removeEventListener("input",C),t.removeAttribute("contenteditable"),t.removeAttribute("role"),t.removeAttribute("aria-label"),t.classList.remove("ff-editing"),e.badge?.remove(),o===e&&(o=null)}function L(){let e=o;if(!e||e.done)return;let t=D(e.element);M(e),u({type:"formfeed:edit-commit",token:e.token,items:t})}function S(e){let t=o;if(!t||t.done)return;let r=t.element;for(;r.firstChild;)r.removeChild(r.firstChild);for(let i of t.saved)r.appendChild(i);M(t),e&&u({type:"formfeed:edit-cancel",token:t.token})}}function D(a){let l=[],f=n=>{let o=l[l.length-1];o?.kind==="text"?o.text+=n:n&&l.push({kind:"text",text:n})},p=n=>{for(let o of Array.from(n.childNodes))if(o.nodeType===3)f(o.data);else if(o.nodeType===1){let d=o,u=d.getAttribute("data-ff-chip");u!==null?l.push({kind:"chip",index:Number(u)}):d.tagName==="BR"?l.push({kind:"break"}):((d.tagName==="DIV"||d.tagName==="P")&&l.length&&l.push({kind:"break"}),p(d))}};for(p(a);l[l.length-1]?.kind==="break";)l.pop();return l}function O(a,l){return Array.from(a.querySelectorAll("[data-ff-layer]")).map(f=>{let p=f.querySelector(":scope > .ff-text"),n=!1;if(p&&f.style.height!=="auto"){let o=l.getComputedStyle(f),d=f.clientHeight-(parseFloat(o.paddingTop)||0)-(parseFloat(o.paddingBottom)||0);n=o.overflow==="hidden"&&(p.scrollHeight>d+1||p.scrollWidth>p.clientWidth+1)}return{id:f.getAttribute("data-ff-layer")??"",width:f.offsetWidth,height:f.offsetHeight,overflow:n}})}function P(a){let l=a.document,f=m=>{try{a.parent.postMessage(m,"*")}catch{}},p=m=>typeof m=="string"?l.querySelector(`[data-ff-layer="${m.replace(/"/g,"")}"]`):null,n=()=>{for(let m of Array.from(l.querySelectorAll("[data-ff-layer]")))for(let s of["left","top","width","height","transform"])m.style.removeProperty(s)},o=()=>{a.formfeedFit?.(),f({type:"formfeed:ready",layers:O(l,a)})};a.addEventListener("message",m=>{if(m.source!==a.parent)return;let s=m.data;if(!(!s||typeof s.type!="string")){if(s.type==="formfeed:layer-style"){let g=p(s.id);if(!g)return;let x=(v,E)=>{typeof E=="number"&&Number.isFinite(E)&&g.style.setProperty(v,`${E}px`)};x("left",s.left),x("top",s.top),x("width",s.width),x("height",s.height),typeof s.rotation=="number"&&Number.isFinite(s.rotation)&&g.style.setProperty("transform",s.rotation?`rotate(${s.rotation}deg)`:"none")}else if(s.type==="formfeed:layer-style-clear")n();else if(s.type==="formfeed:css"&&typeof s.css=="string"){let g=l.querySelector(\'style[data-formfeed="template"]\');g&&(g.textContent=s.css),n(),o()}}}),H(a,{clicks:!1,live:!0});let d=l.fonts,u=()=>d?void d.ready.then(o):o();l.readyState==="complete"?u():a.addEventListener("load",u)}P(window);})();';
|
|
5426
|
+
var auditRuntime = '"use strict";(()=>{var I={"document-title":"error","image-alt":"error","figure-name":"error","heading-order":"error","table-rows":"error","table-cell-empty":"error","masked-text":"error","filtered-text":"warning","document-language":"warning","table-headers":"warning","link-name":"warning","generated-text":"warning","fixed-text":"warning","running-text":"warning"};var S=120;var O=".formfeed-chrome, .ff-running-header, .ff-running-footer",_=".pageNumber, .totalPages, .date, .title, .url, .ff-page-no, .ff-page-total",k=new Set(["script","style","template","noscript","head"]),j=2e4,q=10,B=new Set(["page","pages","of","seite","seiten","von","p","s"]),u=t=>(t??"").replace(/\\s+/g," ").trim(),D=t=>t.replace(/\\s+/g,"").toLowerCase(),$=t=>/[\\p{L}\\p{N}]/u.test(t),Y=/^data-(ref|id|split-(from|to|original)|(previous-|next-)?break-(before|after|inside)|(align-)?last-split-element|nth-of-type|counter-.+|page(-number)?|undisplayed|after-page|following|has-notes|children|item-num)$/;function X(t){let n=t.cloneNode(!1);n.removeAttribute("data-ff-src"),n.removeAttribute("data-ff-edit");let i=t.closest(".pagedjs_page")!==null;for(let s of Array.from(n.attributes))i&&Y.test(s.name)?n.removeAttribute(s.name):s.value.length>48&&n.setAttribute(s.name,`${s.value.slice(0,40)}\\u2026`);let o=n.outerHTML.replace(new RegExp(`</${t.tagName}>$`,"i"),"");return o.length>S?`${o.slice(0,S-1)}\\u2026`:o}function F(t,n={}){let i=t.document,o=i.body,s=[],d=new Set,a=n.findings!==!1,c=(e,r,l={})=>{if(!a)return;let m=r?.closest("[data-ff-src]")?.getAttribute("data-ff-src")??null,h=r?X(r):"",g=`${e}|${m??h}|${JSON.stringify(l)}`;d.has(g)||(d.add(g),s.push({code:e,severity:I[e],src:m,snippet:h,args:l}))},f=new WeakMap,A=e=>{let r=f.get(e);if(r!==void 0)return r;let l=t.getComputedStyle(e),m=l.display==="none"||l.visibility==="hidden"||l.visibility==="collapse"||e.parentElement!==null&&e.parentElement!==i.documentElement&&A(e.parentElement);return f.set(e,m),m},p=e=>e.closest(\'[aria-hidden="true"]\')!==null,E=e=>/^(presentation|none)$/.test(e.getAttribute("role")??""),H=e=>e.closest(O)!==null,y=e=>$(e.textContent??""),x=e=>{let r=u(e.getAttribute("aria-label"));return r||u((e.getAttribute("aria-labelledby")??"").split(/\\s+/).filter(Boolean).map(l=>e.ownerDocument.getElementById(l)?.textContent??"").join(" "))},P=e=>x(e)||u(e.textContent)||u(Array.from(e.querySelectorAll("img[alt]")).map(r=>r.getAttribute("alt")).join(" "))||u(e.getAttribute("title")),T=e=>{let r=e.getAttribute("href")??"";return{href:r.startsWith("#")?r:e.href??r,name:P(e)}};u(i.title)||c("document-title",null),!u(i.documentElement.getAttribute("lang"))&&!n.locale&&c("document-language",null);let M=n.pages??(n.pageHeight&&n.pageHeight>0?Math.ceil(i.documentElement.scrollHeight/n.pageHeight):1),C=[],v=[],R={"masked-text":[],"filtered-text":[],"fixed-text":[]},w=(e,r)=>{R[e].some(l=>l.contains(r))||(R[e].push(r),c(e,r))},V=a&&ne(i),G=o?Array.from(o.querySelectorAll("*")).slice(0,j):[];for(let e of G){let r=e.tagName.toLowerCase();if(k.has(r)||H(e)||A(e))continue;if(r==="a"&&e.hasAttribute("href")){let g=T(e);C.push(g),!g.name&&!p(e)&&c("link-name",e)}if(!a)continue;let l=t.getComputedStyle(e),m=l.getPropertyValue("mask-image")||l.getPropertyValue("-webkit-mask-image");if(m&&m!=="none"&&y(e)&&w("masked-text",e),l.filter&&l.filter!=="none"&&y(e)&&w("filtered-text",e),l.position==="fixed"&&M>1&&y(e)&&w("fixed-text",e),V)for(let g of["::before","::after"]){let U=re(t.getComputedStyle(e,g).content);U&&c("generated-text",e,{text:U})}if(p(e))continue;r==="img"&&!E(e)?e.hasAttribute("alt")||x(e)||u(e.getAttribute("title"))||c("image-alt",e):(r==="canvas"||e.getAttribute("role")==="img"&&r!=="img")&&(x(e)||u(e.getAttribute("title"))||u(e.querySelector(":scope > title")?.textContent)||c("figure-name",e,{tag:r}));let h=/^h[1-6]$/.test(r)?Number(r[1]):e.getAttribute("role")==="heading"?Number(e.getAttribute("aria-level"))||2:0;h&&v.push({element:e,level:h}),r==="table"&&!E(e)&&Q(e,c)}let b=0;for(let{element:e,level:r}of v)(b===0?r!==1:r>b+1)&&c("heading-order",e,{level:r,previous:b}),b=r;let N=[],W=a&&o?D(J(o)):"",L=0;for(let e of["header","footer"])for(let r of z(i,e,n[e])){for(let l of Array.from(r.querySelectorAll("a[href]")))N.push(T(l));if(a)for(let{text:l,element:m}of K(r)){if(L>=q||W.includes(D(l)))continue;let h=s.length;c("running-text",m,{text:l.slice(0,80),part:e}),s.length>h&&L++}}return{findings:s,links:C,templateLinks:N}}function z(t,n,i){if(i!==void 0){if(!i.trim())return[];let o=new DOMParser().parseFromString(`<!doctype html><body>${i}</body>`,"text/html");return o.body?[o.body]:[]}return Array.from(t.querySelectorAll(`.ff-running-${n}, .formfeed-chrome[data-ff-chrome="${n}"]`))}function J(t){let n=[],i=o=>{if(o.nodeType===3){n.push(o.nodeValue??"");return}if(o.nodeType!==1)return;let s=o;if(!(k.has(s.tagName.toLowerCase())||s.matches(O)))for(let d of Array.from(o.childNodes))i(d)};return i(t),n.join(" ")}function K(t){let n=[],i=o=>{let s=o.tagName.toLowerCase();if(k.has(s)||o.matches(_))return;let d=Array.from(o.children).some(a=>a.matches(_));for(let a of Array.from(o.childNodes))if(a.nodeType===1)i(a);else if(a.nodeType===3&&!d)for(let c of(a.nodeValue??"").split(/\\s*[\xB7\u2022|]\\s*|\\s{2,}|\\n/)){let f=u(c);(f.toLowerCase().match(/[\\p{L}\\p{N}]+/gu)??[]).some(p=>!B.has(p))&&n.push({text:f,element:o})}};return i(t),n}function Q(t,n){let i=Array.from(t.rows);if(!(t.querySelector(\'th, [role="columnheader"], [role="rowheader"]\')!==null)){i.length>=2&&n("table-headers",t);return}let s=te(i),d=s.find(c=>c!==s[0]);d!==void 0&&n("table-rows",t,{first:s[0]??0,other:d});let a=i.flatMap(c=>Array.from(c.cells).filter(f=>f.tagName==="TD"&&ee(f)));a[0]&&n("table-cell-empty",a[0],{count:a.length})}var Z=\'img[alt]:not([alt=""]), svg, canvas, input, select, textarea, button, meter, progress\';function ee(t){return!/[^ \\t\\n\\r\\f]/.test(t.textContent??"")&&t.querySelector(Z)===null}function te(t){let n=[];return t.map(i=>{let o=[],s=0,d=()=>{for(;(n[s]??0)>0;)o[s]=n[s]-1,s++};for(let a of Array.from(i.cells)){d();let c=Math.max(1,a.rowSpan||1)-1;for(let f=Math.max(1,a.colSpan||1);f>0;f--)o[s++]=c}d();for(let a=s;a<n.length;a++)(n[a]??0)>0&&(o[a]=n[a]-1,s=a+1);return n=o,s})}function ne(t){let n=i=>{for(let o of Array.from(i??[])){let s=o;if(s.selectorText&&/::?(before|after)/.test(s.selectorText)&&s.style?.content||o.cssRules&&n(o.cssRules))return!0}return!1};for(let i of Array.from(t.styleSheets))try{if(n(i.cssRules))return!0}catch{return!0}return!1}function re(t){if(!t||t==="none"||t==="normal")return"";let n=(t.match(/"(?:[^"\\\\]|\\\\.)*"/g)??[]).map(o=>o.slice(1,-1).replace(/\\\\(.)/g,"$1"));if(/\\bcounters?\\(/.test(t))return u(t).slice(0,80);let i=u(n.join(""));return $(i)?i.slice(0,80):""}window.formfeedAudit=t=>F(window,t);})();';
|
|
5375
5427
|
|
|
5376
5428
|
// packages/engine/src/lib/assemble.ts
|
|
5377
5429
|
var DEFAULT_CHROME_PADDING = "0 10mm";
|
|
@@ -5626,6 +5678,23 @@ document.addEventListener('click', function (event) {
|
|
|
5626
5678
|
}, true);
|
|
5627
5679
|
</script>`;
|
|
5628
5680
|
var textEditScript = `<script>${textEditRuntime.replace(/<\/script/gi, "<\\/script")}</script>`;
|
|
5681
|
+
function auditScript(mode) {
|
|
5682
|
+
return `<script>${auditRuntime.replace(/<\/script/gi, "<\\/script")}</script><script>
|
|
5683
|
+
(function () {
|
|
5684
|
+
window.formfeedRunAudit = function (pages) {
|
|
5685
|
+
try {
|
|
5686
|
+
var report = window.formfeedAudit({
|
|
5687
|
+
locale: true,
|
|
5688
|
+
pages: pages,
|
|
5689
|
+
pageHeight: parseFloat(getComputedStyle(document.body).minHeight) || 0,
|
|
5690
|
+
});
|
|
5691
|
+
parent.postMessage({ type: 'formfeed:audit', findings: report.findings }, '*');
|
|
5692
|
+
} catch (e) {}
|
|
5693
|
+
};
|
|
5694
|
+
${mode === "flow" ? "window.addEventListener('load', function () { (document.fonts ? document.fonts.ready : Promise.resolve()).then(function () { window.formfeedRunAudit(); }); });" : ""}
|
|
5695
|
+
})();
|
|
5696
|
+
</script>`;
|
|
5697
|
+
}
|
|
5629
5698
|
function documentMeta(options) {
|
|
5630
5699
|
const name = (options.document ?? "").replace(/[^A-Za-z0-9_-]/g, "");
|
|
5631
5700
|
return name ? `<meta name="formfeed:document" content="${name}">` : "";
|
|
@@ -5737,6 +5806,15 @@ function intoHead(document, markup) {
|
|
|
5737
5806
|
${markup}`
|
|
5738
5807
|
);
|
|
5739
5808
|
}
|
|
5809
|
+
function intoBody(document, atStart, atEnd = "") {
|
|
5810
|
+
const own = document.indexOf('<body class="formfeed-body');
|
|
5811
|
+
const open2 = own >= 0 ? own : document.search(/<body[^>]*>/);
|
|
5812
|
+
if (open2 < 0) return document;
|
|
5813
|
+
const content = document.indexOf(">", open2) + 1;
|
|
5814
|
+
const close = document.lastIndexOf("</body>");
|
|
5815
|
+
const end = close >= content ? close : document.length;
|
|
5816
|
+
return `${document.slice(0, content)}${atStart}${document.slice(content, end)}${atEnd}${document.slice(end)}`;
|
|
5817
|
+
}
|
|
5740
5818
|
function chromeBoxStyle(settings, which) {
|
|
5741
5819
|
const margin = settings.margin ?? {};
|
|
5742
5820
|
const left = margin.left ?? "0px";
|
|
@@ -5760,12 +5838,16 @@ html { background: #e5e7eb; }
|
|
|
5760
5838
|
body.formfeed-preview { position: relative; box-sizing: border-box; width: ${paper.width}; min-height: ${paper.height}; margin: 24px auto; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.2), 0 8px 24px rgba(0,0,0,.08); padding: ${margin.top ?? "0"} ${margin.right ?? "0"} ${margin.bottom ?? "0"} ${margin.left ?? "0"}; }
|
|
5761
5839
|
.formfeed-chrome { color: #6b7280; font: 10px/1.3 system-ui, sans-serif; }
|
|
5762
5840
|
</style>` : `<style data-formfeed="preview">html { background: #e5e7eb; } body.formfeed-preview { margin: 24px auto; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.2); }</style>`;
|
|
5763
|
-
const header = headerHtml ? `<div class="formfeed-chrome" style="${pdf ? flowChromeStyle(settings, "header") : `${chromeBoxStyle(settings, "header")}margin-bottom:8px`}">${headerHtml}</div>` : "";
|
|
5764
|
-
const footer = footerHtml ? `<div class="formfeed-chrome" style="${pdf ? flowChromeStyle(settings, "footer") : `${chromeBoxStyle(settings, "footer")}margin-top:8px`}">${pageNumberSpans(footerHtml, "1", "1")}</div>` : "";
|
|
5765
|
-
return
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5841
|
+
const header = headerHtml ? `<div class="formfeed-chrome" data-ff-chrome="header" style="${pdf ? flowChromeStyle(settings, "header") : `${chromeBoxStyle(settings, "header")}margin-bottom:8px`}">${headerHtml}</div>` : "";
|
|
5842
|
+
const footer = footerHtml ? `<div class="formfeed-chrome" data-ff-chrome="footer" style="${pdf ? flowChromeStyle(settings, "footer") : `${chromeBoxStyle(settings, "footer")}margin-top:8px`}">${pageNumberSpans(footerHtml, "1", "1")}</div>` : "";
|
|
5843
|
+
return intoBody(
|
|
5844
|
+
intoHead(
|
|
5845
|
+
draft.document,
|
|
5846
|
+
`${documentMeta(options)}${chrome}${options.editing ? textEditScript : ""}${inspectScript}${zoomGestureScript}${pdf ? overflowScript("flow") : ""}${pdf && options.audit ? auditScript("flow") : ""}`
|
|
5847
|
+
),
|
|
5848
|
+
header,
|
|
5849
|
+
footer
|
|
5850
|
+
);
|
|
5769
5851
|
}
|
|
5770
5852
|
function canvasDocument(draft) {
|
|
5771
5853
|
const chrome = `<style data-formfeed="stage">html, body { background: transparent !important; margin: 0 !important; }</style>`;
|
|
@@ -5792,14 +5874,17 @@ html { background: #e5e7eb; }
|
|
|
5792
5874
|
`;
|
|
5793
5875
|
const selectorGuard = `<script>(function(){var q=DocumentFragment.prototype.querySelectorAll;DocumentFragment.prototype.querySelectorAll=function(s){try{return q.call(this,s);}catch(e){console.warn('formfeed paged preview: skipped a selector Paged.js could not use:',s);return q.call(this,':not(*)');}};})();</script>`;
|
|
5794
5876
|
const boxSizingGuard = `<script>(function(){var rule='.pagedjs_pagebox *';var o=new MutationObserver(function(ms){ms.forEach(function(m){m.addedNodes.forEach(function(n){if(n.nodeName==='STYLE'&&n.textContent&&n.textContent.indexOf(rule)>=0){n.textContent=n.textContent.split(rule).join('.pagedjs_pagebox [class*="pagedjs_"]');o.disconnect();}});});});o.observe(document.documentElement,{childList:true,subtree:true});})();</script>`;
|
|
5795
|
-
const config = `<script>window.PagedConfig = { auto: true, after: function (flow) { try { if (window.formfeedDrawCharts) window.formfeedDrawCharts(); } catch (e) {} try { if (window.formfeedFit) window.formfeedFit(); } catch (e) {} try { parent.postMessage({ type: 'formfeed:pages', pages: flow.total }, '*'); } catch (e) {} if (window.formfeedCheckOverflow) window.formfeedCheckOverflow(); try { if (window.formfeedEditReady) window.formfeedEditReady(); } catch (e) {} } };</script>`;
|
|
5877
|
+
const config = `<script>window.PagedConfig = { auto: true, after: function (flow) { try { if (window.formfeedDrawCharts) window.formfeedDrawCharts(); } catch (e) {} try { if (window.formfeedFit) window.formfeedFit(); } catch (e) {} try { parent.postMessage({ type: 'formfeed:pages', pages: flow.total }, '*'); } catch (e) {} if (window.formfeedCheckOverflow) window.formfeedCheckOverflow(); if (window.formfeedRunAudit) window.formfeedRunAudit(flow.total); try { if (window.formfeedEditReady) window.formfeedEditReady(); } catch (e) {} } };</script>`;
|
|
5796
5878
|
const script = `<script src="${options.pagedScriptUrl}"></script>`;
|
|
5797
5879
|
const header = headerHtml ? `<div class="ff-running-header">${pageNumberSpans(headerHtml, '<span class="ff-page-no"></span>', '<span class="ff-page-total"></span>')}</div>` : "";
|
|
5798
5880
|
const footer = footerHtml ? `<div class="ff-running-footer">${pageNumberSpans(footerHtml, '<span class="ff-page-no"></span>', '<span class="ff-page-total"></span>')}</div>` : "";
|
|
5799
|
-
return
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5881
|
+
return intoBody(
|
|
5882
|
+
intoHead(
|
|
5883
|
+
draft.document,
|
|
5884
|
+
`${documentMeta(options)}<style data-formfeed="paged">${runningCss}</style>${selectorGuard}${boxSizingGuard}${overflowScript("paged")}${options.audit ? auditScript("paged") : ""}${config}${script}${options.editing ? textEditScript : ""}${inspectScript}${pageNavScript}${zoomGestureScript}`
|
|
5885
|
+
),
|
|
5886
|
+
`${header}${footer}`
|
|
5887
|
+
);
|
|
5803
5888
|
}
|
|
5804
5889
|
|
|
5805
5890
|
// packages/engine/src/lib/source-scan.ts
|
|
@@ -6289,18 +6374,18 @@ function applyRegionEdit(source, engine, region, items) {
|
|
|
6289
6374
|
const rewritten = source.slice(0, region.start) + whole + source.slice(region.end);
|
|
6290
6375
|
return readsBack(rewritten, engine, region.tagStart, expected) ? { source: rewritten } : { error: "invalid" };
|
|
6291
6376
|
}
|
|
6292
|
-
function translationItems(
|
|
6377
|
+
function translationItems(text4) {
|
|
6293
6378
|
const items = [];
|
|
6294
6379
|
const names = [];
|
|
6295
6380
|
let last = 0;
|
|
6296
|
-
for (const match of
|
|
6381
|
+
for (const match of text4.matchAll(/\{(\w+)\}/g)) {
|
|
6297
6382
|
if (match.index > last)
|
|
6298
|
-
items.push({ kind: "text", text:
|
|
6383
|
+
items.push({ kind: "text", text: text4.slice(last, match.index) });
|
|
6299
6384
|
items.push({ kind: "chip", index: names.length });
|
|
6300
6385
|
names.push(match[1] ?? "");
|
|
6301
6386
|
last = match.index + match[0].length;
|
|
6302
6387
|
}
|
|
6303
|
-
if (last <
|
|
6388
|
+
if (last < text4.length) items.push({ kind: "text", text: text4.slice(last) });
|
|
6304
6389
|
return { items, names };
|
|
6305
6390
|
}
|
|
6306
6391
|
function translationText(items, names) {
|
|
@@ -6544,9 +6629,9 @@ function translationCall(engine, inner) {
|
|
|
6544
6629
|
);
|
|
6545
6630
|
return match ? { key: match[2] ?? "", params: parseParams(match[3] ?? "", "=", " ") } : null;
|
|
6546
6631
|
}
|
|
6547
|
-
function parseParams(
|
|
6632
|
+
function parseParams(text4, assign, separator) {
|
|
6548
6633
|
const params = {};
|
|
6549
|
-
for (const piece of splitTopLevel(
|
|
6634
|
+
for (const piece of splitTopLevel(text4, separator)) {
|
|
6550
6635
|
const at = piece.indexOf(assign);
|
|
6551
6636
|
if (at <= 0) continue;
|
|
6552
6637
|
const name = piece.slice(0, at).trim().replace(/^['"]|['"]$/g, "");
|
|
@@ -6554,12 +6639,12 @@ function parseParams(text3, assign, separator) {
|
|
|
6554
6639
|
}
|
|
6555
6640
|
return params;
|
|
6556
6641
|
}
|
|
6557
|
-
function splitTopLevel(
|
|
6642
|
+
function splitTopLevel(text4, separator) {
|
|
6558
6643
|
const pieces = [];
|
|
6559
6644
|
let depth = 0;
|
|
6560
6645
|
let quote2 = null;
|
|
6561
6646
|
let current = "";
|
|
6562
|
-
for (const ch of
|
|
6647
|
+
for (const ch of text4) {
|
|
6563
6648
|
if (quote2) {
|
|
6564
6649
|
if (ch === quote2) quote2 = null;
|
|
6565
6650
|
} else if (ch === '"' || ch === "'") quote2 = ch;
|
|
@@ -6584,7 +6669,7 @@ function entityChar(reference) {
|
|
|
6584
6669
|
return code === void 0 ? null : String.fromCharCode(code);
|
|
6585
6670
|
}
|
|
6586
6671
|
function decodeText2(raw) {
|
|
6587
|
-
let
|
|
6672
|
+
let text4 = "";
|
|
6588
6673
|
const map = [];
|
|
6589
6674
|
let i = 0;
|
|
6590
6675
|
while (i < raw.length) {
|
|
@@ -6594,23 +6679,23 @@ function decodeText2(raw) {
|
|
|
6594
6679
|
const decoded = match ? entityChar(match[1] ?? "") : null;
|
|
6595
6680
|
if (match && decoded !== null) {
|
|
6596
6681
|
for (let u = 0; u < decoded.length; u++) map.push(i);
|
|
6597
|
-
|
|
6682
|
+
text4 += decoded;
|
|
6598
6683
|
i += match[0].length;
|
|
6599
6684
|
continue;
|
|
6600
6685
|
}
|
|
6601
6686
|
}
|
|
6602
|
-
|
|
6687
|
+
text4 += raw[i];
|
|
6603
6688
|
map.push(i);
|
|
6604
6689
|
i++;
|
|
6605
6690
|
}
|
|
6606
6691
|
map.push(raw.length);
|
|
6607
|
-
return { text:
|
|
6692
|
+
return { text: text4, map };
|
|
6608
6693
|
}
|
|
6609
|
-
function encodeText(
|
|
6694
|
+
function encodeText(text4, keepNbsp, allBraces = false) {
|
|
6610
6695
|
let out = "";
|
|
6611
|
-
for (let k = 0; k <
|
|
6612
|
-
const ch =
|
|
6613
|
-
const next =
|
|
6696
|
+
for (let k = 0; k < text4.length; k++) {
|
|
6697
|
+
const ch = text4[k] ?? "";
|
|
6698
|
+
const next = text4[k + 1];
|
|
6614
6699
|
if (ch === "&") out += "&";
|
|
6615
6700
|
else if (ch === "<") out += "<";
|
|
6616
6701
|
else if (ch === ">") out += ">";
|
|
@@ -6622,8 +6707,8 @@ function encodeText(text3, keepNbsp, allBraces = false) {
|
|
|
6622
6707
|
}
|
|
6623
6708
|
return out;
|
|
6624
6709
|
}
|
|
6625
|
-
function encodeTemplateText(
|
|
6626
|
-
return encodeText(
|
|
6710
|
+
function encodeTemplateText(text4) {
|
|
6711
|
+
return encodeText(text4, true);
|
|
6627
6712
|
}
|
|
6628
6713
|
function spanOf(part) {
|
|
6629
6714
|
return part ? [part.start, part.end] : [0, 0];
|
|
@@ -6657,7 +6742,7 @@ function rewriteSegment(source, segStart, segEnd, parts, next, breakSpelling) {
|
|
|
6657
6742
|
const to = map[old.length - suffix] ?? segEnd;
|
|
6658
6743
|
const middle = next.slice(prefix, next.length - suffix);
|
|
6659
6744
|
const keepNbsp = old.slice(prefix, old.length - suffix).includes(NBSP);
|
|
6660
|
-
const written = middle.split(BREAK).map((
|
|
6745
|
+
const written = middle.split(BREAK).map((text4) => encodeText(text4, keepNbsp)).join(breakSpelling);
|
|
6661
6746
|
return source.slice(segStart, from) + written + source.slice(to, segEnd);
|
|
6662
6747
|
}
|
|
6663
6748
|
var isHighSurrogate = (code) => code >= 55296 && code <= 56319;
|
|
@@ -7412,11 +7497,11 @@ function googleFontsUrl(uses) {
|
|
|
7412
7497
|
|
|
7413
7498
|
// packages/engine/src/lib/design/hash.ts
|
|
7414
7499
|
function designOutputHash(html, css2) {
|
|
7415
|
-
const
|
|
7500
|
+
const text4 = `${html}\0${css2}`;
|
|
7416
7501
|
let a = 2166136261;
|
|
7417
7502
|
let b = 16777619 ^ 2654435769;
|
|
7418
|
-
for (let i = 0; i <
|
|
7419
|
-
const code =
|
|
7503
|
+
for (let i = 0; i < text4.length; i++) {
|
|
7504
|
+
const code = text4.charCodeAt(i);
|
|
7420
7505
|
if (code === 13) continue;
|
|
7421
7506
|
a = Math.imul(a ^ code, 16777619) >>> 0;
|
|
7422
7507
|
b = Math.imul(b ^ code, 16777619) >>> 0;
|
|
@@ -7643,32 +7728,32 @@ function imageSource(source, engine) {
|
|
|
7643
7728
|
return `{{ brand.logo.${source.brandLogo} }}`;
|
|
7644
7729
|
}
|
|
7645
7730
|
function layerCss(layer) {
|
|
7646
|
-
const
|
|
7731
|
+
const text4 = layer.type === "text" ? layer : null;
|
|
7647
7732
|
const box = {
|
|
7648
7733
|
left: px(layer.x),
|
|
7649
7734
|
top: px(layer.y),
|
|
7650
7735
|
width: px(layer.width),
|
|
7651
|
-
height:
|
|
7736
|
+
height: text4?.sizing === "grow" ? void 0 : px(layer.height),
|
|
7652
7737
|
opacity: layer.opacity < 1 ? num(layer.opacity) : void 0,
|
|
7653
7738
|
transform: layer.rotation ? `rotate(${num(layer.rotation)}deg)` : void 0,
|
|
7654
7739
|
"border-radius": layer.type === "shape" && layer.shape === "ellipse" ? "50%" : layer.radius ? px(layer.radius) : void 0,
|
|
7655
7740
|
border: layer.stroke && layer.stroke.width > 0 ? `${px(layer.stroke.width)} solid ${paint(layer.stroke.paint)}` : void 0,
|
|
7656
|
-
"box-shadow": layer.shadow && !
|
|
7741
|
+
"box-shadow": layer.shadow && !text4 ? shadow(layer.shadow) : void 0
|
|
7657
7742
|
};
|
|
7658
|
-
if (
|
|
7743
|
+
if (text4) {
|
|
7659
7744
|
Object.assign(box, {
|
|
7660
7745
|
display: "flex",
|
|
7661
7746
|
"flex-direction": "column",
|
|
7662
|
-
"justify-content":
|
|
7663
|
-
overflow:
|
|
7664
|
-
padding:
|
|
7665
|
-
background:
|
|
7747
|
+
"justify-content": text4.valign === "middle" ? "center" : text4.valign === "bottom" ? "flex-end" : "flex-start",
|
|
7748
|
+
overflow: text4.sizing === "grow" ? void 0 : "hidden",
|
|
7749
|
+
padding: text4.padding ? px(text4.padding) : void 0,
|
|
7750
|
+
background: text4.fill ? paint(text4.fill) : void 0
|
|
7666
7751
|
});
|
|
7667
|
-
const s =
|
|
7668
|
-
const clamp =
|
|
7752
|
+
const s = text4.style;
|
|
7753
|
+
const clamp = text4.maxLines ? {
|
|
7669
7754
|
display: "-webkit-box",
|
|
7670
7755
|
"-webkit-box-orient": "vertical",
|
|
7671
|
-
"-webkit-line-clamp": String(
|
|
7756
|
+
"-webkit-line-clamp": String(text4.maxLines),
|
|
7672
7757
|
overflow: "hidden"
|
|
7673
7758
|
} : {};
|
|
7674
7759
|
const inner = decl({
|
|
@@ -7684,7 +7769,7 @@ function layerCss(layer) {
|
|
|
7684
7769
|
"font-style": s.italic ? "italic" : void 0,
|
|
7685
7770
|
"text-transform": s.uppercase ? "uppercase" : void 0,
|
|
7686
7771
|
"text-decoration": [s.underline && "underline", s.strike && "line-through"].filter(Boolean).join(" ") || void 0,
|
|
7687
|
-
"text-shadow":
|
|
7772
|
+
"text-shadow": text4.shadow ? shadow(text4.shadow) : void 0,
|
|
7688
7773
|
"overflow-wrap": "break-word",
|
|
7689
7774
|
...clamp
|
|
7690
7775
|
});
|
|
@@ -8048,24 +8133,24 @@ var paymentMeansCodes = list2(
|
|
|
8048
8133
|
// packages/engine/src/lib/einvoice/decimal.ts
|
|
8049
8134
|
function decimalText(value) {
|
|
8050
8135
|
if (typeof value === "string") {
|
|
8051
|
-
const
|
|
8052
|
-
return /^-?\d+(\.\d+)?$/.test(
|
|
8136
|
+
const text5 = value.trim();
|
|
8137
|
+
return /^-?\d+(\.\d+)?$/.test(text5) ? trimZeros(text5) : null;
|
|
8053
8138
|
}
|
|
8054
8139
|
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
8055
|
-
const
|
|
8056
|
-
return /^-?\d+(\.\d+)?$/.test(
|
|
8140
|
+
const text4 = value.toPrecision(15);
|
|
8141
|
+
return /^-?\d+(\.\d+)?$/.test(text4) ? trimZeros(text4) : null;
|
|
8057
8142
|
}
|
|
8058
|
-
function trimZeros(
|
|
8059
|
-
const trimmed =
|
|
8143
|
+
function trimZeros(text4) {
|
|
8144
|
+
const trimmed = text4.includes(".") ? text4.replace(/0+$/, "").replace(/\.$/, "") : text4;
|
|
8060
8145
|
return trimmed === "-0" ? "0" : trimmed;
|
|
8061
8146
|
}
|
|
8062
|
-
function decimalPlaces(
|
|
8063
|
-
const dot =
|
|
8064
|
-
return dot === -1 ? 0 :
|
|
8147
|
+
function decimalPlaces(text4) {
|
|
8148
|
+
const dot = text4.indexOf(".");
|
|
8149
|
+
return dot === -1 ? 0 : text4.length - dot - 1;
|
|
8065
8150
|
}
|
|
8066
|
-
function toUnits(
|
|
8067
|
-
const negative =
|
|
8068
|
-
const [whole = "0", fraction = ""] = (negative ?
|
|
8151
|
+
function toUnits(text4, scale) {
|
|
8152
|
+
const negative = text4.startsWith("-");
|
|
8153
|
+
const [whole = "0", fraction = ""] = (negative ? text4.slice(1) : text4).split(
|
|
8069
8154
|
"."
|
|
8070
8155
|
);
|
|
8071
8156
|
const units = BigInt(whole + fraction.padEnd(scale, "0").slice(0, scale));
|
|
@@ -8076,13 +8161,13 @@ function fromUnits(units, scale, places = scale) {
|
|
|
8076
8161
|
const digits = (negative ? -units : units).toString().padStart(scale + 1, "0");
|
|
8077
8162
|
const whole = digits.slice(0, digits.length - scale);
|
|
8078
8163
|
const fraction = digits.slice(digits.length - scale).padEnd(places, "0");
|
|
8079
|
-
const
|
|
8080
|
-
return negative && /[1-9]/.test(
|
|
8164
|
+
const text4 = places > 0 ? `${whole}.${fraction.slice(0, places)}` : whole;
|
|
8165
|
+
return negative && /[1-9]/.test(text4) ? `-${text4}` : text4;
|
|
8081
8166
|
}
|
|
8082
|
-
function withPlaces(
|
|
8083
|
-
const places = decimalPlaces(
|
|
8084
|
-
if (places >= min) return
|
|
8085
|
-
return places === 0 ? `${
|
|
8167
|
+
function withPlaces(text4, min) {
|
|
8168
|
+
const places = decimalPlaces(text4);
|
|
8169
|
+
if (places >= min) return text4;
|
|
8170
|
+
return places === 0 ? `${text4}.${"0".repeat(min)}` : text4 + "0".repeat(min - places);
|
|
8086
8171
|
}
|
|
8087
8172
|
function divideRounded(value, divisor) {
|
|
8088
8173
|
const negative = value < 0n !== divisor < 0n;
|
|
@@ -8504,37 +8589,37 @@ function valueAt(data, path) {
|
|
|
8504
8589
|
}
|
|
8505
8590
|
function normalise(input, add2, options) {
|
|
8506
8591
|
const amount2 = (value, path) => {
|
|
8507
|
-
const
|
|
8508
|
-
if (
|
|
8592
|
+
const text4 = decimalText(value);
|
|
8593
|
+
if (text4 === null) {
|
|
8509
8594
|
add2("not_a_number", path, `_invoice.${path} is not a number`);
|
|
8510
8595
|
return "0";
|
|
8511
8596
|
}
|
|
8512
|
-
if (decimalPlaces(
|
|
8597
|
+
if (decimalPlaces(text4) > 2) {
|
|
8513
8598
|
add2(
|
|
8514
8599
|
"decimals",
|
|
8515
8600
|
path,
|
|
8516
8601
|
`_invoice.${path} has more than 2 decimals; an amount of the invoice is exact to the cent`,
|
|
8517
8602
|
{
|
|
8518
|
-
args: { max: 2, value:
|
|
8603
|
+
args: { max: 2, value: text4 }
|
|
8519
8604
|
}
|
|
8520
8605
|
);
|
|
8521
8606
|
return "0";
|
|
8522
8607
|
}
|
|
8523
|
-
return
|
|
8608
|
+
return text4;
|
|
8524
8609
|
};
|
|
8525
8610
|
const number = (value, path, max2) => {
|
|
8526
|
-
const
|
|
8527
|
-
if (
|
|
8611
|
+
const text4 = decimalText(value);
|
|
8612
|
+
if (text4 === null) {
|
|
8528
8613
|
add2("not_a_number", path, `_invoice.${path} is not a number`);
|
|
8529
8614
|
return "0";
|
|
8530
8615
|
}
|
|
8531
|
-
if (decimalPlaces(
|
|
8616
|
+
if (decimalPlaces(text4) > max2) {
|
|
8532
8617
|
add2("decimals", path, `_invoice.${path} has more than ${max2} decimals`, {
|
|
8533
|
-
args: { max: max2, value:
|
|
8618
|
+
args: { max: max2, value: text4 }
|
|
8534
8619
|
});
|
|
8535
8620
|
return "0";
|
|
8536
8621
|
}
|
|
8537
|
-
return
|
|
8622
|
+
return text4;
|
|
8538
8623
|
};
|
|
8539
8624
|
const optionalAmount = (value, path) => value === void 0 ? void 0 : amount2(value, path);
|
|
8540
8625
|
const date2 = (value, path) => {
|
|
@@ -8912,7 +8997,7 @@ function defined(value) {
|
|
|
8912
8997
|
Object.entries(value).filter(([, v]) => v !== void 0)
|
|
8913
8998
|
);
|
|
8914
8999
|
}
|
|
8915
|
-
var cents = (
|
|
9000
|
+
var cents = (text4) => text4 === void 0 ? 0n : toUnits(text4, 2);
|
|
8916
9001
|
var money = (value) => fromUnits(value, 2);
|
|
8917
9002
|
var rateKey = (tax) => `${tax.category}|${tax.rate ?? ""}`;
|
|
8918
9003
|
function rules(invoice, add2) {
|
|
@@ -9372,14 +9457,14 @@ var CII_GUIDELINES = {
|
|
|
9372
9457
|
en16931: "urn:cen.eu:en16931:2017"
|
|
9373
9458
|
};
|
|
9374
9459
|
var EINVOICE_XML_NAME = "factur-x.xml";
|
|
9375
|
-
function leaf(name,
|
|
9376
|
-
if (
|
|
9460
|
+
function leaf(name, text4, attributes) {
|
|
9461
|
+
if (text4 === void 0 || text4 === "") return void 0;
|
|
9377
9462
|
const kept = Object.entries(attributes ?? {}).filter(
|
|
9378
9463
|
(entry) => entry[1] !== void 0
|
|
9379
9464
|
);
|
|
9380
9465
|
return {
|
|
9381
9466
|
name,
|
|
9382
|
-
text:
|
|
9467
|
+
text: text4,
|
|
9383
9468
|
...kept.length > 0 ? { attributes: Object.fromEntries(kept) } : {}
|
|
9384
9469
|
};
|
|
9385
9470
|
}
|
|
@@ -9636,14 +9721,14 @@ function invoiceToCii(invoice, options) {
|
|
|
9636
9721
|
${serialise(root, 0)}`;
|
|
9637
9722
|
}
|
|
9638
9723
|
var xmlCharacter = (code) => code === 9 || code === 10 || code === 13 || code >= 32 && !(code >= 55296 && code <= 57343) && code !== 65534 && code !== 65535;
|
|
9639
|
-
function carried(
|
|
9724
|
+
function carried(text4) {
|
|
9640
9725
|
let out = "";
|
|
9641
|
-
for (const character of
|
|
9726
|
+
for (const character of text4)
|
|
9642
9727
|
if (xmlCharacter(character.codePointAt(0) ?? 0)) out += character;
|
|
9643
9728
|
return out;
|
|
9644
9729
|
}
|
|
9645
|
-
var escapeText2 = (
|
|
9646
|
-
var escapeAttribute2 = (
|
|
9730
|
+
var escapeText2 = (text4) => carried(text4).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
9731
|
+
var escapeAttribute2 = (text4) => escapeText2(text4).replace(/"/g, """);
|
|
9647
9732
|
function serialise(element, depth) {
|
|
9648
9733
|
const indent = " ".repeat(depth);
|
|
9649
9734
|
const attributes = Object.entries(element.attributes ?? {}).map(([name, value]) => ` ${name}="${escapeAttribute2(value)}"`).join("");
|
|
@@ -9677,7 +9762,7 @@ var DASHES = /* @__PURE__ */ new Set([45, 8208, 8209, 8210, 8211, 8722]);
|
|
|
9677
9762
|
var INVISIBLE = /* @__PURE__ */ new Set([173, 8203, 8204, 8205, 8288, 65279]);
|
|
9678
9763
|
var isDigit = (code) => code >= DIGIT_0 && code <= DIGIT_9;
|
|
9679
9764
|
var MAX_GROUPS = 6;
|
|
9680
|
-
function shownAmounts(
|
|
9765
|
+
function shownAmounts(text4) {
|
|
9681
9766
|
const found = /* @__PURE__ */ new Set();
|
|
9682
9767
|
let run2 = "";
|
|
9683
9768
|
const flush = () => {
|
|
@@ -9701,7 +9786,7 @@ function shownAmounts(text3) {
|
|
|
9701
9786
|
}
|
|
9702
9787
|
}
|
|
9703
9788
|
};
|
|
9704
|
-
for (const character of
|
|
9789
|
+
for (const character of text4) {
|
|
9705
9790
|
const code = character.codePointAt(0) ?? 0;
|
|
9706
9791
|
if (INVISIBLE.has(code)) continue;
|
|
9707
9792
|
if (isDigit(code)) run2 += character;
|
|
@@ -9741,9 +9826,9 @@ function toCents(whole, fraction) {
|
|
|
9741
9826
|
if (whole.length > 18 || /[1-9]/.test(fraction.slice(2))) return null;
|
|
9742
9827
|
return BigInt(whole) * 100n + BigInt((fraction + "00").slice(0, 2));
|
|
9743
9828
|
}
|
|
9744
|
-
function squeeze(
|
|
9829
|
+
function squeeze(text4) {
|
|
9745
9830
|
let out = "";
|
|
9746
|
-
for (const character of
|
|
9831
|
+
for (const character of text4) {
|
|
9747
9832
|
const code = character.codePointAt(0) ?? 0;
|
|
9748
9833
|
if (INVISIBLE.has(code) || /\s/.test(character) || SPACES.has(code))
|
|
9749
9834
|
continue;
|
|
@@ -9751,8 +9836,8 @@ function squeeze(text3) {
|
|
|
9751
9836
|
}
|
|
9752
9837
|
return out;
|
|
9753
9838
|
}
|
|
9754
|
-
function displayCheck(
|
|
9755
|
-
const whole = typeof
|
|
9839
|
+
function displayCheck(text4, invoice) {
|
|
9840
|
+
const whole = typeof text4 === "string" ? text4 : text4.join("\n");
|
|
9756
9841
|
const amounts = shownAmounts(whole);
|
|
9757
9842
|
const squeezed = squeeze(whole);
|
|
9758
9843
|
const values = [];
|
|
@@ -9818,97 +9903,97 @@ function invoicePathSegments(path) {
|
|
|
9818
9903
|
}
|
|
9819
9904
|
return segments;
|
|
9820
9905
|
}
|
|
9821
|
-
function locateJsonPath(
|
|
9822
|
-
let offset = skipSpace(
|
|
9823
|
-
if (offset >=
|
|
9906
|
+
function locateJsonPath(text4, path) {
|
|
9907
|
+
let offset = skipSpace(text4, 0);
|
|
9908
|
+
if (offset >= text4.length) return null;
|
|
9824
9909
|
let best = { offset, depth: 0 };
|
|
9825
9910
|
try {
|
|
9826
9911
|
for (let depth = 0; depth < path.length; depth += 1) {
|
|
9827
9912
|
const segment = path[depth];
|
|
9828
|
-
const found = typeof segment === "number" ? arrayItem(
|
|
9913
|
+
const found = typeof segment === "number" ? arrayItem(text4, offset, segment) : objectMember(text4, offset, String(segment));
|
|
9829
9914
|
if (!found) break;
|
|
9830
9915
|
best = { offset: found.at, depth: depth + 1 };
|
|
9831
9916
|
offset = found.value;
|
|
9832
9917
|
}
|
|
9833
9918
|
} catch {
|
|
9834
9919
|
}
|
|
9835
|
-
return { ...positionAt(
|
|
9920
|
+
return { ...positionAt(text4, best.offset), depth: best.depth };
|
|
9836
9921
|
}
|
|
9837
|
-
function positionAt(
|
|
9922
|
+
function positionAt(text4, offset) {
|
|
9838
9923
|
let line2 = 1;
|
|
9839
9924
|
let lineStart = 0;
|
|
9840
9925
|
for (let i = 0; i < offset; i += 1)
|
|
9841
|
-
if (
|
|
9926
|
+
if (text4.charCodeAt(i) === 10) {
|
|
9842
9927
|
line2 += 1;
|
|
9843
9928
|
lineStart = i + 1;
|
|
9844
9929
|
}
|
|
9845
9930
|
return { line: line2, column: offset - lineStart + 1 };
|
|
9846
9931
|
}
|
|
9847
|
-
function skipSpace(
|
|
9932
|
+
function skipSpace(text4, from) {
|
|
9848
9933
|
let i = from;
|
|
9849
|
-
while (i <
|
|
9934
|
+
while (i < text4.length && /\s/.test(text4[i] ?? "")) i += 1;
|
|
9850
9935
|
return i;
|
|
9851
9936
|
}
|
|
9852
|
-
function stringEnd(
|
|
9853
|
-
if (
|
|
9854
|
-
for (let i = from + 1; i <
|
|
9855
|
-
if (
|
|
9856
|
-
else if (
|
|
9937
|
+
function stringEnd(text4, from) {
|
|
9938
|
+
if (text4[from] !== '"') throw new Error("string");
|
|
9939
|
+
for (let i = from + 1; i < text4.length; i += 1) {
|
|
9940
|
+
if (text4[i] === "\\") i += 1;
|
|
9941
|
+
else if (text4[i] === '"') return i + 1;
|
|
9857
9942
|
}
|
|
9858
9943
|
throw new Error("string");
|
|
9859
9944
|
}
|
|
9860
|
-
function valueEnd(
|
|
9861
|
-
const start = skipSpace(
|
|
9862
|
-
const first =
|
|
9863
|
-
if (first === '"') return stringEnd(
|
|
9945
|
+
function valueEnd(text4, from) {
|
|
9946
|
+
const start = skipSpace(text4, from);
|
|
9947
|
+
const first = text4[start];
|
|
9948
|
+
if (first === '"') return stringEnd(text4, start);
|
|
9864
9949
|
if (first === "{" || first === "[") {
|
|
9865
9950
|
const close = first === "{" ? "}" : "]";
|
|
9866
|
-
let i2 = skipSpace(
|
|
9867
|
-
if (
|
|
9951
|
+
let i2 = skipSpace(text4, start + 1);
|
|
9952
|
+
if (text4[i2] === close) return i2 + 1;
|
|
9868
9953
|
for (; ; ) {
|
|
9869
9954
|
if (first === "{") {
|
|
9870
|
-
i2 = skipSpace(
|
|
9871
|
-
if (
|
|
9955
|
+
i2 = skipSpace(text4, stringEnd(text4, skipSpace(text4, i2)));
|
|
9956
|
+
if (text4[i2] !== ":") throw new Error("colon");
|
|
9872
9957
|
i2 += 1;
|
|
9873
9958
|
}
|
|
9874
|
-
i2 = skipSpace(
|
|
9875
|
-
if (
|
|
9876
|
-
if (
|
|
9959
|
+
i2 = skipSpace(text4, valueEnd(text4, i2));
|
|
9960
|
+
if (text4[i2] === close) return i2 + 1;
|
|
9961
|
+
if (text4[i2] !== ",") throw new Error("comma");
|
|
9877
9962
|
i2 += 1;
|
|
9878
9963
|
}
|
|
9879
9964
|
}
|
|
9880
9965
|
let i = start;
|
|
9881
|
-
while (i <
|
|
9966
|
+
while (i < text4.length && !/[\s,\]}]/.test(text4[i] ?? "")) i += 1;
|
|
9882
9967
|
if (i === start) throw new Error("value");
|
|
9883
9968
|
return i;
|
|
9884
9969
|
}
|
|
9885
|
-
function objectMember(
|
|
9886
|
-
const start = skipSpace(
|
|
9887
|
-
if (
|
|
9888
|
-
let i = skipSpace(
|
|
9889
|
-
while (
|
|
9890
|
-
const at = skipSpace(
|
|
9891
|
-
const end = stringEnd(
|
|
9892
|
-
const colon = skipSpace(
|
|
9893
|
-
if (
|
|
9894
|
-
const value = skipSpace(
|
|
9895
|
-
if (JSON.parse(
|
|
9896
|
-
i = skipSpace(
|
|
9897
|
-
if (
|
|
9898
|
-
else if (
|
|
9970
|
+
function objectMember(text4, from, key) {
|
|
9971
|
+
const start = skipSpace(text4, from);
|
|
9972
|
+
if (text4[start] !== "{") return null;
|
|
9973
|
+
let i = skipSpace(text4, start + 1);
|
|
9974
|
+
while (text4[i] !== "}") {
|
|
9975
|
+
const at = skipSpace(text4, i);
|
|
9976
|
+
const end = stringEnd(text4, at);
|
|
9977
|
+
const colon = skipSpace(text4, end);
|
|
9978
|
+
if (text4[colon] !== ":") throw new Error("colon");
|
|
9979
|
+
const value = skipSpace(text4, colon + 1);
|
|
9980
|
+
if (JSON.parse(text4.slice(at, end)) === key) return { at, value };
|
|
9981
|
+
i = skipSpace(text4, valueEnd(text4, value));
|
|
9982
|
+
if (text4[i] === ",") i = skipSpace(text4, i + 1);
|
|
9983
|
+
else if (text4[i] !== "}") throw new Error("comma");
|
|
9899
9984
|
}
|
|
9900
9985
|
return null;
|
|
9901
9986
|
}
|
|
9902
|
-
function arrayItem(
|
|
9903
|
-
const start = skipSpace(
|
|
9904
|
-
if (
|
|
9905
|
-
let i = skipSpace(
|
|
9906
|
-
for (let n = 0;
|
|
9907
|
-
const at = skipSpace(
|
|
9987
|
+
function arrayItem(text4, from, index) {
|
|
9988
|
+
const start = skipSpace(text4, from);
|
|
9989
|
+
if (text4[start] !== "[") return null;
|
|
9990
|
+
let i = skipSpace(text4, start + 1);
|
|
9991
|
+
for (let n = 0; text4[i] !== "]"; n += 1) {
|
|
9992
|
+
const at = skipSpace(text4, i);
|
|
9908
9993
|
if (n === index) return { at, value: at };
|
|
9909
|
-
i = skipSpace(
|
|
9910
|
-
if (
|
|
9911
|
-
else if (
|
|
9994
|
+
i = skipSpace(text4, valueEnd(text4, at));
|
|
9995
|
+
if (text4[i] === ",") i = skipSpace(text4, i + 1);
|
|
9996
|
+
else if (text4[i] !== "]") throw new Error("comma");
|
|
9912
9997
|
}
|
|
9913
9998
|
return null;
|
|
9914
9999
|
}
|
|
@@ -10021,8 +10106,8 @@ var ENTITIES = {
|
|
|
10021
10106
|
agrave: 224,
|
|
10022
10107
|
ccedil: 231
|
|
10023
10108
|
};
|
|
10024
|
-
function decodeEntities(
|
|
10025
|
-
return
|
|
10109
|
+
function decodeEntities(text4) {
|
|
10110
|
+
return text4.replace(
|
|
10026
10111
|
/&(#x[0-9a-f]+|#\d+|[a-z][a-z0-9]*);/gi,
|
|
10027
10112
|
(whole, reference) => {
|
|
10028
10113
|
const code = reference.startsWith("#") ? reference[1] === "x" || reference[1] === "X" ? Number.parseInt(reference.slice(2), 16) : Number.parseInt(reference.slice(1), 10) : ENTITIES[reference];
|
|
@@ -10148,6 +10233,320 @@ function einvoiceXml(data, options) {
|
|
|
10148
10233
|
};
|
|
10149
10234
|
}
|
|
10150
10235
|
|
|
10236
|
+
// packages/engine/src/lib/accessibility/index.ts
|
|
10237
|
+
var PDFUA_STANDARD = "PDF/UA-1";
|
|
10238
|
+
var UA_CHECKS = ["strict", "report"];
|
|
10239
|
+
function resolveUa(setting) {
|
|
10240
|
+
if (setting === true) return { check: "strict" };
|
|
10241
|
+
if (!setting || typeof setting !== "object" || Array.isArray(setting))
|
|
10242
|
+
return null;
|
|
10243
|
+
const check = setting.check;
|
|
10244
|
+
return { check: check === "report" ? "report" : "strict" };
|
|
10245
|
+
}
|
|
10246
|
+
var UA_REFUSALS = {
|
|
10247
|
+
office: "pdf.ua is not available for Word and PowerPoint templates yet",
|
|
10248
|
+
merge: "pdf.ua cannot be combined with post.merge_after: the tags of merged documents do not survive the merge"
|
|
10249
|
+
};
|
|
10250
|
+
function isUaSetting(value) {
|
|
10251
|
+
if (value === null || typeof value === "boolean") return true;
|
|
10252
|
+
if (typeof value !== "object" || Array.isArray(value)) return false;
|
|
10253
|
+
const entries = Object.entries(value);
|
|
10254
|
+
return entries.every(
|
|
10255
|
+
([key, entry]) => key === "check" && UA_CHECKS.includes(entry)
|
|
10256
|
+
);
|
|
10257
|
+
}
|
|
10258
|
+
var AUDIT_CODES = [
|
|
10259
|
+
"document-title",
|
|
10260
|
+
"image-alt",
|
|
10261
|
+
"figure-name",
|
|
10262
|
+
"heading-order",
|
|
10263
|
+
"table-rows",
|
|
10264
|
+
"table-cell-empty",
|
|
10265
|
+
"masked-text",
|
|
10266
|
+
"filtered-text",
|
|
10267
|
+
"document-language",
|
|
10268
|
+
"table-headers",
|
|
10269
|
+
"link-name",
|
|
10270
|
+
"generated-text",
|
|
10271
|
+
"fixed-text",
|
|
10272
|
+
"running-text"
|
|
10273
|
+
];
|
|
10274
|
+
var AUDIT_SEVERITY = {
|
|
10275
|
+
"document-title": "error",
|
|
10276
|
+
"image-alt": "error",
|
|
10277
|
+
"figure-name": "error",
|
|
10278
|
+
"heading-order": "error",
|
|
10279
|
+
"table-rows": "error",
|
|
10280
|
+
"table-cell-empty": "error",
|
|
10281
|
+
"masked-text": "error",
|
|
10282
|
+
"filtered-text": "warning",
|
|
10283
|
+
"document-language": "warning",
|
|
10284
|
+
"table-headers": "warning",
|
|
10285
|
+
"link-name": "warning",
|
|
10286
|
+
"generated-text": "warning",
|
|
10287
|
+
"fixed-text": "warning",
|
|
10288
|
+
"running-text": "warning"
|
|
10289
|
+
};
|
|
10290
|
+
var AUDIT_RULES = {
|
|
10291
|
+
"document-title": ["7.1-9", "7.1-10"],
|
|
10292
|
+
"image-alt": ["7.3-1"],
|
|
10293
|
+
"figure-name": ["7.3-1"],
|
|
10294
|
+
"heading-order": ["7.4.2-1"],
|
|
10295
|
+
"table-rows": ["7.2-43"],
|
|
10296
|
+
"table-cell-empty": ["7.2-43"],
|
|
10297
|
+
"masked-text": ["7.20-2"],
|
|
10298
|
+
"filtered-text": [],
|
|
10299
|
+
"document-language": [],
|
|
10300
|
+
"table-headers": [],
|
|
10301
|
+
"link-name": [],
|
|
10302
|
+
"generated-text": [],
|
|
10303
|
+
"fixed-text": [],
|
|
10304
|
+
"running-text": []
|
|
10305
|
+
};
|
|
10306
|
+
var AUDIT_TITLES = {
|
|
10307
|
+
"document-title": "No document title",
|
|
10308
|
+
"image-alt": "Image without an alt attribute",
|
|
10309
|
+
"figure-name": "Figure without a name",
|
|
10310
|
+
"heading-order": "Heading level skipped",
|
|
10311
|
+
"table-rows": "Table rows of different lengths",
|
|
10312
|
+
"table-cell-empty": "Empty table cell",
|
|
10313
|
+
"masked-text": "Text under a CSS mask",
|
|
10314
|
+
"filtered-text": "Text under a CSS filter",
|
|
10315
|
+
"document-language": "No language stated",
|
|
10316
|
+
"table-headers": "Table without header cells",
|
|
10317
|
+
"link-name": "Link without a name",
|
|
10318
|
+
"generated-text": "Text generated by CSS",
|
|
10319
|
+
"fixed-text": "Fixed text on every page",
|
|
10320
|
+
"running-text": "Only in the header or footer"
|
|
10321
|
+
};
|
|
10322
|
+
var AUDIT_SNIPPET_LENGTH = 120;
|
|
10323
|
+
var text3 = (value) => String(value ?? "");
|
|
10324
|
+
function auditMessage(finding2) {
|
|
10325
|
+
const args = finding2.args;
|
|
10326
|
+
switch (finding2.code) {
|
|
10327
|
+
case "document-title":
|
|
10328
|
+
return "The document has no title. A PDF viewer shows the title in its title bar and a screen reader says it first: set pdf.metadata.title, or give the page a <title>.";
|
|
10329
|
+
case "image-alt":
|
|
10330
|
+
return 'The image has no alt attribute. Say what it shows, or write alt="" if it is decoration.';
|
|
10331
|
+
case "figure-name":
|
|
10332
|
+
return `The ${text3(args["tag"])} has no text alternative. Give it an aria-label that says what it shows; the chart helper takes alt.`;
|
|
10333
|
+
case "heading-order":
|
|
10334
|
+
return args["previous"] === 0 ? `The first heading is an h${text3(args["level"])}. Start with an h1 and size it with CSS.` : `This h${text3(args["level"])} follows an h${text3(args["previous"])}, so a heading level is skipped. Make it an h${Number(args["previous"]) + 1} and size it with CSS.`;
|
|
10335
|
+
case "table-rows":
|
|
10336
|
+
return `The rows of this table span different numbers of columns (${text3(args["first"])} and ${text3(args["other"])}). Even them out with colspan.`;
|
|
10337
|
+
case "table-cell-empty":
|
|
10338
|
+
return Number(args["count"]) > 1 ? `${text3(args["count"])} cells of this table are empty. Chromium writes no cell for an empty td, so their rows come out shorter than the others: put a non-breaking space ( ) or a dash into each.` : "This table cell is empty. Chromium writes no cell for an empty td, so its row comes out shorter than the others: put a non-breaking space ( ) or a dash into it.";
|
|
10339
|
+
case "masked-text":
|
|
10340
|
+
return "This element has a CSS mask and holds text. Chromium then writes the text in a way PDF/UA-1 does not allow, and no repair reaches it: mask an element without text instead.";
|
|
10341
|
+
case "filtered-text":
|
|
10342
|
+
return "This element has a CSS filter and holds text. The filter turns the text into a picture, which nobody can have read out or select.";
|
|
10343
|
+
case "document-language":
|
|
10344
|
+
return "The document names no language. Set lang on the html element, or the locale in the settings.";
|
|
10345
|
+
case "table-headers":
|
|
10346
|
+
return "The table has no header cells. Use th for the titles of its columns or rows, or a screen reader says the cells without them.";
|
|
10347
|
+
case "link-name":
|
|
10348
|
+
return "The link has no text. A screen reader says its address instead: give it text, an aria-label, or an image with alt.";
|
|
10349
|
+
case "generated-text":
|
|
10350
|
+
return `\u201C${text3(args["text"])}\u201D comes from CSS (::before or ::after). Generated text is not read out: write it into the template.`;
|
|
10351
|
+
case "fixed-text":
|
|
10352
|
+
return "This element is position: fixed, so it is printed on every page and read once per page, one after the other.";
|
|
10353
|
+
case "running-text":
|
|
10354
|
+
return `\u201C${text3(args["text"])}\u201D stands only in the ${text3(args["part"])}. A screen reader skips page headers and footers, so say it in the body too.`;
|
|
10355
|
+
}
|
|
10356
|
+
}
|
|
10357
|
+
var ACCESSIBILITY_MAX_FAILURES = 20;
|
|
10358
|
+
var ACCESSIBILITY_MAX_ELEMENTS = 5;
|
|
10359
|
+
var elementOf = (finding2) => finding2.code === "running-text" || finding2.code === "generated-text" ? text3(finding2.args["text"]) : finding2.snippet;
|
|
10360
|
+
function accessibilityResult(options, verdict, findings) {
|
|
10361
|
+
const failures = verdict.failures.map((failure) => {
|
|
10362
|
+
const about = findings.filter(
|
|
10363
|
+
(finding2) => AUDIT_RULES[finding2.code].includes(failure.rule)
|
|
10364
|
+
);
|
|
10365
|
+
const first = about[0];
|
|
10366
|
+
return {
|
|
10367
|
+
rule: failure.rule,
|
|
10368
|
+
...first ? { code: first.code } : {},
|
|
10369
|
+
count: failure.checks,
|
|
10370
|
+
message: first ? auditMessage(first) : failure.description.replace(/\s+/g, " ").trim(),
|
|
10371
|
+
elements: [...new Set(about.map(elementOf).filter(Boolean))].slice(
|
|
10372
|
+
0,
|
|
10373
|
+
ACCESSIBILITY_MAX_ELEMENTS
|
|
10374
|
+
)
|
|
10375
|
+
};
|
|
10376
|
+
});
|
|
10377
|
+
const warnings = [];
|
|
10378
|
+
for (const finding2 of findings) {
|
|
10379
|
+
if (finding2.severity !== "warning") continue;
|
|
10380
|
+
let warning = warnings.find((entry) => entry.code === finding2.code);
|
|
10381
|
+
if (!warning)
|
|
10382
|
+
warnings.push(warning = { code: finding2.code, count: 0, elements: [] });
|
|
10383
|
+
warning.count++;
|
|
10384
|
+
const element = elementOf(finding2);
|
|
10385
|
+
if (element && warning.elements.length < ACCESSIBILITY_MAX_ELEMENTS && !warning.elements.includes(element))
|
|
10386
|
+
warning.elements.push(element);
|
|
10387
|
+
}
|
|
10388
|
+
return {
|
|
10389
|
+
standard: PDFUA_STANDARD,
|
|
10390
|
+
check: options.check,
|
|
10391
|
+
conformant: verdict.compliant,
|
|
10392
|
+
validator: verdict.validator,
|
|
10393
|
+
rules: verdict.rules,
|
|
10394
|
+
failures: failures.slice(0, ACCESSIBILITY_MAX_FAILURES),
|
|
10395
|
+
warnings,
|
|
10396
|
+
...failures.length > ACCESSIBILITY_MAX_FAILURES ? { truncated: true } : {}
|
|
10397
|
+
};
|
|
10398
|
+
}
|
|
10399
|
+
function accessibilityHeader(result) {
|
|
10400
|
+
return result.conformant ? "conformant" : "not-conformant";
|
|
10401
|
+
}
|
|
10402
|
+
var ACCESSIBILITY_HEADER_LENGTH = 8e3;
|
|
10403
|
+
function accessibilityHeaderValue(result, limit = ACCESSIBILITY_HEADER_LENGTH) {
|
|
10404
|
+
const encode = (report2) => encodeURIComponent(JSON.stringify(report2));
|
|
10405
|
+
const keep = (report2, elements) => ({
|
|
10406
|
+
...report2,
|
|
10407
|
+
truncated: true,
|
|
10408
|
+
failures: report2.failures.map((failure) => ({
|
|
10409
|
+
...failure,
|
|
10410
|
+
elements: failure.elements.slice(0, elements)
|
|
10411
|
+
})),
|
|
10412
|
+
warnings: report2.warnings.map((warning) => ({
|
|
10413
|
+
...warning,
|
|
10414
|
+
elements: warning.elements.slice(0, elements)
|
|
10415
|
+
}))
|
|
10416
|
+
});
|
|
10417
|
+
let value = encode(result);
|
|
10418
|
+
if (value.length <= limit) return value;
|
|
10419
|
+
for (const elements of [1, 0]) {
|
|
10420
|
+
value = encode(keep(result, elements));
|
|
10421
|
+
if (value.length <= limit) return value;
|
|
10422
|
+
}
|
|
10423
|
+
let report = keep(result, 0);
|
|
10424
|
+
while (report.failures.length + report.warnings.length > 0) {
|
|
10425
|
+
report = report.warnings.length ? { ...report, warnings: report.warnings.slice(0, -1) } : { ...report, failures: report.failures.slice(0, -1) };
|
|
10426
|
+
value = encode(report);
|
|
10427
|
+
if (value.length <= limit) return value;
|
|
10428
|
+
}
|
|
10429
|
+
return value;
|
|
10430
|
+
}
|
|
10431
|
+
|
|
10432
|
+
// packages/engine/src/lib/accessibility/static.ts
|
|
10433
|
+
var finding = (code, src, snippet) => ({
|
|
10434
|
+
code,
|
|
10435
|
+
severity: AUDIT_SEVERITY[code],
|
|
10436
|
+
src,
|
|
10437
|
+
snippet,
|
|
10438
|
+
args: {}
|
|
10439
|
+
});
|
|
10440
|
+
var NAMING = /* @__PURE__ */ new Set(["alt", "aria-label", "aria-labelledby", "title"]);
|
|
10441
|
+
function imageIsNamed(attributes, scanner, base) {
|
|
10442
|
+
const n = attributes.length;
|
|
10443
|
+
let i = 0;
|
|
10444
|
+
let named = false;
|
|
10445
|
+
while (i < n) {
|
|
10446
|
+
const ch = attributes[i];
|
|
10447
|
+
if (/[\s/>]/.test(ch)) {
|
|
10448
|
+
i++;
|
|
10449
|
+
continue;
|
|
10450
|
+
}
|
|
10451
|
+
if (ch === "{" && scanner.skipTemplate(base + i) !== null) return null;
|
|
10452
|
+
const start = i;
|
|
10453
|
+
while (i < n && !/[\s=/>]/.test(attributes[i])) i++;
|
|
10454
|
+
const name = attributes.slice(start, i).toLowerCase();
|
|
10455
|
+
while (i < n && /\s/.test(attributes[i])) i++;
|
|
10456
|
+
let value = "";
|
|
10457
|
+
if (attributes[i] === "=") {
|
|
10458
|
+
i++;
|
|
10459
|
+
while (i < n && /\s/.test(attributes[i])) i++;
|
|
10460
|
+
const quote2 = attributes[i];
|
|
10461
|
+
if (quote2 === '"' || quote2 === "'") {
|
|
10462
|
+
const end = scanner.skipTo(base + i + 1, quote2) - base;
|
|
10463
|
+
value = attributes.slice(i + 1, Math.max(i + 1, end - 1));
|
|
10464
|
+
i = end;
|
|
10465
|
+
} else {
|
|
10466
|
+
const from = i;
|
|
10467
|
+
while (i < n && !/[\s>]/.test(attributes[i])) i++;
|
|
10468
|
+
value = attributes.slice(from, i);
|
|
10469
|
+
}
|
|
10470
|
+
}
|
|
10471
|
+
if (NAMING.has(name)) named = true;
|
|
10472
|
+
else if (name === "aria-hidden" && value.trim() !== "false") named = true;
|
|
10473
|
+
else if (name === "role" && /^(presentation|none)$/.test(value.trim()))
|
|
10474
|
+
named = true;
|
|
10475
|
+
}
|
|
10476
|
+
return named;
|
|
10477
|
+
}
|
|
10478
|
+
function staticAuditDiagnostics(input, ua) {
|
|
10479
|
+
return staticAudit(input).map((found) => {
|
|
10480
|
+
const at = /^body:(\d+):(\d+)$/.exec(found.src ?? "");
|
|
10481
|
+
return {
|
|
10482
|
+
severity: found.severity === "error" && ua.check === "strict" ? "error" : "warning",
|
|
10483
|
+
code: `accessibility-${found.code}`,
|
|
10484
|
+
message: auditMessage(found),
|
|
10485
|
+
...at ? { location: { line: Number(at[1]), column: Number(at[2]) } } : {}
|
|
10486
|
+
};
|
|
10487
|
+
});
|
|
10488
|
+
}
|
|
10489
|
+
function staticAudit(input) {
|
|
10490
|
+
const findings = [];
|
|
10491
|
+
if (!input.title?.trim() && !/<title[\s>]/i.test(input.head ?? ""))
|
|
10492
|
+
findings.push(finding("document-title", null, ""));
|
|
10493
|
+
const source = input.html;
|
|
10494
|
+
const scanner = new Scanner(source, input.engine);
|
|
10495
|
+
const lines = lineStarts(source);
|
|
10496
|
+
const n = source.length;
|
|
10497
|
+
let i = 0;
|
|
10498
|
+
while (i < n) {
|
|
10499
|
+
const ch = source[i];
|
|
10500
|
+
if (ch === "{") {
|
|
10501
|
+
i = scanner.skipTemplate(i) ?? i + 1;
|
|
10502
|
+
continue;
|
|
10503
|
+
}
|
|
10504
|
+
if (ch !== "<") {
|
|
10505
|
+
i++;
|
|
10506
|
+
continue;
|
|
10507
|
+
}
|
|
10508
|
+
if (source.startsWith("<!--", i)) {
|
|
10509
|
+
i = scanner.skipTo(i + 4, "-->");
|
|
10510
|
+
continue;
|
|
10511
|
+
}
|
|
10512
|
+
const next = source[i + 1];
|
|
10513
|
+
if (next === "!" || next === "?") {
|
|
10514
|
+
i = scanner.tagEnd(i + 2);
|
|
10515
|
+
continue;
|
|
10516
|
+
}
|
|
10517
|
+
if (next === "/") {
|
|
10518
|
+
i += 2;
|
|
10519
|
+
continue;
|
|
10520
|
+
}
|
|
10521
|
+
tagName.lastIndex = i + 1;
|
|
10522
|
+
const name = tagName.exec(source)?.[0];
|
|
10523
|
+
if (!name) {
|
|
10524
|
+
i++;
|
|
10525
|
+
continue;
|
|
10526
|
+
}
|
|
10527
|
+
const nameEnd = i + 1 + name.length;
|
|
10528
|
+
const end = scanner.tagEnd(nameEnd);
|
|
10529
|
+
if (name.toLowerCase() === "img") {
|
|
10530
|
+
const named = imageIsNamed(source.slice(nameEnd, end), scanner, nameEnd);
|
|
10531
|
+
if (named === false) {
|
|
10532
|
+
const { line: line2, column } = locate(lines, i);
|
|
10533
|
+
const tag = source.slice(i, end).replace(/\s+/g, " ");
|
|
10534
|
+
findings.push(
|
|
10535
|
+
finding(
|
|
10536
|
+
"image-alt",
|
|
10537
|
+
`body:${line2}:${column}`,
|
|
10538
|
+
tag.length > AUDIT_SNIPPET_LENGTH ? `${tag.slice(0, AUDIT_SNIPPET_LENGTH - 1)}\u2026` : tag
|
|
10539
|
+
)
|
|
10540
|
+
);
|
|
10541
|
+
}
|
|
10542
|
+
}
|
|
10543
|
+
i = end;
|
|
10544
|
+
if (rawTextElements.has(name.toLowerCase()) && source[end - 1] === ">")
|
|
10545
|
+
i = scanner.skipToClosingTag(end, name);
|
|
10546
|
+
}
|
|
10547
|
+
return findings;
|
|
10548
|
+
}
|
|
10549
|
+
|
|
10151
10550
|
// packages/engine/src/lib/office/errors.ts
|
|
10152
10551
|
var OfficeError = class extends Error {
|
|
10153
10552
|
constructor(code, message, details = {}) {
|
|
@@ -11467,12 +11866,12 @@ function assertWellFormed(tokens, part) {
|
|
|
11467
11866
|
}
|
|
11468
11867
|
var FORBIDDEN = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
11469
11868
|
var ENTITY = /&(?:#x[0-9A-Fa-f]+|#\d+|amp|lt|gt|quot|apos);/y;
|
|
11470
|
-
function checkText(
|
|
11471
|
-
if (FORBIDDEN.test(
|
|
11472
|
-
if (
|
|
11473
|
-
for (let i =
|
|
11869
|
+
function checkText(text4, part) {
|
|
11870
|
+
if (FORBIDDEN.test(text4)) throw invalid2("a character XML does not allow", part);
|
|
11871
|
+
if (text4.includes("<")) throw invalid2("unescaped < in text", part);
|
|
11872
|
+
for (let i = text4.indexOf("&"); i !== -1; i = text4.indexOf("&", i + 1)) {
|
|
11474
11873
|
ENTITY.lastIndex = i;
|
|
11475
|
-
if (!ENTITY.test(
|
|
11874
|
+
if (!ENTITY.test(text4)) throw invalid2(`invalid entity reference near "${text4.slice(i, i + 12)}"`, part);
|
|
11476
11875
|
}
|
|
11477
11876
|
}
|
|
11478
11877
|
function checkAttributes(raw, part) {
|
|
@@ -11507,13 +11906,13 @@ function decodeText3(raw) {
|
|
|
11507
11906
|
}
|
|
11508
11907
|
});
|
|
11509
11908
|
}
|
|
11510
|
-
function escapeText3(
|
|
11511
|
-
return
|
|
11909
|
+
function escapeText3(text4) {
|
|
11910
|
+
return text4.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
11512
11911
|
}
|
|
11513
11912
|
var FORBIDDEN_GLOBAL = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
|
|
11514
|
-
function stripForbidden(
|
|
11913
|
+
function stripForbidden(text4) {
|
|
11515
11914
|
let removed = 0;
|
|
11516
|
-
const out =
|
|
11915
|
+
const out = text4.replace(FORBIDDEN_GLOBAL, () => {
|
|
11517
11916
|
removed++;
|
|
11518
11917
|
return "";
|
|
11519
11918
|
});
|
|
@@ -11764,13 +12163,13 @@ function placeDrawings(xml2, pattern, markupFor) {
|
|
|
11764
12163
|
pattern.lastIndex = 0;
|
|
11765
12164
|
if (pattern.test(t.raw)) {
|
|
11766
12165
|
const segments = t.raw.split(pattern);
|
|
11767
|
-
let
|
|
12166
|
+
let text4 = segments[0];
|
|
11768
12167
|
for (let s = 1; s < segments.length; s += 2) {
|
|
11769
12168
|
const index = Number(segments[s]);
|
|
11770
|
-
|
|
12169
|
+
text4 += `</w:t></w:r><w:r>${runProps}${markupFor(index)}</w:r>${runOpen}${runProps}<w:t xml:space="preserve">` + segments[s + 1];
|
|
11771
12170
|
}
|
|
11772
12171
|
out[textOpen] = withPreserve(out[textOpen]);
|
|
11773
|
-
out.push(
|
|
12172
|
+
out.push(text4);
|
|
11774
12173
|
continue;
|
|
11775
12174
|
}
|
|
11776
12175
|
}
|
|
@@ -12025,11 +12424,11 @@ function fromTemplateOutput(output, template, part) {
|
|
|
12025
12424
|
let last = 0;
|
|
12026
12425
|
let inText = false;
|
|
12027
12426
|
const emit = (segment) => {
|
|
12028
|
-
const { text:
|
|
12427
|
+
const { text: text4, removed } = stripForbidden(segment);
|
|
12029
12428
|
removedCharacters += removed;
|
|
12030
|
-
if (!inText &&
|
|
12031
|
-
throw new OfficeError("office_document_invalid", `${part ?? "part"}: text outside a text element: "${
|
|
12032
|
-
xml2 += escapeText3(
|
|
12429
|
+
if (!inText && text4.trim() !== "")
|
|
12430
|
+
throw new OfficeError("office_document_invalid", `${part ?? "part"}: text outside a text element: "${text4.trim().slice(0, 40)}"`);
|
|
12431
|
+
xml2 += escapeText3(text4);
|
|
12033
12432
|
};
|
|
12034
12433
|
for (const m of output.matchAll(placeholder)) {
|
|
12035
12434
|
emit(output.slice(last, m.index));
|
|
@@ -12071,15 +12470,15 @@ function layoutText(xml2, flavour, part) {
|
|
|
12071
12470
|
out.push(token2.raw);
|
|
12072
12471
|
continue;
|
|
12073
12472
|
}
|
|
12074
|
-
const
|
|
12473
|
+
const text4 = token2.raw.replace(/\r\n?/g, "\n");
|
|
12075
12474
|
if (flavour === "wordprocessing") {
|
|
12076
|
-
const pieces =
|
|
12077
|
-
if (pieces.length > 1 || /^\s|\s$/.test(
|
|
12475
|
+
const pieces = text4.split(/(\n|\t)/);
|
|
12476
|
+
if (pieces.length > 1 || /^\s|\s$/.test(text4)) out[textOpenIndex] = preserveSpace(out[textOpenIndex]);
|
|
12078
12477
|
out.push(
|
|
12079
12478
|
pieces.map((p) => p === "\n" ? '</w:t><w:br/><w:t xml:space="preserve">' : p === " " ? '</w:t><w:tab/><w:t xml:space="preserve">' : p).join("")
|
|
12080
12479
|
);
|
|
12081
12480
|
} else {
|
|
12082
|
-
out.push(
|
|
12481
|
+
out.push(text4.split("\n").join(`</a:t></a:r><a:br>${runProperties}</a:br><a:r>${runProperties}<a:t>`));
|
|
12083
12482
|
}
|
|
12084
12483
|
}
|
|
12085
12484
|
return out.join("");
|
|
@@ -12112,17 +12511,17 @@ var AUTOCORRECTED = [
|
|
|
12112
12511
|
[/\u200B|\u200C|\u200D|\uFEFF/g, ""]
|
|
12113
12512
|
];
|
|
12114
12513
|
function normaliseTags(template, part) {
|
|
12115
|
-
const { text:
|
|
12514
|
+
const { text: text4, origin, placeholders } = stripPlaceholders(template);
|
|
12116
12515
|
const sourceRange = (from, to) => [
|
|
12117
12516
|
origin[from] ?? template.source.length,
|
|
12118
12517
|
(origin[to - 1] ?? template.source.length - 1) + 1
|
|
12119
12518
|
];
|
|
12120
12519
|
const diagnostics = [];
|
|
12121
12520
|
const edits = [];
|
|
12122
|
-
for (const tag of findTags(
|
|
12521
|
+
for (const tag of findTags(text4)) {
|
|
12123
12522
|
const inside = placeholders.filter((p) => p.at > tag.start && p.at < tag.end);
|
|
12124
12523
|
const paragraph2 = paragraphOf(template, placeholders, tag.start);
|
|
12125
|
-
const raw =
|
|
12524
|
+
const raw = text4.slice(tag.start, tag.end);
|
|
12126
12525
|
const unsafe = inside.filter((p) => {
|
|
12127
12526
|
const piece = template.markup[p.index];
|
|
12128
12527
|
return !piece || piece.paragraphBoundary || piece.containerBoundary;
|
|
@@ -12176,8 +12575,8 @@ function normaliseTags(template, part) {
|
|
|
12176
12575
|
return { template: { ...template, source: applyEdits(template.source, edits) }, diagnostics };
|
|
12177
12576
|
}
|
|
12178
12577
|
var ENTITIES2 = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'" };
|
|
12179
|
-
function decodeEntities2(
|
|
12180
|
-
return
|
|
12578
|
+
function decodeEntities2(text4) {
|
|
12579
|
+
return text4.replace(/&(#x[0-9a-f]+|#\d+|amp|lt|gt|quot|apos);/gi, (whole, name) => {
|
|
12181
12580
|
if (name[0] !== "#") return ENTITIES2[name.toLowerCase()] ?? whole;
|
|
12182
12581
|
const code = name[1] === "x" || name[1] === "X" ? parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10);
|
|
12183
12582
|
return Number.isFinite(code) ? String.fromCodePoint(code) : whole;
|
|
@@ -12185,28 +12584,28 @@ function decodeEntities2(text3) {
|
|
|
12185
12584
|
}
|
|
12186
12585
|
function stripPlaceholders(template) {
|
|
12187
12586
|
const pattern = placeholderPattern(template.nonce);
|
|
12188
|
-
let
|
|
12587
|
+
let text4 = "";
|
|
12189
12588
|
const origin = [];
|
|
12190
12589
|
const placeholders = [];
|
|
12191
12590
|
let last = 0;
|
|
12192
12591
|
for (const m of template.source.matchAll(pattern)) {
|
|
12193
12592
|
for (let i = last; i < (m.index ?? 0); i++) {
|
|
12194
|
-
|
|
12593
|
+
text4 += template.source[i];
|
|
12195
12594
|
origin.push(i);
|
|
12196
12595
|
}
|
|
12197
|
-
placeholders.push({ index: Number(m[1]), at:
|
|
12596
|
+
placeholders.push({ index: Number(m[1]), at: text4.length, from: m.index ?? 0, to: (m.index ?? 0) + m[0].length });
|
|
12198
12597
|
last = (m.index ?? 0) + m[0].length;
|
|
12199
12598
|
}
|
|
12200
12599
|
for (let i = last; i < template.source.length; i++) {
|
|
12201
|
-
|
|
12600
|
+
text4 += template.source[i];
|
|
12202
12601
|
origin.push(i);
|
|
12203
12602
|
}
|
|
12204
|
-
return { text:
|
|
12603
|
+
return { text: text4, origin, placeholders };
|
|
12205
12604
|
}
|
|
12206
12605
|
function listTags(template, part) {
|
|
12207
|
-
const { text:
|
|
12208
|
-
return findTags(
|
|
12209
|
-
const raw =
|
|
12606
|
+
const { text: text4, placeholders } = stripPlaceholders(template);
|
|
12607
|
+
return findTags(text4).map((tag) => {
|
|
12608
|
+
const raw = text4.slice(tag.start, tag.end);
|
|
12210
12609
|
const kind = raw.startsWith("{#") ? "comment" : raw.startsWith("{%") || /^\{\{~?\s*[#/^]/.test(raw) || /^\{\{~?\s*else\b/.test(raw) ? "block" : "output";
|
|
12211
12610
|
return { part, paragraph: paragraphOf(template, placeholders, tag.start), text: raw.replace(/\s+/g, " ").trim(), kind };
|
|
12212
12611
|
});
|
|
@@ -12227,15 +12626,15 @@ function undoAutocorrect(tag) {
|
|
|
12227
12626
|
for (const [pattern, replacement] of AUTOCORRECTED) out = out.replace(pattern, replacement);
|
|
12228
12627
|
return out;
|
|
12229
12628
|
}
|
|
12230
|
-
function findTags(
|
|
12629
|
+
function findTags(text4) {
|
|
12231
12630
|
const tags = [];
|
|
12232
|
-
for (let i = 0; i <
|
|
12233
|
-
const opener = OPENERS.find((o) =>
|
|
12631
|
+
for (let i = 0; i < text4.length - 1; i++) {
|
|
12632
|
+
const opener = OPENERS.find((o) => text4.startsWith(o, i));
|
|
12234
12633
|
if (!opener) continue;
|
|
12235
12634
|
const closer = CLOSERS[opener];
|
|
12236
|
-
const end =
|
|
12635
|
+
const end = text4.indexOf(closer, i + opener.length);
|
|
12237
12636
|
if (end === -1) continue;
|
|
12238
|
-
const stop = end + closer.length + (opener === "{{" &&
|
|
12637
|
+
const stop = end + closer.length + (opener === "{{" && text4[end + closer.length] === "}" ? 1 : 0);
|
|
12239
12638
|
tags.push({ start: i, end: stop });
|
|
12240
12639
|
i = stop - 1;
|
|
12241
12640
|
}
|
|
@@ -12265,8 +12664,8 @@ var CONTENT = /* @__PURE__ */ new Set(["w:drawing", "w:pict", "w:object", "w:fld
|
|
|
12265
12664
|
var JINJA_OPEN = /^(for|if|unless|case|capture|raw|with|macro|call|filter|block|tablerow|comment|autoescape)\b/;
|
|
12266
12665
|
var JINJA_CLOSE = /^end(for|if|unless|case|capture|raw|with|macro|call|filter|block|tablerow|comment|autoescape)\b/;
|
|
12267
12666
|
var JINJA_MIDDLE = /^(else|elif|elsif|when)\b/;
|
|
12268
|
-
function blockRole(
|
|
12269
|
-
const t =
|
|
12667
|
+
function blockRole(text4) {
|
|
12668
|
+
const t = text4.trim();
|
|
12270
12669
|
let m = /^\{%-?\s*([\s\S]*?)\s*-?%\}$/.exec(t);
|
|
12271
12670
|
if (m && !t.slice(2, -2).includes("%}")) {
|
|
12272
12671
|
const body = m[1] ?? "";
|
|
@@ -12298,14 +12697,14 @@ function dropTaggedFallbacks(xml2, part) {
|
|
|
12298
12697
|
if (t.kind === "open" && t.name === "mc:Fallback" && !t.selfClosing) {
|
|
12299
12698
|
let depth = 1;
|
|
12300
12699
|
let j = i + 1;
|
|
12301
|
-
let
|
|
12700
|
+
let text4 = "";
|
|
12302
12701
|
for (; j < tokens.length && depth > 0; j++) {
|
|
12303
12702
|
const u = tokens[j];
|
|
12304
12703
|
if (u.kind === "open" && u.name === "mc:Fallback" && !u.selfClosing) depth++;
|
|
12305
12704
|
else if (u.kind === "close" && u.name === "mc:Fallback") depth--;
|
|
12306
|
-
else if (u.kind === "text")
|
|
12705
|
+
else if (u.kind === "text") text4 += decodeText3(u.raw);
|
|
12307
12706
|
}
|
|
12308
|
-
if (/\{\{|\{%|\{#/.test(
|
|
12707
|
+
if (/\{\{|\{%|\{#/.test(text4)) {
|
|
12309
12708
|
i = j - 1;
|
|
12310
12709
|
continue;
|
|
12311
12710
|
}
|
|
@@ -12378,9 +12777,9 @@ function applyStructure(xml2, part) {
|
|
|
12378
12777
|
for (const [span, s] of structural) {
|
|
12379
12778
|
if (rowOf.has(span)) continue;
|
|
12380
12779
|
const keep = s.info.sectionProperties;
|
|
12381
|
-
let
|
|
12382
|
-
if (keep)
|
|
12383
|
-
replacements.push({ start: span.start, end: span.end, text:
|
|
12780
|
+
let text4 = element(s.tag);
|
|
12781
|
+
if (keep) text4 = s.role === "open" ? `<w:p>${keep}</w:p>${text4}` : `${text4}<w:p>${keep}</w:p>`;
|
|
12782
|
+
replacements.push({ start: span.start, end: span.end, text: text4 });
|
|
12384
12783
|
const holder = span.parent && BODIES.has(span.parent.name) ? span.parent : null;
|
|
12385
12784
|
if (holder && !keep) cellsEmptied.set(holder, (cellsEmptied.get(holder) ?? 0) + 1);
|
|
12386
12785
|
}
|
|
@@ -12434,7 +12833,7 @@ function collectParagraphs(tokens, root) {
|
|
|
12434
12833
|
const out = [];
|
|
12435
12834
|
const walk3 = (span) => {
|
|
12436
12835
|
if (PARAGRAPH.has(span.name)) {
|
|
12437
|
-
let
|
|
12836
|
+
let text4 = "";
|
|
12438
12837
|
let hasContent = false;
|
|
12439
12838
|
let sectionProperties = null;
|
|
12440
12839
|
let inText = false;
|
|
@@ -12445,10 +12844,10 @@ function collectParagraphs(tokens, root) {
|
|
|
12445
12844
|
else if (CONTENT.has(t.name)) hasContent = true;
|
|
12446
12845
|
else if (t.name === "w:sectPr") sectionProperties = "";
|
|
12447
12846
|
} else if (t.kind === "close" && TEXT.has(t.name)) inText = false;
|
|
12448
|
-
else if (t.kind === "text" && inText)
|
|
12847
|
+
else if (t.kind === "text" && inText) text4 += decodeText3(t.raw);
|
|
12449
12848
|
}
|
|
12450
12849
|
if (sectionProperties !== null) sectionProperties = propertiesOf(tokens, span);
|
|
12451
|
-
out.push({ span, number: out.length + 1, text:
|
|
12850
|
+
out.push({ span, number: out.length + 1, text: text4, hasContent, sectionProperties });
|
|
12452
12851
|
}
|
|
12453
12852
|
for (const child2 of span.children) walk3(child2);
|
|
12454
12853
|
};
|
|
@@ -12556,7 +12955,7 @@ function placeSlidePictures(xml2, pattern, drawingFor, pictureMarkup, slide) {
|
|
|
12556
12955
|
for (const container of containers) {
|
|
12557
12956
|
const indexes = [];
|
|
12558
12957
|
const edits = [];
|
|
12559
|
-
let
|
|
12958
|
+
let text4 = "";
|
|
12560
12959
|
let inText = false;
|
|
12561
12960
|
for (let i = container.start + 1; i < container.end; i++) {
|
|
12562
12961
|
const t = tokens[i];
|
|
@@ -12565,7 +12964,7 @@ function placeSlidePictures(xml2, pattern, drawingFor, pictureMarkup, slide) {
|
|
|
12565
12964
|
else if (t.kind === "text" && inText) {
|
|
12566
12965
|
pattern.lastIndex = 0;
|
|
12567
12966
|
if (!pattern.test(t.raw)) {
|
|
12568
|
-
|
|
12967
|
+
text4 += decodeText3(t.raw);
|
|
12569
12968
|
continue;
|
|
12570
12969
|
}
|
|
12571
12970
|
const segments = t.raw.split(pattern);
|
|
@@ -12574,7 +12973,7 @@ function placeSlidePictures(xml2, pattern, drawingFor, pictureMarkup, slide) {
|
|
|
12574
12973
|
if (s % 2 === 1) indexes.push(Number(segments[s]));
|
|
12575
12974
|
else kept += segments[s];
|
|
12576
12975
|
}
|
|
12577
|
-
|
|
12976
|
+
text4 += decodeText3(kept);
|
|
12578
12977
|
edits.push({ at: i, raw: kept });
|
|
12579
12978
|
}
|
|
12580
12979
|
}
|
|
@@ -12593,7 +12992,7 @@ function placeSlidePictures(xml2, pattern, drawingFor, pictureMarkup, slide) {
|
|
|
12593
12992
|
}
|
|
12594
12993
|
const autoFit = tokens.slice(container.start, container.end).some((t) => t.kind === "open" && t.name === "a:spAutoFit");
|
|
12595
12994
|
const placed = layoutPictures(pictures, box, autoFit).map((b, i) => pictureMarkup(pictures[i], b)).join("");
|
|
12596
|
-
const onlyPictures = container.name === "p:sp" &&
|
|
12995
|
+
const onlyPictures = container.name === "p:sp" && text4.trim() === "";
|
|
12597
12996
|
if (onlyPictures) replacements.push({ start: container.start, end: container.end, text: placed });
|
|
12598
12997
|
else {
|
|
12599
12998
|
for (const edit of edits) replacements.push({ start: edit.at, end: edit.at, text: edit.raw });
|
|
@@ -12866,8 +13265,8 @@ function starterTags(engine) {
|
|
|
12866
13265
|
codeFit: engine === "liquid" ? "{{ offer.url | qrcode }}" : "{{ qrcode(offer.url) }}"
|
|
12867
13266
|
};
|
|
12868
13267
|
}
|
|
12869
|
-
var paragraph = (
|
|
12870
|
-
var cell = (
|
|
13268
|
+
var paragraph = (text4, style2, bold = false) => `<w:p>${style2 ? `<w:pPr><w:pStyle w:val="${style2}"/></w:pPr>` : ""}<w:r>${bold ? "<w:rPr><w:b/></w:rPr>" : ""}<w:t xml:space="preserve">${escapeText3(text4)}</w:t></w:r></w:p>`;
|
|
13269
|
+
var cell = (text4, width, bold = false) => `<w:tc><w:tcPr><w:tcW w:w="${width}" w:type="dxa"/></w:tcPr>${paragraph(text4, void 0, bold)}</w:tc>`;
|
|
12871
13270
|
var row = (cells) => `<w:tr>${cells}</w:tr>`;
|
|
12872
13271
|
function starterDocument(engine) {
|
|
12873
13272
|
const t = starterTags(engine);
|
|
@@ -12910,7 +13309,7 @@ function starterDocument(engine) {
|
|
|
12910
13309
|
["word/document.xml", `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:document xmlns:w="${W}"><w:body>${body}</w:body></w:document>`]
|
|
12911
13310
|
];
|
|
12912
13311
|
return {
|
|
12913
|
-
bytes: writeZip(files.map(([name,
|
|
13312
|
+
bytes: writeZip(files.map(([name, text4]) => ({ name, data: encoder2.encode(text4) }))),
|
|
12914
13313
|
sampleData: starterSampleData()
|
|
12915
13314
|
};
|
|
12916
13315
|
}
|
|
@@ -12938,15 +13337,15 @@ var CM = 36e4;
|
|
|
12938
13337
|
var FONT = "Carlito";
|
|
12939
13338
|
var ACCENT = "0F766E";
|
|
12940
13339
|
var emptyTree = '<p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/>';
|
|
12941
|
-
var run = (
|
|
12942
|
-
var para = (
|
|
13340
|
+
var run = (text4, size, options = {}) => `<a:r><a:rPr lang="en-GB" sz="${size * 100}"${options.bold ? ' b="1"' : ""} dirty="0">${options.color ? `<a:solidFill><a:srgbClr val="${options.color}"/></a:solidFill>` : ""}<a:latin typeface="${FONT}"/></a:rPr><a:t>${escapeText3(text4)}</a:t></a:r>`;
|
|
13341
|
+
var para = (text4, size, options = {}) => `<a:p>${run(text4, size, options)}</a:p>`;
|
|
12943
13342
|
function textBox(id, name, x, y, cx, cy, paragraphs) {
|
|
12944
13343
|
return `<p:sp><p:nvSpPr><p:cNvPr id="${id}" name="${name}"/><p:cNvSpPr txBox="1"/><p:nvPr/></p:nvSpPr><p:spPr><a:xfrm><a:off x="${x}" y="${y}"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:noFill/></p:spPr><p:txBody><a:bodyPr wrap="square" rtlCol="0"><a:noAutofit/></a:bodyPr><a:lstStyle/>${paragraphs}</p:txBody></p:sp>`;
|
|
12945
13344
|
}
|
|
12946
|
-
function cell2(
|
|
13345
|
+
function cell2(text4, header) {
|
|
12947
13346
|
const fill = header ? `<a:solidFill><a:srgbClr val="${ACCENT}"/></a:solidFill>` : "<a:noFill/>";
|
|
12948
13347
|
const line2 = `<a:lnB w="6350"><a:solidFill><a:srgbClr val="BFBFBF"/></a:solidFill></a:lnB>`;
|
|
12949
|
-
return `<a:tc><a:txBody><a:bodyPr/><a:lstStyle/>${para(
|
|
13348
|
+
return `<a:tc><a:txBody><a:bodyPr/><a:lstStyle/>${para(text4, 14, header ? { bold: true, color: "FFFFFF" } : {})}</a:txBody><a:tcPr marL="91440" marR="91440" marT="45720" marB="45720">${line2}${fill}</a:tcPr></a:tc>`;
|
|
12950
13349
|
}
|
|
12951
13350
|
var tableRow = (a, b, header = false) => `<a:tr h="${Math.round(0.9 * CM)}">${cell2(a, header)}${cell2(b, header)}</a:tr>`;
|
|
12952
13351
|
function table2(id, x, y, rows) {
|
|
@@ -13036,11 +13435,19 @@ function starterPresentation(engine) {
|
|
|
13036
13435
|
];
|
|
13037
13436
|
const encoder2 = new TextEncoder();
|
|
13038
13437
|
return {
|
|
13039
|
-
bytes: writeZip(files.map(([name,
|
|
13438
|
+
bytes: writeZip(files.map(([name, text4]) => ({ name, data: encoder2.encode(text4) }))),
|
|
13040
13439
|
sampleData: starterSampleData()
|
|
13041
13440
|
};
|
|
13042
13441
|
}
|
|
13043
13442
|
export {
|
|
13443
|
+
ACCESSIBILITY_HEADER_LENGTH,
|
|
13444
|
+
ACCESSIBILITY_MAX_ELEMENTS,
|
|
13445
|
+
ACCESSIBILITY_MAX_FAILURES,
|
|
13446
|
+
AUDIT_CODES,
|
|
13447
|
+
AUDIT_RULES,
|
|
13448
|
+
AUDIT_SEVERITY,
|
|
13449
|
+
AUDIT_SNIPPET_LENGTH,
|
|
13450
|
+
AUDIT_TITLES,
|
|
13044
13451
|
CII_GUIDELINES,
|
|
13045
13452
|
CODE_LIST_RELEASE,
|
|
13046
13453
|
DEFAULT_CHROME_PADDING,
|
|
@@ -13060,9 +13467,15 @@ export {
|
|
|
13060
13467
|
INVOICE_DATA_KEY,
|
|
13061
13468
|
OFFICE_FILLED_MAX_BYTES,
|
|
13062
13469
|
OfficeTemplateError,
|
|
13470
|
+
PDFUA_STANDARD,
|
|
13063
13471
|
RenderError,
|
|
13064
13472
|
RenderLimitError,
|
|
13473
|
+
UA_CHECKS,
|
|
13474
|
+
UA_REFUSALS,
|
|
13065
13475
|
VAT_CATEGORIES,
|
|
13476
|
+
accessibilityHeader,
|
|
13477
|
+
accessibilityHeaderValue,
|
|
13478
|
+
accessibilityResult,
|
|
13066
13479
|
analyzeHandlebars,
|
|
13067
13480
|
analyzeJinja2,
|
|
13068
13481
|
analyzeLiquid,
|
|
@@ -13071,6 +13484,8 @@ export {
|
|
|
13071
13484
|
apitemplateRegions,
|
|
13072
13485
|
applyRegionEdit,
|
|
13073
13486
|
assembleDocument,
|
|
13487
|
+
auditMessage,
|
|
13488
|
+
auditRuntime,
|
|
13074
13489
|
brandCss,
|
|
13075
13490
|
builtinHelpers,
|
|
13076
13491
|
canvasDocument,
|
|
@@ -13143,6 +13558,7 @@ export {
|
|
|
13143
13558
|
isOfficeKind,
|
|
13144
13559
|
isOutputFormat,
|
|
13145
13560
|
isScss,
|
|
13561
|
+
isUaSetting,
|
|
13146
13562
|
jinja2Engine,
|
|
13147
13563
|
jinjaTags,
|
|
13148
13564
|
jsreportTemplates,
|
|
@@ -13184,6 +13600,7 @@ export {
|
|
|
13184
13600
|
resolveEinvoiceOptions,
|
|
13185
13601
|
resolvePath,
|
|
13186
13602
|
resolveTranslation,
|
|
13603
|
+
resolveUa,
|
|
13187
13604
|
scanBlocks,
|
|
13188
13605
|
schemaPaths,
|
|
13189
13606
|
shownAmounts,
|
|
@@ -13195,6 +13612,8 @@ export {
|
|
|
13195
13612
|
splitApitemplateCss,
|
|
13196
13613
|
starterDocument,
|
|
13197
13614
|
starterPresentation,
|
|
13615
|
+
staticAudit,
|
|
13616
|
+
staticAuditDiagnostics,
|
|
13198
13617
|
strftimeToDateFns,
|
|
13199
13618
|
svgDataUri,
|
|
13200
13619
|
toDate,
|