@formfeed/mcp 0.2.0 → 0.3.1
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/THIRD_PARTY_LICENSES.md +28 -0
- package/bin/formfeed-mcp.mjs +2522 -370
- package/package.json +1 -1
package/bin/formfeed-mcp.mjs
CHANGED
|
@@ -1531,7 +1531,7 @@ var require_segments = __commonJS({
|
|
|
1531
1531
|
return nodes;
|
|
1532
1532
|
}
|
|
1533
1533
|
function buildGraph(nodes, version) {
|
|
1534
|
-
const
|
|
1534
|
+
const table2 = {};
|
|
1535
1535
|
const graph = { start: {} };
|
|
1536
1536
|
let prevNodeIds = ["start"];
|
|
1537
1537
|
for (let i = 0; i < nodes.length; i++) {
|
|
@@ -1541,15 +1541,15 @@ var require_segments = __commonJS({
|
|
|
1541
1541
|
const node = nodeGroup[j2];
|
|
1542
1542
|
const key = "" + i + j2;
|
|
1543
1543
|
currentNodeIds.push(key);
|
|
1544
|
-
|
|
1544
|
+
table2[key] = { node, lastCount: 0 };
|
|
1545
1545
|
graph[key] = {};
|
|
1546
1546
|
for (let n = 0; n < prevNodeIds.length; n++) {
|
|
1547
1547
|
const prevNodeId = prevNodeIds[n];
|
|
1548
|
-
if (
|
|
1549
|
-
graph[prevNodeId][key] = getSegmentBitsLength(
|
|
1550
|
-
|
|
1548
|
+
if (table2[prevNodeId] && table2[prevNodeId].node.mode === node.mode) {
|
|
1549
|
+
graph[prevNodeId][key] = getSegmentBitsLength(table2[prevNodeId].lastCount + node.length, node.mode) - getSegmentBitsLength(table2[prevNodeId].lastCount, node.mode);
|
|
1550
|
+
table2[prevNodeId].lastCount += node.length;
|
|
1551
1551
|
} else {
|
|
1552
|
-
if (
|
|
1552
|
+
if (table2[prevNodeId]) table2[prevNodeId].lastCount = node.length;
|
|
1553
1553
|
graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) + 4 + Mode.getCharCountIndicator(node.mode, version);
|
|
1554
1554
|
}
|
|
1555
1555
|
}
|
|
@@ -1559,7 +1559,7 @@ var require_segments = __commonJS({
|
|
|
1559
1559
|
for (let n = 0; n < prevNodeIds.length; n++) {
|
|
1560
1560
|
graph[prevNodeIds[n]].end = 0;
|
|
1561
1561
|
}
|
|
1562
|
-
return { map: graph, table };
|
|
1562
|
+
return { map: graph, table: table2 };
|
|
1563
1563
|
}
|
|
1564
1564
|
function buildSingleSegment(data, modesHint) {
|
|
1565
1565
|
let mode;
|
|
@@ -1673,22 +1673,22 @@ var require_qrcode = __commonJS({
|
|
|
1673
1673
|
}
|
|
1674
1674
|
function setupVersionInfo(matrix, version) {
|
|
1675
1675
|
const size = matrix.size;
|
|
1676
|
-
const
|
|
1676
|
+
const bits2 = Version.getEncodedBits(version);
|
|
1677
1677
|
let row, col, mod;
|
|
1678
1678
|
for (let i = 0; i < 18; i++) {
|
|
1679
1679
|
row = Math.floor(i / 3);
|
|
1680
1680
|
col = i % 3 + size - 8 - 3;
|
|
1681
|
-
mod = (
|
|
1681
|
+
mod = (bits2 >> i & 1) === 1;
|
|
1682
1682
|
matrix.set(row, col, mod, true);
|
|
1683
1683
|
matrix.set(col, row, mod, true);
|
|
1684
1684
|
}
|
|
1685
1685
|
}
|
|
1686
1686
|
function setupFormatInfo(matrix, errorCorrectionLevel, maskPattern) {
|
|
1687
1687
|
const size = matrix.size;
|
|
1688
|
-
const
|
|
1688
|
+
const bits2 = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern);
|
|
1689
1689
|
let i, mod;
|
|
1690
1690
|
for (i = 0; i < 15; i++) {
|
|
1691
|
-
mod = (
|
|
1691
|
+
mod = (bits2 >> i & 1) === 1;
|
|
1692
1692
|
if (i < 6) {
|
|
1693
1693
|
matrix.set(i, 8, mod, true);
|
|
1694
1694
|
} else if (i < 8) {
|
|
@@ -2747,17 +2747,17 @@ var require_bitmapper = __commonJS({
|
|
|
2747
2747
|
}
|
|
2748
2748
|
return rawPos;
|
|
2749
2749
|
}
|
|
2750
|
-
function mapImageCustomBit(image, pxData, getPxPos, bpp,
|
|
2750
|
+
function mapImageCustomBit(image, pxData, getPxPos, bpp, bits2, maxBit) {
|
|
2751
2751
|
let imageWidth = image.width;
|
|
2752
2752
|
let imageHeight = image.height;
|
|
2753
2753
|
let imagePass = image.index;
|
|
2754
2754
|
for (let y2 = 0; y2 < imageHeight; y2++) {
|
|
2755
2755
|
for (let x2 = 0; x2 < imageWidth; x2++) {
|
|
2756
|
-
let pixelData =
|
|
2756
|
+
let pixelData = bits2.get(bpp);
|
|
2757
2757
|
let pxPos = getPxPos(x2, y2, imagePass);
|
|
2758
2758
|
pixelBppCustomMapper[bpp](pxData, pixelData, pxPos, maxBit);
|
|
2759
2759
|
}
|
|
2760
|
-
|
|
2760
|
+
bits2.resetAfterLine();
|
|
2761
2761
|
}
|
|
2762
2762
|
}
|
|
2763
2763
|
exports.dataToBitMap = function(data, bitmapInfo) {
|
|
@@ -2766,9 +2766,9 @@ var require_bitmapper = __commonJS({
|
|
|
2766
2766
|
let depth = bitmapInfo.depth;
|
|
2767
2767
|
let bpp = bitmapInfo.bpp;
|
|
2768
2768
|
let interlace = bitmapInfo.interlace;
|
|
2769
|
-
let
|
|
2769
|
+
let bits2;
|
|
2770
2770
|
if (depth !== 8) {
|
|
2771
|
-
|
|
2771
|
+
bits2 = bitRetriever(data, depth);
|
|
2772
2772
|
}
|
|
2773
2773
|
let pxData;
|
|
2774
2774
|
if (depth <= 8) {
|
|
@@ -2808,7 +2808,7 @@ var require_bitmapper = __commonJS({
|
|
|
2808
2808
|
pxData,
|
|
2809
2809
|
getPxPos,
|
|
2810
2810
|
bpp,
|
|
2811
|
-
|
|
2811
|
+
bits2,
|
|
2812
2812
|
maxBit
|
|
2813
2813
|
);
|
|
2814
2814
|
}
|
|
@@ -2818,7 +2818,7 @@ var require_bitmapper = __commonJS({
|
|
|
2818
2818
|
throw new Error("extra data found");
|
|
2819
2819
|
}
|
|
2820
2820
|
} else {
|
|
2821
|
-
|
|
2821
|
+
bits2.end();
|
|
2822
2822
|
}
|
|
2823
2823
|
return pxData;
|
|
2824
2824
|
};
|
|
@@ -2936,8 +2936,8 @@ var require_parser_async = __commonJS({
|
|
|
2936
2936
|
this._parser.start();
|
|
2937
2937
|
};
|
|
2938
2938
|
util.inherits(ParserAsync, ChunkStream);
|
|
2939
|
-
ParserAsync.prototype._handleError = function(
|
|
2940
|
-
this.emit("error",
|
|
2939
|
+
ParserAsync.prototype._handleError = function(err2) {
|
|
2940
|
+
this.emit("error", err2);
|
|
2941
2941
|
this.writable = false;
|
|
2942
2942
|
this.destroy();
|
|
2943
2943
|
if (this._inflate && this._inflate.destroy) {
|
|
@@ -2964,11 +2964,11 @@ var require_parser_async = __commonJS({
|
|
|
2964
2964
|
this._inflate = zlib.createInflate({ chunkSize });
|
|
2965
2965
|
let leftToInflate = imageSize;
|
|
2966
2966
|
let emitError = this.emit.bind(this, "error");
|
|
2967
|
-
this._inflate.on("error", function(
|
|
2967
|
+
this._inflate.on("error", function(err2) {
|
|
2968
2968
|
if (!leftToInflate) {
|
|
2969
2969
|
return;
|
|
2970
2970
|
}
|
|
2971
|
-
emitError(
|
|
2971
|
+
emitError(err2);
|
|
2972
2972
|
});
|
|
2973
2973
|
this._filter.on("complete", this._complete.bind(this));
|
|
2974
2974
|
let filterWrite = this._filter.write.bind(this._filter);
|
|
@@ -3474,9 +3474,9 @@ var require_sync_inflate = __commonJS({
|
|
|
3474
3474
|
var zlib = __require("zlib");
|
|
3475
3475
|
var util = __require("util");
|
|
3476
3476
|
var kMaxLength = __require("buffer").kMaxLength;
|
|
3477
|
-
function
|
|
3478
|
-
if (!(this instanceof
|
|
3479
|
-
return new
|
|
3477
|
+
function Inflate2(opts) {
|
|
3478
|
+
if (!(this instanceof Inflate2)) {
|
|
3479
|
+
return new Inflate2(opts);
|
|
3480
3480
|
}
|
|
3481
3481
|
if (opts && opts.chunkSize < zlib.Z_MIN_CHUNK) {
|
|
3482
3482
|
opts.chunkSize = zlib.Z_MIN_CHUNK;
|
|
@@ -3489,7 +3489,7 @@ var require_sync_inflate = __commonJS({
|
|
|
3489
3489
|
}
|
|
3490
3490
|
}
|
|
3491
3491
|
function createInflate(opts) {
|
|
3492
|
-
return new
|
|
3492
|
+
return new Inflate2(opts);
|
|
3493
3493
|
}
|
|
3494
3494
|
function _close(engine, callback) {
|
|
3495
3495
|
if (callback) {
|
|
@@ -3501,7 +3501,7 @@ var require_sync_inflate = __commonJS({
|
|
|
3501
3501
|
engine._handle.close();
|
|
3502
3502
|
engine._handle = null;
|
|
3503
3503
|
}
|
|
3504
|
-
|
|
3504
|
+
Inflate2.prototype._processChunk = function(chunk, flushFlag, asyncCb) {
|
|
3505
3505
|
if (typeof asyncCb === "function") {
|
|
3506
3506
|
return zlib.Inflate._processChunk.call(this, chunk, flushFlag, asyncCb);
|
|
3507
3507
|
}
|
|
@@ -3513,8 +3513,8 @@ var require_sync_inflate = __commonJS({
|
|
|
3513
3513
|
let buffers = [];
|
|
3514
3514
|
let nread = 0;
|
|
3515
3515
|
let error;
|
|
3516
|
-
this.on("error", function(
|
|
3517
|
-
error =
|
|
3516
|
+
this.on("error", function(err2) {
|
|
3517
|
+
error = err2;
|
|
3518
3518
|
});
|
|
3519
3519
|
function handleChunk(availInAfter, availOutAfter) {
|
|
3520
3520
|
if (self2._hadError) {
|
|
@@ -3579,7 +3579,7 @@ var require_sync_inflate = __commonJS({
|
|
|
3579
3579
|
_close(this);
|
|
3580
3580
|
return buf;
|
|
3581
3581
|
};
|
|
3582
|
-
util.inherits(
|
|
3582
|
+
util.inherits(Inflate2, zlib.Inflate);
|
|
3583
3583
|
function zlibBufferSync(engine, buffer) {
|
|
3584
3584
|
if (typeof buffer === "string") {
|
|
3585
3585
|
buffer = Buffer.from(buffer);
|
|
@@ -3594,10 +3594,10 @@ var require_sync_inflate = __commonJS({
|
|
|
3594
3594
|
return engine._processChunk(buffer, flushFlag);
|
|
3595
3595
|
}
|
|
3596
3596
|
function inflateSync(buffer, opts) {
|
|
3597
|
-
return zlibBufferSync(new
|
|
3597
|
+
return zlibBufferSync(new Inflate2(opts), buffer);
|
|
3598
3598
|
}
|
|
3599
3599
|
module.exports = exports = inflateSync;
|
|
3600
|
-
exports.Inflate =
|
|
3600
|
+
exports.Inflate = Inflate2;
|
|
3601
3601
|
exports.createInflate = createInflate;
|
|
3602
3602
|
exports.inflateSync = inflateSync;
|
|
3603
3603
|
}
|
|
@@ -3686,9 +3686,9 @@ var require_parser_sync = __commonJS({
|
|
|
3686
3686
|
"To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0"
|
|
3687
3687
|
);
|
|
3688
3688
|
}
|
|
3689
|
-
let
|
|
3689
|
+
let err2;
|
|
3690
3690
|
function handleError(_err_) {
|
|
3691
|
-
|
|
3691
|
+
err2 = _err_;
|
|
3692
3692
|
}
|
|
3693
3693
|
let metaData;
|
|
3694
3694
|
function handleMetaData(_metaData_) {
|
|
@@ -3724,8 +3724,8 @@ var require_parser_sync = __commonJS({
|
|
|
3724
3724
|
});
|
|
3725
3725
|
parser.start();
|
|
3726
3726
|
reader.process();
|
|
3727
|
-
if (
|
|
3728
|
-
throw
|
|
3727
|
+
if (err2) {
|
|
3728
|
+
throw err2;
|
|
3729
3729
|
}
|
|
3730
3730
|
let inflateData = Buffer.concat(inflateDataList);
|
|
3731
3731
|
inflateDataList.length = 0;
|
|
@@ -3876,9 +3876,9 @@ var require_png = __commonJS({
|
|
|
3876
3876
|
this.data = parsedData;
|
|
3877
3877
|
callback(null, this);
|
|
3878
3878
|
}.bind(this);
|
|
3879
|
-
onError = function(
|
|
3879
|
+
onError = function(err2) {
|
|
3880
3880
|
this.removeListener("parsed", onParsed);
|
|
3881
|
-
callback(
|
|
3881
|
+
callback(err2, null);
|
|
3882
3882
|
}.bind(this);
|
|
3883
3883
|
this.once("parsed", onParsed);
|
|
3884
3884
|
this.once("error", onError);
|
|
@@ -4056,8 +4056,8 @@ var require_png2 = __commonJS({
|
|
|
4056
4056
|
cb = options;
|
|
4057
4057
|
options = void 0;
|
|
4058
4058
|
}
|
|
4059
|
-
exports.renderToBuffer(qrData, options, function(
|
|
4060
|
-
if (
|
|
4059
|
+
exports.renderToBuffer(qrData, options, function(err2, output) {
|
|
4060
|
+
if (err2) cb(err2);
|
|
4061
4061
|
let url = "data:image/png;base64,";
|
|
4062
4062
|
url += output.toString("base64");
|
|
4063
4063
|
cb(null, url);
|
|
@@ -4535,8 +4535,8 @@ var require_server = __commonJS({
|
|
|
4535
4535
|
return new Promise(function(resolve2, reject) {
|
|
4536
4536
|
try {
|
|
4537
4537
|
const data = QRCode.create(text2, params.opts);
|
|
4538
|
-
return renderFunc(data, params.opts, function(
|
|
4539
|
-
return
|
|
4538
|
+
return renderFunc(data, params.opts, function(err2, data2) {
|
|
4539
|
+
return err2 ? reject(err2) : resolve2(data2);
|
|
4540
4540
|
});
|
|
4541
4541
|
} catch (e) {
|
|
4542
4542
|
reject(e);
|
|
@@ -6037,7 +6037,7 @@ var require_parser2 = __commonJS({
|
|
|
6037
6037
|
throw new Error(str2);
|
|
6038
6038
|
},
|
|
6039
6039
|
parse: function parse(input) {
|
|
6040
|
-
var self2 = this, stack = [0], vstack = [null], lstack = [],
|
|
6040
|
+
var self2 = this, stack = [0], vstack = [null], lstack = [], table2 = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
|
|
6041
6041
|
this.lexer.setInput(input);
|
|
6042
6042
|
this.lexer.yy = this.yy;
|
|
6043
6043
|
this.yy.lexer = this.lexer;
|
|
@@ -6069,13 +6069,13 @@ var require_parser2 = __commonJS({
|
|
|
6069
6069
|
if (symbol === null || typeof symbol == "undefined") {
|
|
6070
6070
|
symbol = lex();
|
|
6071
6071
|
}
|
|
6072
|
-
action =
|
|
6072
|
+
action = table2[state] && table2[state][symbol];
|
|
6073
6073
|
}
|
|
6074
6074
|
if (typeof action === "undefined" || !action.length || !action[0]) {
|
|
6075
6075
|
var errStr = "";
|
|
6076
6076
|
if (!recovering) {
|
|
6077
6077
|
expected = [];
|
|
6078
|
-
for (p in
|
|
6078
|
+
for (p in table2[state]) if (this.terminals_[p] && p > 2) {
|
|
6079
6079
|
expected.push("'" + this.terminals_[p] + "'");
|
|
6080
6080
|
}
|
|
6081
6081
|
if (this.lexer.showPosition) {
|
|
@@ -6126,7 +6126,7 @@ var require_parser2 = __commonJS({
|
|
|
6126
6126
|
stack.push(this.productions_[action[1]][0]);
|
|
6127
6127
|
vstack.push(yyval.$);
|
|
6128
6128
|
lstack.push(yyval._$);
|
|
6129
|
-
newState =
|
|
6129
|
+
newState = table2[stack[stack.length - 2]][stack[stack.length - 1]];
|
|
6130
6130
|
stack.push(newState);
|
|
6131
6131
|
break;
|
|
6132
6132
|
case 3:
|
|
@@ -9236,7 +9236,7 @@ var require_code_gen = __commonJS({
|
|
|
9236
9236
|
SourceMap = require_source_map();
|
|
9237
9237
|
SourceNode = SourceMap.SourceNode;
|
|
9238
9238
|
}
|
|
9239
|
-
} catch (
|
|
9239
|
+
} catch (err2) {
|
|
9240
9240
|
}
|
|
9241
9241
|
var SourceMap;
|
|
9242
9242
|
if (!SourceNode) {
|
|
@@ -10586,42 +10586,42 @@ var require_nunjucks = __commonJS({
|
|
|
10586
10586
|
function lookupEscape(ch) {
|
|
10587
10587
|
return escapeMap[ch];
|
|
10588
10588
|
}
|
|
10589
|
-
function _prettifyError(path, withInternals,
|
|
10590
|
-
if (!
|
|
10591
|
-
|
|
10589
|
+
function _prettifyError(path, withInternals, err2) {
|
|
10590
|
+
if (!err2.Update) {
|
|
10591
|
+
err2 = new exports2.TemplateError(err2);
|
|
10592
10592
|
}
|
|
10593
|
-
|
|
10593
|
+
err2.Update(path);
|
|
10594
10594
|
if (!withInternals) {
|
|
10595
|
-
var old =
|
|
10596
|
-
|
|
10597
|
-
|
|
10595
|
+
var old = err2;
|
|
10596
|
+
err2 = new Error(old.message);
|
|
10597
|
+
err2.name = old.name;
|
|
10598
10598
|
}
|
|
10599
|
-
return
|
|
10599
|
+
return err2;
|
|
10600
10600
|
}
|
|
10601
10601
|
exports2._prettifyError = _prettifyError;
|
|
10602
10602
|
function TemplateError(message2, lineno, colno) {
|
|
10603
|
-
var
|
|
10603
|
+
var err2;
|
|
10604
10604
|
var cause;
|
|
10605
10605
|
if (message2 instanceof Error) {
|
|
10606
10606
|
cause = message2;
|
|
10607
10607
|
message2 = cause.name + ": " + cause.message;
|
|
10608
10608
|
}
|
|
10609
10609
|
if (Object.setPrototypeOf) {
|
|
10610
|
-
|
|
10611
|
-
Object.setPrototypeOf(
|
|
10610
|
+
err2 = new Error(message2);
|
|
10611
|
+
Object.setPrototypeOf(err2, TemplateError.prototype);
|
|
10612
10612
|
} else {
|
|
10613
|
-
|
|
10614
|
-
Object.defineProperty(
|
|
10613
|
+
err2 = this;
|
|
10614
|
+
Object.defineProperty(err2, "message", {
|
|
10615
10615
|
enumerable: false,
|
|
10616
10616
|
writable: true,
|
|
10617
10617
|
value: message2
|
|
10618
10618
|
});
|
|
10619
10619
|
}
|
|
10620
|
-
Object.defineProperty(
|
|
10620
|
+
Object.defineProperty(err2, "name", {
|
|
10621
10621
|
value: "Template render error"
|
|
10622
10622
|
});
|
|
10623
10623
|
if (Error.captureStackTrace) {
|
|
10624
|
-
Error.captureStackTrace(
|
|
10624
|
+
Error.captureStackTrace(err2, this.constructor);
|
|
10625
10625
|
}
|
|
10626
10626
|
var getStack;
|
|
10627
10627
|
if (cause) {
|
|
@@ -10640,18 +10640,18 @@ var require_nunjucks = __commonJS({
|
|
|
10640
10640
|
return stack;
|
|
10641
10641
|
};
|
|
10642
10642
|
}
|
|
10643
|
-
Object.defineProperty(
|
|
10643
|
+
Object.defineProperty(err2, "stack", {
|
|
10644
10644
|
get: function get2() {
|
|
10645
|
-
return getStack.call(
|
|
10645
|
+
return getStack.call(err2);
|
|
10646
10646
|
}
|
|
10647
10647
|
});
|
|
10648
|
-
Object.defineProperty(
|
|
10648
|
+
Object.defineProperty(err2, "cause", {
|
|
10649
10649
|
value: cause
|
|
10650
10650
|
});
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10651
|
+
err2.lineno = lineno;
|
|
10652
|
+
err2.colno = colno;
|
|
10653
|
+
err2.firstUpdate = true;
|
|
10654
|
+
err2.Update = function Update(path) {
|
|
10655
10655
|
var msg = "(" + (path || "unknown path") + ")";
|
|
10656
10656
|
if (this.firstUpdate) {
|
|
10657
10657
|
if (this.lineno && this.colno) {
|
|
@@ -10668,7 +10668,7 @@ var require_nunjucks = __commonJS({
|
|
|
10668
10668
|
this.firstUpdate = false;
|
|
10669
10669
|
return this;
|
|
10670
10670
|
};
|
|
10671
|
-
return
|
|
10671
|
+
return err2;
|
|
10672
10672
|
}
|
|
10673
10673
|
if (Object.setPrototypeOf) {
|
|
10674
10674
|
Object.setPrototypeOf(TemplateError.prototype, Error.prototype);
|
|
@@ -11819,8 +11819,8 @@ var require_nunjucks = __commonJS({
|
|
|
11819
11819
|
this._scopeClosers = _scopeClosers;
|
|
11820
11820
|
};
|
|
11821
11821
|
_proto._makeCallback = function _makeCallback(res) {
|
|
11822
|
-
var
|
|
11823
|
-
return "function(" +
|
|
11822
|
+
var err2 = this._tmpid();
|
|
11823
|
+
return "function(" + err2 + (res ? "," + res : "") + ") {\nif(" + err2 + ") { cb(" + err2 + "); return; }";
|
|
11824
11824
|
};
|
|
11825
11825
|
_proto._tmpid = function _tmpid() {
|
|
11826
11826
|
this.lastId++;
|
|
@@ -12704,9 +12704,9 @@ var require_nunjucks = __commonJS({
|
|
|
12704
12704
|
var globalRuntime = __webpack_require__(2);
|
|
12705
12705
|
var handleError = globalRuntime.handleError, Frame = globalRuntime.Frame;
|
|
12706
12706
|
var expressApp = __webpack_require__(22);
|
|
12707
|
-
function callbackAsap(cb,
|
|
12707
|
+
function callbackAsap(cb, err2, res) {
|
|
12708
12708
|
asap(function() {
|
|
12709
|
-
cb(
|
|
12709
|
+
cb(err2, res);
|
|
12710
12710
|
});
|
|
12711
12711
|
}
|
|
12712
12712
|
var noopTmplSrc = {
|
|
@@ -12883,16 +12883,16 @@ var require_nunjucks = __commonJS({
|
|
|
12883
12883
|
}
|
|
12884
12884
|
}
|
|
12885
12885
|
var syncResult;
|
|
12886
|
-
var createTemplate = function createTemplate2(
|
|
12887
|
-
if (!info && !
|
|
12888
|
-
|
|
12886
|
+
var createTemplate = function createTemplate2(err2, info) {
|
|
12887
|
+
if (!info && !err2 && !ignoreMissing) {
|
|
12888
|
+
err2 = new Error("template not found: " + name);
|
|
12889
12889
|
}
|
|
12890
|
-
if (
|
|
12890
|
+
if (err2) {
|
|
12891
12891
|
if (cb) {
|
|
12892
|
-
cb(
|
|
12892
|
+
cb(err2);
|
|
12893
12893
|
return;
|
|
12894
12894
|
} else {
|
|
12895
|
-
throw
|
|
12895
|
+
throw err2;
|
|
12896
12896
|
}
|
|
12897
12897
|
}
|
|
12898
12898
|
var newTmpl;
|
|
@@ -12911,9 +12911,9 @@ var require_nunjucks = __commonJS({
|
|
|
12911
12911
|
}
|
|
12912
12912
|
};
|
|
12913
12913
|
lib.asyncIter(this.loaders, function(loader2, i2, next, done) {
|
|
12914
|
-
function handle(
|
|
12915
|
-
if (
|
|
12916
|
-
done(
|
|
12914
|
+
function handle(err2, src) {
|
|
12915
|
+
if (err2) {
|
|
12916
|
+
done(err2);
|
|
12917
12917
|
} else if (src) {
|
|
12918
12918
|
src.loader = loader2;
|
|
12919
12919
|
done(null, src);
|
|
@@ -12939,11 +12939,11 @@ var require_nunjucks = __commonJS({
|
|
|
12939
12939
|
ctx = null;
|
|
12940
12940
|
}
|
|
12941
12941
|
var syncResult = null;
|
|
12942
|
-
this.getTemplate(name, function(
|
|
12943
|
-
if (
|
|
12944
|
-
callbackAsap(cb,
|
|
12945
|
-
} else if (
|
|
12946
|
-
throw
|
|
12942
|
+
this.getTemplate(name, function(err2, tmpl) {
|
|
12943
|
+
if (err2 && cb) {
|
|
12944
|
+
callbackAsap(cb, err2);
|
|
12945
|
+
} else if (err2) {
|
|
12946
|
+
throw err2;
|
|
12947
12947
|
} else {
|
|
12948
12948
|
syncResult = tmpl.render(ctx, cb);
|
|
12949
12949
|
}
|
|
@@ -13054,8 +13054,8 @@ var require_nunjucks = __commonJS({
|
|
|
13054
13054
|
if (eagerCompile) {
|
|
13055
13055
|
try {
|
|
13056
13056
|
this._compile();
|
|
13057
|
-
} catch (
|
|
13058
|
-
throw lib._prettifyError(this.path, this.env.opts.dev,
|
|
13057
|
+
} catch (err2) {
|
|
13058
|
+
throw lib._prettifyError(this.path, this.env.opts.dev, err2);
|
|
13059
13059
|
}
|
|
13060
13060
|
} else {
|
|
13061
13061
|
this.compiled = false;
|
|
@@ -13074,11 +13074,11 @@ var require_nunjucks = __commonJS({
|
|
|
13074
13074
|
try {
|
|
13075
13075
|
this.compile();
|
|
13076
13076
|
} catch (e) {
|
|
13077
|
-
var
|
|
13077
|
+
var err2 = lib._prettifyError(this.path, this.env.opts.dev, e);
|
|
13078
13078
|
if (cb) {
|
|
13079
|
-
return callbackAsap(cb,
|
|
13079
|
+
return callbackAsap(cb, err2);
|
|
13080
13080
|
} else {
|
|
13081
|
-
throw
|
|
13081
|
+
throw err2;
|
|
13082
13082
|
}
|
|
13083
13083
|
}
|
|
13084
13084
|
var context = new Context(ctx || {}, this.blocks, this.env);
|
|
@@ -13086,23 +13086,23 @@ var require_nunjucks = __commonJS({
|
|
|
13086
13086
|
frame.topLevel = true;
|
|
13087
13087
|
var syncResult = null;
|
|
13088
13088
|
var didError = false;
|
|
13089
|
-
this.rootRenderFunc(this.env, context, frame, globalRuntime, function(
|
|
13089
|
+
this.rootRenderFunc(this.env, context, frame, globalRuntime, function(err3, res) {
|
|
13090
13090
|
if (didError && cb && typeof res !== "undefined") {
|
|
13091
13091
|
return;
|
|
13092
13092
|
}
|
|
13093
|
-
if (
|
|
13094
|
-
|
|
13093
|
+
if (err3) {
|
|
13094
|
+
err3 = lib._prettifyError(_this6.path, _this6.env.opts.dev, err3);
|
|
13095
13095
|
didError = true;
|
|
13096
13096
|
}
|
|
13097
13097
|
if (cb) {
|
|
13098
13098
|
if (forceAsync) {
|
|
13099
|
-
callbackAsap(cb,
|
|
13099
|
+
callbackAsap(cb, err3, res);
|
|
13100
13100
|
} else {
|
|
13101
|
-
cb(
|
|
13101
|
+
cb(err3, res);
|
|
13102
13102
|
}
|
|
13103
13103
|
} else {
|
|
13104
|
-
if (
|
|
13105
|
-
throw
|
|
13104
|
+
if (err3) {
|
|
13105
|
+
throw err3;
|
|
13106
13106
|
}
|
|
13107
13107
|
syncResult = res;
|
|
13108
13108
|
}
|
|
@@ -13130,9 +13130,9 @@ var require_nunjucks = __commonJS({
|
|
|
13130
13130
|
var frame = parentFrame ? parentFrame.push() : new Frame();
|
|
13131
13131
|
frame.topLevel = true;
|
|
13132
13132
|
var context = new Context(ctx || {}, this.blocks, this.env);
|
|
13133
|
-
this.rootRenderFunc(this.env, context, frame, globalRuntime, function(
|
|
13134
|
-
if (
|
|
13135
|
-
cb(
|
|
13133
|
+
this.rootRenderFunc(this.env, context, frame, globalRuntime, function(err2) {
|
|
13134
|
+
if (err2) {
|
|
13135
|
+
cb(err2, null);
|
|
13136
13136
|
} else {
|
|
13137
13137
|
cb(null, context.getExported());
|
|
13138
13138
|
}
|
|
@@ -14553,14 +14553,14 @@ var require_nunjucks = __commonJS({
|
|
|
14553
14553
|
var _this2 = this;
|
|
14554
14554
|
var useCache = this.useCache;
|
|
14555
14555
|
var result;
|
|
14556
|
-
this.fetch(this.baseURL + "/" + name, function(
|
|
14557
|
-
if (
|
|
14556
|
+
this.fetch(this.baseURL + "/" + name, function(err2, src) {
|
|
14557
|
+
if (err2) {
|
|
14558
14558
|
if (cb) {
|
|
14559
|
-
cb(
|
|
14560
|
-
} else if (
|
|
14559
|
+
cb(err2.content);
|
|
14560
|
+
} else if (err2.status === 404) {
|
|
14561
14561
|
result = null;
|
|
14562
14562
|
} else {
|
|
14563
|
-
throw
|
|
14563
|
+
throw err2.content;
|
|
14564
14564
|
}
|
|
14565
14565
|
} else {
|
|
14566
14566
|
result = {
|
|
@@ -14856,15 +14856,15 @@ var require_nunjucks = __commonJS({
|
|
|
14856
14856
|
callback = callback || function() {
|
|
14857
14857
|
};
|
|
14858
14858
|
if (!_isArray(tasks)) {
|
|
14859
|
-
var
|
|
14860
|
-
return callback(
|
|
14859
|
+
var err2 = new Error("First argument to waterfall must be an array of functions");
|
|
14860
|
+
return callback(err2);
|
|
14861
14861
|
}
|
|
14862
14862
|
if (!tasks.length) {
|
|
14863
14863
|
return callback();
|
|
14864
14864
|
}
|
|
14865
14865
|
var wrapIterator = function(iterator) {
|
|
14866
|
-
return function(
|
|
14867
|
-
if (
|
|
14866
|
+
return function(err3) {
|
|
14867
|
+
if (err3) {
|
|
14868
14868
|
callback.apply(null, arguments);
|
|
14869
14869
|
callback = function() {
|
|
14870
14870
|
};
|
|
@@ -14986,9 +14986,9 @@ var require_nunjucks = __commonJS({
|
|
|
14986
14986
|
if (er instanceof Error) {
|
|
14987
14987
|
throw er;
|
|
14988
14988
|
}
|
|
14989
|
-
var
|
|
14990
|
-
|
|
14991
|
-
throw
|
|
14989
|
+
var err2 = new Error("Unhandled error." + (er ? " (" + er.message + ")" : ""));
|
|
14990
|
+
err2.context = er;
|
|
14991
|
+
throw err2;
|
|
14992
14992
|
}
|
|
14993
14993
|
var handler = events[type];
|
|
14994
14994
|
if (handler === void 0)
|
|
@@ -15221,9 +15221,9 @@ var require_nunjucks = __commonJS({
|
|
|
15221
15221
|
}
|
|
15222
15222
|
function once(emitter, name) {
|
|
15223
15223
|
return new Promise(function(resolve2, reject) {
|
|
15224
|
-
function errorListener(
|
|
15224
|
+
function errorListener(err2) {
|
|
15225
15225
|
emitter.removeListener(name, resolver);
|
|
15226
|
-
reject(
|
|
15226
|
+
reject(err2);
|
|
15227
15227
|
}
|
|
15228
15228
|
function resolver() {
|
|
15229
15229
|
if (typeof emitter.removeListener === "function") {
|
|
@@ -16227,8 +16227,8 @@ var require_nunjucks = __commonJS({
|
|
|
16227
16227
|
name = name.replace(/\\/g, "/");
|
|
16228
16228
|
try {
|
|
16229
16229
|
template = compiler.compile(str2, asyncFilters, extensions, name, env.opts);
|
|
16230
|
-
} catch (
|
|
16231
|
-
throw _prettifyError(name, false,
|
|
16230
|
+
} catch (err2) {
|
|
16231
|
+
throw _prettifyError(name, false, err2);
|
|
16232
16232
|
}
|
|
16233
16233
|
return {
|
|
16234
16234
|
name,
|
|
@@ -16603,8 +16603,8 @@ var require_liquid_node = __commonJS({
|
|
|
16603
16603
|
function promisify(fn) {
|
|
16604
16604
|
return function(...args2) {
|
|
16605
16605
|
return new Promise((resolve3, reject2) => {
|
|
16606
|
-
fn(...args2, (
|
|
16607
|
-
|
|
16606
|
+
fn(...args2, (err2, result) => {
|
|
16607
|
+
err2 ? reject2(err2) : resolve3(result);
|
|
16608
16608
|
});
|
|
16609
16609
|
});
|
|
16610
16610
|
};
|
|
@@ -16769,11 +16769,11 @@ var require_liquid_node = __commonJS({
|
|
|
16769
16769
|
}
|
|
16770
16770
|
var TRAIT = "__liquidClass__";
|
|
16771
16771
|
var LiquidError = class extends Error {
|
|
16772
|
-
constructor(
|
|
16773
|
-
super(typeof
|
|
16772
|
+
constructor(err2, token) {
|
|
16773
|
+
super(typeof err2 === "string" ? err2 : err2.message);
|
|
16774
16774
|
this.context = "";
|
|
16775
|
-
if (typeof
|
|
16776
|
-
Object.defineProperty(this, "originalError", { value:
|
|
16775
|
+
if (typeof err2 !== "string")
|
|
16776
|
+
Object.defineProperty(this, "originalError", { value: err2, enumerable: false });
|
|
16777
16777
|
Object.defineProperty(this, "token", { value: token, enumerable: false });
|
|
16778
16778
|
Object.defineProperty(this, TRAIT, { value: "LiquidError", enumerable: false });
|
|
16779
16779
|
}
|
|
@@ -16796,18 +16796,18 @@ var require_liquid_node = __commonJS({
|
|
|
16796
16796
|
}
|
|
16797
16797
|
};
|
|
16798
16798
|
var ParseError = class extends LiquidError {
|
|
16799
|
-
constructor(
|
|
16800
|
-
super(
|
|
16799
|
+
constructor(err2, token) {
|
|
16800
|
+
super(err2, token);
|
|
16801
16801
|
this.name = "ParseError";
|
|
16802
|
-
this.message =
|
|
16802
|
+
this.message = err2.message;
|
|
16803
16803
|
super.update();
|
|
16804
16804
|
}
|
|
16805
16805
|
};
|
|
16806
16806
|
var RenderError2 = class extends LiquidError {
|
|
16807
|
-
constructor(
|
|
16808
|
-
super(
|
|
16807
|
+
constructor(err2, tpl) {
|
|
16808
|
+
super(err2, tpl.token);
|
|
16809
16809
|
this.name = "RenderError";
|
|
16810
|
-
this.message =
|
|
16810
|
+
this.message = err2.message;
|
|
16811
16811
|
super.update();
|
|
16812
16812
|
}
|
|
16813
16813
|
static is(obj) {
|
|
@@ -16828,10 +16828,10 @@ var require_liquid_node = __commonJS({
|
|
|
16828
16828
|
}
|
|
16829
16829
|
};
|
|
16830
16830
|
var UndefinedVariableError = class extends LiquidError {
|
|
16831
|
-
constructor(
|
|
16832
|
-
super(
|
|
16831
|
+
constructor(err2, token) {
|
|
16832
|
+
super(err2, token);
|
|
16833
16833
|
this.name = "UndefinedVariableError";
|
|
16834
|
-
this.message =
|
|
16834
|
+
this.message = err2.message;
|
|
16835
16835
|
super.update();
|
|
16836
16836
|
}
|
|
16837
16837
|
};
|
|
@@ -17007,8 +17007,8 @@ var require_liquid_node = __commonJS({
|
|
|
17007
17007
|
write(html) {
|
|
17008
17008
|
this.stream.write(stringify(html));
|
|
17009
17009
|
}
|
|
17010
|
-
error(
|
|
17011
|
-
this.stream.emit("error",
|
|
17010
|
+
error(err2) {
|
|
17011
|
+
this.stream.emit("error", err2);
|
|
17012
17012
|
}
|
|
17013
17013
|
end() {
|
|
17014
17014
|
this.stream.end();
|
|
@@ -17098,9 +17098,9 @@ var require_liquid_node = __commonJS({
|
|
|
17098
17098
|
value = toPromise(value);
|
|
17099
17099
|
if (isPromise(value))
|
|
17100
17100
|
value = await value;
|
|
17101
|
-
} catch (
|
|
17101
|
+
} catch (err2) {
|
|
17102
17102
|
next = "throw";
|
|
17103
|
-
value =
|
|
17103
|
+
value = err2;
|
|
17104
17104
|
}
|
|
17105
17105
|
} while (!done);
|
|
17106
17106
|
return value;
|
|
@@ -17119,9 +17119,9 @@ var require_liquid_node = __commonJS({
|
|
|
17119
17119
|
if (isIterator(value)) {
|
|
17120
17120
|
try {
|
|
17121
17121
|
value = toValueSync(value);
|
|
17122
|
-
} catch (
|
|
17122
|
+
} catch (err2) {
|
|
17123
17123
|
next = "throw";
|
|
17124
|
-
value =
|
|
17124
|
+
value = err2;
|
|
17125
17125
|
}
|
|
17126
17126
|
}
|
|
17127
17127
|
} while (!done);
|
|
@@ -17445,16 +17445,16 @@ var require_liquid_node = __commonJS({
|
|
|
17445
17445
|
this.trimLeft = false;
|
|
17446
17446
|
this.trimRight = false;
|
|
17447
17447
|
const tl = input[contentBegin] === "-";
|
|
17448
|
-
const
|
|
17448
|
+
const tr2 = input[contentEnd - 1] === "-";
|
|
17449
17449
|
let l3 = tl ? contentBegin + 1 : contentBegin;
|
|
17450
|
-
let r =
|
|
17450
|
+
let r = tr2 ? contentEnd - 1 : contentEnd;
|
|
17451
17451
|
while (l3 < r && TYPES[input.charCodeAt(l3)] & BLANK)
|
|
17452
17452
|
l3++;
|
|
17453
17453
|
while (r > l3 && TYPES[input.charCodeAt(r - 1)] & BLANK)
|
|
17454
17454
|
r--;
|
|
17455
17455
|
this.contentRange = [l3, r];
|
|
17456
17456
|
this.trimLeft = tl || trimLeft2;
|
|
17457
|
-
this.trimRight =
|
|
17457
|
+
this.trimRight = tr2 || trimRight2;
|
|
17458
17458
|
}
|
|
17459
17459
|
get content() {
|
|
17460
17460
|
return this.input.slice(this.contentRange[0], this.contentRange[1]);
|
|
@@ -17689,7 +17689,7 @@ var require_liquid_node = __commonJS({
|
|
|
17689
17689
|
var Render = class {
|
|
17690
17690
|
renderTemplatesToNodeStream(templates, ctx) {
|
|
17691
17691
|
const emitter = new StreamedEmitter();
|
|
17692
|
-
Promise.resolve().then(() => toPromise(this.renderTemplates(templates, ctx, emitter))).then(() => emitter.end(), (
|
|
17692
|
+
Promise.resolve().then(() => toPromise(this.renderTemplates(templates, ctx, emitter))).then(() => emitter.end(), (err2) => emitter.error(err2));
|
|
17693
17693
|
return emitter.stream;
|
|
17694
17694
|
}
|
|
17695
17695
|
*renderTemplates(templates, ctx, emitter) {
|
|
@@ -17706,11 +17706,11 @@ var require_liquid_node = __commonJS({
|
|
|
17706
17706
|
if (ctx.breakCalled || ctx.continueCalled)
|
|
17707
17707
|
break;
|
|
17708
17708
|
} catch (e) {
|
|
17709
|
-
const
|
|
17709
|
+
const err2 = LiquidError.is(e) ? e : new RenderError2(e, tpl);
|
|
17710
17710
|
if (ctx.opts.catchAllErrors)
|
|
17711
|
-
errors.push(
|
|
17711
|
+
errors.push(err2);
|
|
17712
17712
|
else
|
|
17713
|
-
throw
|
|
17713
|
+
throw err2;
|
|
17714
17714
|
}
|
|
17715
17715
|
}
|
|
17716
17716
|
if (errors.length) {
|
|
@@ -17973,7 +17973,7 @@ var require_liquid_node = __commonJS({
|
|
|
17973
17973
|
try {
|
|
17974
17974
|
await statAsync(filepath);
|
|
17975
17975
|
return true;
|
|
17976
|
-
} catch (
|
|
17976
|
+
} catch (err2) {
|
|
17977
17977
|
return false;
|
|
17978
17978
|
}
|
|
17979
17979
|
}
|
|
@@ -17984,7 +17984,7 @@ var require_liquid_node = __commonJS({
|
|
|
17984
17984
|
try {
|
|
17985
17985
|
fs$1.statSync(filepath);
|
|
17986
17986
|
return true;
|
|
17987
|
-
} catch (
|
|
17987
|
+
} catch (err2) {
|
|
17988
17988
|
return false;
|
|
17989
17989
|
}
|
|
17990
17990
|
}
|
|
@@ -19281,10 +19281,10 @@ var require_liquid_node = __commonJS({
|
|
|
19281
19281
|
return fs2.dirname(path2);
|
|
19282
19282
|
}
|
|
19283
19283
|
lookupError(file, roots) {
|
|
19284
|
-
const
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
return
|
|
19284
|
+
const err2 = new Error("ENOENT");
|
|
19285
|
+
err2.message = `ENOENT: Failed to lookup "${file}" in "${roots}"`;
|
|
19286
|
+
err2.code = "ENOENT";
|
|
19287
|
+
return err2;
|
|
19288
19288
|
}
|
|
19289
19289
|
};
|
|
19290
19290
|
var Parser = class {
|
|
@@ -19313,11 +19313,11 @@ var require_liquid_node = __commonJS({
|
|
|
19313
19313
|
while (token = tokens.shift()) {
|
|
19314
19314
|
try {
|
|
19315
19315
|
templates.push(this.parseToken(token, tokens));
|
|
19316
|
-
} catch (
|
|
19316
|
+
} catch (err2) {
|
|
19317
19317
|
if (this.liquid.options.catchAllErrors)
|
|
19318
|
-
errors.push(
|
|
19318
|
+
errors.push(err2);
|
|
19319
19319
|
else
|
|
19320
|
-
throw
|
|
19320
|
+
throw err2;
|
|
19321
19321
|
}
|
|
19322
19322
|
}
|
|
19323
19323
|
if (errors.length)
|
|
@@ -19355,9 +19355,9 @@ var require_liquid_node = __commonJS({
|
|
|
19355
19355
|
cache.write(key, taskOrTpl);
|
|
19356
19356
|
try {
|
|
19357
19357
|
return yield taskOrTpl;
|
|
19358
|
-
} catch (
|
|
19358
|
+
} catch (err2) {
|
|
19359
19359
|
cache.remove(key);
|
|
19360
|
-
throw
|
|
19360
|
+
throw err2;
|
|
19361
19361
|
}
|
|
19362
19362
|
}
|
|
19363
19363
|
*_parseFile(file, sync, type = exports.LookupType.Root, currentFile) {
|
|
@@ -19724,14 +19724,14 @@ var require_liquid_node = __commonJS({
|
|
|
19724
19724
|
this.context.memoryLimit.use(array.length);
|
|
19725
19725
|
return Array.prototype.filter.call(array, (x2) => !isNil(toValue(x2)));
|
|
19726
19726
|
}
|
|
19727
|
-
function
|
|
19727
|
+
function concat2(v2, arg = []) {
|
|
19728
19728
|
const lhs = toArray(v2);
|
|
19729
19729
|
const rhs = toArray(arg);
|
|
19730
19730
|
this.context.memoryLimit.use(lhs.length + rhs.length);
|
|
19731
19731
|
return Array.prototype.concat.call(lhs, rhs);
|
|
19732
19732
|
}
|
|
19733
19733
|
function push(v2, arg) {
|
|
19734
|
-
return
|
|
19734
|
+
return concat2.call(this, v2, [arg]);
|
|
19735
19735
|
}
|
|
19736
19736
|
function unshift(v2, arg) {
|
|
19737
19737
|
const array = toArray(v2);
|
|
@@ -19914,7 +19914,7 @@ var require_liquid_node = __commonJS({
|
|
|
19914
19914
|
map,
|
|
19915
19915
|
sum,
|
|
19916
19916
|
compact,
|
|
19917
|
-
concat,
|
|
19917
|
+
concat: concat2,
|
|
19918
19918
|
push,
|
|
19919
19919
|
unshift,
|
|
19920
19920
|
pop,
|
|
@@ -22099,10 +22099,10 @@ function bwipp_processoptions() {
|
|
|
22099
22099
|
}
|
|
22100
22100
|
function bwipp_fifocache() {
|
|
22101
22101
|
var limit = $k[--$j];
|
|
22102
|
-
var
|
|
22102
|
+
var max2 = $k[--$j];
|
|
22103
22103
|
var dict = {
|
|
22104
22104
|
limit,
|
|
22105
|
-
max,
|
|
22105
|
+
max: max2,
|
|
22106
22106
|
cache: /* @__PURE__ */ new Map(),
|
|
22107
22107
|
fifo: [],
|
|
22108
22108
|
state: {
|
|
@@ -22131,7 +22131,7 @@ function bwipp_fifocache_fetch() {
|
|
|
22131
22131
|
return;
|
|
22132
22132
|
}
|
|
22133
22133
|
var fifo = self2.fifo;
|
|
22134
|
-
var
|
|
22134
|
+
var max2 = self2.max;
|
|
22135
22135
|
var limit = self2.limit;
|
|
22136
22136
|
genfn();
|
|
22137
22137
|
var result = $k[$j - 1];
|
|
@@ -22140,7 +22140,7 @@ function bwipp_fifocache_fetch() {
|
|
|
22140
22140
|
var state = self2.state;
|
|
22141
22141
|
if (card < limit) {
|
|
22142
22142
|
for (; ; ) {
|
|
22143
|
-
if (state.total + card <= limit && state.cnt <
|
|
22143
|
+
if (state.total + card <= limit && state.cnt < max2) {
|
|
22144
22144
|
break;
|
|
22145
22145
|
}
|
|
22146
22146
|
var oldkey = fifo[state.head];
|
|
@@ -22148,11 +22148,11 @@ function bwipp_fifocache_fetch() {
|
|
|
22148
22148
|
cardfn();
|
|
22149
22149
|
state.total = state.total - $k[--$j];
|
|
22150
22150
|
cache.delete(oldkey);
|
|
22151
|
-
state.head = (state.head + 1) %
|
|
22151
|
+
state.head = (state.head + 1) % max2;
|
|
22152
22152
|
state.cnt--;
|
|
22153
22153
|
}
|
|
22154
22154
|
cache.set(key, result);
|
|
22155
|
-
fifo[(state.head + state.cnt) %
|
|
22155
|
+
fifo[(state.head + state.cnt) % max2] = key;
|
|
22156
22156
|
state.cnt++;
|
|
22157
22157
|
state.total = state.total + card;
|
|
22158
22158
|
}
|
|
@@ -28009,10 +28009,10 @@ function bwipp_rsecbinary() {
|
|
|
28009
28009
|
if ($_.rsprod() === true) {
|
|
28010
28010
|
break;
|
|
28011
28011
|
}
|
|
28012
|
-
var
|
|
28012
|
+
var _b2 = $k[--$j];
|
|
28013
28013
|
var _c = $k[--$j];
|
|
28014
28014
|
var _d = $k[--$j];
|
|
28015
|
-
$put(_d, _c,
|
|
28015
|
+
$put(_d, _c, _b2);
|
|
28016
28016
|
$j--;
|
|
28017
28017
|
}
|
|
28018
28018
|
$_ = $__;
|
|
@@ -29700,8 +29700,8 @@ function bwipp_isbn() {
|
|
|
29700
29700
|
$k[$j++] = "ISBN-13 penultimate character must be a dash";
|
|
29701
29701
|
bwipp_raiseerror();
|
|
29702
29702
|
}
|
|
29703
|
-
var
|
|
29704
|
-
if (
|
|
29703
|
+
var _a2 = $get($_.barcode, 16);
|
|
29704
|
+
if (_a2 < 48 || _a2 > 57) {
|
|
29705
29705
|
$k[$j++] = "bwipp.isbn13character17#8115";
|
|
29706
29706
|
$k[$j++] = "ISBN-13 final character must be a digit";
|
|
29707
29707
|
bwipp_raiseerror();
|
|
@@ -30014,8 +30014,8 @@ function bwipp_ismn() {
|
|
|
30014
30014
|
$k[$j++] = "ISMN-13 penultimate character must be a dash";
|
|
30015
30015
|
bwipp_raiseerror();
|
|
30016
30016
|
}
|
|
30017
|
-
var
|
|
30018
|
-
if (
|
|
30017
|
+
var _a2 = $get($_.barcode, 16);
|
|
30018
|
+
if (_a2 < 48 || _a2 > 57) {
|
|
30019
30019
|
$k[$j++] = "bwipp.ismn13character17#8438";
|
|
30020
30020
|
$k[$j++] = "ISMN-13 final character must be a digit";
|
|
30021
30021
|
bwipp_raiseerror();
|
|
@@ -32339,10 +32339,10 @@ function bwipp_code32() {
|
|
|
32339
32339
|
}
|
|
32340
32340
|
$puti($_.barcode, 6 - $_.val.length, $_.val);
|
|
32341
32341
|
for (var _Z = 0; _Z <= 5; _Z += 1) {
|
|
32342
|
-
var
|
|
32342
|
+
var _b2 = $get($_.barcode, _Z);
|
|
32343
32343
|
$k[$j++] = _Z;
|
|
32344
|
-
$k[$j++] =
|
|
32345
|
-
$k[$j++] =
|
|
32344
|
+
$k[$j++] = _b2;
|
|
32345
|
+
$k[$j++] = _b2;
|
|
32346
32346
|
for (var _c = 0, _d = "AEIO".length; _c < _d; _c++) {
|
|
32347
32347
|
var _e2 = $get("AEIO", _c);
|
|
32348
32348
|
var _f = $k[--$j];
|
|
@@ -32918,10 +32918,10 @@ function bwipp_itf14() {
|
|
|
32918
32918
|
bwipp_raiseerror();
|
|
32919
32919
|
}
|
|
32920
32920
|
} else {
|
|
32921
|
-
var
|
|
32922
|
-
$puti(
|
|
32923
|
-
$put(
|
|
32924
|
-
$_.barcode =
|
|
32921
|
+
var _b2 = $s(14);
|
|
32922
|
+
$puti(_b2, 0, $_.barcode);
|
|
32923
|
+
$put(_b2, 13, $_.checksum + 48);
|
|
32924
|
+
$_.barcode = _b2;
|
|
32925
32925
|
var _g = $_.hasspace ? 2 : 1;
|
|
32926
32926
|
var _h = $s($_.text.length + _g);
|
|
32927
32927
|
$puti(_h, _h.length - 2, " ");
|
|
@@ -33176,12 +33176,12 @@ function bwipp_databaromni() {
|
|
|
33176
33176
|
for (var _S = 0; _S <= 12; _S += 1) {
|
|
33177
33177
|
$_.i = _S;
|
|
33178
33178
|
var _W = $get($_.barcode, $_.i + 4);
|
|
33179
|
-
var
|
|
33179
|
+
var _a2 = $_.checksum;
|
|
33180
33180
|
var _Z = _W - 48;
|
|
33181
33181
|
if ($_.i % 2 == 0) {
|
|
33182
33182
|
_Z = _Z * 3;
|
|
33183
33183
|
}
|
|
33184
|
-
$_.checksum = $f(
|
|
33184
|
+
$_.checksum = $f(_a2 + _Z);
|
|
33185
33185
|
}
|
|
33186
33186
|
$_.checksum = (10 - $_.checksum % 10) % 10;
|
|
33187
33187
|
if ($_.barcode.length == 18) {
|
|
@@ -34472,8 +34472,8 @@ function bwipp_databarexpanded() {
|
|
|
34472
34472
|
$k[$j++] = Infinity;
|
|
34473
34473
|
for (var _X = 48; _X <= 57; _X += 1) {
|
|
34474
34474
|
var _Z = $strcpy($s(5), "00000");
|
|
34475
|
-
var
|
|
34476
|
-
$puti(_Z, 5 -
|
|
34475
|
+
var _b2 = $cvrs($s(5), _X - 43, 2);
|
|
34476
|
+
$puti(_Z, 5 - _b2.length, _b2);
|
|
34477
34477
|
$k[$j++] = _X;
|
|
34478
34478
|
$k[$j++] = _Z;
|
|
34479
34479
|
}
|
|
@@ -36077,8 +36077,8 @@ function bwipp_gs1northamericancoupon() {
|
|
|
36077
36077
|
$puti($_.coupontext, $_.gcp.length, "-");
|
|
36078
36078
|
$puti($_.coupontext, $_.gcp.length + 1, $_.cod);
|
|
36079
36079
|
if ($_.includetext) {
|
|
36080
|
-
var
|
|
36081
|
-
$put($_.options, "text1",
|
|
36080
|
+
var _b2 = $eq($_.text1, "unset") ? $_.coupontext : $_.text1;
|
|
36081
|
+
$put($_.options, "text1", _b2);
|
|
36082
36082
|
var _h = $_.options;
|
|
36083
36083
|
var _g = "text1font";
|
|
36084
36084
|
var _f = $eq($_.text1font, "unset") ? "OCR-B" : $_.text1font;
|
|
@@ -37061,8 +37061,8 @@ function bwipp_rationalizedCodabar() {
|
|
|
37061
37061
|
bwipp_raiseerror();
|
|
37062
37062
|
}
|
|
37063
37063
|
}
|
|
37064
|
-
for (var
|
|
37065
|
-
if (!$has($_.bodyvals, $geti($_.barcode,
|
|
37064
|
+
for (var _a2 = 1, _Z = $_.barcode.length - 2; _a2 <= _Z; _a2 += 1) {
|
|
37065
|
+
if (!$has($_.bodyvals, $geti($_.barcode, _a2, 1))) {
|
|
37066
37066
|
$k[$j++] = "bwipp.rationalizedCodabarBadCharacter#15513";
|
|
37067
37067
|
$k[$j++] = "Codabar body must contain only digits and symbols - $ : / . +";
|
|
37068
37068
|
bwipp_raiseerror();
|
|
@@ -38015,9 +38015,9 @@ function bwipp_auspost() {
|
|
|
38015
38015
|
$j--;
|
|
38016
38016
|
$_.rstable = $_.rstable;
|
|
38017
38017
|
$_.rspoly = $a([1, 0, 0, 0, 0]);
|
|
38018
|
-
for (var
|
|
38019
|
-
$k[$j++] = $bs(1,
|
|
38020
|
-
for (var _c =
|
|
38018
|
+
for (var _b2 = 1; _b2 <= 4; _b2 += 1) {
|
|
38019
|
+
$k[$j++] = $bs(1, _b2);
|
|
38020
|
+
for (var _c = _b2; _c >= 1; _c -= 1) {
|
|
38021
38021
|
var _d = $_.rspoly;
|
|
38022
38022
|
var _e2 = $get(_d, _c - 1);
|
|
38023
38023
|
var _g = $get($_.rspoly, _c);
|
|
@@ -38684,10 +38684,10 @@ function bwipp_msi() {
|
|
|
38684
38684
|
});
|
|
38685
38685
|
var _Y = $k[--$j];
|
|
38686
38686
|
$j--;
|
|
38687
|
-
var
|
|
38687
|
+
var _b2 = $k[--$j];
|
|
38688
38688
|
var _d = $s($_.code.length + 1);
|
|
38689
38689
|
$puti(_d, 0, $_.code);
|
|
38690
|
-
$put(_d, $_.code.length, (10 - $f(
|
|
38690
|
+
$put(_d, $_.code.length, (10 - $f(_b2 + _Y) % 10) % 10 + 48);
|
|
38691
38691
|
$k[$j++] = _d;
|
|
38692
38692
|
};
|
|
38693
38693
|
$_.mod11 = function() {
|
|
@@ -39096,10 +39096,10 @@ function bwipp_telepen() {
|
|
|
39096
39096
|
$k[$j++] = -1;
|
|
39097
39097
|
} else {
|
|
39098
39098
|
var _Y = $get($_.np, 0);
|
|
39099
|
-
var
|
|
39099
|
+
var _b2 = $get($_.np, 1) - 48;
|
|
39100
39100
|
$k[$j++] = _Y - 48;
|
|
39101
|
-
$k[$j++] =
|
|
39102
|
-
if (
|
|
39101
|
+
$k[$j++] = _b2;
|
|
39102
|
+
if (_b2 != 40) {
|
|
39103
39103
|
var _c = $k[--$j];
|
|
39104
39104
|
var _d = $k[--$j];
|
|
39105
39105
|
$k[$j++] = $f(_c + _d * 10) + 10;
|
|
@@ -42103,11 +42103,11 @@ function bwipp_flattermarken() {
|
|
|
42103
42103
|
_X[_U] = $_.height;
|
|
42104
42104
|
}
|
|
42105
42105
|
_X = $a(_X);
|
|
42106
|
-
var
|
|
42107
|
-
for (var _Z = 0,
|
|
42108
|
-
|
|
42106
|
+
var _b2 = [];
|
|
42107
|
+
for (var _Z = 0, _a2 = ~~(($_.sbs.length + 1) / 2); _Z < _a2; _Z++) {
|
|
42108
|
+
_b2[_Z] = 0;
|
|
42109
42109
|
}
|
|
42110
|
-
|
|
42110
|
+
_b2 = $a(_b2);
|
|
42111
42111
|
var _g = $a([$a([$_.barcode, 0, 0, $_.text1font, $_.text1size])]);
|
|
42112
42112
|
$k[$j++] = "ren";
|
|
42113
42113
|
$k[$j++] = "renlinear";
|
|
@@ -42116,7 +42116,7 @@ function bwipp_flattermarken() {
|
|
|
42116
42116
|
$k[$j++] = "bhs";
|
|
42117
42117
|
$k[$j++] = _X;
|
|
42118
42118
|
$k[$j++] = "bbs";
|
|
42119
|
-
$k[$j++] =
|
|
42119
|
+
$k[$j++] = _b2;
|
|
42120
42120
|
$k[$j++] = "txt";
|
|
42121
42121
|
$k[$j++] = _g;
|
|
42122
42122
|
$k[$j++] = "text1xalign";
|
|
@@ -42353,11 +42353,11 @@ function bwipp_symbol() {
|
|
|
42353
42353
|
$k[$j++] = 1;
|
|
42354
42354
|
}
|
|
42355
42355
|
$k[$j++] = 1;
|
|
42356
|
-
var
|
|
42357
|
-
$_.symbol_zebrasbs =
|
|
42356
|
+
var _a2 = $a();
|
|
42357
|
+
$_.symbol_zebrasbs = _a2;
|
|
42358
42358
|
var _d = [];
|
|
42359
|
-
for (var
|
|
42360
|
-
_d[
|
|
42359
|
+
for (var _b2 = 0, _c = ~~($_.symbol_zebrasbs.length / 2) + 1; _b2 < _c; _b2++) {
|
|
42360
|
+
_d[_b2] = 1;
|
|
42361
42361
|
}
|
|
42362
42362
|
_d = $a(_d);
|
|
42363
42363
|
$_.symbol_zebrabhs = _d;
|
|
@@ -58478,11 +58478,11 @@ function bwipp_ultracode() {
|
|
|
58478
58478
|
$k[$j++] = 0;
|
|
58479
58479
|
}
|
|
58480
58480
|
$_.coeffs = $a();
|
|
58481
|
-
for (var
|
|
58481
|
+
for (var _b2 = 1, _a2 = $_.k; _b2 <= _a2; _b2 += 1) {
|
|
58482
58482
|
var _c = $_.coeffs;
|
|
58483
|
-
$put(_c,
|
|
58484
|
-
$k[$j++] = $get($_.rsalog,
|
|
58485
|
-
for (var _g =
|
|
58483
|
+
$put(_c, _b2, $get(_c, _b2 - 1));
|
|
58484
|
+
$k[$j++] = $get($_.rsalog, _b2);
|
|
58485
|
+
for (var _g = _b2 - 1; _g >= 1; _g -= 1) {
|
|
58486
58486
|
var _h = $_.coeffs;
|
|
58487
58487
|
var _i = $get(_h, _g);
|
|
58488
58488
|
var _j = $k[$j - 1];
|
|
@@ -59039,9 +59039,9 @@ function bwipp_gs1_cc() {
|
|
|
59039
59039
|
$put(_Y, 1, 94);
|
|
59040
59040
|
}
|
|
59041
59041
|
var _Z = $k[--$j];
|
|
59042
|
-
var
|
|
59042
|
+
var _a2 = $k[--$j];
|
|
59043
59043
|
var _c = $strcpy($s(7), "0000000");
|
|
59044
|
-
var _e2 = $cvrs($s(7),
|
|
59044
|
+
var _e2 = $cvrs($s(7), _a2 + 8, 2);
|
|
59045
59045
|
$puti(_c, 7 - _e2.length, _e2);
|
|
59046
59046
|
$k[$j++] = _Z;
|
|
59047
59047
|
$k[$j++] = _c;
|
|
@@ -62377,8 +62377,8 @@ function bwipp_databarstackedcomposite() {
|
|
|
62377
62377
|
$_.sepfinder = function() {
|
|
62378
62378
|
var _W = $k[--$j];
|
|
62379
62379
|
$_.fp = _W;
|
|
62380
|
-
for (var
|
|
62381
|
-
$_.i =
|
|
62380
|
+
for (var _a2 = $_.fp, _Z = $_.fp + 12; _a2 <= _Z; _a2 += 1) {
|
|
62381
|
+
$_.i = _a2;
|
|
62382
62382
|
if ($get($_.bot, $_.i) == 0) {
|
|
62383
62383
|
if ($get($_.bot, $_.i - 1) == 1) {
|
|
62384
62384
|
$k[$j++] = 1;
|
|
@@ -62662,8 +62662,8 @@ function bwipp_databarstackedomnicomposite() {
|
|
|
62662
62662
|
$_.sepfinder = function() {
|
|
62663
62663
|
var _W = $k[--$j];
|
|
62664
62664
|
$_.fp = _W;
|
|
62665
|
-
for (var
|
|
62666
|
-
$_.i =
|
|
62665
|
+
for (var _a2 = $_.fp, _Z = $_.fp + 12; _a2 <= _Z; _a2 += 1) {
|
|
62666
|
+
$_.i = _a2;
|
|
62667
62667
|
if ($get($_.bot, $_.i) == 0) {
|
|
62668
62668
|
if ($get($_.bot, $_.i - 1) == 1) {
|
|
62669
62669
|
$k[$j++] = 1;
|
|
@@ -63249,9 +63249,9 @@ function bwipp_databarlimitedcomposite() {
|
|
|
63249
63249
|
}
|
|
63250
63250
|
$_.linpixs = $a();
|
|
63251
63251
|
$k[$j++] = Infinity;
|
|
63252
|
-
var
|
|
63253
|
-
for (var
|
|
63254
|
-
$k[$j++] = 1 - $get(
|
|
63252
|
+
var _a2 = $_.linpixs;
|
|
63253
|
+
for (var _b2 = 0, _c = _a2.length; _b2 < _c; _b2++) {
|
|
63254
|
+
$k[$j++] = 1 - $get(_a2, _b2);
|
|
63255
63255
|
}
|
|
63256
63256
|
$_.sep = $a();
|
|
63257
63257
|
$puti($_.sep, 0, $_.databarlimitedcomposite_sepleft);
|
|
@@ -64896,8 +64896,8 @@ function bwipp_gs1qrcode() {
|
|
|
64896
64896
|
$puti($_.barcode, $_.j, "^FNC1");
|
|
64897
64897
|
$_.j = $_.j + 5;
|
|
64898
64898
|
} else {
|
|
64899
|
-
var
|
|
64900
|
-
$put($_.barcode, $_.j,
|
|
64899
|
+
var _b2 = $k[--$j];
|
|
64900
|
+
$put($_.barcode, $_.j, _b2);
|
|
64901
64901
|
$_.j = $_.j + 1;
|
|
64902
64902
|
}
|
|
64903
64903
|
});
|
|
@@ -65027,8 +65027,8 @@ function bwipp_gs1dotcode() {
|
|
|
65027
65027
|
$puti($_.barcode, $_.j, "^FNC1");
|
|
65028
65028
|
$_.j = $_.j + 5;
|
|
65029
65029
|
} else {
|
|
65030
|
-
var
|
|
65031
|
-
$put($_.barcode, $_.j,
|
|
65030
|
+
var _b2 = $k[--$j];
|
|
65031
|
+
$put($_.barcode, $_.j, _b2);
|
|
65032
65032
|
$_.j = $_.j + 1;
|
|
65033
65033
|
}
|
|
65034
65034
|
});
|
|
@@ -67264,9 +67264,9 @@ function bwipp_validatetext() {
|
|
|
67264
67264
|
} else {
|
|
67265
67265
|
$j--;
|
|
67266
67266
|
}
|
|
67267
|
-
var
|
|
67268
|
-
$k[$j++] =
|
|
67269
|
-
if ($ne(
|
|
67267
|
+
var _b2 = $get($_.td, "yalign");
|
|
67268
|
+
$k[$j++] = _b2;
|
|
67269
|
+
if ($ne(_b2, "unset")) {
|
|
67270
67270
|
var _c = $k[--$j];
|
|
67271
67271
|
if (!$has($_.validatetext_yalignopts, _c)) {
|
|
67272
67272
|
$k[$j++] = "yalign";
|
|
@@ -67718,7 +67718,7 @@ var BWIPJS = (function() {
|
|
|
67718
67718
|
var round = Math.round;
|
|
67719
67719
|
var ceil = Math.ceil;
|
|
67720
67720
|
var min = Math.min;
|
|
67721
|
-
var
|
|
67721
|
+
var max2 = Math.max;
|
|
67722
67722
|
function BWIPJS2(drawing) {
|
|
67723
67723
|
if (this.constructor !== BWIPJS2) {
|
|
67724
67724
|
return new BWIPJS2(drawing);
|
|
@@ -68135,9 +68135,9 @@ var BWIPJS = (function() {
|
|
|
68135
68135
|
var pts2 = a2.poly;
|
|
68136
68136
|
self2.transform(pts2);
|
|
68137
68137
|
var x02 = min(pts2[0][0], pts2[2][0]);
|
|
68138
|
-
var x12 =
|
|
68138
|
+
var x12 = max2(pts2[0][0], pts2[2][0]);
|
|
68139
68139
|
var y02 = min(pts2[0][1], pts2[2][1]);
|
|
68140
|
-
var y12 =
|
|
68140
|
+
var y12 = max2(pts2[0][1], pts2[2][1]);
|
|
68141
68141
|
self2.drawing.polygon([
|
|
68142
68142
|
[x02 - bigw2, y02 - bigh2],
|
|
68143
68143
|
[x02 - bigw2, y12 + bigh2 + 1],
|
|
@@ -76336,11 +76336,11 @@ function parseNumericString(str2) {
|
|
|
76336
76336
|
}
|
|
76337
76337
|
|
|
76338
76338
|
// node_modules/.pnpm/n2words@6.1.2/node_modules/n2words/src/utils/check-max.js
|
|
76339
|
-
function checkMax(value,
|
|
76340
|
-
if (
|
|
76341
|
-
if (value <
|
|
76342
|
-
const exponent =
|
|
76343
|
-
const largest =
|
|
76339
|
+
function checkMax(value, max2, fraction) {
|
|
76340
|
+
if (max2 === null) return;
|
|
76341
|
+
if (value < max2 && !(fraction && BigInt(fraction) >= max2)) return;
|
|
76342
|
+
const exponent = max2.toString().length - 1;
|
|
76343
|
+
const largest = max2 === 10n ** BigInt(exponent) ? `10^${exponent} - 1` : `${max2 - 1n}`;
|
|
76344
76344
|
throw new RangeError(`Number too large to convert: the largest supported value is ${largest}`);
|
|
76345
76345
|
}
|
|
76346
76346
|
|
|
@@ -77456,6 +77456,12 @@ var currencyValues6 = { currency: (
|
|
|
77456
77456
|
Object.keys(nl2)
|
|
77457
77457
|
) };
|
|
77458
77458
|
|
|
77459
|
+
// packages/engine/src/lib/helpers/office.ts
|
|
77460
|
+
var officeUnsupportedHelpers = /* @__PURE__ */ new Set(["chart", "markdown"]);
|
|
77461
|
+
function officeUnsupported(name) {
|
|
77462
|
+
return `${name}() is not supported in office templates`;
|
|
77463
|
+
}
|
|
77464
|
+
|
|
77459
77465
|
// packages/engine/src/lib/helpers/format.ts
|
|
77460
77466
|
var dateLocales = {
|
|
77461
77467
|
de,
|
|
@@ -77683,9 +77689,9 @@ var formatHelpers = [
|
|
|
77683
77689
|
},
|
|
77684
77690
|
fn: (_ctx, value, length, suffix) => {
|
|
77685
77691
|
const s = str(value);
|
|
77686
|
-
const
|
|
77692
|
+
const max2 = opt(Number(length), 255);
|
|
77687
77693
|
const end = opt(suffix, "\u2026");
|
|
77688
|
-
return s.length <=
|
|
77694
|
+
return s.length <= max2 ? s : s.slice(0, Math.max(0, max2 - end.length)) + end;
|
|
77689
77695
|
}
|
|
77690
77696
|
},
|
|
77691
77697
|
{
|
|
@@ -77738,7 +77744,8 @@ var formatHelpers = [
|
|
|
77738
77744
|
example: "{{ address | nl2br }}",
|
|
77739
77745
|
category: "text"
|
|
77740
77746
|
},
|
|
77741
|
-
|
|
77747
|
+
// office templates turn line breaks into breaks themselves, and escape the text once
|
|
77748
|
+
fn: (ctx, value) => ctx.mode === "office" ? str(value) : escapeHtml(str(value)).replace(/\r?\n/g, "<br>\n")
|
|
77742
77749
|
},
|
|
77743
77750
|
{
|
|
77744
77751
|
name: "markdown",
|
|
@@ -77749,11 +77756,14 @@ var formatHelpers = [
|
|
|
77749
77756
|
example: "{{ notes | markdown }}",
|
|
77750
77757
|
category: "text"
|
|
77751
77758
|
},
|
|
77752
|
-
fn: (
|
|
77753
|
-
|
|
77754
|
-
|
|
77755
|
-
|
|
77756
|
-
|
|
77759
|
+
fn: (ctx, value) => {
|
|
77760
|
+
if (ctx.mode === "office") throw new Error(officeUnsupported("markdown"));
|
|
77761
|
+
return f.parse(str(value), {
|
|
77762
|
+
async: false,
|
|
77763
|
+
gfm: true,
|
|
77764
|
+
breaks: false
|
|
77765
|
+
});
|
|
77766
|
+
}
|
|
77757
77767
|
},
|
|
77758
77768
|
{
|
|
77759
77769
|
name: "safe",
|
|
@@ -77831,7 +77841,7 @@ var formatHelpers = [
|
|
|
77831
77841
|
example: "{{ pageBreak() }}",
|
|
77832
77842
|
category: "document"
|
|
77833
77843
|
},
|
|
77834
|
-
fn: () => '<div class="page-break" style="break-after:page"></div>'
|
|
77844
|
+
fn: (ctx) => ctx.drawing ? ctx.drawing({ kind: "page-break" }) : '<div class="page-break" style="break-after:page"></div>'
|
|
77835
77845
|
}
|
|
77836
77846
|
];
|
|
77837
77847
|
|
|
@@ -77888,7 +77898,12 @@ var codeHelpers = [
|
|
|
77888
77898
|
example: '<img src="{{ qrcode(order.url, { size: 120 }) }}">',
|
|
77889
77899
|
category: "code"
|
|
77890
77900
|
},
|
|
77891
|
-
fn: (
|
|
77901
|
+
fn: (ctx, value, options) => {
|
|
77902
|
+
const o = options ?? {};
|
|
77903
|
+
const svg = qrSvg(String(value ?? ""), o);
|
|
77904
|
+
if (ctx.drawing) return ctx.drawing({ kind: "svg", svg, width: o.size, height: o.size, alt: "QR code" });
|
|
77905
|
+
return svgDataUri(svg);
|
|
77906
|
+
}
|
|
77892
77907
|
},
|
|
77893
77908
|
{
|
|
77894
77909
|
name: "barcode",
|
|
@@ -77898,7 +77913,7 @@ var codeHelpers = [
|
|
|
77898
77913
|
example: `<img src="{{ barcode(item.sku, { type: 'code128' }) }}">`,
|
|
77899
77914
|
category: "code"
|
|
77900
77915
|
},
|
|
77901
|
-
fn: (
|
|
77916
|
+
fn: (ctx, value, options) => {
|
|
77902
77917
|
const o = options ?? {};
|
|
77903
77918
|
const bcid = barcodeTypes[String(o.type ?? "code128").toLowerCase()] ?? "code128";
|
|
77904
77919
|
const svg = ToSVG({
|
|
@@ -77910,6 +77925,7 @@ var codeHelpers = [
|
|
|
77910
77925
|
includetext: o.text !== false,
|
|
77911
77926
|
textxalign: "center"
|
|
77912
77927
|
});
|
|
77928
|
+
if (ctx.drawing) return ctx.drawing({ kind: "svg", svg, alt: `Barcode ${String(value ?? "")}` });
|
|
77913
77929
|
return svgDataUri(svg);
|
|
77914
77930
|
}
|
|
77915
77931
|
},
|
|
@@ -77926,7 +77942,7 @@ var codeHelpers = [
|
|
|
77926
77942
|
// hash (`{{epcQr name=… iban=… size=200}}`), and Liquid, which cannot build an object literal,
|
|
77927
77943
|
// keyword arguments (`{{ company.iban | epcQr: name: company.name, amount: invoice.total }}`,
|
|
77928
77944
|
// where a string input is the IBAN). They are merged and split by field name.
|
|
77929
|
-
fn: (
|
|
77945
|
+
fn: (ctx, input, options) => {
|
|
77930
77946
|
const fields = {
|
|
77931
77947
|
...input && typeof input === "object" ? input : typeof input === "string" && input ? { iban: input } : {},
|
|
77932
77948
|
...options ?? {}
|
|
@@ -77935,12 +77951,10 @@ var codeHelpers = [
|
|
|
77935
77951
|
const qr = {};
|
|
77936
77952
|
for (const [key, value] of Object.entries(fields))
|
|
77937
77953
|
(EPC_FIELDS.has(key) ? payment : qr)[key] = value;
|
|
77938
|
-
|
|
77939
|
-
|
|
77940
|
-
|
|
77941
|
-
|
|
77942
|
-
})
|
|
77943
|
-
);
|
|
77954
|
+
const o = { ecc: "M", ...qr };
|
|
77955
|
+
const svg = qrSvg(epcPayload(payment), o);
|
|
77956
|
+
if (ctx.drawing) return ctx.drawing({ kind: "svg", svg, width: o.size, height: o.size, alt: "GiroCode" });
|
|
77957
|
+
return svgDataUri(svg);
|
|
77944
77958
|
}
|
|
77945
77959
|
}
|
|
77946
77960
|
];
|
|
@@ -78130,6 +78144,29 @@ var collectionHelpers = [
|
|
|
78130
78144
|
];
|
|
78131
78145
|
|
|
78132
78146
|
// packages/engine/src/lib/helpers/document.ts
|
|
78147
|
+
var CHART_PALETTE = ["#3E63DD", "#12A594", "#E5484D", "#F76B15", "#8E4EC6", "#FFC53D", "#0090FF", "#978365"];
|
|
78148
|
+
var SLICED = /* @__PURE__ */ new Set(["pie", "doughnut", "polarArea"]);
|
|
78149
|
+
var colour = (value) => typeof value === "string" && value ? value : Array.isArray(value) && value.length ? value.map(String) : void 0;
|
|
78150
|
+
function chartDataFromPlain(spec) {
|
|
78151
|
+
const type = spec.type ?? "bar";
|
|
78152
|
+
const series = Array.isArray(spec.series) ? spec.series.map((s) => asObject(s)) : [{ label: spec.label, values: spec.values, color: spec.color }];
|
|
78153
|
+
const labels = Array.isArray(spec.labels) ? spec.labels : [];
|
|
78154
|
+
const datasets = series.map((s, index) => {
|
|
78155
|
+
const data = (Array.isArray(s.values) ? s.values : []).map((v2) => {
|
|
78156
|
+
const n = toNumber(v2);
|
|
78157
|
+
return Number.isFinite(n) ? n : null;
|
|
78158
|
+
});
|
|
78159
|
+
const own = colour(s.color);
|
|
78160
|
+
const fill = SLICED.has(type) ? own ?? labels.map((_2, i) => CHART_PALETTE[i % CHART_PALETTE.length]) : own ?? CHART_PALETTE[index % CHART_PALETTE.length];
|
|
78161
|
+
const dataset = { data, backgroundColor: fill, borderColor: fill };
|
|
78162
|
+
if (s.label !== void 0 && s.label !== null && s.label !== "") dataset["label"] = String(s.label);
|
|
78163
|
+
if (type === "line") dataset["fill"] = false;
|
|
78164
|
+
return dataset;
|
|
78165
|
+
});
|
|
78166
|
+
return { labels, datasets };
|
|
78167
|
+
}
|
|
78168
|
+
var isPlain = (spec) => spec.data === void 0 && (Array.isArray(spec.values) || Array.isArray(spec.series));
|
|
78169
|
+
var asObject = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
78133
78170
|
var css = (value) => {
|
|
78134
78171
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
78135
78172
|
const n = toNumber(value);
|
|
@@ -78139,7 +78176,13 @@ function chartPayload(spec) {
|
|
|
78139
78176
|
const options = { ...spec.options ?? {} };
|
|
78140
78177
|
options["animation"] = false;
|
|
78141
78178
|
options["responsive"] = false;
|
|
78142
|
-
return { type: spec.type ?? "bar", data: spec.data ?? {}, options };
|
|
78179
|
+
if (!isPlain(spec)) return { type: spec.type ?? "bar", data: spec.data ?? {}, options };
|
|
78180
|
+
const data = chartDataFromPlain(spec);
|
|
78181
|
+
const unnamed = data.datasets.length === 1 && data.datasets[0]?.["label"] === void 0;
|
|
78182
|
+
const plugins = asObject(options["plugins"]);
|
|
78183
|
+
if (unnamed && !SLICED.has(spec.type ?? "bar") && plugins["legend"] === void 0)
|
|
78184
|
+
options["plugins"] = { ...plugins, legend: { display: false } };
|
|
78185
|
+
return { type: spec.type ?? "bar", data, options };
|
|
78143
78186
|
}
|
|
78144
78187
|
function chartMarkup(spec, id) {
|
|
78145
78188
|
const width = toNumber(spec.width ?? 480) || 480;
|
|
@@ -78158,18 +78201,24 @@ function imageMarkup(url, options = {}) {
|
|
|
78158
78201
|
const style = styles ? ` style="${styles}"` : "";
|
|
78159
78202
|
return `<img src="${escapeHtml(url)}" alt="${escapeHtml(options.alt ?? "")}"${cls}${style}>`;
|
|
78160
78203
|
}
|
|
78161
|
-
|
|
78204
|
+
function resolveAsset(base, url) {
|
|
78205
|
+
if (!base || /^[a-z][a-z0-9+.-]*:/i.test(url)) return url;
|
|
78206
|
+
return `${base.replace(/\/$/, "")}/${url.replace(/^\//, "")}`;
|
|
78207
|
+
}
|
|
78162
78208
|
var documentHelpers = [
|
|
78163
78209
|
{
|
|
78164
78210
|
name: "chart",
|
|
78165
78211
|
html: true,
|
|
78166
78212
|
doc: {
|
|
78167
|
-
signature: "chart({ type, data, options, width, height })",
|
|
78168
|
-
description: "Draws a Chart.js chart (bar, line, pie, doughnut, radar, \u2026) from a
|
|
78169
|
-
example: "{{ chart({ type: '
|
|
78213
|
+
signature: "chart({ type, labels, values, label, color } | { type, labels, series } | { type, data, options }, { width, height })",
|
|
78214
|
+
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.",
|
|
78215
|
+
example: "{{ chart({ type: 'line', labels: ['Q1', 'Q2', 'Q3'], values: sales.quarters, width: 480 }) }}",
|
|
78170
78216
|
category: "document"
|
|
78171
78217
|
},
|
|
78172
|
-
fn: (
|
|
78218
|
+
fn: (ctx, spec, extra) => {
|
|
78219
|
+
if (ctx.mode === "office") throw new Error(officeUnsupported("chart"));
|
|
78220
|
+
return chartMarkup({ ...asObject(spec), ...asObject(extra) });
|
|
78221
|
+
}
|
|
78173
78222
|
},
|
|
78174
78223
|
{
|
|
78175
78224
|
name: "image",
|
|
@@ -78180,7 +78229,12 @@ var documentHelpers = [
|
|
|
78180
78229
|
example: "{{ image(product.photo, { width: 120, height: 80, fit: 'cover' }) }}",
|
|
78181
78230
|
category: "document"
|
|
78182
78231
|
},
|
|
78183
|
-
fn: (
|
|
78232
|
+
fn: (ctx, url, options) => {
|
|
78233
|
+
const o = asObject(options);
|
|
78234
|
+
if (ctx.drawing)
|
|
78235
|
+
return ctx.drawing({ kind: "url", url: resolveAsset(ctx.assetBaseUrl, String(url ?? "")), width: o.width, height: o.height, alt: o.alt });
|
|
78236
|
+
return imageMarkup(String(url ?? ""), o);
|
|
78237
|
+
}
|
|
78184
78238
|
}
|
|
78185
78239
|
];
|
|
78186
78240
|
|
|
@@ -78528,6 +78582,8 @@ var builtinHelpers2 = /* @__PURE__ */ new Set([
|
|
|
78528
78582
|
"helperMissing"
|
|
78529
78583
|
]);
|
|
78530
78584
|
var builtinRoots = /* @__PURE__ */ new Set([
|
|
78585
|
+
// the organisation's brand kit (spec 18), merged under the data
|
|
78586
|
+
"brand",
|
|
78531
78587
|
"this",
|
|
78532
78588
|
"@index",
|
|
78533
78589
|
"@key",
|
|
@@ -78536,6 +78592,11 @@ var builtinRoots = /* @__PURE__ */ new Set([
|
|
|
78536
78592
|
"@root",
|
|
78537
78593
|
"lookup"
|
|
78538
78594
|
]);
|
|
78595
|
+
function withBrand(data, ctx) {
|
|
78596
|
+
const root = data ?? {};
|
|
78597
|
+
if (!ctx.brand || typeof root !== "object" || Array.isArray(root)) return root;
|
|
78598
|
+
return { brand: ctx.brand, ...root };
|
|
78599
|
+
}
|
|
78539
78600
|
function createInstance(ctx) {
|
|
78540
78601
|
const hb = import_handlebars.default.create();
|
|
78541
78602
|
for (const [name, { fn, html }] of ctx.helpers.bind(ctx)) {
|
|
@@ -78561,11 +78622,11 @@ var validationContext = {
|
|
|
78561
78622
|
limits: { ms: 2e3, outputBytes: 20 * 1024 * 1024, includeDepth: 8 }
|
|
78562
78623
|
};
|
|
78563
78624
|
function toSyntaxError(e) {
|
|
78564
|
-
const
|
|
78565
|
-
const message2 = String(
|
|
78625
|
+
const err2 = e;
|
|
78626
|
+
const message2 = String(err2.message ?? e);
|
|
78566
78627
|
const m2 = /Parse error on line (\d+)/.exec(message2);
|
|
78567
|
-
const line =
|
|
78568
|
-
const column = typeof
|
|
78628
|
+
const line = err2.lineNumber ?? (m2 ? Number(m2[1]) : 1);
|
|
78629
|
+
const column = typeof err2.column === "number" ? err2.column + 1 : 1;
|
|
78569
78630
|
return new EngineSyntaxError(
|
|
78570
78631
|
"handlebars",
|
|
78571
78632
|
message2.split("\n")[0] ?? message2,
|
|
@@ -78736,12 +78797,12 @@ function analyzeHandlebars(source, opts = {}) {
|
|
|
78736
78797
|
try {
|
|
78737
78798
|
walk(import_handlebars.default.parse(source), w);
|
|
78738
78799
|
} catch (e) {
|
|
78739
|
-
const
|
|
78800
|
+
const err2 = toSyntaxError(e);
|
|
78740
78801
|
diagnostics.push({
|
|
78741
78802
|
severity: "error",
|
|
78742
78803
|
code: "syntax-error",
|
|
78743
|
-
message:
|
|
78744
|
-
range: rangeAt(
|
|
78804
|
+
message: err2.message,
|
|
78805
|
+
range: rangeAt(err2.line, err2.column, 1)
|
|
78745
78806
|
});
|
|
78746
78807
|
}
|
|
78747
78808
|
const registry = helpers;
|
|
@@ -78806,7 +78867,8 @@ var HandlebarsCompiled = class {
|
|
|
78806
78867
|
hb,
|
|
78807
78868
|
template: hb.compile(this.source, {
|
|
78808
78869
|
strict: false,
|
|
78809
|
-
|
|
78870
|
+
// office text is escaped when its markup is restored (office/template-text.ts)
|
|
78871
|
+
noEscape: ctx.mode === "office",
|
|
78810
78872
|
preventIndent: true
|
|
78811
78873
|
})
|
|
78812
78874
|
};
|
|
@@ -78835,7 +78897,7 @@ var HandlebarsCompiled = class {
|
|
|
78835
78897
|
};
|
|
78836
78898
|
collect(this.source, 0);
|
|
78837
78899
|
try {
|
|
78838
|
-
const out = template(data
|
|
78900
|
+
const out = template(withBrand(data, ctx), {
|
|
78839
78901
|
partials,
|
|
78840
78902
|
allowProtoPropertiesByDefault: false,
|
|
78841
78903
|
allowProtoMethodsByDefault: false
|
|
@@ -78843,12 +78905,12 @@ var HandlebarsCompiled = class {
|
|
|
78843
78905
|
return enforceLimits(out, started, ctx.limits);
|
|
78844
78906
|
} catch (e) {
|
|
78845
78907
|
if (e instanceof Error && e.name === "RenderLimitError") throw e;
|
|
78846
|
-
const
|
|
78908
|
+
const err2 = e;
|
|
78847
78909
|
throw new RenderError(
|
|
78848
78910
|
"handlebars",
|
|
78849
|
-
String(
|
|
78850
|
-
|
|
78851
|
-
|
|
78911
|
+
String(err2.message ?? e),
|
|
78912
|
+
err2.lineNumber,
|
|
78913
|
+
err2.column === void 0 ? void 0 : err2.column + 1
|
|
78852
78914
|
);
|
|
78853
78915
|
}
|
|
78854
78916
|
}
|
|
@@ -79060,6 +79122,7 @@ var nunjucksBuiltinFilters = /* @__PURE__ */ new Set([
|
|
|
79060
79122
|
"urlize",
|
|
79061
79123
|
"wordcount"
|
|
79062
79124
|
]);
|
|
79125
|
+
var jinjaLiterals = /* @__PURE__ */ new Set(["True", "False", "None"]);
|
|
79063
79126
|
var builtinRoots2 = /* @__PURE__ */ new Set([
|
|
79064
79127
|
"loop",
|
|
79065
79128
|
"caller",
|
|
@@ -79071,6 +79134,8 @@ var builtinRoots2 = /* @__PURE__ */ new Set([
|
|
|
79071
79134
|
"varargs",
|
|
79072
79135
|
"kwargs",
|
|
79073
79136
|
"namespace",
|
|
79137
|
+
// the organisation's brand kit (spec 18), a global beside the data
|
|
79138
|
+
"brand",
|
|
79074
79139
|
// Jinja2's spelling of the literals, which the compat layer resolves at runtime
|
|
79075
79140
|
"True",
|
|
79076
79141
|
"False",
|
|
@@ -79100,7 +79165,7 @@ var stringMethods = {
|
|
|
79100
79165
|
}
|
|
79101
79166
|
return out;
|
|
79102
79167
|
},
|
|
79103
|
-
split: (s, sep,
|
|
79168
|
+
split: (s, sep, max2) => sep === void 0 || sep === null ? s.trim().split(/\s+/) : s.split(String(sep), max2 === void 0 ? void 0 : Number(max2) + 1),
|
|
79104
79169
|
join: (s, list2) => Array.isArray(list2) ? list2.join(s) : String(list2),
|
|
79105
79170
|
format: (s, ...args2) => {
|
|
79106
79171
|
const named = keywordArgs(args2);
|
|
@@ -79175,6 +79240,14 @@ function installJinjaFilters(env) {
|
|
|
79175
79240
|
const space = cut.lastIndexOf(" ");
|
|
79176
79241
|
return (space >= 0 ? cut.slice(0, space) : cut) + end;
|
|
79177
79242
|
});
|
|
79243
|
+
const helperSum = lookup.getFilter("sum");
|
|
79244
|
+
lookup.addFilter("sum", function(value, ...args2) {
|
|
79245
|
+
const named = keywordArgs(args2);
|
|
79246
|
+
if (!named) return helperSum.call(this, value, ...args2);
|
|
79247
|
+
const p = args2.slice(0, -1);
|
|
79248
|
+
const total = helperSum.call(this, value, p[0] ?? named["attribute"]);
|
|
79249
|
+
return total + Number(p[1] ?? named["start"] ?? 0);
|
|
79250
|
+
});
|
|
79178
79251
|
const helperMap = lookup.getFilter("map");
|
|
79179
79252
|
lookup.addFilter("map", function(value, ...args2) {
|
|
79180
79253
|
const named = keywordArgs(args2);
|
|
@@ -79215,6 +79288,25 @@ function trimChars(s, chars, side) {
|
|
|
79215
79288
|
if (side !== "left") while (end > start && set.has(s[end - 1] ?? "")) end--;
|
|
79216
79289
|
return s.slice(start, end);
|
|
79217
79290
|
}
|
|
79291
|
+
function isPlainObject2(v2) {
|
|
79292
|
+
if (v2 === null || typeof v2 !== "object") return false;
|
|
79293
|
+
const proto = Object.getPrototypeOf(v2);
|
|
79294
|
+
return proto === Object.prototype || proto === null;
|
|
79295
|
+
}
|
|
79296
|
+
function pythonRepr(v2) {
|
|
79297
|
+
if (v2 === null || v2 === void 0) return "None";
|
|
79298
|
+
if (v2 === true) return "True";
|
|
79299
|
+
if (v2 === false) return "False";
|
|
79300
|
+
if (typeof v2 === "number") return Number.isNaN(v2) ? "nan" : Number.isFinite(v2) ? String(v2) : v2 > 0 ? "inf" : "-inf";
|
|
79301
|
+
if (typeof v2 === "string") {
|
|
79302
|
+
const quote = v2.includes("'") && !v2.includes('"') ? '"' : "'";
|
|
79303
|
+
const escaped = v2.replace(/\\/g, "\\\\").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
79304
|
+
return quote + (quote === "'" ? escaped.replace(/'/g, "\\'") : escaped) + quote;
|
|
79305
|
+
}
|
|
79306
|
+
if (Array.isArray(v2)) return `[${v2.map(pythonRepr).join(", ")}]`;
|
|
79307
|
+
if (isPlainObject2(v2)) return `{${Object.entries(v2).map(([k2, item]) => `${pythonRepr(k2)}: ${pythonRepr(item)}`).join(", ")}}`;
|
|
79308
|
+
return String(v2);
|
|
79309
|
+
}
|
|
79218
79310
|
var compatInstalled = false;
|
|
79219
79311
|
function installCompat() {
|
|
79220
79312
|
if (compatInstalled) return;
|
|
@@ -79239,6 +79331,8 @@ function installCompat() {
|
|
|
79239
79331
|
else this.compile(node.body, frame);
|
|
79240
79332
|
this._emitLine(");");
|
|
79241
79333
|
};
|
|
79334
|
+
const suppressValue = import_nunjucks.default.runtime.suppressValue;
|
|
79335
|
+
import_nunjucks.default.runtime.suppressValue = (val2, autoescape) => suppressValue(Array.isArray(val2) || isPlainObject2(val2) ? pythonRepr(val2) : val2, autoescape);
|
|
79242
79336
|
const original = import_nunjucks.default.runtime.memberLookup;
|
|
79243
79337
|
import_nunjucks.default.runtime.memberLookup = (obj, val2, ...rest) => {
|
|
79244
79338
|
if (typeof obj === "string" && typeof val2 === "string" && Object.prototype.hasOwnProperty.call(stringMethods, val2)) {
|
|
@@ -79271,7 +79365,8 @@ function createEnvironment(ctx) {
|
|
|
79271
79365
|
const env = new import_nunjucks.default.Environment(
|
|
79272
79366
|
new PartialLoader(ctx.partials),
|
|
79273
79367
|
{
|
|
79274
|
-
|
|
79368
|
+
// office text is escaped when its markup is restored, so escaping here would double it
|
|
79369
|
+
autoescape: ctx.mode !== "office",
|
|
79275
79370
|
throwOnUndefined: false,
|
|
79276
79371
|
trimBlocks: false,
|
|
79277
79372
|
lstripBlocks: false
|
|
@@ -79286,6 +79381,7 @@ function createEnvironment(ctx) {
|
|
|
79286
79381
|
env.addGlobal(name, wrapped);
|
|
79287
79382
|
}
|
|
79288
79383
|
env.addGlobal("namespace", namespace);
|
|
79384
|
+
if (ctx.brand) env.addGlobal("brand", ctx.brand);
|
|
79289
79385
|
installJinjaFilters(env);
|
|
79290
79386
|
return env;
|
|
79291
79387
|
}
|
|
@@ -79299,13 +79395,13 @@ var validationContext2 = {
|
|
|
79299
79395
|
i18n: {}
|
|
79300
79396
|
};
|
|
79301
79397
|
function toSyntaxError2(e, fallbackLine = 1) {
|
|
79302
|
-
const
|
|
79303
|
-
const message2 = String(
|
|
79398
|
+
const err2 = e;
|
|
79399
|
+
const message2 = String(err2.message ?? e).replace(/^\(.*?\)\s*/, "").replace(/^\[Line \d+, Column \d+\]\s*/, "").trim();
|
|
79304
79400
|
const fromMessage = /\[Line (\d+), Column (\d+)\]/.exec(
|
|
79305
|
-
String(
|
|
79401
|
+
String(err2.message ?? "")
|
|
79306
79402
|
);
|
|
79307
|
-
const line = typeof
|
|
79308
|
-
const column = typeof
|
|
79403
|
+
const line = typeof err2.lineno === "number" ? err2.lineno + 1 : fromMessage ? Number(fromMessage[1]) : fallbackLine;
|
|
79404
|
+
const column = typeof err2.colno === "number" ? err2.colno + 1 : fromMessage ? Number(fromMessage[2]) : 1;
|
|
79309
79405
|
return new EngineSyntaxError("jinja2", message2, line, column);
|
|
79310
79406
|
}
|
|
79311
79407
|
function nodeRange(node, length = 1) {
|
|
@@ -79340,6 +79436,7 @@ function walk2(node, w) {
|
|
|
79340
79436
|
case "Symbol":
|
|
79341
79437
|
case "LookupVal": {
|
|
79342
79438
|
const p = pathOf(node);
|
|
79439
|
+
if (node.typename === "Symbol" && jinjaLiterals.has(String(node.value))) return;
|
|
79343
79440
|
if (p) {
|
|
79344
79441
|
const root = p.path[0] ?? "";
|
|
79345
79442
|
const bound = inScope(w, root);
|
|
@@ -79507,13 +79604,13 @@ function analyzeJinja2(source, opts = {}) {
|
|
|
79507
79604
|
const root = import_nunjucks.default.parser.parse(source, [], {});
|
|
79508
79605
|
walk2(root, w);
|
|
79509
79606
|
} catch (e) {
|
|
79510
|
-
const
|
|
79607
|
+
const err2 = toSyntaxError2(e);
|
|
79511
79608
|
if (!diagnostics.some((d) => d.severity === "error")) {
|
|
79512
79609
|
diagnostics.push({
|
|
79513
79610
|
severity: "error",
|
|
79514
79611
|
code: "syntax-error",
|
|
79515
|
-
message:
|
|
79516
|
-
range: rangeAt(
|
|
79612
|
+
message: err2.message,
|
|
79613
|
+
range: rangeAt(err2.line, err2.column, 1)
|
|
79517
79614
|
});
|
|
79518
79615
|
}
|
|
79519
79616
|
}
|
|
@@ -79582,13 +79679,13 @@ var Jinja2Template = class {
|
|
|
79582
79679
|
try {
|
|
79583
79680
|
tpl.render(
|
|
79584
79681
|
data ?? {},
|
|
79585
|
-
(
|
|
79586
|
-
if (
|
|
79587
|
-
const e =
|
|
79682
|
+
(err2, res) => {
|
|
79683
|
+
if (err2) {
|
|
79684
|
+
const e = err2;
|
|
79588
79685
|
reject(
|
|
79589
79686
|
new RenderError(
|
|
79590
79687
|
"jinja2",
|
|
79591
|
-
String(e.message ??
|
|
79688
|
+
String(e.message ?? err2).replace(/^\(.*?\)\s*/, ""),
|
|
79592
79689
|
e.lineno === void 0 ? void 0 : e.lineno + 1,
|
|
79593
79690
|
e.colno === void 0 ? void 0 : e.colno + 1
|
|
79594
79691
|
)
|
|
@@ -79706,6 +79803,8 @@ var liquidBuiltinFilters = /* @__PURE__ */ new Set([
|
|
|
79706
79803
|
"time_zone"
|
|
79707
79804
|
]);
|
|
79708
79805
|
var builtinRoots3 = /* @__PURE__ */ new Set([
|
|
79806
|
+
// the organisation's brand kit (spec 18), a global beside the data
|
|
79807
|
+
"brand",
|
|
79709
79808
|
"forloop",
|
|
79710
79809
|
"tablerowloop",
|
|
79711
79810
|
"true",
|
|
@@ -79771,6 +79870,8 @@ function createLiquid(ctx) {
|
|
|
79771
79870
|
extname: "",
|
|
79772
79871
|
root: [""],
|
|
79773
79872
|
fs: partialFs(ctx.partials),
|
|
79873
|
+
// scope data shadows globals, so `data.brand` still wins
|
|
79874
|
+
globals: ctx.brand ? { brand: ctx.brand } : {},
|
|
79774
79875
|
renderLimit: ctx.limits.ms,
|
|
79775
79876
|
memoryLimit: ctx.limits.outputBytes * 4,
|
|
79776
79877
|
parseLimit: 2e6
|
|
@@ -79793,12 +79894,12 @@ var validationContext3 = {
|
|
|
79793
79894
|
limits: { ms: 2e3, outputBytes: 20 * 1024 * 1024, includeDepth: 8 }
|
|
79794
79895
|
};
|
|
79795
79896
|
function toSyntaxError3(e) {
|
|
79796
|
-
const
|
|
79797
|
-
let line =
|
|
79798
|
-
let column =
|
|
79799
|
-
const pos =
|
|
79897
|
+
const err2 = e;
|
|
79898
|
+
let line = err2.line ?? 1;
|
|
79899
|
+
let column = err2.col ?? 1;
|
|
79900
|
+
const pos = err2.token?.getPosition?.();
|
|
79800
79901
|
if (pos) [line, column] = pos;
|
|
79801
|
-
const message2 = String(
|
|
79902
|
+
const message2 = String(err2.message ?? e).replace(/,\s*line:\d+,\s*col:\d+/, "").trim();
|
|
79802
79903
|
return new EngineSyntaxError("liquid", message2, line, column);
|
|
79803
79904
|
}
|
|
79804
79905
|
var identifier = /(?<![\w."'])([A-Za-z_][\w]*)((?:\.[A-Za-z_]\w*|\[\d+\])*)/g;
|
|
@@ -79830,15 +79931,15 @@ function analyzeLiquid(source, opts = {}) {
|
|
|
79830
79931
|
try {
|
|
79831
79932
|
new import_liquidjs.Liquid({ strictFilters: false, fs: partialFs(() => "") }).parse(source);
|
|
79832
79933
|
} catch (e) {
|
|
79833
|
-
const
|
|
79934
|
+
const err2 = toSyntaxError3(e);
|
|
79834
79935
|
if (!diagnostics.some((d) => d.severity === "error")) {
|
|
79835
79936
|
diagnostics.push({
|
|
79836
79937
|
severity: "error",
|
|
79837
79938
|
code: "syntax-error",
|
|
79838
|
-
message:
|
|
79939
|
+
message: err2.message,
|
|
79839
79940
|
range: {
|
|
79840
|
-
start: { line:
|
|
79841
|
-
end: { line:
|
|
79941
|
+
start: { line: err2.line, column: err2.column },
|
|
79942
|
+
end: { line: err2.line, column: err2.column + 1 }
|
|
79842
79943
|
}
|
|
79843
79944
|
});
|
|
79844
79945
|
}
|
|
@@ -79999,11 +80100,11 @@ var LiquidCompiled = class {
|
|
|
79999
80100
|
return enforceLimits(out, started, ctx.limits);
|
|
80000
80101
|
} catch (e) {
|
|
80001
80102
|
if (e instanceof Error && e.name === "RenderLimitError") throw e;
|
|
80002
|
-
const
|
|
80003
|
-
const pos =
|
|
80103
|
+
const err2 = e;
|
|
80104
|
+
const pos = err2.token?.getPosition?.();
|
|
80004
80105
|
throw new RenderError(
|
|
80005
80106
|
"liquid",
|
|
80006
|
-
String(
|
|
80107
|
+
String(err2.message ?? e),
|
|
80007
80108
|
pos?.[0],
|
|
80008
80109
|
pos?.[1]
|
|
80009
80110
|
);
|
|
@@ -80041,6 +80142,26 @@ function getEngine(id) {
|
|
|
80041
80142
|
return engine;
|
|
80042
80143
|
}
|
|
80043
80144
|
|
|
80145
|
+
// packages/engine/src/lib/schema-diff.ts
|
|
80146
|
+
var LOWER_BOUNDS = ["minimum", "exclusiveMinimum", "minLength", "minItems", "minProperties"];
|
|
80147
|
+
var UPPER_BOUNDS = ["maximum", "exclusiveMaximum", "maxLength", "maxItems", "maxProperties"];
|
|
80148
|
+
var ANALYSED = /* @__PURE__ */ new Set([
|
|
80149
|
+
"type",
|
|
80150
|
+
"properties",
|
|
80151
|
+
"required",
|
|
80152
|
+
"additionalProperties",
|
|
80153
|
+
"items",
|
|
80154
|
+
"enum",
|
|
80155
|
+
"const",
|
|
80156
|
+
"format",
|
|
80157
|
+
"pattern",
|
|
80158
|
+
"$ref",
|
|
80159
|
+
"$defs",
|
|
80160
|
+
"definitions",
|
|
80161
|
+
...LOWER_BOUNDS,
|
|
80162
|
+
...UPPER_BOUNDS
|
|
80163
|
+
]);
|
|
80164
|
+
|
|
80044
80165
|
// packages/engine/src/lib/schema.ts
|
|
80045
80166
|
var isoDateTime = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
|
|
80046
80167
|
var isoDate = /^\d{4}-\d{2}-\d{2}$/;
|
|
@@ -80131,9 +80252,16 @@ function inferSchema(sample) {
|
|
|
80131
80252
|
};
|
|
80132
80253
|
}
|
|
80133
80254
|
|
|
80255
|
+
// packages/engine/src/lib/output.ts
|
|
80256
|
+
var outputFormats = ["pdf", "png", "jpg", "webp", "docx", "pptx"];
|
|
80257
|
+
var officeKinds = ["docx", "pptx"];
|
|
80258
|
+
function isOfficeKind(value) {
|
|
80259
|
+
return typeof value === "string" && officeKinds.includes(value);
|
|
80260
|
+
}
|
|
80261
|
+
|
|
80134
80262
|
// packages/engine/src/lib/snippets.ts
|
|
80135
80263
|
var loop = (engine, item, list2, body) => engine === "handlebars" ? `{{#each ${list2}}}
|
|
80136
|
-
${body.replace(
|
|
80264
|
+
${body.replace(new RegExp(`(?<![\\w.])${item}\\.`, "g"), "")}
|
|
80137
80265
|
{{/each}}` : `{% for ${item} in ${list2} %}
|
|
80138
80266
|
${body}
|
|
80139
80267
|
{% endfor %}`;
|
|
@@ -80143,6 +80271,15 @@ var val = (engine, expr, filter) => {
|
|
|
80143
80271
|
return `{{${filter.split("(")[0]} ${expr}${filter.includes("(") ? " " + filter.slice(filter.indexOf("(") + 1, -1) : ""}}}`;
|
|
80144
80272
|
return engine === "liquid" ? `{{ ${expr} | ${filter.replace("(", ": ").replace(")", "")} }}` : `{{ ${expr} | ${filter} }}`;
|
|
80145
80273
|
};
|
|
80274
|
+
var ifElse = (engine, cond, then, otherwise) => engine === "handlebars" ? `{{#if ${cond}}}${then}{{else}}${otherwise}{{/if}}` : `{% if ${cond} %}${then}{% else %}${otherwise}{% endif %}`;
|
|
80275
|
+
var tr = (engine, key, params = {}) => {
|
|
80276
|
+
const entries = Object.entries(params);
|
|
80277
|
+
if (engine === "handlebars")
|
|
80278
|
+
return `{{t '${key}'${entries.map(([k2, v2]) => ` ${k2}=${v2}`).join("")}}}`;
|
|
80279
|
+
if (engine === "liquid")
|
|
80280
|
+
return `{{ '${key}' | t${entries.length ? ": " + entries.map(([k2, v2]) => `${k2}: ${v2}`).join(", ") : ""} }}`;
|
|
80281
|
+
return `{{ t('${key}'${entries.length ? `, { ${entries.map(([k2, v2]) => `${k2}: ${v2}`).join(", ")} }` : ""}) }}`;
|
|
80282
|
+
};
|
|
80146
80283
|
function forAll(build) {
|
|
80147
80284
|
return {
|
|
80148
80285
|
jinja2: build("jinja2"),
|
|
@@ -80150,14 +80287,101 @@ function forAll(build) {
|
|
|
80150
80287
|
handlebars: build("handlebars")
|
|
80151
80288
|
};
|
|
80152
80289
|
}
|
|
80290
|
+
var rule = "var(--brand-color-primary, #222)";
|
|
80153
80291
|
var snippets = [
|
|
80292
|
+
{
|
|
80293
|
+
id: "letterhead",
|
|
80294
|
+
group: "letter",
|
|
80295
|
+
title: "Letterhead",
|
|
80296
|
+
description: "Logo from the brand kit, or the organisation name when no logo is set.",
|
|
80297
|
+
source: forAll(
|
|
80298
|
+
(e) => `<header class="ff-letterhead">
|
|
80299
|
+
${ifElse(e, "brand.logo.primary", `<img class="logo" src="${val(e, "brand.logo.primary")}" alt="${val(e, "brand.name")}">`, `<strong class="name">${val(e, "brand.name")}</strong>`)}
|
|
80300
|
+
</header>$0`
|
|
80301
|
+
),
|
|
80302
|
+
css: `.ff-letterhead { display: flex; justify-content: flex-end; align-items: center; min-height: 48px; margin-bottom: 24px; padding-bottom: 8px; border-bottom: 2px solid ${rule}; }
|
|
80303
|
+
.ff-letterhead .logo { max-height: 56px; max-width: 200px; }
|
|
80304
|
+
.ff-letterhead .name { font-family: var(--brand-font-heading, inherit); font-size: 18pt; color: var(--brand-color-primary, inherit); }`
|
|
80305
|
+
},
|
|
80306
|
+
{
|
|
80307
|
+
id: "window-address",
|
|
80308
|
+
group: "letter",
|
|
80309
|
+
kinds: ["pdf"],
|
|
80310
|
+
title: "Window envelope address",
|
|
80311
|
+
description: "Return address and recipient in the 85 \xD7 45 mm field of a DIN 5008 window envelope.",
|
|
80312
|
+
source: forAll(
|
|
80313
|
+
(e) => `<div class="ff-window">
|
|
80314
|
+
<div class="sender">${val(e, "company.name")} \xB7 ${val(e, "company.street")} \xB7 ${val(e, "company.zip")} ${val(e, "company.city")}</div>
|
|
80315
|
+
<address>
|
|
80316
|
+
<strong>${val(e, "customer.name")}</strong><br>
|
|
80317
|
+
${val(e, "customer.street")}<br>
|
|
80318
|
+
${val(e, "customer.zip")} ${val(e, "customer.city")}
|
|
80319
|
+
</address>
|
|
80320
|
+
</div>$0`
|
|
80321
|
+
),
|
|
80322
|
+
sampleData: {
|
|
80323
|
+
company: { name: "Fennlor Studio GmbH", street: "Musterstra\xDFe 1", zip: "12345", city: "Musterstadt" },
|
|
80324
|
+
customer: { name: "Olvarest GmbH", street: "Beispielweg 2", zip: "54321", city: "Beispielstadt" }
|
|
80325
|
+
},
|
|
80326
|
+
// Form B puts the field 45 mm below the top edge and 20 mm from the left; the page margins decide where it lands
|
|
80327
|
+
css: `.ff-window { width: 85mm; height: 45mm; box-sizing: border-box; padding: 0 5mm; overflow: hidden; }
|
|
80328
|
+
.ff-window .sender { height: 5mm; line-height: 5mm; margin-bottom: 3mm; font-size: 7pt; color: #555; border-bottom: 0.5pt solid #999; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
80329
|
+
.ff-window address { font-style: normal; font-size: 10pt; line-height: 1.35; }`
|
|
80330
|
+
},
|
|
80331
|
+
{
|
|
80332
|
+
id: "reference-block",
|
|
80333
|
+
group: "letter",
|
|
80334
|
+
title: "Reference block",
|
|
80335
|
+
description: "Customer number, invoice number and date as a right-aligned table; put it in a two-column layout to sit beside the address.",
|
|
80336
|
+
source: forAll(
|
|
80337
|
+
(e) => `<table class="ff-reference">
|
|
80338
|
+
<tr><th>${tr(e, "reference.customer")}</th><td>${val(e, "customer.number")}</td></tr>
|
|
80339
|
+
<tr><th>${tr(e, "reference.invoice")}</th><td>${val(e, "invoice.number")}</td></tr>
|
|
80340
|
+
<tr><th>${tr(e, "reference.date")}</th><td>${val(e, "invoice.date", "date('P')")}</td></tr>
|
|
80341
|
+
</table>$0`
|
|
80342
|
+
),
|
|
80343
|
+
sampleData: {
|
|
80344
|
+
customer: { number: "K-1042" },
|
|
80345
|
+
invoice: { number: "2026-0042", date: "2026-09-13" }
|
|
80346
|
+
},
|
|
80347
|
+
css: `.ff-reference { margin-left: auto; border-collapse: collapse; font-size: 9pt; }
|
|
80348
|
+
.ff-reference th { text-align: left; font-weight: normal; color: #555; padding: 1px 12px 1px 0; }
|
|
80349
|
+
.ff-reference td { text-align: right; padding: 1px 0; }`,
|
|
80350
|
+
i18n: {
|
|
80351
|
+
en: { "reference.customer": "Customer no.", "reference.invoice": "Invoice no.", "reference.date": "Date" },
|
|
80352
|
+
de: { "reference.customer": "Kundennummer", "reference.invoice": "Rechnungsnummer", "reference.date": "Datum" }
|
|
80353
|
+
}
|
|
80354
|
+
},
|
|
80355
|
+
{
|
|
80356
|
+
id: "invoice-heading",
|
|
80357
|
+
group: "invoice",
|
|
80358
|
+
title: "Invoice heading",
|
|
80359
|
+
description: "Invoice number as the title and the service period below it.",
|
|
80360
|
+
source: forAll(
|
|
80361
|
+
(e) => `<div class="ff-heading">
|
|
80362
|
+
<h1>${tr(e, "heading.title", { number: "invoice.number" })}</h1>
|
|
80363
|
+
<p>${tr(e, "heading.period")} ${val(e, "invoice.period_start", "date('P')")} \u2013 ${val(e, "invoice.period_end", "date('P')")}</p>
|
|
80364
|
+
</div>$0`
|
|
80365
|
+
),
|
|
80366
|
+
sampleData: {
|
|
80367
|
+
invoice: { number: "2026-0042", period_start: "2026-09-01", period_end: "2026-09-30" }
|
|
80368
|
+
},
|
|
80369
|
+
css: `.ff-heading { margin: 24px 0 16px; }
|
|
80370
|
+
.ff-heading h1 { font-family: var(--brand-font-heading, inherit); font-size: 18pt; color: var(--brand-color-primary, inherit); margin: 0 0 4px; }
|
|
80371
|
+
.ff-heading p { margin: 0; color: #555; }`,
|
|
80372
|
+
i18n: {
|
|
80373
|
+
en: { "heading.title": "Invoice {number}", "heading.period": "Service period:" },
|
|
80374
|
+
de: { "heading.title": "Rechnung {number}", "heading.period": "Leistungszeitraum:" }
|
|
80375
|
+
}
|
|
80376
|
+
},
|
|
80154
80377
|
{
|
|
80155
80378
|
id: "invoice-table",
|
|
80379
|
+
group: "invoice",
|
|
80156
80380
|
title: "Invoice table",
|
|
80157
80381
|
description: "Line items with description, quantity, unit price and line total.",
|
|
80158
80382
|
source: forAll(
|
|
80159
80383
|
(e) => `<table class="ff-lines">
|
|
80160
|
-
<thead><tr><th
|
|
80384
|
+
<thead><tr><th>${tr(e, "lines.description")}</th><th class="num">${tr(e, "lines.qty")}</th><th class="num">${tr(e, "lines.price")}</th><th class="num">${tr(e, "lines.total")}</th></tr></thead>
|
|
80161
80385
|
<tbody>
|
|
80162
80386
|
${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</td><td class="num">${val(e, "line.qty", "number(0)")}</td><td class="num">${val(e, "line.price", "money")}</td><td class="num">${val(e, "line.total", "money")}</td></tr>`)}
|
|
80163
80387
|
</tbody>
|
|
@@ -80174,17 +80398,32 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80174
80398
|
css: `.ff-lines { width: 100%; border-collapse: collapse; font-size: 10pt; }
|
|
80175
80399
|
.ff-lines th, .ff-lines td { padding: 6px 8px; border-bottom: 1px solid #ddd; text-align: left; }
|
|
80176
80400
|
.ff-lines .num { text-align: right; white-space: nowrap; }
|
|
80177
|
-
.ff-lines thead th { border-bottom: 2px solid
|
|
80401
|
+
.ff-lines thead th { border-bottom: 2px solid ${rule}; }`,
|
|
80402
|
+
i18n: {
|
|
80403
|
+
en: {
|
|
80404
|
+
"lines.description": "Description",
|
|
80405
|
+
"lines.qty": "Qty",
|
|
80406
|
+
"lines.price": "Unit price",
|
|
80407
|
+
"lines.total": "Total"
|
|
80408
|
+
},
|
|
80409
|
+
de: {
|
|
80410
|
+
"lines.description": "Beschreibung",
|
|
80411
|
+
"lines.qty": "Menge",
|
|
80412
|
+
"lines.price": "Einzelpreis",
|
|
80413
|
+
"lines.total": "Gesamt"
|
|
80414
|
+
}
|
|
80415
|
+
}
|
|
80178
80416
|
},
|
|
80179
80417
|
{
|
|
80180
80418
|
id: "totals",
|
|
80419
|
+
group: "invoice",
|
|
80181
80420
|
title: "Totals block",
|
|
80182
80421
|
description: "Net, VAT and gross totals right-aligned under a table.",
|
|
80183
80422
|
source: forAll(
|
|
80184
80423
|
(e) => `<table class="ff-totals">
|
|
80185
|
-
<tr><td
|
|
80186
|
-
<tr><td
|
|
80187
|
-
<tr class="grand"><td
|
|
80424
|
+
<tr><td>${tr(e, "totals.net")}</td><td class="num">${val(e, "invoice.net", "money")}</td></tr>
|
|
80425
|
+
<tr><td>${tr(e, "totals.vat", { rate: "invoice.vat_rate" })}</td><td class="num">${val(e, "invoice.vat", "money")}</td></tr>
|
|
80426
|
+
<tr class="grand"><td>${tr(e, "totals.total")}</td><td class="num">${val(e, "invoice.total", "money")}</td></tr>
|
|
80188
80427
|
</table>$0`
|
|
80189
80428
|
),
|
|
80190
80429
|
sampleData: {
|
|
@@ -80193,10 +80432,103 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80193
80432
|
css: `.ff-totals { margin-left: auto; margin-top: 12px; border-collapse: collapse; font-size: 10pt; }
|
|
80194
80433
|
.ff-totals td { padding: 4px 8px; }
|
|
80195
80434
|
.ff-totals .num { text-align: right; min-width: 90px; }
|
|
80196
|
-
.ff-totals .grand td { border-top: 2px solid
|
|
80435
|
+
.ff-totals .grand td { border-top: 2px solid ${rule}; font-weight: 600; }`,
|
|
80436
|
+
i18n: {
|
|
80437
|
+
en: {
|
|
80438
|
+
"totals.net": "Net",
|
|
80439
|
+
"totals.vat": "VAT {rate} %",
|
|
80440
|
+
"totals.total": "Total"
|
|
80441
|
+
},
|
|
80442
|
+
de: {
|
|
80443
|
+
"totals.net": "Netto",
|
|
80444
|
+
"totals.vat": "USt. {rate} %",
|
|
80445
|
+
"totals.total": "Gesamtbetrag"
|
|
80446
|
+
}
|
|
80447
|
+
}
|
|
80448
|
+
},
|
|
80449
|
+
{
|
|
80450
|
+
id: "payment-terms",
|
|
80451
|
+
group: "invoice",
|
|
80452
|
+
title: "Payment terms and bank details",
|
|
80453
|
+
description: "Amount, due date and the account to transfer it to.",
|
|
80454
|
+
source: forAll(
|
|
80455
|
+
(e) => `<div class="ff-payment">
|
|
80456
|
+
<p>${tr(e, "payment.transfer")} <strong>${val(e, "payment.amount", "money")}</strong> ${tr(e, "payment.until")} <strong>${val(e, "invoice.due_date", "date('P')")}</strong> ${tr(e, "payment.account")}</p>
|
|
80457
|
+
<table>
|
|
80458
|
+
<tr><th>${tr(e, "payment.holder")}</th><td>${val(e, "payment.name")}</td></tr>
|
|
80459
|
+
<tr><th>IBAN</th><td>${val(e, "payment.iban")}</td></tr>
|
|
80460
|
+
<tr><th>BIC</th><td>${val(e, "payment.bic")}</td></tr>
|
|
80461
|
+
<tr><th>${tr(e, "payment.reference")}</th><td>${val(e, "payment.reference")}</td></tr>
|
|
80462
|
+
</table>
|
|
80463
|
+
</div>$0`
|
|
80464
|
+
),
|
|
80465
|
+
sampleData: {
|
|
80466
|
+
invoice: { due_date: "2026-10-13" },
|
|
80467
|
+
payment: {
|
|
80468
|
+
name: "Fennlor Studio GmbH",
|
|
80469
|
+
iban: "DE00000000000000000000",
|
|
80470
|
+
bic: "XXXXDEXXXXX",
|
|
80471
|
+
amount: 3760.4,
|
|
80472
|
+
reference: "2026-0042"
|
|
80473
|
+
}
|
|
80474
|
+
},
|
|
80475
|
+
css: `.ff-payment { margin-top: 16px; font-size: 9.5pt; break-inside: avoid; }
|
|
80476
|
+
.ff-payment p { margin: 0 0 6px; }
|
|
80477
|
+
.ff-payment table { border-collapse: collapse; }
|
|
80478
|
+
.ff-payment th { text-align: left; font-weight: normal; color: #555; padding: 1px 16px 1px 0; }`,
|
|
80479
|
+
i18n: {
|
|
80480
|
+
en: {
|
|
80481
|
+
"payment.transfer": "Please transfer",
|
|
80482
|
+
"payment.until": "by",
|
|
80483
|
+
"payment.account": "to the following account:",
|
|
80484
|
+
"payment.holder": "Account holder",
|
|
80485
|
+
"payment.reference": "Reference"
|
|
80486
|
+
},
|
|
80487
|
+
de: {
|
|
80488
|
+
"payment.transfer": "Bitte \xFCberweisen Sie",
|
|
80489
|
+
"payment.until": "bis zum",
|
|
80490
|
+
"payment.account": "auf folgendes Konto:",
|
|
80491
|
+
"payment.holder": "Kontoinhaber",
|
|
80492
|
+
"payment.reference": "Verwendungszweck"
|
|
80493
|
+
}
|
|
80494
|
+
}
|
|
80495
|
+
},
|
|
80496
|
+
{
|
|
80497
|
+
id: "small-business-note",
|
|
80498
|
+
group: "invoice",
|
|
80499
|
+
title: "Small business VAT note",
|
|
80500
|
+
description: "States that no VAT is charged under \xA7 19 UStG (Kleinunternehmerregelung).",
|
|
80501
|
+
source: forAll((e) => `<p class="ff-note">${tr(e, "vat.small_business")}</p>$0`),
|
|
80502
|
+
css: `.ff-note { margin-top: 12px; font-size: 9pt; color: #444; }`,
|
|
80503
|
+
i18n: {
|
|
80504
|
+
en: { "vat.small_business": "No VAT is charged under the small business scheme of \xA7 19 UStG." },
|
|
80505
|
+
de: { "vat.small_business": "Gem\xE4\xDF \xA7 19 UStG wird keine Umsatzsteuer berechnet." }
|
|
80506
|
+
}
|
|
80507
|
+
},
|
|
80508
|
+
{
|
|
80509
|
+
id: "reverse-charge-note",
|
|
80510
|
+
group: "invoice",
|
|
80511
|
+
title: "Reverse charge note",
|
|
80512
|
+
description: "EU business customers: the recipient owes the VAT, with their VAT ID.",
|
|
80513
|
+
source: forAll(
|
|
80514
|
+
(e) => `<p class="ff-note">${tr(e, "vat.reverse_charge")} ${tr(e, "vat.customer_id")} ${val(e, "customer.vat_id")}</p>$0`
|
|
80515
|
+
),
|
|
80516
|
+
sampleData: { customer: { vat_id: "ATU00000000" } },
|
|
80517
|
+
css: `.ff-note { margin-top: 12px; font-size: 9pt; color: #444; }`,
|
|
80518
|
+
i18n: {
|
|
80519
|
+
en: {
|
|
80520
|
+
"vat.reverse_charge": "Reverse charge: the recipient of the service is liable for VAT.",
|
|
80521
|
+
"vat.customer_id": "Customer VAT ID:"
|
|
80522
|
+
},
|
|
80523
|
+
de: {
|
|
80524
|
+
"vat.reverse_charge": "Steuerschuldnerschaft des Leistungsempf\xE4ngers.",
|
|
80525
|
+
"vat.customer_id": "USt-IdNr. des Leistungsempf\xE4ngers:"
|
|
80526
|
+
}
|
|
80527
|
+
}
|
|
80197
80528
|
},
|
|
80198
80529
|
{
|
|
80199
80530
|
id: "address-block",
|
|
80531
|
+
group: "letter",
|
|
80200
80532
|
title: "Address block",
|
|
80201
80533
|
description: "Recipient name and postal address lines.",
|
|
80202
80534
|
source: forAll(
|
|
@@ -80209,10 +80541,10 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80209
80541
|
),
|
|
80210
80542
|
sampleData: {
|
|
80211
80543
|
customer: {
|
|
80212
|
-
name: "
|
|
80213
|
-
street: "
|
|
80214
|
-
zip: "
|
|
80215
|
-
city: "
|
|
80544
|
+
name: "Olvarest GmbH",
|
|
80545
|
+
street: "Beispielweg 2",
|
|
80546
|
+
zip: "54321",
|
|
80547
|
+
city: "Beispielstadt",
|
|
80216
80548
|
country: "Deutschland"
|
|
80217
80549
|
}
|
|
80218
80550
|
},
|
|
@@ -80220,18 +80552,38 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80220
80552
|
},
|
|
80221
80553
|
{
|
|
80222
80554
|
id: "page-footer",
|
|
80555
|
+
group: "page",
|
|
80556
|
+
kinds: ["pdf"],
|
|
80223
80557
|
title: "Footer with page numbers",
|
|
80224
|
-
description: "
|
|
80558
|
+
description: "Company line and \u201CPage x of y\u201D in the page footer.",
|
|
80559
|
+
target: "footer",
|
|
80225
80560
|
source: forAll(
|
|
80226
80561
|
(e) => `<div style="width:100%;display:flex;justify-content:space-between;font-size:9px;color:#666">
|
|
80227
80562
|
<span>${val(e, "company.name")} \xB7 ${val(e, "company.email")}</span>
|
|
80228
|
-
<span
|
|
80563
|
+
<span>${tr(e, "footer.page")} <span class="pageNumber"></span> ${tr(e, "footer.of")} <span class="totalPages"></span></span>
|
|
80229
80564
|
</div>$0`
|
|
80230
80565
|
),
|
|
80231
|
-
sampleData: { company: { name: "
|
|
80566
|
+
sampleData: { company: { name: "Fennlor Studio GmbH", email: "hello@fennlor.example" } },
|
|
80567
|
+
i18n: {
|
|
80568
|
+
en: { "footer.page": "Page", "footer.of": "of" },
|
|
80569
|
+
de: { "footer.page": "Seite", "footer.of": "von" }
|
|
80570
|
+
}
|
|
80571
|
+
},
|
|
80572
|
+
{
|
|
80573
|
+
id: "legal-footer",
|
|
80574
|
+
group: "page",
|
|
80575
|
+
kinds: ["pdf"],
|
|
80576
|
+
title: "Legal footer",
|
|
80577
|
+
description: "The legal footer from the brand kit, centred in the page footer.",
|
|
80578
|
+
target: "footer",
|
|
80579
|
+
source: forAll(
|
|
80580
|
+
(e) => `<div style="width:100%;text-align:center;font-size:8px;color:#666">${val(e, "brand.legal_footer")}</div>$0`
|
|
80581
|
+
)
|
|
80232
80582
|
},
|
|
80233
80583
|
{
|
|
80234
80584
|
id: "cover-page",
|
|
80585
|
+
group: "report",
|
|
80586
|
+
kinds: ["pdf"],
|
|
80235
80587
|
title: "Cover page",
|
|
80236
80588
|
description: "Title, subtitle and date on a page of its own.",
|
|
80237
80589
|
source: forAll(
|
|
@@ -80250,12 +80602,13 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80250
80602
|
}
|
|
80251
80603
|
},
|
|
80252
80604
|
css: `.ff-cover { min-height: 60vh; display: flex; flex-direction: column; justify-content: center; }
|
|
80253
|
-
.ff-cover h1 { font-size: 32pt; margin: 0 0 8px; }
|
|
80605
|
+
.ff-cover h1 { font-family: var(--brand-font-heading, inherit); font-size: 32pt; color: var(--brand-color-primary, inherit); margin: 0 0 8px; }
|
|
80254
80606
|
.ff-cover .subtitle { font-size: 16pt; color: #444; margin: 0; }
|
|
80255
80607
|
.ff-cover .date { margin-top: 24px; color: #666; }`
|
|
80256
80608
|
},
|
|
80257
80609
|
{
|
|
80258
80610
|
id: "signature",
|
|
80611
|
+
group: "letter",
|
|
80259
80612
|
title: "Signature line",
|
|
80260
80613
|
description: "Place, date and a signature line.",
|
|
80261
80614
|
source: forAll(
|
|
@@ -80268,7 +80621,7 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80268
80621
|
signature: {
|
|
80269
80622
|
place: "Berlin",
|
|
80270
80623
|
date: "2026-09-07",
|
|
80271
|
-
name: "
|
|
80624
|
+
name: "Erika Mustermann"
|
|
80272
80625
|
}
|
|
80273
80626
|
},
|
|
80274
80627
|
css: `.ff-signature { margin-top: 48px; width: 260px; font-size: 9pt; color: #444; }
|
|
@@ -80276,33 +80629,32 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80276
80629
|
},
|
|
80277
80630
|
{
|
|
80278
80631
|
id: "epc-qr",
|
|
80632
|
+
group: "invoice",
|
|
80279
80633
|
title: "SEPA payment QR code",
|
|
80280
80634
|
description: "GiroCode that banking apps scan to prefill the transfer.",
|
|
80281
80635
|
source: {
|
|
80282
80636
|
jinja2: `<figure class="ff-qr">
|
|
80283
|
-
<img src="{{ epcQr(
|
|
80284
|
-
<figcaption
|
|
80637
|
+
<img src="{{ epcQr(payment, { size: 120 }) }}" alt="${tr("jinja2", "qr.alt")}">
|
|
80638
|
+
<figcaption>${tr("jinja2", "qr.caption")}</figcaption>
|
|
80285
80639
|
</figure>$0`,
|
|
80286
80640
|
liquid: `<figure class="ff-qr">
|
|
80287
|
-
<img src="{{ payment | epcQr }}" alt="
|
|
80288
|
-
<figcaption
|
|
80641
|
+
<img src="{{ payment | epcQr: size: 120 }}" alt="${tr("liquid", "qr.alt")}">
|
|
80642
|
+
<figcaption>${tr("liquid", "qr.caption")}</figcaption>
|
|
80289
80643
|
</figure>$0`,
|
|
80290
80644
|
handlebars: `<figure class="ff-qr">
|
|
80291
|
-
<img src="{{epcQr payment size=120}}" alt="
|
|
80292
|
-
<figcaption
|
|
80645
|
+
<img src="{{epcQr payment size=120}}" alt="${tr("handlebars", "qr.alt")}">
|
|
80646
|
+
<figcaption>${tr("handlebars", "qr.caption")}</figcaption>
|
|
80293
80647
|
</figure>$0`
|
|
80294
80648
|
},
|
|
80649
|
+
i18n: {
|
|
80650
|
+
en: { "qr.alt": "Payment QR code", "qr.caption": "Scan to pay" },
|
|
80651
|
+
de: { "qr.alt": "QR-Code zur Zahlung", "qr.caption": "Zum Bezahlen scannen" }
|
|
80652
|
+
},
|
|
80295
80653
|
sampleData: {
|
|
80296
|
-
company: {
|
|
80297
|
-
name: "Acme GmbH",
|
|
80298
|
-
iban: "DE02120300000000202051",
|
|
80299
|
-
bic: "BYLADEM1001"
|
|
80300
|
-
},
|
|
80301
|
-
invoice: { number: "2026-0042", total: 3760.4 },
|
|
80302
80654
|
payment: {
|
|
80303
|
-
name: "
|
|
80304
|
-
iban: "
|
|
80305
|
-
bic: "
|
|
80655
|
+
name: "Fennlor Studio GmbH",
|
|
80656
|
+
iban: "DE00000000000000000000",
|
|
80657
|
+
bic: "XXXXDEXXXXX",
|
|
80306
80658
|
amount: 3760.4,
|
|
80307
80659
|
reference: "2026-0042"
|
|
80308
80660
|
}
|
|
@@ -80312,38 +80664,29 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80312
80664
|
},
|
|
80313
80665
|
{
|
|
80314
80666
|
id: "chart",
|
|
80667
|
+
group: "report",
|
|
80315
80668
|
title: "Chart",
|
|
80316
|
-
description: "Bar chart
|
|
80669
|
+
description: "Bar chart from labels and values in the data, in the brand colour.",
|
|
80670
|
+
// the colour comes from the brand kit; without one the helper takes its palette
|
|
80317
80671
|
source: {
|
|
80318
80672
|
jinja2: `<figure class="ff-chart-box">
|
|
80319
|
-
{{ chart(
|
|
80320
|
-
<figcaption>{{
|
|
80673
|
+
{{ chart(sales, { type: '\${1:bar}', width: 480, height: 240, color: brand.colors.primary }) }}
|
|
80674
|
+
<figcaption>{{ sales.caption }}</figcaption>
|
|
80321
80675
|
</figure>$0`,
|
|
80322
80676
|
liquid: `<figure class="ff-chart-box">
|
|
80323
|
-
{{
|
|
80324
|
-
<figcaption>{{
|
|
80677
|
+
{{ sales | chart: type: '\${1:bar}', width: 480, height: 240, color: brand.colors.primary }}
|
|
80678
|
+
<figcaption>{{ sales.caption }}</figcaption>
|
|
80325
80679
|
</figure>$0`,
|
|
80326
80680
|
handlebars: `<figure class="ff-chart-box">
|
|
80327
|
-
{{chart
|
|
80328
|
-
<figcaption>{{
|
|
80681
|
+
{{chart sales type='\${1:bar}' width=480 height=240 color=brand.colors.primary}}
|
|
80682
|
+
<figcaption>{{sales.caption}}</figcaption>
|
|
80329
80683
|
</figure>$0`
|
|
80330
80684
|
},
|
|
80331
80685
|
sampleData: {
|
|
80332
|
-
|
|
80333
|
-
type: "bar",
|
|
80686
|
+
sales: {
|
|
80334
80687
|
caption: "Revenue per quarter",
|
|
80335
|
-
|
|
80336
|
-
|
|
80337
|
-
data: {
|
|
80338
|
-
labels: ["Q1", "Q2", "Q3", "Q4"],
|
|
80339
|
-
datasets: [
|
|
80340
|
-
{
|
|
80341
|
-
label: "Revenue",
|
|
80342
|
-
data: [12e3, 15500, 14200, 18900],
|
|
80343
|
-
backgroundColor: "#3E63DD"
|
|
80344
|
-
}
|
|
80345
|
-
]
|
|
80346
|
-
}
|
|
80688
|
+
labels: ["Q1", "Q2", "Q3", "Q4"],
|
|
80689
|
+
values: [12e3, 15500, 14200, 18900]
|
|
80347
80690
|
}
|
|
80348
80691
|
},
|
|
80349
80692
|
css: `.ff-chart-box { margin: 16px 0; break-inside: avoid; }
|
|
@@ -80351,6 +80694,7 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80351
80694
|
},
|
|
80352
80695
|
{
|
|
80353
80696
|
id: "two-columns",
|
|
80697
|
+
group: "page",
|
|
80354
80698
|
title: "Two-column layout",
|
|
80355
80699
|
description: "Two equal columns that stay side by side in print.",
|
|
80356
80700
|
source: forAll(
|
|
@@ -80361,6 +80705,50 @@ ${loop(e, "line", "invoice.lines", ` <tr><td>${val(e, "line.description")}</t
|
|
|
80361
80705
|
),
|
|
80362
80706
|
css: `.ff-columns { display: flex; gap: 24px; }
|
|
80363
80707
|
.ff-columns > div { flex: 1 1 0; min-width: 0; }`
|
|
80708
|
+
},
|
|
80709
|
+
{
|
|
80710
|
+
id: "keep-together",
|
|
80711
|
+
group: "page",
|
|
80712
|
+
kinds: ["pdf"],
|
|
80713
|
+
title: "Keep together",
|
|
80714
|
+
description: "Content that is never split across two pages.",
|
|
80715
|
+
source: forAll(() => `<div class="avoid-break">
|
|
80716
|
+
$0
|
|
80717
|
+
</div>`)
|
|
80718
|
+
},
|
|
80719
|
+
{
|
|
80720
|
+
id: "page-break",
|
|
80721
|
+
group: "page",
|
|
80722
|
+
kinds: ["pdf"],
|
|
80723
|
+
title: "Page break",
|
|
80724
|
+
description: "Starts a new page in the PDF.",
|
|
80725
|
+
source: forAll(() => `<div class="page-break"></div>
|
|
80726
|
+
$0`)
|
|
80727
|
+
},
|
|
80728
|
+
{
|
|
80729
|
+
id: "kpi-cards",
|
|
80730
|
+
group: "report",
|
|
80731
|
+
title: "Key figures",
|
|
80732
|
+
description: "A row of cards with label, value and change for each figure.",
|
|
80733
|
+
source: forAll(
|
|
80734
|
+
(e) => `<div class="ff-kpis">
|
|
80735
|
+
${loop(e, "kpi", "report.kpis", ` <div class="kpi"><span class="label">${val(e, "kpi.label")}</span><strong>${val(e, "kpi.value")}</strong><span class="change">${val(e, "kpi.change")}</span></div>`)}
|
|
80736
|
+
</div>$0`
|
|
80737
|
+
),
|
|
80738
|
+
sampleData: {
|
|
80739
|
+
report: {
|
|
80740
|
+
kpis: [
|
|
80741
|
+
{ label: "Revenue", value: "\u20AC 61,600", change: "+12 % on Q2" },
|
|
80742
|
+
{ label: "New customers", value: "48", change: "+9 on Q2" },
|
|
80743
|
+
{ label: "Churn", value: "1.8 %", change: "\u22120.4 pt on Q2" }
|
|
80744
|
+
]
|
|
80745
|
+
}
|
|
80746
|
+
},
|
|
80747
|
+
css: `.ff-kpis { display: flex; gap: 12px; margin: 16px 0; break-inside: avoid; }
|
|
80748
|
+
.ff-kpis .kpi { flex: 1 1 0; padding: 10px 12px; border: 1px solid #e5e5e5; border-top: 3px solid ${rule}; border-radius: 4px; }
|
|
80749
|
+
.ff-kpis .label { display: block; font-size: 8pt; color: #666; text-transform: uppercase; letter-spacing: 0.04em; }
|
|
80750
|
+
.ff-kpis strong { display: block; margin: 2px 0; font-size: 18pt; }
|
|
80751
|
+
.ff-kpis .change { font-size: 8pt; color: #555; }`
|
|
80364
80752
|
}
|
|
80365
80753
|
];
|
|
80366
80754
|
|
|
@@ -80369,7 +80757,1610 @@ var SEGMENT = "[A-Za-z0-9][A-Za-z0-9._-]*";
|
|
|
80369
80757
|
var ASSET_NAME_PATTERN = new RegExp(`^${SEGMENT}(?:/${SEGMENT})*$`);
|
|
80370
80758
|
var ASSET_MAX_BYTES = 10 * 1024 * 1024;
|
|
80371
80759
|
|
|
80760
|
+
// packages/engine/src/lib/office/errors.ts
|
|
80761
|
+
var OfficeError = class extends Error {
|
|
80762
|
+
constructor(code, message2, details = {}) {
|
|
80763
|
+
super(message2);
|
|
80764
|
+
this.code = code;
|
|
80765
|
+
this.details = details;
|
|
80766
|
+
this.name = "OfficeError";
|
|
80767
|
+
}
|
|
80768
|
+
};
|
|
80769
|
+
var officeLimits = {
|
|
80770
|
+
/** Entries in one container. */
|
|
80771
|
+
maxEntries: 2e3,
|
|
80772
|
+
/** Sum of the uncompressed sizes the central directory declares. */
|
|
80773
|
+
maxDeclaredBytes: 200 * 1024 * 1024,
|
|
80774
|
+
/** One part we inflate; enforced while inflating, because the declared size can lie. */
|
|
80775
|
+
maxPartBytes: 20 * 1024 * 1024,
|
|
80776
|
+
/** A conversion upload or a template file. */
|
|
80777
|
+
maxFileBytes: 20 * 1024 * 1024
|
|
80778
|
+
};
|
|
80779
|
+
|
|
80780
|
+
// node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/index.mjs
|
|
80781
|
+
import { createRequire } from "module";
|
|
80782
|
+
var require2 = createRequire("/");
|
|
80783
|
+
var _a;
|
|
80784
|
+
var Worker;
|
|
80785
|
+
var isMarkedAsUntransferable;
|
|
80786
|
+
try {
|
|
80787
|
+
_a = require2("worker_threads"), Worker = _a.Worker, isMarkedAsUntransferable = _a.isMarkedAsUntransferable;
|
|
80788
|
+
} catch (e) {
|
|
80789
|
+
}
|
|
80790
|
+
var u8 = Uint8Array;
|
|
80791
|
+
var u16 = Uint16Array;
|
|
80792
|
+
var i32 = Int32Array;
|
|
80793
|
+
var fleb = new u8([
|
|
80794
|
+
0,
|
|
80795
|
+
0,
|
|
80796
|
+
0,
|
|
80797
|
+
0,
|
|
80798
|
+
0,
|
|
80799
|
+
0,
|
|
80800
|
+
0,
|
|
80801
|
+
0,
|
|
80802
|
+
1,
|
|
80803
|
+
1,
|
|
80804
|
+
1,
|
|
80805
|
+
1,
|
|
80806
|
+
2,
|
|
80807
|
+
2,
|
|
80808
|
+
2,
|
|
80809
|
+
2,
|
|
80810
|
+
3,
|
|
80811
|
+
3,
|
|
80812
|
+
3,
|
|
80813
|
+
3,
|
|
80814
|
+
4,
|
|
80815
|
+
4,
|
|
80816
|
+
4,
|
|
80817
|
+
4,
|
|
80818
|
+
5,
|
|
80819
|
+
5,
|
|
80820
|
+
5,
|
|
80821
|
+
5,
|
|
80822
|
+
0,
|
|
80823
|
+
/* unused */
|
|
80824
|
+
0,
|
|
80825
|
+
0,
|
|
80826
|
+
/* impossible */
|
|
80827
|
+
0
|
|
80828
|
+
]);
|
|
80829
|
+
var fdeb = new u8([
|
|
80830
|
+
0,
|
|
80831
|
+
0,
|
|
80832
|
+
0,
|
|
80833
|
+
0,
|
|
80834
|
+
1,
|
|
80835
|
+
1,
|
|
80836
|
+
2,
|
|
80837
|
+
2,
|
|
80838
|
+
3,
|
|
80839
|
+
3,
|
|
80840
|
+
4,
|
|
80841
|
+
4,
|
|
80842
|
+
5,
|
|
80843
|
+
5,
|
|
80844
|
+
6,
|
|
80845
|
+
6,
|
|
80846
|
+
7,
|
|
80847
|
+
7,
|
|
80848
|
+
8,
|
|
80849
|
+
8,
|
|
80850
|
+
9,
|
|
80851
|
+
9,
|
|
80852
|
+
10,
|
|
80853
|
+
10,
|
|
80854
|
+
11,
|
|
80855
|
+
11,
|
|
80856
|
+
12,
|
|
80857
|
+
12,
|
|
80858
|
+
13,
|
|
80859
|
+
13,
|
|
80860
|
+
/* unused */
|
|
80861
|
+
0,
|
|
80862
|
+
0
|
|
80863
|
+
]);
|
|
80864
|
+
var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
80865
|
+
var freb = function(eb, start) {
|
|
80866
|
+
var b2 = new u16(31);
|
|
80867
|
+
for (var i = 0; i < 31; ++i) {
|
|
80868
|
+
b2[i] = start += 1 << eb[i - 1];
|
|
80869
|
+
}
|
|
80870
|
+
var r = new i32(b2[30]);
|
|
80871
|
+
for (var i = 1; i < 30; ++i) {
|
|
80872
|
+
for (var j2 = b2[i]; j2 < b2[i + 1]; ++j2) {
|
|
80873
|
+
r[j2] = j2 - b2[i] << 5 | i;
|
|
80874
|
+
}
|
|
80875
|
+
}
|
|
80876
|
+
return { b: b2, r };
|
|
80877
|
+
};
|
|
80878
|
+
var _a = freb(fleb, 2);
|
|
80879
|
+
var fl = _a.b;
|
|
80880
|
+
var revfl = _a.r;
|
|
80881
|
+
fl[28] = 258, revfl[258] = 28;
|
|
80882
|
+
var _b = freb(fdeb, 0);
|
|
80883
|
+
var fd = _b.b;
|
|
80884
|
+
var revfd = _b.r;
|
|
80885
|
+
var rev = new u16(32768);
|
|
80886
|
+
for (i = 0; i < 32768; ++i) {
|
|
80887
|
+
x2 = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
80888
|
+
x2 = (x2 & 52428) >> 2 | (x2 & 13107) << 2;
|
|
80889
|
+
x2 = (x2 & 61680) >> 4 | (x2 & 3855) << 4;
|
|
80890
|
+
rev[i] = ((x2 & 65280) >> 8 | (x2 & 255) << 8) >> 1;
|
|
80891
|
+
}
|
|
80892
|
+
var x2;
|
|
80893
|
+
var i;
|
|
80894
|
+
var hMap = (function(cd, mb, r) {
|
|
80895
|
+
var s = cd.length;
|
|
80896
|
+
var i = 0;
|
|
80897
|
+
var l3 = new u16(mb);
|
|
80898
|
+
for (; i < s; ++i) {
|
|
80899
|
+
if (cd[i])
|
|
80900
|
+
++l3[cd[i] - 1];
|
|
80901
|
+
}
|
|
80902
|
+
var le2 = new u16(mb);
|
|
80903
|
+
for (i = 1; i < mb; ++i) {
|
|
80904
|
+
le2[i] = le2[i - 1] + l3[i - 1] << 1;
|
|
80905
|
+
}
|
|
80906
|
+
var co;
|
|
80907
|
+
if (r) {
|
|
80908
|
+
co = new u16(1 << mb);
|
|
80909
|
+
var rvb = 15 - mb;
|
|
80910
|
+
for (i = 0; i < s; ++i) {
|
|
80911
|
+
if (cd[i]) {
|
|
80912
|
+
var sv = i << 4 | cd[i];
|
|
80913
|
+
var r_1 = mb - cd[i];
|
|
80914
|
+
var v2 = le2[cd[i] - 1]++ << r_1;
|
|
80915
|
+
for (var m2 = v2 | (1 << r_1) - 1; v2 <= m2; ++v2) {
|
|
80916
|
+
co[rev[v2] >> rvb] = sv;
|
|
80917
|
+
}
|
|
80918
|
+
}
|
|
80919
|
+
}
|
|
80920
|
+
} else {
|
|
80921
|
+
co = new u16(s);
|
|
80922
|
+
for (i = 0; i < s; ++i) {
|
|
80923
|
+
if (cd[i]) {
|
|
80924
|
+
co[i] = rev[le2[cd[i] - 1]++] >> 15 - cd[i];
|
|
80925
|
+
}
|
|
80926
|
+
}
|
|
80927
|
+
}
|
|
80928
|
+
return co;
|
|
80929
|
+
});
|
|
80930
|
+
var flt = new u8(288);
|
|
80931
|
+
for (i = 0; i < 144; ++i)
|
|
80932
|
+
flt[i] = 8;
|
|
80933
|
+
var i;
|
|
80934
|
+
for (i = 144; i < 256; ++i)
|
|
80935
|
+
flt[i] = 9;
|
|
80936
|
+
var i;
|
|
80937
|
+
for (i = 256; i < 280; ++i)
|
|
80938
|
+
flt[i] = 7;
|
|
80939
|
+
var i;
|
|
80940
|
+
for (i = 280; i < 288; ++i)
|
|
80941
|
+
flt[i] = 8;
|
|
80942
|
+
var i;
|
|
80943
|
+
var fdt = new u8(32);
|
|
80944
|
+
for (i = 0; i < 32; ++i)
|
|
80945
|
+
fdt[i] = 5;
|
|
80946
|
+
var i;
|
|
80947
|
+
var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
|
|
80948
|
+
var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
80949
|
+
var max = function(a) {
|
|
80950
|
+
var m2 = a[0];
|
|
80951
|
+
for (var i = 1; i < a.length; ++i) {
|
|
80952
|
+
if (a[i] > m2)
|
|
80953
|
+
m2 = a[i];
|
|
80954
|
+
}
|
|
80955
|
+
return m2;
|
|
80956
|
+
};
|
|
80957
|
+
var bits = function(d, p, m2) {
|
|
80958
|
+
var o = p / 8 | 0;
|
|
80959
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m2;
|
|
80960
|
+
};
|
|
80961
|
+
var bits16 = function(d, p) {
|
|
80962
|
+
var o = p / 8 | 0;
|
|
80963
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
80964
|
+
};
|
|
80965
|
+
var shft = function(p) {
|
|
80966
|
+
return (p + 7) / 8 | 0;
|
|
80967
|
+
};
|
|
80968
|
+
var slc = function(v2, s, e) {
|
|
80969
|
+
if (s == null || s < 0)
|
|
80970
|
+
s = 0;
|
|
80971
|
+
if (e == null || e > v2.length)
|
|
80972
|
+
e = v2.length;
|
|
80973
|
+
return new u8(v2.subarray(s, e));
|
|
80974
|
+
};
|
|
80975
|
+
var ec = [
|
|
80976
|
+
"unexpected EOF",
|
|
80977
|
+
"invalid block type",
|
|
80978
|
+
"invalid length/literal",
|
|
80979
|
+
"invalid distance",
|
|
80980
|
+
"stream finished",
|
|
80981
|
+
"no stream handler",
|
|
80982
|
+
,
|
|
80983
|
+
// determined by compression function
|
|
80984
|
+
"no callback",
|
|
80985
|
+
"invalid UTF-8 data",
|
|
80986
|
+
"extra field too long",
|
|
80987
|
+
"date not in range 1980-2099",
|
|
80988
|
+
"filename too long",
|
|
80989
|
+
"stream finishing",
|
|
80990
|
+
"invalid zip data"
|
|
80991
|
+
// determined by unknown compression method
|
|
80992
|
+
];
|
|
80993
|
+
var err = function(ind, msg, nt2) {
|
|
80994
|
+
var e = new Error(msg || ec[ind]);
|
|
80995
|
+
e.code = ind;
|
|
80996
|
+
if (Error.captureStackTrace)
|
|
80997
|
+
Error.captureStackTrace(e, err);
|
|
80998
|
+
if (!nt2)
|
|
80999
|
+
throw e;
|
|
81000
|
+
return e;
|
|
81001
|
+
};
|
|
81002
|
+
var inflt = function(dat, st2, buf, dict) {
|
|
81003
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
81004
|
+
if (!sl || st2.f && !st2.l)
|
|
81005
|
+
return buf || new u8(0);
|
|
81006
|
+
var noBuf = !buf;
|
|
81007
|
+
var resize = noBuf || st2.i != 2;
|
|
81008
|
+
var noSt = st2.i;
|
|
81009
|
+
if (noBuf)
|
|
81010
|
+
buf = new u8(sl * 3);
|
|
81011
|
+
var cbuf = function(l4) {
|
|
81012
|
+
var bl = buf.length;
|
|
81013
|
+
if (l4 > bl) {
|
|
81014
|
+
var nbuf = new u8(Math.max(bl * 2, l4));
|
|
81015
|
+
nbuf.set(buf);
|
|
81016
|
+
buf = nbuf;
|
|
81017
|
+
}
|
|
81018
|
+
};
|
|
81019
|
+
var final = st2.f || 0, pos = st2.p || 0, bt = st2.b || 0, lm = st2.l, dm = st2.d, lbt = st2.m, dbt = st2.n;
|
|
81020
|
+
var tbts = sl * 8;
|
|
81021
|
+
do {
|
|
81022
|
+
if (!lm) {
|
|
81023
|
+
final = bits(dat, pos, 1);
|
|
81024
|
+
var type = bits(dat, pos + 1, 3);
|
|
81025
|
+
pos += 3;
|
|
81026
|
+
if (!type) {
|
|
81027
|
+
var s = shft(pos) + 4, l3 = dat[s - 4] | dat[s - 3] << 8, t = s + l3;
|
|
81028
|
+
if (t > sl) {
|
|
81029
|
+
if (noSt)
|
|
81030
|
+
err(0);
|
|
81031
|
+
break;
|
|
81032
|
+
}
|
|
81033
|
+
if (resize)
|
|
81034
|
+
cbuf(bt + l3);
|
|
81035
|
+
buf.set(dat.subarray(s, t), bt);
|
|
81036
|
+
st2.b = bt += l3, st2.p = pos = t * 8, st2.f = final;
|
|
81037
|
+
continue;
|
|
81038
|
+
} else if (type == 1)
|
|
81039
|
+
lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
81040
|
+
else if (type == 2) {
|
|
81041
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
81042
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
81043
|
+
pos += 14;
|
|
81044
|
+
var ldt = new u8(tl);
|
|
81045
|
+
var clt = new u8(19);
|
|
81046
|
+
for (var i = 0; i < hcLen; ++i) {
|
|
81047
|
+
clt[clim[i]] = bits(dat, pos + i * 3, 7);
|
|
81048
|
+
}
|
|
81049
|
+
pos += hcLen * 3;
|
|
81050
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
81051
|
+
var clm = hMap(clt, clb, 1);
|
|
81052
|
+
for (var i = 0; i < tl; ) {
|
|
81053
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
81054
|
+
pos += r & 15;
|
|
81055
|
+
var s = r >> 4;
|
|
81056
|
+
if (s < 16) {
|
|
81057
|
+
ldt[i++] = s;
|
|
81058
|
+
} else {
|
|
81059
|
+
var c = 0, n = 0;
|
|
81060
|
+
if (s == 16)
|
|
81061
|
+
n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
|
|
81062
|
+
else if (s == 17)
|
|
81063
|
+
n = 3 + bits(dat, pos, 7), pos += 3;
|
|
81064
|
+
else if (s == 18)
|
|
81065
|
+
n = 11 + bits(dat, pos, 127), pos += 7;
|
|
81066
|
+
while (n--)
|
|
81067
|
+
ldt[i++] = c;
|
|
81068
|
+
}
|
|
81069
|
+
}
|
|
81070
|
+
var lt2 = ldt.subarray(0, hLit), dt2 = ldt.subarray(hLit);
|
|
81071
|
+
lbt = max(lt2);
|
|
81072
|
+
dbt = max(dt2);
|
|
81073
|
+
lm = hMap(lt2, lbt, 1);
|
|
81074
|
+
dm = hMap(dt2, dbt, 1);
|
|
81075
|
+
} else
|
|
81076
|
+
err(1);
|
|
81077
|
+
if (pos > tbts) {
|
|
81078
|
+
if (noSt)
|
|
81079
|
+
err(0);
|
|
81080
|
+
break;
|
|
81081
|
+
}
|
|
81082
|
+
}
|
|
81083
|
+
if (resize)
|
|
81084
|
+
cbuf(bt + 131072);
|
|
81085
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
81086
|
+
var lpos = pos;
|
|
81087
|
+
for (; ; lpos = pos) {
|
|
81088
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
81089
|
+
pos += c & 15;
|
|
81090
|
+
if (pos > tbts) {
|
|
81091
|
+
if (noSt)
|
|
81092
|
+
err(0);
|
|
81093
|
+
break;
|
|
81094
|
+
}
|
|
81095
|
+
if (!c)
|
|
81096
|
+
err(2);
|
|
81097
|
+
if (sym < 256)
|
|
81098
|
+
buf[bt++] = sym;
|
|
81099
|
+
else if (sym == 256) {
|
|
81100
|
+
lpos = pos, lm = null;
|
|
81101
|
+
break;
|
|
81102
|
+
} else {
|
|
81103
|
+
var add2 = sym - 254;
|
|
81104
|
+
if (sym > 264) {
|
|
81105
|
+
var i = sym - 257, b2 = fleb[i];
|
|
81106
|
+
add2 = bits(dat, pos, (1 << b2) - 1) + fl[i];
|
|
81107
|
+
pos += b2;
|
|
81108
|
+
}
|
|
81109
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
81110
|
+
if (!d)
|
|
81111
|
+
err(3);
|
|
81112
|
+
pos += d & 15;
|
|
81113
|
+
var dt2 = fd[dsym];
|
|
81114
|
+
if (dsym > 3) {
|
|
81115
|
+
var b2 = fdeb[dsym];
|
|
81116
|
+
dt2 += bits16(dat, pos) & (1 << b2) - 1, pos += b2;
|
|
81117
|
+
}
|
|
81118
|
+
if (pos > tbts) {
|
|
81119
|
+
if (noSt)
|
|
81120
|
+
err(0);
|
|
81121
|
+
break;
|
|
81122
|
+
}
|
|
81123
|
+
if (resize)
|
|
81124
|
+
cbuf(bt + 131072);
|
|
81125
|
+
var end = bt + add2;
|
|
81126
|
+
if (bt < dt2) {
|
|
81127
|
+
var shift = dl - dt2, dend = Math.min(dt2, end);
|
|
81128
|
+
if (shift + bt < 0)
|
|
81129
|
+
err(3);
|
|
81130
|
+
for (; bt < dend; ++bt)
|
|
81131
|
+
buf[bt] = dict[shift + bt];
|
|
81132
|
+
}
|
|
81133
|
+
for (; bt < end; ++bt)
|
|
81134
|
+
buf[bt] = buf[bt - dt2];
|
|
81135
|
+
}
|
|
81136
|
+
}
|
|
81137
|
+
st2.l = lm, st2.p = lpos, st2.b = bt, st2.f = final;
|
|
81138
|
+
if (lm)
|
|
81139
|
+
final = 1, st2.m = lbt, st2.d = dm, st2.n = dbt;
|
|
81140
|
+
} while (!final);
|
|
81141
|
+
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
81142
|
+
};
|
|
81143
|
+
var et2 = /* @__PURE__ */ new u8(0);
|
|
81144
|
+
var Inflate = /* @__PURE__ */ (function() {
|
|
81145
|
+
function Inflate2(opts, cb) {
|
|
81146
|
+
if (typeof opts == "function")
|
|
81147
|
+
cb = opts, opts = {};
|
|
81148
|
+
this.ondata = cb;
|
|
81149
|
+
var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);
|
|
81150
|
+
this.s = { i: 0, b: dict ? dict.length : 0 };
|
|
81151
|
+
this.o = new u8(32768);
|
|
81152
|
+
this.p = new u8(0);
|
|
81153
|
+
if (dict)
|
|
81154
|
+
this.o.set(dict);
|
|
81155
|
+
}
|
|
81156
|
+
Inflate2.prototype.e = function(c) {
|
|
81157
|
+
if (!this.ondata)
|
|
81158
|
+
err(5);
|
|
81159
|
+
if (this.d)
|
|
81160
|
+
err(4);
|
|
81161
|
+
if (!this.p.length)
|
|
81162
|
+
this.p = c;
|
|
81163
|
+
else if (c.length) {
|
|
81164
|
+
var n = new u8(this.p.length + c.length);
|
|
81165
|
+
n.set(this.p), n.set(c, this.p.length), this.p = n;
|
|
81166
|
+
}
|
|
81167
|
+
};
|
|
81168
|
+
Inflate2.prototype.c = function(final) {
|
|
81169
|
+
this.s.i = +(this.d = final || false);
|
|
81170
|
+
var bts = this.s.b;
|
|
81171
|
+
var dt2 = inflt(this.p, this.s, this.o);
|
|
81172
|
+
this.ondata(slc(dt2, bts, this.s.b), this.d);
|
|
81173
|
+
this.o = slc(dt2, this.s.b - 32768), this.s.b = this.o.length;
|
|
81174
|
+
this.p = slc(this.p, this.s.p / 8 | 0), this.s.p &= 7;
|
|
81175
|
+
};
|
|
81176
|
+
Inflate2.prototype.push = function(chunk, final) {
|
|
81177
|
+
this.e(chunk), this.c(final);
|
|
81178
|
+
};
|
|
81179
|
+
return Inflate2;
|
|
81180
|
+
})();
|
|
81181
|
+
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
81182
|
+
var tds = 0;
|
|
81183
|
+
try {
|
|
81184
|
+
td.decode(et2, { stream: true });
|
|
81185
|
+
tds = 1;
|
|
81186
|
+
} catch (e) {
|
|
81187
|
+
}
|
|
81188
|
+
|
|
81189
|
+
// packages/engine/src/lib/office/zip.ts
|
|
81190
|
+
var SIG_EOCD = 101010256;
|
|
81191
|
+
var SIG_EOCD64 = 101075792;
|
|
81192
|
+
var SIG_EOCD64_LOCATOR = 117853008;
|
|
81193
|
+
var SIG_CENTRAL = 33639248;
|
|
81194
|
+
var SIG_LOCAL = 67324752;
|
|
81195
|
+
var MAX32 = 4294967295;
|
|
81196
|
+
var invalid = (message2, details = {}) => new OfficeError("office_document_invalid", message2, details);
|
|
81197
|
+
function isZip(bytes) {
|
|
81198
|
+
return bytes.length >= 4 && bytes[0] === 80 && bytes[1] === 75 && bytes[2] === 3 && bytes[3] === 4;
|
|
81199
|
+
}
|
|
81200
|
+
function isSafeEntryName(name) {
|
|
81201
|
+
if (!name || name.length > 1024) return false;
|
|
81202
|
+
if (name.startsWith("/") || name.includes("\\") || /^[A-Za-z]:/.test(name))
|
|
81203
|
+
return false;
|
|
81204
|
+
if (/[\u0000-\u001F]/.test(name)) return false;
|
|
81205
|
+
return !name.split("/").some((segment) => segment === "..");
|
|
81206
|
+
}
|
|
81207
|
+
function readZip(bytes, limits = officeLimits) {
|
|
81208
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
81209
|
+
const u162 = (at3) => view.getUint16(at3, true);
|
|
81210
|
+
const u32 = (at3) => view.getUint32(at3, true);
|
|
81211
|
+
const within = (at3, length) => at3 >= 0 && length >= 0 && at3 + length <= bytes.length;
|
|
81212
|
+
let eocd = -1;
|
|
81213
|
+
for (let at3 = bytes.length - 22; at3 >= Math.max(0, bytes.length - 22 - 65535); at3--) {
|
|
81214
|
+
if (u32(at3) === SIG_EOCD) {
|
|
81215
|
+
eocd = at3;
|
|
81216
|
+
break;
|
|
81217
|
+
}
|
|
81218
|
+
}
|
|
81219
|
+
if (eocd < 0) throw invalid("The file is not a valid ZIP container");
|
|
81220
|
+
let count = u162(eocd + 10);
|
|
81221
|
+
let cdSize = u32(eocd + 12);
|
|
81222
|
+
let cdOffset = u32(eocd + 16);
|
|
81223
|
+
if (u162(eocd + 4) !== 0 || u162(eocd + 6) !== 0)
|
|
81224
|
+
throw invalid("Multi-part ZIP archives are not supported");
|
|
81225
|
+
if (count === 65535 || cdSize === MAX32 || cdOffset === MAX32) {
|
|
81226
|
+
const locator = eocd - 20;
|
|
81227
|
+
if (!within(locator, 20) || u32(locator) !== SIG_EOCD64_LOCATOR)
|
|
81228
|
+
throw invalid("The ZIP64 directory is missing");
|
|
81229
|
+
const at3 = Number(view.getBigUint64(locator + 8, true));
|
|
81230
|
+
if (!within(at3, 56) || u32(at3) !== SIG_EOCD64)
|
|
81231
|
+
throw invalid("The ZIP64 directory is invalid");
|
|
81232
|
+
count = Number(view.getBigUint64(at3 + 32, true));
|
|
81233
|
+
cdSize = Number(view.getBigUint64(at3 + 40, true));
|
|
81234
|
+
cdOffset = Number(view.getBigUint64(at3 + 48, true));
|
|
81235
|
+
}
|
|
81236
|
+
if (count > limits.maxEntries)
|
|
81237
|
+
throw invalid(
|
|
81238
|
+
`The container has ${count} entries; the limit is ${limits.maxEntries}`,
|
|
81239
|
+
{ entries: count }
|
|
81240
|
+
);
|
|
81241
|
+
if (!within(cdOffset, cdSize))
|
|
81242
|
+
throw invalid("The ZIP central directory lies outside the file");
|
|
81243
|
+
const decoder = new TextDecoder();
|
|
81244
|
+
const entries = [];
|
|
81245
|
+
const byName = /* @__PURE__ */ new Map();
|
|
81246
|
+
const lowerNames = /* @__PURE__ */ new Set();
|
|
81247
|
+
let declared = 0;
|
|
81248
|
+
let at2 = cdOffset;
|
|
81249
|
+
for (let i = 0; i < count; i++) {
|
|
81250
|
+
if (!within(at2, 46) || u32(at2) !== SIG_CENTRAL)
|
|
81251
|
+
throw invalid("The ZIP central directory is corrupt");
|
|
81252
|
+
const flags = u162(at2 + 8);
|
|
81253
|
+
const method = u162(at2 + 10);
|
|
81254
|
+
const dosTime = u162(at2 + 12);
|
|
81255
|
+
const dosDate = u162(at2 + 14);
|
|
81256
|
+
const crc322 = u32(at2 + 16);
|
|
81257
|
+
let compressedSize = u32(at2 + 20);
|
|
81258
|
+
let size = u32(at2 + 24);
|
|
81259
|
+
const nameLength = u162(at2 + 28);
|
|
81260
|
+
const extraLength = u162(at2 + 30);
|
|
81261
|
+
const commentLength = u162(at2 + 32);
|
|
81262
|
+
let localOffset = u32(at2 + 42);
|
|
81263
|
+
if (!within(at2 + 46, nameLength + extraLength + commentLength))
|
|
81264
|
+
throw invalid("The ZIP central directory is corrupt");
|
|
81265
|
+
const nameBytes = bytes.subarray(at2 + 46, at2 + 46 + nameLength);
|
|
81266
|
+
const name = flags & 2048 ? decoder.decode(nameBytes) : String.fromCharCode(...nameBytes);
|
|
81267
|
+
let extra = at2 + 46 + nameLength;
|
|
81268
|
+
const extraEnd = extra + extraLength;
|
|
81269
|
+
while (extra + 4 <= extraEnd) {
|
|
81270
|
+
const id = u162(extra);
|
|
81271
|
+
const length = u162(extra + 2);
|
|
81272
|
+
if (id === 1) {
|
|
81273
|
+
let field = extra + 4;
|
|
81274
|
+
const read64 = () => {
|
|
81275
|
+
if (field + 8 > extra + 4 + length)
|
|
81276
|
+
throw invalid("The ZIP64 extra field is truncated");
|
|
81277
|
+
const value = Number(view.getBigUint64(field, true));
|
|
81278
|
+
field += 8;
|
|
81279
|
+
return value;
|
|
81280
|
+
};
|
|
81281
|
+
if (size === MAX32) size = read64();
|
|
81282
|
+
if (compressedSize === MAX32) compressedSize = read64();
|
|
81283
|
+
if (localOffset === MAX32) localOffset = read64();
|
|
81284
|
+
}
|
|
81285
|
+
extra += 4 + length;
|
|
81286
|
+
}
|
|
81287
|
+
at2 = extraEnd + commentLength;
|
|
81288
|
+
if (flags & 1)
|
|
81289
|
+
throw new OfficeError(
|
|
81290
|
+
"source_encrypted",
|
|
81291
|
+
"The container has encrypted entries",
|
|
81292
|
+
{ entry: name }
|
|
81293
|
+
);
|
|
81294
|
+
if (method !== 0 && method !== 8)
|
|
81295
|
+
throw invalid(`Entry ${name} uses an unsupported compression method`, {
|
|
81296
|
+
entry: name,
|
|
81297
|
+
method
|
|
81298
|
+
});
|
|
81299
|
+
if (!isSafeEntryName(name))
|
|
81300
|
+
throw invalid("The container has an entry with an unsafe name", {
|
|
81301
|
+
entry: name
|
|
81302
|
+
});
|
|
81303
|
+
const lower = name.toLowerCase();
|
|
81304
|
+
if (lowerNames.has(lower))
|
|
81305
|
+
throw invalid("The container has duplicate entries", { entry: name });
|
|
81306
|
+
lowerNames.add(lower);
|
|
81307
|
+
declared += size;
|
|
81308
|
+
if (declared > limits.maxDeclaredBytes)
|
|
81309
|
+
throw new OfficeError(
|
|
81310
|
+
"office_document_too_large",
|
|
81311
|
+
"The container unpacks to more than the limit",
|
|
81312
|
+
{
|
|
81313
|
+
limit: limits.maxDeclaredBytes
|
|
81314
|
+
}
|
|
81315
|
+
);
|
|
81316
|
+
if (!within(localOffset, 30) || u32(localOffset) !== SIG_LOCAL)
|
|
81317
|
+
throw invalid(`Entry ${name} has no local header`);
|
|
81318
|
+
const dataStart = localOffset + 30 + u162(localOffset + 26) + u162(localOffset + 28);
|
|
81319
|
+
if (!within(dataStart, compressedSize))
|
|
81320
|
+
throw invalid(`Entry ${name} lies outside the file`);
|
|
81321
|
+
if (method === 0 && compressedSize !== size)
|
|
81322
|
+
throw invalid(`Entry ${name} has inconsistent sizes`);
|
|
81323
|
+
const entry = {
|
|
81324
|
+
name,
|
|
81325
|
+
method,
|
|
81326
|
+
crc32: crc322,
|
|
81327
|
+
compressedSize,
|
|
81328
|
+
size,
|
|
81329
|
+
dosTime,
|
|
81330
|
+
dosDate,
|
|
81331
|
+
raw: bytes.subarray(dataStart, dataStart + compressedSize)
|
|
81332
|
+
};
|
|
81333
|
+
entries.push(entry);
|
|
81334
|
+
byName.set(name, entry);
|
|
81335
|
+
}
|
|
81336
|
+
return { entries, get: (name) => byName.get(name) };
|
|
81337
|
+
}
|
|
81338
|
+
function readEntry(entry, maxBytes = officeLimits.maxPartBytes) {
|
|
81339
|
+
const tooLarge = () => new OfficeError(
|
|
81340
|
+
"office_document_too_large",
|
|
81341
|
+
`Part ${entry.name} is larger than ${maxBytes} bytes`,
|
|
81342
|
+
{
|
|
81343
|
+
entry: entry.name,
|
|
81344
|
+
limit: maxBytes
|
|
81345
|
+
}
|
|
81346
|
+
);
|
|
81347
|
+
if (entry.size > maxBytes) throw tooLarge();
|
|
81348
|
+
let out;
|
|
81349
|
+
if (entry.method === 0) out = entry.raw;
|
|
81350
|
+
else {
|
|
81351
|
+
const chunks = [];
|
|
81352
|
+
let total = 0;
|
|
81353
|
+
const inflate = new Inflate((chunk) => {
|
|
81354
|
+
total += chunk.length;
|
|
81355
|
+
if (total > maxBytes) throw tooLarge();
|
|
81356
|
+
chunks.push(chunk);
|
|
81357
|
+
});
|
|
81358
|
+
try {
|
|
81359
|
+
inflate.push(entry.raw, true);
|
|
81360
|
+
} catch (e) {
|
|
81361
|
+
if (e instanceof OfficeError) throw e;
|
|
81362
|
+
throw invalid(`Part ${entry.name} cannot be decompressed`, {
|
|
81363
|
+
entry: entry.name
|
|
81364
|
+
});
|
|
81365
|
+
}
|
|
81366
|
+
out = concat(chunks, total);
|
|
81367
|
+
}
|
|
81368
|
+
if (out.length !== entry.size || crc32(out) !== entry.crc32)
|
|
81369
|
+
throw invalid(`Part ${entry.name} is corrupt`, { entry: entry.name });
|
|
81370
|
+
return out;
|
|
81371
|
+
}
|
|
81372
|
+
function readText(entry, maxBytes) {
|
|
81373
|
+
return decodeXml(readEntry(entry, maxBytes));
|
|
81374
|
+
}
|
|
81375
|
+
function decodeXml(bytes) {
|
|
81376
|
+
if (bytes[0] === 255 && bytes[1] === 254)
|
|
81377
|
+
return decodeUtf16(bytes.subarray(2), true);
|
|
81378
|
+
if (bytes[0] === 254 && bytes[1] === 255)
|
|
81379
|
+
return decodeUtf16(bytes.subarray(2), false);
|
|
81380
|
+
return new TextDecoder().decode(bytes);
|
|
81381
|
+
}
|
|
81382
|
+
function decodeUtf16(bytes, littleEndian) {
|
|
81383
|
+
const units = new Uint16Array(bytes.length >> 1);
|
|
81384
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
81385
|
+
for (let i = 0; i < units.length; i++)
|
|
81386
|
+
units[i] = view.getUint16(i * 2, littleEndian);
|
|
81387
|
+
let out = "";
|
|
81388
|
+
for (let i = 0; i < units.length; i += 8192)
|
|
81389
|
+
out += String.fromCharCode(...units.subarray(i, i + 8192));
|
|
81390
|
+
return out;
|
|
81391
|
+
}
|
|
81392
|
+
function concat(chunks, total) {
|
|
81393
|
+
if (chunks.length === 1) return chunks[0];
|
|
81394
|
+
const out = new Uint8Array(total);
|
|
81395
|
+
let at2 = 0;
|
|
81396
|
+
for (const chunk of chunks) {
|
|
81397
|
+
out.set(chunk, at2);
|
|
81398
|
+
at2 += chunk.length;
|
|
81399
|
+
}
|
|
81400
|
+
return out;
|
|
81401
|
+
}
|
|
81402
|
+
var table = null;
|
|
81403
|
+
function crc32(data) {
|
|
81404
|
+
if (!table) {
|
|
81405
|
+
table = new Uint32Array(256);
|
|
81406
|
+
for (let n = 0; n < 256; n++) {
|
|
81407
|
+
let c = n;
|
|
81408
|
+
for (let k2 = 0; k2 < 8; k2++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
81409
|
+
table[n] = c >>> 0;
|
|
81410
|
+
}
|
|
81411
|
+
}
|
|
81412
|
+
let crc = 4294967295;
|
|
81413
|
+
for (let i = 0; i < data.length; i++)
|
|
81414
|
+
crc = table[(crc ^ data[i]) & 255] ^ crc >>> 8;
|
|
81415
|
+
return (crc ^ 4294967295) >>> 0;
|
|
81416
|
+
}
|
|
81417
|
+
|
|
81418
|
+
// packages/engine/src/lib/office/detect.ts
|
|
81419
|
+
var OOXML_MAIN = {
|
|
81420
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": "docx",
|
|
81421
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "xlsx",
|
|
81422
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": "pptx"
|
|
81423
|
+
};
|
|
81424
|
+
var OOXML_REFUSED = {
|
|
81425
|
+
"application/vnd.ms-word.document.macroenabled.main+xml": "a macro-enabled Word document (.docm)",
|
|
81426
|
+
"application/vnd.ms-word.template.macroenabledtemplate.main+xml": "a macro-enabled Word template (.dotm)",
|
|
81427
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": "a Word template (.dotx)",
|
|
81428
|
+
"application/vnd.ms-excel.sheet.macroenabled.main+xml": "a macro-enabled workbook (.xlsm)",
|
|
81429
|
+
"application/vnd.ms-excel.sheet.binary.macroenabled.main": "a binary workbook (.xlsb)",
|
|
81430
|
+
"application/vnd.ms-excel.template.macroenabled.main+xml": "a macro-enabled Excel template (.xltm)",
|
|
81431
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": "an Excel template (.xltx)",
|
|
81432
|
+
"application/vnd.ms-powerpoint.presentation.macroenabled.main+xml": "a macro-enabled presentation (.pptm)",
|
|
81433
|
+
"application/vnd.ms-powerpoint.slideshow.macroenabled.main+xml": "a macro-enabled slide show (.ppsm)",
|
|
81434
|
+
"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": "a slide show (.ppsx)",
|
|
81435
|
+
"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": "a PowerPoint template (.potx)"
|
|
81436
|
+
};
|
|
81437
|
+
var ODF_MIME = {
|
|
81438
|
+
"application/vnd.oasis.opendocument.text": "odt",
|
|
81439
|
+
"application/vnd.oasis.opendocument.spreadsheet": "ods",
|
|
81440
|
+
"application/vnd.oasis.opendocument.presentation": "odp"
|
|
81441
|
+
};
|
|
81442
|
+
var unsupported = (message2, details = {}) => new OfficeError("file_type_unsupported", message2, details);
|
|
81443
|
+
var ACCEPTED = "Accepted are DOCX, XLSX, PPTX, ODT, ODS, ODP, DOC, XLS, PPT, RTF and HTML";
|
|
81444
|
+
function detectOfficeFormat(bytes) {
|
|
81445
|
+
if (bytes.length > officeLimits.maxFileBytes)
|
|
81446
|
+
throw new OfficeError(
|
|
81447
|
+
"office_document_too_large",
|
|
81448
|
+
`The file is larger than ${officeLimits.maxFileBytes / 1024 / 1024} MB`,
|
|
81449
|
+
{
|
|
81450
|
+
bytes: bytes.length,
|
|
81451
|
+
limit: officeLimits.maxFileBytes
|
|
81452
|
+
}
|
|
81453
|
+
);
|
|
81454
|
+
if (isZip(bytes)) return detectZip(bytes);
|
|
81455
|
+
if (isCfb(bytes)) return { format: detectCfb(bytes), archive: null };
|
|
81456
|
+
if (startsWithAscii(bytes, "{\\rtf")) return { format: "rtf", archive: null };
|
|
81457
|
+
if (isHtml(bytes)) return { format: "html", archive: null };
|
|
81458
|
+
throw unsupported(`The file is not an office document. ${ACCEPTED}.`);
|
|
81459
|
+
}
|
|
81460
|
+
function detectZip(bytes) {
|
|
81461
|
+
const archive = readZip(bytes);
|
|
81462
|
+
const macro = archive.entries.find((e) => isMacroPart(e.name));
|
|
81463
|
+
if (macro)
|
|
81464
|
+
throw unsupported("Macro-enabled documents are not accepted", {
|
|
81465
|
+
entry: macro.name
|
|
81466
|
+
});
|
|
81467
|
+
const mimetype = archive.get("mimetype");
|
|
81468
|
+
if (mimetype) {
|
|
81469
|
+
const value = readText(mimetype, 1024).trim();
|
|
81470
|
+
const format2 = ODF_MIME[value];
|
|
81471
|
+
if (!format2)
|
|
81472
|
+
throw unsupported(
|
|
81473
|
+
`OpenDocument type ${value.slice(0, 100)} is not accepted. ${ACCEPTED}.`
|
|
81474
|
+
);
|
|
81475
|
+
const manifest = archive.get("META-INF/manifest.xml");
|
|
81476
|
+
if (manifest && readText(manifest, 1024 * 1024).includes("encryption-data"))
|
|
81477
|
+
throw new OfficeError(
|
|
81478
|
+
"source_encrypted",
|
|
81479
|
+
"The document is password-protected"
|
|
81480
|
+
);
|
|
81481
|
+
return { format: format2, archive };
|
|
81482
|
+
}
|
|
81483
|
+
const types = archive.get("[Content_Types].xml");
|
|
81484
|
+
if (!types)
|
|
81485
|
+
throw unsupported(`The ZIP file is not an office document. ${ACCEPTED}.`);
|
|
81486
|
+
const xml = readText(types, 1024 * 1024);
|
|
81487
|
+
if (hasDoctype(xml))
|
|
81488
|
+
throw new OfficeError(
|
|
81489
|
+
"office_document_invalid",
|
|
81490
|
+
"The document declares a DOCTYPE"
|
|
81491
|
+
);
|
|
81492
|
+
const contentTypes = [...xml.matchAll(/ContentType\s*=\s*"([^"]*)"/g)].map(
|
|
81493
|
+
(m2) => m2[1].toLowerCase()
|
|
81494
|
+
);
|
|
81495
|
+
const refused = contentTypes.find((t) => OOXML_REFUSED[t]);
|
|
81496
|
+
if (refused)
|
|
81497
|
+
throw unsupported(
|
|
81498
|
+
`The file is ${OOXML_REFUSED[refused]}, which is not accepted. ${ACCEPTED}.`
|
|
81499
|
+
);
|
|
81500
|
+
const mains = [
|
|
81501
|
+
...new Set(contentTypes.map((t) => OOXML_MAIN[t]).filter(Boolean))
|
|
81502
|
+
];
|
|
81503
|
+
if (mains.length !== 1)
|
|
81504
|
+
throw unsupported(
|
|
81505
|
+
`The file is not a Word, Excel or PowerPoint document. ${ACCEPTED}.`
|
|
81506
|
+
);
|
|
81507
|
+
return { format: mains[0], archive };
|
|
81508
|
+
}
|
|
81509
|
+
function isMacroPart(name) {
|
|
81510
|
+
const lower = name.toLowerCase();
|
|
81511
|
+
const base = lower.split("/").pop() ?? "";
|
|
81512
|
+
if (base === "vbaproject.bin" || base === "vbadata.xml") return true;
|
|
81513
|
+
if (lower.startsWith("scripts/")) return !lower.endsWith("/");
|
|
81514
|
+
if (lower.startsWith("basic/"))
|
|
81515
|
+
return !lower.endsWith("/") && base !== "script-lc.xml" && base !== "script-lb.xml";
|
|
81516
|
+
return false;
|
|
81517
|
+
}
|
|
81518
|
+
function hasDoctype(xml) {
|
|
81519
|
+
return /<!DOCTYPE/i.test(xml) || /<!ENTITY/i.test(xml);
|
|
81520
|
+
}
|
|
81521
|
+
function isHtml(bytes) {
|
|
81522
|
+
let start = 0;
|
|
81523
|
+
if (bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) start = 3;
|
|
81524
|
+
const head = new TextDecoder().decode(bytes.subarray(start, start + 4096));
|
|
81525
|
+
const withoutProlog = head.replace(/^\s+/, "").replace(/^<\?xml[^>]*\?>\s*/i, "");
|
|
81526
|
+
const withoutComments = withoutProlog.replace(/^(?:<!--[\s\S]*?-->\s*)+/, "");
|
|
81527
|
+
return /^(?:<!doctype\s+html|<html[\s>])/i.test(withoutComments);
|
|
81528
|
+
}
|
|
81529
|
+
function startsWithAscii(bytes, prefix) {
|
|
81530
|
+
if (bytes.length < prefix.length) return false;
|
|
81531
|
+
for (let i = 0; i < prefix.length; i++)
|
|
81532
|
+
if (bytes[i] !== prefix.charCodeAt(i)) return false;
|
|
81533
|
+
return true;
|
|
81534
|
+
}
|
|
81535
|
+
var CFB_MAGIC = [208, 207, 17, 224, 161, 177, 26, 225];
|
|
81536
|
+
function isCfb(bytes) {
|
|
81537
|
+
return bytes.length >= 512 && CFB_MAGIC.every((b2, i) => bytes[i] === b2);
|
|
81538
|
+
}
|
|
81539
|
+
function cfbStreamNames(bytes) {
|
|
81540
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
81541
|
+
const invalid3 = () => new OfficeError(
|
|
81542
|
+
"office_document_invalid",
|
|
81543
|
+
"The compound document is corrupt"
|
|
81544
|
+
);
|
|
81545
|
+
const shift = view.getUint16(30, true);
|
|
81546
|
+
if (shift !== 9 && shift !== 12) throw invalid3();
|
|
81547
|
+
const sectorSize = 1 << shift;
|
|
81548
|
+
const sectorAt = (sector2) => (sector2 + 1) * sectorSize;
|
|
81549
|
+
const fatSectorCount = view.getUint32(44, true);
|
|
81550
|
+
const firstDirSector = view.getUint32(48, true);
|
|
81551
|
+
const firstDifatSector = view.getUint32(68, true);
|
|
81552
|
+
const totalSectors = Math.ceil(bytes.length / sectorSize);
|
|
81553
|
+
if (fatSectorCount > totalSectors) throw invalid3();
|
|
81554
|
+
const fatSectors = [];
|
|
81555
|
+
for (let i = 0; i < 109 && fatSectors.length < fatSectorCount; i++)
|
|
81556
|
+
fatSectors.push(view.getUint32(76 + i * 4, true));
|
|
81557
|
+
let difat = firstDifatSector;
|
|
81558
|
+
for (let guard = 0; fatSectors.length < fatSectorCount && difat < 4294967290; guard++) {
|
|
81559
|
+
if (guard > totalSectors || sectorAt(difat) + sectorSize > bytes.length)
|
|
81560
|
+
throw invalid3();
|
|
81561
|
+
for (let i = 0; i < sectorSize / 4 - 1 && fatSectors.length < fatSectorCount; i++)
|
|
81562
|
+
fatSectors.push(view.getUint32(sectorAt(difat) + i * 4, true));
|
|
81563
|
+
difat = view.getUint32(sectorAt(difat) + sectorSize - 4, true);
|
|
81564
|
+
}
|
|
81565
|
+
const next = (sector2) => {
|
|
81566
|
+
const index = Math.floor(sector2 / (sectorSize / 4));
|
|
81567
|
+
const fat = fatSectors[index];
|
|
81568
|
+
if (fat === void 0 || sectorAt(fat) + sectorSize > bytes.length)
|
|
81569
|
+
throw invalid3();
|
|
81570
|
+
return view.getUint32(
|
|
81571
|
+
sectorAt(fat) + sector2 % (sectorSize / 4) * 4,
|
|
81572
|
+
true
|
|
81573
|
+
);
|
|
81574
|
+
};
|
|
81575
|
+
const names = [];
|
|
81576
|
+
let sector = firstDirSector;
|
|
81577
|
+
for (let guard = 0; sector < 4294967290; guard++) {
|
|
81578
|
+
if (guard > totalSectors || sectorAt(sector) + sectorSize > bytes.length)
|
|
81579
|
+
throw invalid3();
|
|
81580
|
+
for (let at2 = sectorAt(sector); at2 < sectorAt(sector) + sectorSize; at2 += 128) {
|
|
81581
|
+
const length = view.getUint16(at2 + 64, true);
|
|
81582
|
+
const type = bytes[at2 + 66];
|
|
81583
|
+
if (type === 0 || length < 2 || length > 64) continue;
|
|
81584
|
+
let name = "";
|
|
81585
|
+
for (let c = 0; c < length - 2; c += 2)
|
|
81586
|
+
name += String.fromCharCode(view.getUint16(at2 + c, true));
|
|
81587
|
+
names.push(name);
|
|
81588
|
+
}
|
|
81589
|
+
sector = next(sector);
|
|
81590
|
+
}
|
|
81591
|
+
return names;
|
|
81592
|
+
}
|
|
81593
|
+
function detectCfb(bytes) {
|
|
81594
|
+
const names = new Set(cfbStreamNames(bytes));
|
|
81595
|
+
if (names.has("EncryptionInfo") || names.has("EncryptedPackage"))
|
|
81596
|
+
throw new OfficeError(
|
|
81597
|
+
"source_encrypted",
|
|
81598
|
+
"The document is password-protected"
|
|
81599
|
+
);
|
|
81600
|
+
if (names.has("_VBA_PROJECT_CUR") || names.has("VBA") || names.has("Macros"))
|
|
81601
|
+
throw unsupported("Macro-enabled documents are not accepted");
|
|
81602
|
+
if (names.has("WordDocument")) return "doc";
|
|
81603
|
+
if (names.has("Workbook") || names.has("Book")) return "xls";
|
|
81604
|
+
if (names.has("PowerPoint Document")) return "ppt";
|
|
81605
|
+
throw unsupported(
|
|
81606
|
+
`The compound file is not a Word, Excel or PowerPoint document. ${ACCEPTED}.`
|
|
81607
|
+
);
|
|
81608
|
+
}
|
|
81609
|
+
|
|
81610
|
+
// packages/engine/src/lib/office/xml.ts
|
|
81611
|
+
var NAME = /^[A-Za-z_][\w.-]*(?::[A-Za-z_][\w.-]*)?/;
|
|
81612
|
+
var invalid2 = (message2, part) => new OfficeError("office_document_invalid", part ? `${part}: ${message2}` : message2, part ? { entry: part } : {});
|
|
81613
|
+
function tokenize(xml, part) {
|
|
81614
|
+
const tokens = [];
|
|
81615
|
+
let at2 = 0;
|
|
81616
|
+
while (at2 < xml.length) {
|
|
81617
|
+
const lt2 = xml.indexOf("<", at2);
|
|
81618
|
+
if (lt2 === -1) {
|
|
81619
|
+
tokens.push({ kind: "text", raw: xml.slice(at2) });
|
|
81620
|
+
break;
|
|
81621
|
+
}
|
|
81622
|
+
if (lt2 > at2) tokens.push({ kind: "text", raw: xml.slice(at2, lt2) });
|
|
81623
|
+
if (xml.startsWith("<!--", lt2)) {
|
|
81624
|
+
const end = xml.indexOf("-->", lt2 + 4);
|
|
81625
|
+
if (end === -1) throw invalid2("unterminated comment", part);
|
|
81626
|
+
tokens.push({ kind: "comment", raw: xml.slice(lt2, end + 3) });
|
|
81627
|
+
at2 = end + 3;
|
|
81628
|
+
} else if (xml.startsWith("<![CDATA[", lt2)) {
|
|
81629
|
+
const end = xml.indexOf("]]>", lt2 + 9);
|
|
81630
|
+
if (end === -1) throw invalid2("unterminated CDATA section", part);
|
|
81631
|
+
tokens.push({ kind: "cdata", raw: xml.slice(lt2, end + 3) });
|
|
81632
|
+
at2 = end + 3;
|
|
81633
|
+
} else if (xml.startsWith("<?", lt2)) {
|
|
81634
|
+
const end = xml.indexOf("?>", lt2 + 2);
|
|
81635
|
+
if (end === -1) throw invalid2("unterminated processing instruction", part);
|
|
81636
|
+
tokens.push({ kind: "pi", raw: xml.slice(lt2, end + 2) });
|
|
81637
|
+
at2 = end + 2;
|
|
81638
|
+
} else if (xml.startsWith("<!", lt2)) {
|
|
81639
|
+
throw invalid2("declarations such as DOCTYPE are not allowed", part);
|
|
81640
|
+
} else {
|
|
81641
|
+
const end = tagEnd(xml, lt2);
|
|
81642
|
+
if (end === -1) throw invalid2("unterminated tag", part);
|
|
81643
|
+
const raw = xml.slice(lt2, end + 1);
|
|
81644
|
+
if (raw[1] === "/") {
|
|
81645
|
+
const name = NAME.exec(raw.slice(2))?.[0];
|
|
81646
|
+
if (!name || raw.slice(2 + name.length, -1).trim() !== "") throw invalid2(`malformed end tag ${raw.slice(0, 40)}`, part);
|
|
81647
|
+
tokens.push({ kind: "close", raw, name });
|
|
81648
|
+
} else {
|
|
81649
|
+
const name = NAME.exec(raw.slice(1))?.[0];
|
|
81650
|
+
if (!name) throw invalid2(`malformed tag ${raw.slice(0, 40)}`, part);
|
|
81651
|
+
tokens.push({ kind: "open", raw, name, selfClosing: raw.endsWith("/>") });
|
|
81652
|
+
}
|
|
81653
|
+
at2 = end + 1;
|
|
81654
|
+
}
|
|
81655
|
+
}
|
|
81656
|
+
return tokens;
|
|
81657
|
+
}
|
|
81658
|
+
function tagEnd(xml, start) {
|
|
81659
|
+
let quote = null;
|
|
81660
|
+
for (let i = start + 1; i < xml.length; i++) {
|
|
81661
|
+
const c = xml[i];
|
|
81662
|
+
if (quote) {
|
|
81663
|
+
if (c === quote) quote = null;
|
|
81664
|
+
} else if (c === '"' || c === "'") quote = c;
|
|
81665
|
+
else if (c === ">") return i;
|
|
81666
|
+
else if (c === "<") return -1;
|
|
81667
|
+
}
|
|
81668
|
+
return -1;
|
|
81669
|
+
}
|
|
81670
|
+
function assertWellFormed(tokens, part) {
|
|
81671
|
+
const stack = [];
|
|
81672
|
+
let roots = 0;
|
|
81673
|
+
for (const token of tokens) {
|
|
81674
|
+
switch (token.kind) {
|
|
81675
|
+
case "open": {
|
|
81676
|
+
checkAttributes(token.raw, part);
|
|
81677
|
+
if (stack.length === 0) roots++;
|
|
81678
|
+
if (!token.selfClosing) stack.push(token.name);
|
|
81679
|
+
break;
|
|
81680
|
+
}
|
|
81681
|
+
case "close": {
|
|
81682
|
+
const open = stack.pop();
|
|
81683
|
+
if (open !== token.name) throw invalid2(`</${token.name}> closes <${open ?? "nothing"}>`, part);
|
|
81684
|
+
break;
|
|
81685
|
+
}
|
|
81686
|
+
case "text":
|
|
81687
|
+
if (stack.length === 0 && token.raw.trim() !== "") throw invalid2("text outside the root element", part);
|
|
81688
|
+
checkText(token.raw, part);
|
|
81689
|
+
break;
|
|
81690
|
+
default:
|
|
81691
|
+
break;
|
|
81692
|
+
}
|
|
81693
|
+
}
|
|
81694
|
+
if (stack.length) throw invalid2(`<${stack.at(-1)}> is not closed`, part);
|
|
81695
|
+
if (roots !== 1) throw invalid2(roots === 0 ? "no root element" : "more than one root element", part);
|
|
81696
|
+
}
|
|
81697
|
+
var FORBIDDEN = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
81698
|
+
var ENTITY = /&(?:#x[0-9A-Fa-f]+|#\d+|amp|lt|gt|quot|apos);/y;
|
|
81699
|
+
function checkText(text2, part) {
|
|
81700
|
+
if (FORBIDDEN.test(text2)) throw invalid2("a character XML does not allow", part);
|
|
81701
|
+
if (text2.includes("<")) throw invalid2("unescaped < in text", part);
|
|
81702
|
+
for (let i = text2.indexOf("&"); i !== -1; i = text2.indexOf("&", i + 1)) {
|
|
81703
|
+
ENTITY.lastIndex = i;
|
|
81704
|
+
if (!ENTITY.test(text2)) throw invalid2(`invalid entity reference near "${text2.slice(i, i + 12)}"`, part);
|
|
81705
|
+
}
|
|
81706
|
+
}
|
|
81707
|
+
function checkAttributes(raw, part) {
|
|
81708
|
+
const body = raw.replace(/^<[^\s/>]+/, "").replace(/\/?>$/, "");
|
|
81709
|
+
const seen = /* @__PURE__ */ new Set();
|
|
81710
|
+
const rest = body.replace(/\s*([\w.:-]+)\s*=\s*("([^"]*)"|'([^']*)')/g, (_m, name, _q, dq, sq) => {
|
|
81711
|
+
if (seen.has(name)) throw invalid2(`duplicate attribute ${name}`, part);
|
|
81712
|
+
seen.add(name);
|
|
81713
|
+
const value = dq ?? sq ?? "";
|
|
81714
|
+
checkText(value, part);
|
|
81715
|
+
return "";
|
|
81716
|
+
});
|
|
81717
|
+
if (rest.trim() !== "") throw invalid2(`malformed attributes in ${raw.slice(0, 40)}`, part);
|
|
81718
|
+
}
|
|
81719
|
+
function decodeText(raw) {
|
|
81720
|
+
return raw.replace(/&(#x[0-9A-Fa-f]+|#\d+|amp|lt|gt|quot|apos);/g, (whole, name) => {
|
|
81721
|
+
switch (name) {
|
|
81722
|
+
case "amp":
|
|
81723
|
+
return "&";
|
|
81724
|
+
case "lt":
|
|
81725
|
+
return "<";
|
|
81726
|
+
case "gt":
|
|
81727
|
+
return ">";
|
|
81728
|
+
case "quot":
|
|
81729
|
+
return '"';
|
|
81730
|
+
case "apos":
|
|
81731
|
+
return "'";
|
|
81732
|
+
default: {
|
|
81733
|
+
const code = name.startsWith("#x") ? parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10);
|
|
81734
|
+
return code > 0 && code <= 1114111 ? String.fromCodePoint(code) : whole;
|
|
81735
|
+
}
|
|
81736
|
+
}
|
|
81737
|
+
});
|
|
81738
|
+
}
|
|
81739
|
+
function escapeText(text2) {
|
|
81740
|
+
return text2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
81741
|
+
}
|
|
81742
|
+
|
|
81743
|
+
// packages/engine/src/lib/office/drawings.ts
|
|
81744
|
+
var OPEN = String.fromCharCode(57346);
|
|
81745
|
+
var CLOSE = String.fromCharCode(57347);
|
|
81746
|
+
var officeDrawingLimits = {
|
|
81747
|
+
/** Drawings per render. */
|
|
81748
|
+
maxDrawings: 50,
|
|
81749
|
+
/** Image bytes placed per render. */
|
|
81750
|
+
maxImageBytes: 20 * 1024 * 1024,
|
|
81751
|
+
/** Largest raster edge in pixels. */
|
|
81752
|
+
maxPixels: 2400
|
|
81753
|
+
};
|
|
81754
|
+
|
|
81755
|
+
// packages/engine/src/lib/office/fonts.ts
|
|
81756
|
+
var METRIC_COMPATIBLE = {
|
|
81757
|
+
calibri: "Carlito",
|
|
81758
|
+
cambria: "Caladea",
|
|
81759
|
+
arial: "Liberation Sans",
|
|
81760
|
+
helvetica: "Liberation Sans",
|
|
81761
|
+
"times new roman": "Liberation Serif",
|
|
81762
|
+
"courier new": "Liberation Mono"
|
|
81763
|
+
};
|
|
81764
|
+
var THEME_REFERENCES = /^\+(mj|mn)-/;
|
|
81765
|
+
function documentFonts(archive) {
|
|
81766
|
+
const fonts = /* @__PURE__ */ new Map();
|
|
81767
|
+
const add2 = (name, embedded = false) => {
|
|
81768
|
+
const clean = decodeText(name).trim();
|
|
81769
|
+
if (!clean || THEME_REFERENCES.test(clean)) return;
|
|
81770
|
+
const key = clean.toLowerCase();
|
|
81771
|
+
const known = fonts.get(key);
|
|
81772
|
+
fonts.set(key, { name: known?.name ?? clean, embedded: embedded || (known?.embedded ?? false) });
|
|
81773
|
+
};
|
|
81774
|
+
const table2 = archive.get("word/fontTable.xml");
|
|
81775
|
+
if (table2)
|
|
81776
|
+
for (const m2 of readText(table2).matchAll(/<w:font\b[^>]*\bw:name="([^"]*)"[^>]*?(?:\/>|>([\s\S]*?)<\/w:font>)/g))
|
|
81777
|
+
add2(m2[1] ?? "", /<w:embed(?:Regular|Bold|Italic|BoldItalic)\b/.test(m2[2] ?? ""));
|
|
81778
|
+
for (const entry of archive.entries)
|
|
81779
|
+
if (/^(word|ppt)\/theme\/theme\d*\.xml$/.test(entry.name))
|
|
81780
|
+
for (const m2 of readText(entry).matchAll(/<a:(?:major|minor)Font>\s*<a:latin\s+typeface="([^"]*)"/g)) add2(m2[1] ?? "");
|
|
81781
|
+
const presentation = archive.get("ppt/presentation.xml");
|
|
81782
|
+
if (presentation)
|
|
81783
|
+
for (const m2 of readText(presentation).matchAll(/<p:embeddedFont>\s*<p:font\s+typeface="([^"]*)"/g)) add2(m2[1] ?? "", true);
|
|
81784
|
+
return [...fonts.values()].sort((a, b2) => a.name.localeCompare(b2.name));
|
|
81785
|
+
}
|
|
81786
|
+
function fontDiagnostics(fonts, installed, part = "word/fontTable.xml") {
|
|
81787
|
+
const have = new Set(installed.map((f2) => f2.toLowerCase()));
|
|
81788
|
+
const out = [];
|
|
81789
|
+
for (const font of fonts) {
|
|
81790
|
+
const key = font.name.toLowerCase();
|
|
81791
|
+
if (font.embedded || have.has(key)) continue;
|
|
81792
|
+
const substitute = METRIC_COMPATIBLE[key];
|
|
81793
|
+
out.push(
|
|
81794
|
+
substitute && have.has(substitute.toLowerCase()) ? {
|
|
81795
|
+
severity: "info",
|
|
81796
|
+
code: "office-font-substituted",
|
|
81797
|
+
message: `${font.name} is replaced by ${substitute}, which has the same metrics; lines and pages break the same.`,
|
|
81798
|
+
part,
|
|
81799
|
+
paragraph: 1,
|
|
81800
|
+
text: font.name
|
|
81801
|
+
} : {
|
|
81802
|
+
severity: "warning",
|
|
81803
|
+
code: "office-font-substituted",
|
|
81804
|
+
message: `${font.name} is not available to the converter and is replaced, so the PDF can look different. Embed the font in Word (File > Options > Save > Embed fonts in the file).`,
|
|
81805
|
+
part,
|
|
81806
|
+
paragraph: 1,
|
|
81807
|
+
text: font.name
|
|
81808
|
+
}
|
|
81809
|
+
);
|
|
81810
|
+
}
|
|
81811
|
+
return out;
|
|
81812
|
+
}
|
|
81813
|
+
|
|
81814
|
+
// packages/engine/src/lib/office/template-text.ts
|
|
81815
|
+
var TEXT_ELEMENT = { wordprocessing: "w:t", drawing: "a:t" };
|
|
81816
|
+
var CONTAINERS = /* @__PURE__ */ new Set([
|
|
81817
|
+
"w:hyperlink",
|
|
81818
|
+
"w:sdt",
|
|
81819
|
+
"w:sdtContent",
|
|
81820
|
+
"w:ins",
|
|
81821
|
+
"w:del",
|
|
81822
|
+
"w:smartTag",
|
|
81823
|
+
"w:fldSimple",
|
|
81824
|
+
"w:fldChar",
|
|
81825
|
+
"w:instrText",
|
|
81826
|
+
"mc:AlternateContent",
|
|
81827
|
+
"mc:Choice",
|
|
81828
|
+
"mc:Fallback",
|
|
81829
|
+
"w:txbxContent",
|
|
81830
|
+
"w:tbl",
|
|
81831
|
+
"w:tr",
|
|
81832
|
+
"w:tc",
|
|
81833
|
+
"a:tbl",
|
|
81834
|
+
"a:tr",
|
|
81835
|
+
"a:tc"
|
|
81836
|
+
]);
|
|
81837
|
+
var PARAGRAPHS = /* @__PURE__ */ new Set(["w:p", "a:p"]);
|
|
81838
|
+
var OPEN2 = "\uE000";
|
|
81839
|
+
var CLOSE2 = "\uE001";
|
|
81840
|
+
var STRUCTURAL = "ff:tag";
|
|
81841
|
+
function isTextElement(name, textElement) {
|
|
81842
|
+
return name === textElement || name === STRUCTURAL;
|
|
81843
|
+
}
|
|
81844
|
+
function emptyPiece() {
|
|
81845
|
+
return { raw: "", paragraphOpens: 0, paragraphBoundary: false, containerBoundary: false };
|
|
81846
|
+
}
|
|
81847
|
+
function placeholderPattern(nonce) {
|
|
81848
|
+
return new RegExp(`${OPEN2}${nonce}(\\d+)${CLOSE2}`, "g");
|
|
81849
|
+
}
|
|
81850
|
+
function createNonce(random = Math.random) {
|
|
81851
|
+
let nonce = "";
|
|
81852
|
+
for (let i = 0; i < 16; i++) nonce += String.fromCharCode(97 + Math.floor(random() * 26));
|
|
81853
|
+
return nonce;
|
|
81854
|
+
}
|
|
81855
|
+
function toTemplateSource(xml, flavour, nonce, part) {
|
|
81856
|
+
const tokens = tokenize(xml, part);
|
|
81857
|
+
assertWellFormed(tokens, part);
|
|
81858
|
+
const textElement = TEXT_ELEMENT[flavour];
|
|
81859
|
+
const markup = [];
|
|
81860
|
+
let source = "";
|
|
81861
|
+
let pending = emptyPiece();
|
|
81862
|
+
let inText = false;
|
|
81863
|
+
const flush = () => {
|
|
81864
|
+
if (!pending.raw) return;
|
|
81865
|
+
pending.endsInText = inText;
|
|
81866
|
+
source += `${OPEN2}${nonce}${markup.length}${CLOSE2}`;
|
|
81867
|
+
markup.push(pending);
|
|
81868
|
+
pending = emptyPiece();
|
|
81869
|
+
};
|
|
81870
|
+
for (const token of tokens) {
|
|
81871
|
+
if (token.kind === "text" && inText) {
|
|
81872
|
+
flush();
|
|
81873
|
+
source += decodeText(token.raw);
|
|
81874
|
+
continue;
|
|
81875
|
+
}
|
|
81876
|
+
pending.raw += token.raw;
|
|
81877
|
+
if (token.kind === "open" || token.kind === "close") {
|
|
81878
|
+
if (PARAGRAPHS.has(token.name) || token.name === STRUCTURAL) {
|
|
81879
|
+
pending.paragraphBoundary = true;
|
|
81880
|
+
if (token.kind === "open" && !token.selfClosing) pending.paragraphOpens++;
|
|
81881
|
+
} else if (CONTAINERS.has(token.name)) pending.containerBoundary = true;
|
|
81882
|
+
}
|
|
81883
|
+
if (token.kind === "open" && isTextElement(token.name, textElement) && !token.selfClosing) inText = true;
|
|
81884
|
+
else if (token.kind === "close" && isTextElement(token.name, textElement)) inText = false;
|
|
81885
|
+
}
|
|
81886
|
+
flush();
|
|
81887
|
+
return { source, markup, nonce, flavour };
|
|
81888
|
+
}
|
|
81889
|
+
|
|
81890
|
+
// packages/engine/src/lib/office/tags.ts
|
|
81891
|
+
var OPENERS = ["{{", "{%", "{#"];
|
|
81892
|
+
var CLOSERS = { "{{": "}}", "{%": "%}", "{#": "#}" };
|
|
81893
|
+
var AUTOCORRECTED = [
|
|
81894
|
+
[/[“”„‟″]/g, '"'],
|
|
81895
|
+
[/[‘’‚‛′]/g, "'"],
|
|
81896
|
+
[/…/g, "..."],
|
|
81897
|
+
[/[–—]/g, "-"],
|
|
81898
|
+
[/[\u00A0\u202F\u2007]/g, " "],
|
|
81899
|
+
[/\u200B|\u200C|\u200D|\uFEFF/g, ""]
|
|
81900
|
+
];
|
|
81901
|
+
function normaliseTags(template, part) {
|
|
81902
|
+
const { text: text2, origin, placeholders } = stripPlaceholders(template);
|
|
81903
|
+
const sourceRange = (from, to) => [
|
|
81904
|
+
origin[from] ?? template.source.length,
|
|
81905
|
+
(origin[to - 1] ?? template.source.length - 1) + 1
|
|
81906
|
+
];
|
|
81907
|
+
const diagnostics = [];
|
|
81908
|
+
const edits = [];
|
|
81909
|
+
for (const tag of findTags(text2)) {
|
|
81910
|
+
const inside = placeholders.filter((p) => p.at > tag.start && p.at < tag.end);
|
|
81911
|
+
const paragraph = paragraphOf(template, placeholders, tag.start);
|
|
81912
|
+
const raw = text2.slice(tag.start, tag.end);
|
|
81913
|
+
const unsafe = inside.filter((p) => {
|
|
81914
|
+
const piece = template.markup[p.index];
|
|
81915
|
+
return !piece || piece.paragraphBoundary || piece.containerBoundary;
|
|
81916
|
+
});
|
|
81917
|
+
if (unsafe.length) {
|
|
81918
|
+
diagnostics.push({
|
|
81919
|
+
severity: "error",
|
|
81920
|
+
code: "office-tag-spans-elements",
|
|
81921
|
+
message: `The tag ${short(raw)} is split across a paragraph, a link, a field or a tracked change. Retype it in one go.`,
|
|
81922
|
+
part,
|
|
81923
|
+
paragraph,
|
|
81924
|
+
text: short(raw)
|
|
81925
|
+
});
|
|
81926
|
+
continue;
|
|
81927
|
+
}
|
|
81928
|
+
const corrected = undoAutocorrect(raw);
|
|
81929
|
+
if (inside.length || corrected !== raw) {
|
|
81930
|
+
const [from, to] = sourceRange(tag.start, tag.end);
|
|
81931
|
+
edits.push({ from, to, text: corrected });
|
|
81932
|
+
}
|
|
81933
|
+
if (corrected !== raw) {
|
|
81934
|
+
diagnostics.push({
|
|
81935
|
+
severity: "info",
|
|
81936
|
+
code: "office-tag-autocorrected",
|
|
81937
|
+
message: `Word's autocorrect changed quotes or spaces in ${short(corrected)}; they were read as typed.`,
|
|
81938
|
+
part,
|
|
81939
|
+
paragraph,
|
|
81940
|
+
text: short(corrected)
|
|
81941
|
+
});
|
|
81942
|
+
}
|
|
81943
|
+
}
|
|
81944
|
+
const reported = /* @__PURE__ */ new Set();
|
|
81945
|
+
for (const p of placeholders) {
|
|
81946
|
+
const raw = template.markup[p.index]?.raw ?? "";
|
|
81947
|
+
for (const m2 of raw.matchAll(/<w:instrText\b[^>]*>([^<]*)<\/w:instrText>/g)) {
|
|
81948
|
+
const code = decodeEntities(m2[1] ?? "");
|
|
81949
|
+
if (!/\{\{|\{%|\{#/.test(code)) continue;
|
|
81950
|
+
const paragraph = paragraphOf(template, placeholders, p.at);
|
|
81951
|
+
if (reported.has(paragraph)) continue;
|
|
81952
|
+
reported.add(paragraph);
|
|
81953
|
+
diagnostics.push({
|
|
81954
|
+
severity: "warning",
|
|
81955
|
+
code: "office-tag-in-field",
|
|
81956
|
+
message: `The field code ${short(code.trim())} contains a tag, which stays as typed: fields are not filled. Put the tag in the document text instead.`,
|
|
81957
|
+
part,
|
|
81958
|
+
paragraph,
|
|
81959
|
+
text: short(code.trim())
|
|
81960
|
+
});
|
|
81961
|
+
}
|
|
81962
|
+
}
|
|
81963
|
+
return { template: { ...template, source: applyEdits(template.source, edits) }, diagnostics };
|
|
81964
|
+
}
|
|
81965
|
+
var ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'" };
|
|
81966
|
+
function decodeEntities(text2) {
|
|
81967
|
+
return text2.replace(/&(#x[0-9a-f]+|#\d+|amp|lt|gt|quot|apos);/gi, (whole, name) => {
|
|
81968
|
+
if (name[0] !== "#") return ENTITIES[name.toLowerCase()] ?? whole;
|
|
81969
|
+
const code = name[1] === "x" || name[1] === "X" ? parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10);
|
|
81970
|
+
return Number.isFinite(code) ? String.fromCodePoint(code) : whole;
|
|
81971
|
+
});
|
|
81972
|
+
}
|
|
81973
|
+
function stripPlaceholders(template) {
|
|
81974
|
+
const pattern = placeholderPattern(template.nonce);
|
|
81975
|
+
let text2 = "";
|
|
81976
|
+
const origin = [];
|
|
81977
|
+
const placeholders = [];
|
|
81978
|
+
let last = 0;
|
|
81979
|
+
for (const m2 of template.source.matchAll(pattern)) {
|
|
81980
|
+
for (let i = last; i < (m2.index ?? 0); i++) {
|
|
81981
|
+
text2 += template.source[i];
|
|
81982
|
+
origin.push(i);
|
|
81983
|
+
}
|
|
81984
|
+
placeholders.push({ index: Number(m2[1]), at: text2.length, from: m2.index ?? 0, to: (m2.index ?? 0) + m2[0].length });
|
|
81985
|
+
last = (m2.index ?? 0) + m2[0].length;
|
|
81986
|
+
}
|
|
81987
|
+
for (let i = last; i < template.source.length; i++) {
|
|
81988
|
+
text2 += template.source[i];
|
|
81989
|
+
origin.push(i);
|
|
81990
|
+
}
|
|
81991
|
+
return { text: text2, origin, placeholders };
|
|
81992
|
+
}
|
|
81993
|
+
function listTags(template, part) {
|
|
81994
|
+
const { text: text2, placeholders } = stripPlaceholders(template);
|
|
81995
|
+
return findTags(text2).map((tag) => {
|
|
81996
|
+
const raw = text2.slice(tag.start, tag.end);
|
|
81997
|
+
const kind = raw.startsWith("{#") ? "comment" : raw.startsWith("{%") || /^\{\{~?\s*[#/^]/.test(raw) || /^\{\{~?\s*else\b/.test(raw) ? "block" : "output";
|
|
81998
|
+
return { part, paragraph: paragraphOf(template, placeholders, tag.start), text: raw.replace(/\s+/g, " ").trim(), kind };
|
|
81999
|
+
});
|
|
82000
|
+
}
|
|
82001
|
+
function paragraphAtSource(template, offset) {
|
|
82002
|
+
const { origin, placeholders } = stripPlaceholders(template);
|
|
82003
|
+
let at2 = origin.findIndex((o) => o >= offset);
|
|
82004
|
+
if (at2 === -1) at2 = origin.length;
|
|
82005
|
+
return paragraphOf(template, placeholders, at2);
|
|
82006
|
+
}
|
|
82007
|
+
function applyEdits(source, edits) {
|
|
82008
|
+
let out = source;
|
|
82009
|
+
for (const edit of [...edits].sort((a, b2) => b2.from - a.from)) out = out.slice(0, edit.from) + edit.text + out.slice(edit.to);
|
|
82010
|
+
return out;
|
|
82011
|
+
}
|
|
82012
|
+
function undoAutocorrect(tag) {
|
|
82013
|
+
let out = tag;
|
|
82014
|
+
for (const [pattern, replacement] of AUTOCORRECTED) out = out.replace(pattern, replacement);
|
|
82015
|
+
return out;
|
|
82016
|
+
}
|
|
82017
|
+
function findTags(text2) {
|
|
82018
|
+
const tags = [];
|
|
82019
|
+
for (let i = 0; i < text2.length - 1; i++) {
|
|
82020
|
+
const opener = OPENERS.find((o) => text2.startsWith(o, i));
|
|
82021
|
+
if (!opener) continue;
|
|
82022
|
+
const closer = CLOSERS[opener];
|
|
82023
|
+
const end = text2.indexOf(closer, i + opener.length);
|
|
82024
|
+
if (end === -1) continue;
|
|
82025
|
+
const stop = end + closer.length + (opener === "{{" && text2[end + closer.length] === "}" ? 1 : 0);
|
|
82026
|
+
tags.push({ start: i, end: stop });
|
|
82027
|
+
i = stop - 1;
|
|
82028
|
+
}
|
|
82029
|
+
return tags;
|
|
82030
|
+
}
|
|
82031
|
+
function paragraphOf(template, placeholders, at2) {
|
|
82032
|
+
let paragraphs = 0;
|
|
82033
|
+
for (const p of placeholders) {
|
|
82034
|
+
if (p.at > at2) break;
|
|
82035
|
+
paragraphs += template.markup[p.index]?.paragraphOpens ?? 0;
|
|
82036
|
+
}
|
|
82037
|
+
return Math.max(1, paragraphs);
|
|
82038
|
+
}
|
|
82039
|
+
function short(tag) {
|
|
82040
|
+
const oneLine = tag.replace(/\s+/g, " ").trim();
|
|
82041
|
+
return oneLine.length > 60 ? `${oneLine.slice(0, 57)}\u2026` : oneLine;
|
|
82042
|
+
}
|
|
82043
|
+
|
|
82044
|
+
// packages/engine/src/lib/office/structure.ts
|
|
82045
|
+
var STRUCTURAL_ELEMENT = "ff:tag";
|
|
82046
|
+
var PARAGRAPH = /* @__PURE__ */ new Set(["w:p", "a:p"]);
|
|
82047
|
+
var ROW = /* @__PURE__ */ new Set(["w:tr", "a:tr"]);
|
|
82048
|
+
var CELL = /* @__PURE__ */ new Set(["w:tc", "a:tc"]);
|
|
82049
|
+
var BODIES = /* @__PURE__ */ new Set(["w:tc", "w:txbxContent", "p:txBody", "a:txBody"]);
|
|
82050
|
+
var TEXT = /* @__PURE__ */ new Set(["w:t", "a:t"]);
|
|
82051
|
+
var CONTENT = /* @__PURE__ */ new Set(["w:drawing", "w:pict", "w:object", "w:fldChar", "w:fldSimple", "w:br", "w:tab", "w:sym", "a:br", "a:fld", "w:footnoteReference", "w:endnoteReference"]);
|
|
82052
|
+
var JINJA_OPEN = /^(for|if|unless|case|capture|raw|with|macro|call|filter|block|tablerow|comment|autoescape)\b/;
|
|
82053
|
+
var JINJA_CLOSE = /^end(for|if|unless|case|capture|raw|with|macro|call|filter|block|tablerow|comment|autoescape)\b/;
|
|
82054
|
+
var JINJA_MIDDLE = /^(else|elif|elsif|when)\b/;
|
|
82055
|
+
function blockRole(text2) {
|
|
82056
|
+
const t = text2.trim();
|
|
82057
|
+
let m2 = /^\{%-?\s*([\s\S]*?)\s*-?%\}$/.exec(t);
|
|
82058
|
+
if (m2 && !t.slice(2, -2).includes("%}")) {
|
|
82059
|
+
const body = m2[1] ?? "";
|
|
82060
|
+
const word = /^\w+/.exec(body)?.[0] ?? "";
|
|
82061
|
+
if (JINJA_CLOSE.test(body)) return { role: "close", keyword: word.slice(3) };
|
|
82062
|
+
if (JINJA_OPEN.test(body)) return { role: "open", keyword: word };
|
|
82063
|
+
if (JINJA_MIDDLE.test(body)) return { role: "middle", keyword: word };
|
|
82064
|
+
return { role: "single", keyword: word };
|
|
82065
|
+
}
|
|
82066
|
+
if (/^\{#[\s\S]*#\}$/.test(t)) return { role: "single", keyword: "comment" };
|
|
82067
|
+
m2 = /^\{\{~?\s*([#^/]?)\s*([\w.-]*)[\s\S]*?~?\}\}$/.exec(t);
|
|
82068
|
+
if (m2 && t.indexOf("}}") === t.length - 2) {
|
|
82069
|
+
const sigil = m2[1] ?? "";
|
|
82070
|
+
const word = m2[2] ?? "";
|
|
82071
|
+
if (sigil === "#" || sigil === "^" && word) return { role: "open", keyword: word };
|
|
82072
|
+
if (sigil === "/") return { role: "close", keyword: word };
|
|
82073
|
+
if (sigil === "^" && !word || word === "else") return { role: "middle", keyword: "else" };
|
|
82074
|
+
}
|
|
82075
|
+
return null;
|
|
82076
|
+
}
|
|
82077
|
+
var REFERENCES = /* @__PURE__ */ new Set(["w:footnoteReference", "w:endnoteReference", "w:commentRangeStart", "w:commentReference"]);
|
|
82078
|
+
var LOOPS = /* @__PURE__ */ new Set(["for", "each", "tablerow"]);
|
|
82079
|
+
function dropTaggedFallbacks(xml, part) {
|
|
82080
|
+
if (!xml.includes("mc:Fallback")) return xml;
|
|
82081
|
+
const tokens = tokenize(xml, part);
|
|
82082
|
+
let out = "";
|
|
82083
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
82084
|
+
const t = tokens[i];
|
|
82085
|
+
if (t.kind === "open" && t.name === "mc:Fallback" && !t.selfClosing) {
|
|
82086
|
+
let depth = 1;
|
|
82087
|
+
let j2 = i + 1;
|
|
82088
|
+
let text2 = "";
|
|
82089
|
+
for (; j2 < tokens.length && depth > 0; j2++) {
|
|
82090
|
+
const u = tokens[j2];
|
|
82091
|
+
if (u.kind === "open" && u.name === "mc:Fallback" && !u.selfClosing) depth++;
|
|
82092
|
+
else if (u.kind === "close" && u.name === "mc:Fallback") depth--;
|
|
82093
|
+
else if (u.kind === "text") text2 += decodeText(u.raw);
|
|
82094
|
+
}
|
|
82095
|
+
if (/\{\{|\{%|\{#/.test(text2)) {
|
|
82096
|
+
i = j2 - 1;
|
|
82097
|
+
continue;
|
|
82098
|
+
}
|
|
82099
|
+
}
|
|
82100
|
+
out += t.raw;
|
|
82101
|
+
}
|
|
82102
|
+
return out;
|
|
82103
|
+
}
|
|
82104
|
+
function applyStructure(xml, part) {
|
|
82105
|
+
const tokens = tokenize(xml, part);
|
|
82106
|
+
const root = buildSpans(tokens);
|
|
82107
|
+
const paragraphs = collectParagraphs(tokens, root);
|
|
82108
|
+
const diagnostics = [];
|
|
82109
|
+
const structural = /* @__PURE__ */ new Map();
|
|
82110
|
+
for (const info of paragraphs) {
|
|
82111
|
+
if (info.hasContent) continue;
|
|
82112
|
+
const tag = undoAutocorrect(info.text);
|
|
82113
|
+
const role = blockRole(tag);
|
|
82114
|
+
if (role) structural.set(info.span, { info, ...role, tag: tag.trim() });
|
|
82115
|
+
}
|
|
82116
|
+
if (!structural.size) return { xml, diagnostics };
|
|
82117
|
+
const replacedRows = /* @__PURE__ */ new Map();
|
|
82118
|
+
const rowOf = /* @__PURE__ */ new Map();
|
|
82119
|
+
for (const [span, s] of structural) {
|
|
82120
|
+
const cell = ancestor(span, CELL);
|
|
82121
|
+
const row = cell && ancestor(cell, ROW);
|
|
82122
|
+
if (!row) continue;
|
|
82123
|
+
const others = paragraphs.filter((p) => p.span !== span && isInside(p.span, row));
|
|
82124
|
+
if (others.every((p) => p.text.trim() === "" && !p.hasContent)) {
|
|
82125
|
+
replacedRows.set(row, s.tag);
|
|
82126
|
+
rowOf.set(span, row);
|
|
82127
|
+
}
|
|
82128
|
+
}
|
|
82129
|
+
const unitOf = (span) => rowOf.get(span) ?? span;
|
|
82130
|
+
const stack = [];
|
|
82131
|
+
for (const [span, s] of [...structural].sort((a, b2) => a[0].start - b2[0].start)) {
|
|
82132
|
+
const parent = unitOf(span).parent;
|
|
82133
|
+
if (s.role === "open")
|
|
82134
|
+
stack.push({ keyword: s.keyword, parent, paragraph: s.info.number, tag: s.tag, after: unitOf(span).end });
|
|
82135
|
+
else if (s.role === "close" || s.role === "middle") {
|
|
82136
|
+
const open = s.role === "close" ? stack.pop() : stack.at(-1);
|
|
82137
|
+
if (open && s.role === "close" && LOOPS.has(open.keyword)) {
|
|
82138
|
+
const body = tokens.slice(open.after, unitOf(span).start);
|
|
82139
|
+
const reference = body.find((t) => t.kind === "open" && REFERENCES.has(t.name));
|
|
82140
|
+
if (reference && reference.kind === "open")
|
|
82141
|
+
diagnostics.push({
|
|
82142
|
+
severity: "error",
|
|
82143
|
+
code: "office-reference-in-loop",
|
|
82144
|
+
message: `The loop from paragraph ${open.paragraph} repeats a ${reference.name.includes("comment") ? "comment" : "footnote or endnote"}, which cannot be copied. Move it out of the loop.`,
|
|
82145
|
+
part,
|
|
82146
|
+
paragraph: open.paragraph,
|
|
82147
|
+
text: short2(open.tag)
|
|
82148
|
+
});
|
|
82149
|
+
}
|
|
82150
|
+
if (open && open.parent !== parent)
|
|
82151
|
+
diagnostics.push({
|
|
82152
|
+
severity: "error",
|
|
82153
|
+
code: "office-block-unbalanced",
|
|
82154
|
+
message: `${short2(open.tag)} (paragraph ${open.paragraph}) and ${short2(s.tag)} are in different places: one in a table cell or text box, the other outside it. Put both in the same place.`,
|
|
82155
|
+
part,
|
|
82156
|
+
paragraph: s.info.number,
|
|
82157
|
+
text: short2(s.tag)
|
|
82158
|
+
});
|
|
82159
|
+
}
|
|
82160
|
+
}
|
|
82161
|
+
const replacements = [];
|
|
82162
|
+
const element = (tag) => `<${STRUCTURAL_ELEMENT}>${escapeText(tag)}</${STRUCTURAL_ELEMENT}>`;
|
|
82163
|
+
for (const [row, tag] of replacedRows) replacements.push({ start: row.start, end: row.end, text: element(tag) });
|
|
82164
|
+
const cellsEmptied = /* @__PURE__ */ new Map();
|
|
82165
|
+
for (const [span, s] of structural) {
|
|
82166
|
+
if (rowOf.has(span)) continue;
|
|
82167
|
+
const keep = s.info.sectionProperties;
|
|
82168
|
+
let text2 = element(s.tag);
|
|
82169
|
+
if (keep) text2 = s.role === "open" ? `<w:p>${keep}</w:p>${text2}` : `${text2}<w:p>${keep}</w:p>`;
|
|
82170
|
+
replacements.push({ start: span.start, end: span.end, text: text2 });
|
|
82171
|
+
const holder = span.parent && BODIES.has(span.parent.name) ? span.parent : null;
|
|
82172
|
+
if (holder && !keep) cellsEmptied.set(holder, (cellsEmptied.get(holder) ?? 0) + 1);
|
|
82173
|
+
}
|
|
82174
|
+
for (const [holder, emptied] of cellsEmptied) {
|
|
82175
|
+
const total = paragraphs.filter((p) => p.span.parent === holder).length;
|
|
82176
|
+
if (emptied >= total) {
|
|
82177
|
+
const empty = holder.name.startsWith("w:") ? "<w:p/>" : "<a:p/>";
|
|
82178
|
+
replacements.push({ start: holder.end, end: holder.end - 1, text: empty });
|
|
82179
|
+
}
|
|
82180
|
+
}
|
|
82181
|
+
return { xml: rewrite(tokens, replacements), diagnostics };
|
|
82182
|
+
}
|
|
82183
|
+
function buildSpans(tokens) {
|
|
82184
|
+
const root = { name: "#root", start: -1, end: tokens.length, parent: null, children: [] };
|
|
82185
|
+
const stack = [root];
|
|
82186
|
+
tokens.forEach((token, index) => {
|
|
82187
|
+
if (token.kind === "open") {
|
|
82188
|
+
const parent = stack.at(-1);
|
|
82189
|
+
const span = { name: token.name, start: index, end: index, parent, children: [] };
|
|
82190
|
+
parent.children.push(span);
|
|
82191
|
+
if (!token.selfClosing) stack.push(span);
|
|
82192
|
+
} else if (token.kind === "close") {
|
|
82193
|
+
const span = stack.pop();
|
|
82194
|
+
if (span) span.end = index;
|
|
82195
|
+
}
|
|
82196
|
+
});
|
|
82197
|
+
return root;
|
|
82198
|
+
}
|
|
82199
|
+
function collectParagraphs(tokens, root) {
|
|
82200
|
+
const out = [];
|
|
82201
|
+
const walk3 = (span) => {
|
|
82202
|
+
if (PARAGRAPH.has(span.name)) {
|
|
82203
|
+
let text2 = "";
|
|
82204
|
+
let hasContent = false;
|
|
82205
|
+
let sectionProperties = null;
|
|
82206
|
+
let inText = false;
|
|
82207
|
+
for (let i = span.start + 1; i < span.end; i++) {
|
|
82208
|
+
const t = tokens[i];
|
|
82209
|
+
if (t.kind === "open") {
|
|
82210
|
+
if (TEXT.has(t.name) && !t.selfClosing) inText = true;
|
|
82211
|
+
else if (CONTENT.has(t.name)) hasContent = true;
|
|
82212
|
+
else if (t.name === "w:sectPr") sectionProperties = "";
|
|
82213
|
+
} else if (t.kind === "close" && TEXT.has(t.name)) inText = false;
|
|
82214
|
+
else if (t.kind === "text" && inText) text2 += decodeText(t.raw);
|
|
82215
|
+
}
|
|
82216
|
+
if (sectionProperties !== null) sectionProperties = propertiesOf(tokens, span);
|
|
82217
|
+
out.push({ span, number: out.length + 1, text: text2, hasContent, sectionProperties });
|
|
82218
|
+
}
|
|
82219
|
+
for (const child of span.children) walk3(child);
|
|
82220
|
+
};
|
|
82221
|
+
walk3(root);
|
|
82222
|
+
return out;
|
|
82223
|
+
}
|
|
82224
|
+
function propertiesOf(tokens, paragraph) {
|
|
82225
|
+
const props = paragraph.children.find((c) => c.name === "w:pPr");
|
|
82226
|
+
if (!props) return "";
|
|
82227
|
+
return tokens.slice(props.start, props.end + 1).map((t) => t.raw).join("");
|
|
82228
|
+
}
|
|
82229
|
+
function ancestor(span, names) {
|
|
82230
|
+
for (let p = span.parent; p; p = p.parent) if (names.has(p.name)) return p;
|
|
82231
|
+
return null;
|
|
82232
|
+
}
|
|
82233
|
+
function isInside(span, container) {
|
|
82234
|
+
return span.start > container.start && span.end < container.end;
|
|
82235
|
+
}
|
|
82236
|
+
function rewrite(tokens, replacements) {
|
|
82237
|
+
const byStart = /* @__PURE__ */ new Map();
|
|
82238
|
+
for (const r of replacements) {
|
|
82239
|
+
const list2 = byStart.get(r.start) ?? [];
|
|
82240
|
+
list2.push({ end: r.end, text: r.text });
|
|
82241
|
+
byStart.set(r.start, list2);
|
|
82242
|
+
}
|
|
82243
|
+
let out = "";
|
|
82244
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
82245
|
+
const here = byStart.get(i);
|
|
82246
|
+
if (here) {
|
|
82247
|
+
let skipTo = -1;
|
|
82248
|
+
for (const r of here) {
|
|
82249
|
+
out += r.text;
|
|
82250
|
+
if (r.end >= i) skipTo = Math.max(skipTo, r.end);
|
|
82251
|
+
}
|
|
82252
|
+
if (skipTo >= i) {
|
|
82253
|
+
i = skipTo;
|
|
82254
|
+
continue;
|
|
82255
|
+
}
|
|
82256
|
+
}
|
|
82257
|
+
out += tokens[i].raw;
|
|
82258
|
+
}
|
|
82259
|
+
return out;
|
|
82260
|
+
}
|
|
82261
|
+
function short2(tag) {
|
|
82262
|
+
const oneLine = tag.replace(/\s+/g, " ").trim();
|
|
82263
|
+
return oneLine.length > 50 ? `${oneLine.slice(0, 47)}\u2026` : oneLine;
|
|
82264
|
+
}
|
|
82265
|
+
|
|
82266
|
+
// packages/engine/src/lib/office/render.ts
|
|
82267
|
+
var OFFICE_FILLED_MAX_BYTES = 50 * 1024 * 1024;
|
|
82268
|
+
var PARTS = {
|
|
82269
|
+
docx: /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes)\.xml$/,
|
|
82270
|
+
pptx: /^ppt\/(?:slides\/slide\d+|notesSlides\/notesSlide\d+)\.xml$/
|
|
82271
|
+
};
|
|
82272
|
+
var FLAVOUR = { docx: "wordprocessing", pptx: "drawing" };
|
|
82273
|
+
var INCLUDES = /\{%-?\s*(?:include|render|extends|import|from)\b|\{\{~?\s*>/;
|
|
82274
|
+
function preparePart(xml, name, format2, random) {
|
|
82275
|
+
const structured = applyStructure(dropTaggedFallbacks(xml, name), name);
|
|
82276
|
+
const normal = normaliseTags(toTemplateSource(structured.xml, FLAVOUR[format2], createNonce(random), name), name);
|
|
82277
|
+
const diagnostics = [...structured.diagnostics, ...normal.diagnostics];
|
|
82278
|
+
const include = INCLUDES.exec(normal.template.source);
|
|
82279
|
+
if (include)
|
|
82280
|
+
diagnostics.push({
|
|
82281
|
+
severity: "error",
|
|
82282
|
+
code: "unsupported-in-office",
|
|
82283
|
+
message: "Office templates cannot include partials; put the content into the document.",
|
|
82284
|
+
part: name,
|
|
82285
|
+
paragraph: paragraphAtSource(normal.template, include.index),
|
|
82286
|
+
text: include[0]
|
|
82287
|
+
});
|
|
82288
|
+
return { template: normal.template, diagnostics };
|
|
82289
|
+
}
|
|
82290
|
+
function openTemplate(file) {
|
|
82291
|
+
const { format: format2, archive } = detectOfficeFormat(file);
|
|
82292
|
+
if (format2 !== "docx" && format2 !== "pptx" || !archive)
|
|
82293
|
+
throw new OfficeError("file_type_unsupported", "Office templates are Word (DOCX) or PowerPoint (PPTX) files");
|
|
82294
|
+
return { format: format2, archive };
|
|
82295
|
+
}
|
|
82296
|
+
function analyzeOffice(file, options) {
|
|
82297
|
+
const { format: format2, archive } = openTemplate(file);
|
|
82298
|
+
const engine = getEngine(options.engine);
|
|
82299
|
+
const registry = defaultHelpers();
|
|
82300
|
+
const tags = [];
|
|
82301
|
+
const diagnostics = [];
|
|
82302
|
+
const variables = /* @__PURE__ */ new Map();
|
|
82303
|
+
for (const entry of archive.entries) {
|
|
82304
|
+
if (!PARTS[format2].test(entry.name)) continue;
|
|
82305
|
+
const xml = readText(entry);
|
|
82306
|
+
if (!/\{\{|\{%|\{#/.test(xml)) continue;
|
|
82307
|
+
const part = preparePart(xml, entry.name, format2);
|
|
82308
|
+
diagnostics.push(...part.diagnostics);
|
|
82309
|
+
tags.push(...listTags(part.template, entry.name));
|
|
82310
|
+
const analysis = engine.analyze(part.template.source, { sampleData: options.sampleData });
|
|
82311
|
+
const lineStarts = [0];
|
|
82312
|
+
for (let i = 0; i < part.template.source.length; i++) if (part.template.source[i] === "\n") lineStarts.push(i + 1);
|
|
82313
|
+
for (const d of analysis.diagnostics) {
|
|
82314
|
+
const offset = (lineStarts[d.range.start.line - 1] ?? 0) + d.range.start.column - 1;
|
|
82315
|
+
const end = (lineStarts[d.range.end.line - 1] ?? 0) + d.range.end.column - 1;
|
|
82316
|
+
diagnostics.push({
|
|
82317
|
+
severity: d.severity,
|
|
82318
|
+
code: d.code,
|
|
82319
|
+
message: d.message,
|
|
82320
|
+
part: entry.name,
|
|
82321
|
+
paragraph: paragraphAtSource(part.template, offset),
|
|
82322
|
+
text: part.template.source.slice(offset, Math.max(offset, end)).replace(placeholderPattern(part.template.nonce), "").slice(0, 60)
|
|
82323
|
+
});
|
|
82324
|
+
}
|
|
82325
|
+
for (const f2 of analysis.filters) {
|
|
82326
|
+
const name = registry.get(f2.name)?.name ?? f2.name;
|
|
82327
|
+
if (!officeUnsupportedHelpers.has(name)) continue;
|
|
82328
|
+
diagnostics.push({
|
|
82329
|
+
severity: "error",
|
|
82330
|
+
code: "unsupported-in-office",
|
|
82331
|
+
message: `${name}() is not supported in office templates; it returns HTML.`,
|
|
82332
|
+
part: entry.name,
|
|
82333
|
+
paragraph: paragraphAtSource(part.template, (lineStarts[f2.range.start.line - 1] ?? 0) + f2.range.start.column - 1),
|
|
82334
|
+
text: f2.name
|
|
82335
|
+
});
|
|
82336
|
+
}
|
|
82337
|
+
for (const v2 of analysis.variables) {
|
|
82338
|
+
const key = `${v2.kind}:${v2.path.join(".")}`;
|
|
82339
|
+
if (!variables.has(key)) variables.set(key, { path: v2.path, kind: v2.kind });
|
|
82340
|
+
}
|
|
82341
|
+
}
|
|
82342
|
+
const fonts = format2 === "docx" ? documentFonts(archive) : [];
|
|
82343
|
+
if (options.installedFonts) diagnostics.push(...fontDiagnostics(fonts, options.installedFonts));
|
|
82344
|
+
return { format: format2, tags, diagnostics, variables: [...variables.values()], fonts };
|
|
82345
|
+
}
|
|
82346
|
+
|
|
80372
82347
|
// packages/sdk-ts/src/lib/client.ts
|
|
82348
|
+
var isOfficeInput = (input) => "file" in input;
|
|
82349
|
+
function blobOf(file) {
|
|
82350
|
+
const blob = file.data instanceof Blob ? file.data : new Blob([file.data]);
|
|
82351
|
+
const own = typeof File !== "undefined" && file.data instanceof File ? file.data.name : void 0;
|
|
82352
|
+
return { blob, name: file.name ?? own ?? "document" };
|
|
82353
|
+
}
|
|
82354
|
+
function multipart(fields, file) {
|
|
82355
|
+
const form = new FormData();
|
|
82356
|
+
const { blob, name } = blobOf(file);
|
|
82357
|
+
form.set("file", blob, name);
|
|
82358
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
82359
|
+
if (value === void 0) continue;
|
|
82360
|
+
form.set(key, typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value));
|
|
82361
|
+
}
|
|
82362
|
+
return form;
|
|
82363
|
+
}
|
|
80373
82364
|
var FormfeedError = class extends Error {
|
|
80374
82365
|
constructor(code, message2, status, problem = null, requestId = null) {
|
|
80375
82366
|
super(message2);
|
|
@@ -80461,6 +82452,11 @@ var Formfeed = class {
|
|
|
80461
82452
|
},
|
|
80462
82453
|
/** Removes the stored files of a render before they expire. Needs the `file:delete` scope. */
|
|
80463
82454
|
deleteOutputs: (id, options = {}) => this.request("DELETE", `/renders/${encodeURIComponent(id)}/outputs`, void 0, options),
|
|
82455
|
+
/**
|
|
82456
|
+
* The stored request of a render, to render it again. Needs `render:input`; throws
|
|
82457
|
+
* `render_input_expired` (410) when the workspace keeps no requests or the period ended.
|
|
82458
|
+
*/
|
|
82459
|
+
input: (id, options = {}) => this.request("GET", `/renders/${encodeURIComponent(id)}/input`, void 0, options),
|
|
80464
82460
|
batch: (request, options = {}) => this.request("POST", "/renders/batch", request, {
|
|
80465
82461
|
...options,
|
|
80466
82462
|
idempotencyKey: options.idempotencyKey ?? randomKey()
|
|
@@ -80475,7 +82471,18 @@ var Formfeed = class {
|
|
|
80475
82471
|
merge: (sources, output = {}, options = {}) => this.request("POST", "/pdf/merge", { ...output, sources: sources.map(idOf) }, withKey(options)),
|
|
80476
82472
|
protect: (source, protect, options = {}) => this.request("POST", "/pdf/protect", { ...protect, source: idOf(source) }, withKey(options)),
|
|
80477
82473
|
watermark: (source, watermark, options = {}) => this.request("POST", "/pdf/watermark", { ...watermark, source: idOf(source) }, withKey(options)),
|
|
80478
|
-
info: (source, options = {}) => this.request("POST", "/pdf/info", { source: idOf(source) }, options)
|
|
82474
|
+
info: (source, options = {}) => this.request("POST", "/pdf/info", { source: idOf(source) }, options),
|
|
82475
|
+
/**
|
|
82476
|
+
* Converts an office document to a PDF render (Starter plan and above): an uploaded file (Word,
|
|
82477
|
+
* Excel, PowerPoint, OpenDocument, RTF or HTML, up to 20 MB, not kept), or the output of a Word or
|
|
82478
|
+
* PowerPoint template render. Costs follow the PDF rule. A busy converter answers 503, which is
|
|
82479
|
+
* retried like any other.
|
|
82480
|
+
*/
|
|
82481
|
+
convert: (source, convert = {}, options = {}) => {
|
|
82482
|
+
if (typeof source === "object" && "file" in source)
|
|
82483
|
+
return this.request("POST", "/pdf/convert", multipart({ ...convert }, source.file), withKey(options));
|
|
82484
|
+
return this.request("POST", "/pdf/convert", { ...convert, source: idOf(source) }, withKey(options));
|
|
82485
|
+
}
|
|
80479
82486
|
};
|
|
80480
82487
|
/**
|
|
80481
82488
|
* The workspace file library (`/files`): images and PDFs a template references by name with
|
|
@@ -80514,6 +82521,27 @@ var Formfeed = class {
|
|
|
80514
82521
|
/** Removes the file and its bytes; templates that name it render a missing image afterwards. */
|
|
80515
82522
|
delete: (file, options = {}) => this.request("DELETE", `/files/${encodeURIComponent(idOf(file))}`, void 0, options)
|
|
80516
82523
|
};
|
|
82524
|
+
/** The organisation's brand kit, read-only through the API (it is edited in the app). Needs `template:read`. */
|
|
82525
|
+
brand = {
|
|
82526
|
+
get: (options = {}) => this.request("GET", "/brand", void 0, options)
|
|
82527
|
+
};
|
|
82528
|
+
/**
|
|
82529
|
+
* Shared partials of the organisation. Renders use the current source, so a change reaches every
|
|
82530
|
+
* template that includes the partial without a new version. Needs `template:read` or `template:write`.
|
|
82531
|
+
*/
|
|
82532
|
+
partials = {
|
|
82533
|
+
/** Every shared partial, without its source. */
|
|
82534
|
+
list: async (options = {}) => (await this.request("GET", "/partials", void 0, options)).data,
|
|
82535
|
+
/** One partial with its source. */
|
|
82536
|
+
get: (name, options = {}) => this.request("GET", `/partials/${encodeURIComponent(name)}`, void 0, options),
|
|
82537
|
+
/** Creates or replaces a partial; pass `base_version` to fail with 409 when it changed since you read it. */
|
|
82538
|
+
put: async (name, input, options = {}) => {
|
|
82539
|
+
const { status, body } = await this.send("PUT", `/partials/${encodeURIComponent(name)}`, input, options);
|
|
82540
|
+
return { partial: body, created: status === 201 };
|
|
82541
|
+
},
|
|
82542
|
+
/** Removes a partial; templates that still include it fail to render afterwards. */
|
|
82543
|
+
delete: (name, options = {}) => this.request("DELETE", `/partials/${encodeURIComponent(name)}`, void 0, options)
|
|
82544
|
+
};
|
|
80517
82545
|
jobs = {
|
|
80518
82546
|
get: (id, options = {}) => this.request("GET", `/jobs/${encodeURIComponent(id)}`, void 0, options),
|
|
80519
82547
|
waitFor: async (id, options = {}) => {
|
|
@@ -80533,7 +82561,20 @@ var Formfeed = class {
|
|
|
80533
82561
|
create: (input, options = {}) => this.request("POST", "/webhooks", input, options),
|
|
80534
82562
|
update: (id, patch, options = {}) => this.request("PUT", `/webhooks/${encodeURIComponent(id)}`, patch, options),
|
|
80535
82563
|
delete: (id, options = {}) => this.request("DELETE", `/webhooks/${encodeURIComponent(id)}`, void 0, options),
|
|
80536
|
-
test: (id, options = {}) => this.request("POST", `/webhooks/${encodeURIComponent(id)}/test`, void 0, options)
|
|
82564
|
+
test: (id, options = {}) => this.request("POST", `/webhooks/${encodeURIComponent(id)}/test`, void 0, options),
|
|
82565
|
+
/**
|
|
82566
|
+
* Sends a stored event (`evt_…`) again as a new delivery to a registered endpoint (`webhook:manage`)
|
|
82567
|
+
* or a running listen session (`webhook:listen`).
|
|
82568
|
+
*/
|
|
82569
|
+
resend: (eventId, endpointId, options = {}) => this.request("POST", `/webhooks/events/${encodeURIComponent(eventId)}/resend`, { endpoint_id: endpointId }, options),
|
|
82570
|
+
/**
|
|
82571
|
+
* Listen sessions, what `formfeed listen` uses. Needs `webhook:listen`. Starting a session ends the
|
|
82572
|
+
* previous one of the same key; the WebSocket itself is up to the caller.
|
|
82573
|
+
*/
|
|
82574
|
+
listen: {
|
|
82575
|
+
start: (input = {}, options = {}) => this.request("POST", "/webhooks/listen", input, options),
|
|
82576
|
+
end: (id, options = {}) => this.request("DELETE", `/webhooks/listen/${encodeURIComponent(id)}`, void 0, options)
|
|
82577
|
+
}
|
|
80537
82578
|
};
|
|
80538
82579
|
templates = {
|
|
80539
82580
|
list: (query = {}, options = {}) => {
|
|
@@ -80554,15 +82595,79 @@ var Formfeed = class {
|
|
|
80554
82595
|
return out;
|
|
80555
82596
|
},
|
|
80556
82597
|
get: (idOrSlug, options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}`, void 0, options),
|
|
80557
|
-
|
|
82598
|
+
/** A Word or PowerPoint template (`kind` `docx` or `pptx`) is created from its `file`, sent as multipart. */
|
|
82599
|
+
create: (input, options = {}) => {
|
|
82600
|
+
if (isOfficeInput(input) && input.file) {
|
|
82601
|
+
const { file, ...fields } = input;
|
|
82602
|
+
return this.request("POST", "/templates", multipart(fields, file), options);
|
|
82603
|
+
}
|
|
82604
|
+
return this.request("POST", "/templates", input, options);
|
|
82605
|
+
},
|
|
80558
82606
|
update: (idOrSlug, patch, options = {}) => this.request("PUT", `/templates/${encodeURIComponent(idOrSlug)}`, patch, options),
|
|
80559
82607
|
archive: (idOrSlug, options = {}) => this.request("DELETE", `/templates/${encodeURIComponent(idOrSlug)}`, void 0, options),
|
|
80560
82608
|
versions: {
|
|
80561
82609
|
list: async (idOrSlug, options = {}) => (await this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/versions`, void 0, options)).data,
|
|
80562
|
-
/** `which`: 'published', 'latest' or a version
|
|
80563
|
-
get: (idOrSlug, which = "published", options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/versions/${which}`, void 0, options),
|
|
80564
|
-
|
|
80565
|
-
|
|
82610
|
+
/** `which`: 'published', 'latest', a version number or a channel name (its main version). Carries the files. */
|
|
82611
|
+
get: (idOrSlug, which = "published", options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/versions/${encodeURIComponent(String(which))}`, void 0, options),
|
|
82612
|
+
/** For a Word or PowerPoint template, pass `file` to replace the document; without it the latest file is kept. */
|
|
82613
|
+
create: (idOrSlug, input, options = {}) => {
|
|
82614
|
+
const path = `/templates/${encodeURIComponent(idOrSlug)}/versions`;
|
|
82615
|
+
if (isOfficeInput(input)) {
|
|
82616
|
+
const { file, ...fields } = input;
|
|
82617
|
+
if (file) return this.request("POST", path, multipart(fields, file), options);
|
|
82618
|
+
return this.request("POST", path, fields, options);
|
|
82619
|
+
}
|
|
82620
|
+
return this.request("POST", path, input, options);
|
|
82621
|
+
},
|
|
82622
|
+
/** The Word or PowerPoint file of a version (`which` as for `get`); needs `template:read`. */
|
|
82623
|
+
file: async (idOrSlug, which = "published", options = {}) => {
|
|
82624
|
+
const path = `/templates/${encodeURIComponent(idOrSlug)}/versions/${encodeURIComponent(String(which))}/file`;
|
|
82625
|
+
return (await this.send("GET", path, void 0, options, "bytes")).body;
|
|
82626
|
+
},
|
|
82627
|
+
/**
|
|
82628
|
+
* Publishes a version. When both versions store a data schema and the new one breaks callers of the
|
|
82629
|
+
* published one, the API refuses with `schema_breaking_change` unless `allowBreaking` is set.
|
|
82630
|
+
*/
|
|
82631
|
+
publish: (idOrSlug, number, options = {}) => {
|
|
82632
|
+
const { allowBreaking, ...rest } = options;
|
|
82633
|
+
return this.request(
|
|
82634
|
+
"POST",
|
|
82635
|
+
`/templates/${encodeURIComponent(idOrSlug)}/versions/${number}/publish`,
|
|
82636
|
+
allowBreaking ? { allow_breaking: true } : void 0,
|
|
82637
|
+
rest
|
|
82638
|
+
);
|
|
82639
|
+
}
|
|
82640
|
+
},
|
|
82641
|
+
/**
|
|
82642
|
+
* Release channels (`published` and named ones such as `staging`): a render with `version: 'staging'`
|
|
82643
|
+
* uses the version the channel points at. Moves reach renders within a minute.
|
|
82644
|
+
*/
|
|
82645
|
+
channels: {
|
|
82646
|
+
list: (idOrSlug, options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/channels`, void 0, options),
|
|
82647
|
+
/** Creates or moves a channel; on `published` this publishes. */
|
|
82648
|
+
set: (idOrSlug, name, move, options = {}) => {
|
|
82649
|
+
const { allowBreaking, ...rest } = options;
|
|
82650
|
+
return this.request(
|
|
82651
|
+
"PUT",
|
|
82652
|
+
`/templates/${encodeURIComponent(idOrSlug)}/channels/${encodeURIComponent(name)}`,
|
|
82653
|
+
{ ...move, ...allowBreaking ? { allow_breaking: true } : {} },
|
|
82654
|
+
rest
|
|
82655
|
+
);
|
|
82656
|
+
},
|
|
82657
|
+
/** The canary becomes the main version. */
|
|
82658
|
+
promote: (idOrSlug, name, options = {}) => this.channelAction(idOrSlug, name, "promote", options),
|
|
82659
|
+
/** Back to the version before the last move. */
|
|
82660
|
+
rollback: (idOrSlug, name, options = {}) => this.channelAction(idOrSlug, name, "rollback", options),
|
|
82661
|
+
/** Refused with `channel_in_use` while renders of the last hour used the channel, unless `force`. */
|
|
82662
|
+
delete: (idOrSlug, name, options = {}) => {
|
|
82663
|
+
const { force, ...rest } = options;
|
|
82664
|
+
return this.request(
|
|
82665
|
+
"DELETE",
|
|
82666
|
+
`/templates/${encodeURIComponent(idOrSlug)}/channels/${encodeURIComponent(name)}${force ? "?force=true" : ""}`,
|
|
82667
|
+
void 0,
|
|
82668
|
+
rest
|
|
82669
|
+
);
|
|
82670
|
+
}
|
|
80566
82671
|
},
|
|
80567
82672
|
schema: (idOrSlug, options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/schema`, void 0, options),
|
|
80568
82673
|
/**
|
|
@@ -80577,13 +82682,37 @@ var Formfeed = class {
|
|
|
80577
82682
|
/** Units of the current period, or of `YYYY-MM`, with a daily series and a breakdown per template. */
|
|
80578
82683
|
usage: (period = "current", options = {}) => this.request("GET", `/usage?period=${encodeURIComponent(period)}`, void 0, options)
|
|
80579
82684
|
};
|
|
82685
|
+
/** Workspaces of the key's organisation. Needs `workspace:delete`, which no key has by default. */
|
|
82686
|
+
workspaces = {
|
|
82687
|
+
/**
|
|
82688
|
+
* Deletes a workspace: it leaves the app and the API at once, its keys are revoked and its content
|
|
82689
|
+
* is removed after 30 days. The organisation's last workspace is refused with `last_workspace`.
|
|
82690
|
+
*/
|
|
82691
|
+
delete: (id, options = {}) => this.request("DELETE", `/workspaces/${encodeURIComponent(id)}`, void 0, options)
|
|
82692
|
+
};
|
|
82693
|
+
channelAction(idOrSlug, name, action, options) {
|
|
82694
|
+
const { allowBreaking, ...rest } = options;
|
|
82695
|
+
return this.request(
|
|
82696
|
+
"POST",
|
|
82697
|
+
`/templates/${encodeURIComponent(idOrSlug)}/channels/${encodeURIComponent(name)}/${action}`,
|
|
82698
|
+
allowBreaking ? { allow_breaking: true } : void 0,
|
|
82699
|
+
rest
|
|
82700
|
+
);
|
|
82701
|
+
}
|
|
80580
82702
|
/** Raw request with auth, retries and problem mapping; use it for endpoints without a helper. */
|
|
80581
82703
|
async request(method, path, body, options = {}) {
|
|
82704
|
+
return (await this.send(method, path, body, options)).body;
|
|
82705
|
+
}
|
|
82706
|
+
/**
|
|
82707
|
+
* `request` with the HTTP status, for endpoints whose answer depends on it (201 created, 200 updated).
|
|
82708
|
+
* `bytes` returns a successful body as bytes (file downloads); problems are JSON either way.
|
|
82709
|
+
*/
|
|
82710
|
+
async send(method, path, body, options = {}, as = "json") {
|
|
80582
82711
|
const url = `${this.baseUrl}${path}`;
|
|
80583
82712
|
const headers = {
|
|
80584
82713
|
authorization: `Bearer ${this.apiKey}`,
|
|
80585
|
-
accept: "application/json",
|
|
80586
|
-
"user-agent": "formfeed-sdk-ts/0.
|
|
82714
|
+
accept: as === "bytes" ? "*/*" : "application/json",
|
|
82715
|
+
"user-agent": "formfeed-sdk-ts/0.3"
|
|
80587
82716
|
};
|
|
80588
82717
|
const isForm = typeof FormData !== "undefined" && body instanceof FormData;
|
|
80589
82718
|
if (body !== void 0 && !isForm) headers["content-type"] = "application/json";
|
|
@@ -80616,9 +82745,15 @@ var Formfeed = class {
|
|
|
80616
82745
|
await sleep(this.backoff(attempt, res.headers.get("retry-after")), options.signal);
|
|
80617
82746
|
continue;
|
|
80618
82747
|
}
|
|
80619
|
-
if (res.status === 204) return void 0;
|
|
82748
|
+
if (res.status === 204) return { status: 204, body: void 0 };
|
|
82749
|
+
if (as === "bytes" && res.ok) return { status: res.status, body: new Uint8Array(await res.arrayBuffer()) };
|
|
80620
82750
|
const text2 = await res.text();
|
|
80621
|
-
|
|
82751
|
+
let json = null;
|
|
82752
|
+
try {
|
|
82753
|
+
json = text2 ? JSON.parse(text2) : null;
|
|
82754
|
+
} catch {
|
|
82755
|
+
if (res.ok) throw new FormfeedError("invalid_response", `the API answered HTTP ${res.status} with a body that is not JSON`, res.status);
|
|
82756
|
+
}
|
|
80622
82757
|
if (!res.ok) {
|
|
80623
82758
|
const problem = json ?? {};
|
|
80624
82759
|
throw new FormfeedError(
|
|
@@ -80629,7 +82764,7 @@ var Formfeed = class {
|
|
|
80629
82764
|
res.headers.get("x-request-id")
|
|
80630
82765
|
);
|
|
80631
82766
|
}
|
|
80632
|
-
return json;
|
|
82767
|
+
return { status: res.status, body: json };
|
|
80633
82768
|
}
|
|
80634
82769
|
}
|
|
80635
82770
|
backoff(attempt, retryAfter) {
|
|
@@ -80644,9 +82779,10 @@ var encoder2 = new TextEncoder();
|
|
|
80644
82779
|
|
|
80645
82780
|
// packages/mcp/src/lib/server.ts
|
|
80646
82781
|
import { z as z2 } from "zod";
|
|
80647
|
-
var SERVER_INFO = { name: "formfeed", version: "0.
|
|
82782
|
+
var SERVER_INFO = { name: "formfeed", version: "0.3.1" };
|
|
80648
82783
|
var engineSchema = z2.enum(["jinja2", "liquid", "handlebars"]);
|
|
80649
|
-
var outputSchema = z2.enum(
|
|
82784
|
+
var outputSchema = z2.enum(outputFormats);
|
|
82785
|
+
var kindSchema = z2.enum(["pdf", "image", "docx", "pptx"]);
|
|
80650
82786
|
var templateSummary = (t) => ({
|
|
80651
82787
|
id: t.id,
|
|
80652
82788
|
slug: t.slug,
|
|
@@ -80684,15 +82820,15 @@ function createFormfeedServer(options) {
|
|
|
80684
82820
|
...options.fetch ? { fetch: options.fetch } : {}
|
|
80685
82821
|
});
|
|
80686
82822
|
const server = new McpServer(SERVER_INFO, {
|
|
80687
|
-
instructions: "Formfeed renders PDFs and images from templates. Start with list_templates, read the data shape with get_template_schema, check data with validate_template, then call render and hand the download_url to the user."
|
|
82823
|
+
instructions: "Formfeed renders PDFs and images from HTML templates, and fills Word and PowerPoint templates (as DOCX, PPTX or PDF). Start with list_templates, read the data shape with get_template_schema, check data with validate_template, then call render and hand the download_url to the user."
|
|
80688
82824
|
});
|
|
80689
82825
|
server.registerTool(
|
|
80690
82826
|
"list_templates",
|
|
80691
82827
|
{
|
|
80692
82828
|
title: "List templates",
|
|
80693
|
-
description: "Templates of the workspace the API key belongs to, with slug, kind (pdf
|
|
82829
|
+
description: "Templates of the workspace the API key belongs to, with slug, kind (pdf, image, docx for Word, pptx for PowerPoint), engine and published version.",
|
|
80694
82830
|
inputSchema: {
|
|
80695
|
-
kind:
|
|
82831
|
+
kind: kindSchema.optional(),
|
|
80696
82832
|
engine: engineSchema.optional(),
|
|
80697
82833
|
tag: z2.string().optional(),
|
|
80698
82834
|
q: z2.string().optional().describe("Search in name and slug")
|
|
@@ -80733,7 +82869,7 @@ function createFormfeedServer(options) {
|
|
|
80733
82869
|
"validate_template",
|
|
80734
82870
|
{
|
|
80735
82871
|
title: "Validate a template with data",
|
|
80736
|
-
description: "Compiles a template offline and reports errors (unknown filters, syntax) and warnings (variables missing from the data) without rendering. Pass a template slug, or html plus engine for ad-hoc HTML.",
|
|
82872
|
+
description: "Compiles a template offline and reports errors (unknown filters, syntax) and warnings (variables missing from the data) without rendering. Pass a template slug, or html plus engine for ad-hoc HTML. For Word and PowerPoint templates the findings name the document part and paragraph.",
|
|
80737
82873
|
inputSchema: {
|
|
80738
82874
|
template: z2.string().optional().describe("Template slug or tpl_ id"),
|
|
80739
82875
|
html: z2.string().optional().describe("Template source when no slug is given"),
|
|
@@ -80750,6 +82886,20 @@ function createFormfeedServer(options) {
|
|
|
80750
82886
|
if (template) {
|
|
80751
82887
|
const version = await client.templates.versions.get(template, "latest");
|
|
80752
82888
|
const meta = await client.templates.get(template);
|
|
82889
|
+
if (isOfficeKind(meta.kind)) {
|
|
82890
|
+
const file = await client.templates.versions.file(template, version.number);
|
|
82891
|
+
const analysis = analyzeOffice(file, { engine: meta.engine, sampleData: data ?? version.sample_data ?? {} });
|
|
82892
|
+
return text({
|
|
82893
|
+
ok: !analysis.diagnostics.some((d) => d.severity === "error"),
|
|
82894
|
+
diagnostics: analysis.diagnostics.map((d) => ({
|
|
82895
|
+
severity: d.severity,
|
|
82896
|
+
code: d.code,
|
|
82897
|
+
message: d.text ? `${d.message} (${d.text})` : d.message,
|
|
82898
|
+
part: d.part,
|
|
82899
|
+
paragraph: d.paragraph
|
|
82900
|
+
}))
|
|
82901
|
+
});
|
|
82902
|
+
}
|
|
80753
82903
|
source = version.html ?? "";
|
|
80754
82904
|
engineId = meta.engine;
|
|
80755
82905
|
sample = data ?? version.sample_data ?? {};
|
|
@@ -80776,13 +82926,15 @@ function createFormfeedServer(options) {
|
|
|
80776
82926
|
"render",
|
|
80777
82927
|
{
|
|
80778
82928
|
title: "Render a document",
|
|
80779
|
-
description: "Renders a template (with data) or raw HTML to a PDF or image and returns a download URL. Live keys consume units; test keys render free with a watermark.",
|
|
82929
|
+
description: "Renders a template (with data) or raw HTML to a PDF or image, or a Word or PowerPoint template to DOCX, PPTX or PDF, and returns a download URL. Live keys consume units; test keys render free with a watermark.",
|
|
80780
82930
|
inputSchema: {
|
|
80781
82931
|
template: z2.string().optional().describe("Template slug or tpl_ id"),
|
|
80782
82932
|
html: z2.string().optional().describe("Raw HTML instead of a template"),
|
|
80783
82933
|
engine: engineSchema.optional().describe("Engine for html that contains template syntax"),
|
|
80784
82934
|
data: z2.record(z2.string(), z2.unknown()).optional(),
|
|
80785
|
-
output: outputSchema.
|
|
82935
|
+
output: outputSchema.optional().describe(
|
|
82936
|
+
"Left out, the template decides: PDF for PDF templates and html, its image format for image templates, its default output for Word and PowerPoint templates. Word templates render docx or pdf, PowerPoint templates pptx or pdf"
|
|
82937
|
+
),
|
|
80786
82938
|
filename: z2.string().optional(),
|
|
80787
82939
|
locale: z2.string().optional().describe("BCP 47 tag for helpers and translations, e.g. de-DE"),
|
|
80788
82940
|
wait: z2.boolean().default(true).describe("Wait for the render to finish (sync renders finish immediately)")
|
|
@@ -80797,7 +82949,7 @@ function createFormfeedServer(options) {
|
|
|
80797
82949
|
...html ? { html } : {},
|
|
80798
82950
|
...engine ? { engine } : {},
|
|
80799
82951
|
data: data ?? {},
|
|
80800
|
-
output,
|
|
82952
|
+
...output ? { output } : {},
|
|
80801
82953
|
...filename ? { filename } : {},
|
|
80802
82954
|
...locale ? { locale } : {},
|
|
80803
82955
|
meta: { source: "mcp" }
|