@poe-platform/safe-bash 0.1.756 → 0.1.757

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/image-ast/index.browser.js +4 -4
  2. package/dist/image-ast/index.js +4 -4
  3. package/dist/safe-bash/chunks/{chunk-LESPJ3OG.js → chunk-WNWIBBJZ.js} +15 -2
  4. package/dist/safe-bash/command-chunks/{chunk-S4J6MSLY.js → chunk-444OTXM7.js} +3 -3
  5. package/dist/safe-bash/command-chunks/{chunk-6AIOGLZO.js → chunk-CE6Z2ULX.js} +2 -2
  6. package/dist/safe-bash/command-chunks/{chunk-5VSGEE6J.js → chunk-F4IQCXZG.js} +5 -5
  7. package/dist/safe-bash/command-chunks/{chunk-F5MORDSU.js → chunk-FDNCPZQS.js} +32 -1
  8. package/dist/safe-bash/command-chunks/{chunk-SG3ZDZCX.js → chunk-FLMLM7Y4.js} +2 -2
  9. package/dist/safe-bash/command-chunks/{chunk-CT3FB722.js → chunk-J7UMKBRK.js} +1 -1
  10. package/dist/safe-bash/command-chunks/{chunk-QQOAK7JQ.js → chunk-KKJCKPTA.js} +1 -1
  11. package/dist/safe-bash/command-chunks/{chunk-7KS6PX4U.js → chunk-KSIGF4AG.js} +3 -3
  12. package/dist/safe-bash/command-chunks/{chunk-4HQ7WYSI.js → chunk-MED2BOOW.js} +30 -5
  13. package/dist/safe-bash/command-chunks/{chunk-JRNLDPLI.js → chunk-OZSWW23M.js} +1 -1
  14. package/dist/safe-bash/command-chunks/{chunk-DKQ5REXF.js → chunk-QDPRSPHQ.js} +1 -1
  15. package/dist/safe-bash/command-chunks/{chunk-WOPU2VWF.js → chunk-RID3B5RE.js} +1 -1
  16. package/dist/safe-bash/command-chunks/{chunk-DVZCHNB5.js → chunk-S4MLIYSN.js} +7 -7
  17. package/dist/safe-bash/command-chunks/{chunk-REYTQLLB.js → chunk-TT2DMDBY.js} +1 -1
  18. package/dist/safe-bash/command-chunks/{chunk-UGX6MXDD.js → chunk-UIIT4ULR.js} +3 -3
  19. package/dist/safe-bash/command-chunks/{chunk-A6NFLWZI.js → chunk-WKPOGTZY.js} +22 -6
  20. package/dist/safe-bash/command-chunks/{chunk-3DOHQQJR.js → chunk-Y64PA6IA.js} +8 -8
  21. package/dist/safe-bash/command-chunks/{chunk-6Z7OS3TZ.js → chunk-ZP5KDHB4.js} +7 -7
  22. package/dist/safe-bash/commands/pandoc/index.d.ts +1 -1
  23. package/dist/safe-bash/commands/pandoc/index.js +5 -3
  24. package/dist/safe-bash/commands/python/index.browser.js +1 -1
  25. package/dist/safe-bash/commands/python/index.js +6 -0
  26. package/dist/safe-bash/commands/python/jspi.js +11 -2
  27. package/dist/safe-bash/core.browser.js +6 -4
  28. package/dist/safe-bash-command-csvkit/index.js +8 -8
  29. package/dist/safe-bash-command-soffice/index.js +16 -16
  30. package/dist/safe-bash-command-ssconvert/core.js +8 -8
  31. package/dist/safe-bash-command-ssconvert/formats/csv.js +9 -9
  32. package/dist/safe-bash-command-ssconvert/formats/ods.js +8 -8
  33. package/dist/safe-bash-command-ssconvert/formats/spreadsheetml.js +1 -1
  34. package/dist/safe-bash-command-ssconvert/formats/xls.js +9 -8
  35. package/dist/safe-bash-command-ssconvert/formats/xlsx.js +8 -8
  36. package/dist/safe-bash-command-ssconvert/index.js +107 -27
  37. package/dist/safe-bash-contracts/filesystem-descriptor.js +1 -1
  38. package/dist/safe-bash-contracts/filesystem-output.js +1 -1
  39. package/dist/safe-bash-mcp/index.js +4 -4
  40. package/dist/spreadsheet-engine/formulas/ast.d.ts +13 -0
  41. package/dist/spreadsheet-engine/formulas/conventions.js +1 -1
  42. package/dist/spreadsheet-engine/formulas/dependencies.js +2 -2
  43. package/dist/spreadsheet-engine/formulas/evaluator.js +2 -2
  44. package/dist/spreadsheet-engine/formulas/named-expressions.d.ts +2 -2
  45. package/dist/spreadsheet-engine/formulas/named-expressions.js +31 -5
  46. package/dist/spreadsheet-engine/formulas/parser.js +34 -0
  47. package/dist/spreadsheet-engine/formulas/rewriting.js +19 -1
  48. package/dist/spreadsheet-engine/formulas/serialization.js +6 -0
  49. package/dist/spreadsheet-format-xls/biff-write-formulas.js +2 -0
  50. package/dist/xlsx-ast/formula-semantics.js +2 -0
  51. package/package.json +2 -2
  52. package/dist/safe-bash/chunks/browser-ECQX6GMK.js +0 -6766
  53. package/dist/safe-bash/chunks/bz2-4OP3OWW3.js +0 -8
  54. package/dist/safe-bash/chunks/chunk-22XPAAOI.js +0 -173
  55. package/dist/safe-bash/chunks/chunk-44WUNUPV.js +0 -649
  56. package/dist/safe-bash/chunks/chunk-4E3SGG37.js +0 -876
  57. package/dist/safe-bash/chunks/chunk-4QTSSQKP.js +0 -898
  58. package/dist/safe-bash/chunks/chunk-5UVGPVXP.js +0 -410
  59. package/dist/safe-bash/chunks/chunk-64OE6Q6X.js +0 -3487
  60. package/dist/safe-bash/chunks/chunk-6IIFUPN2.js +0 -1526
  61. package/dist/safe-bash/chunks/chunk-BENDLTQD.js +0 -7065
  62. package/dist/safe-bash/chunks/chunk-BMO5LWEX.js +0 -534
  63. package/dist/safe-bash/chunks/chunk-BPMCPTNP.js +0 -1920
  64. package/dist/safe-bash/chunks/chunk-BRJTAWP5.js +0 -2955
  65. package/dist/safe-bash/chunks/chunk-C3GEIN7Q.js +0 -20054
  66. package/dist/safe-bash/chunks/chunk-CBVANNKK.js +0 -174814
  67. package/dist/safe-bash/chunks/chunk-CEWCRI6H.js +0 -2813
  68. package/dist/safe-bash/chunks/chunk-CGL53DQQ.js +0 -37
  69. package/dist/safe-bash/chunks/chunk-CTYJJD4O.js +0 -869
  70. package/dist/safe-bash/chunks/chunk-CWSS4MQA.js +0 -7
  71. package/dist/safe-bash/chunks/chunk-DLIGMTCP.js +0 -3266
  72. package/dist/safe-bash/chunks/chunk-EMAJ7WUW.js +0 -1031
  73. package/dist/safe-bash/chunks/chunk-FDKIZ2IJ.js +0 -1950
  74. package/dist/safe-bash/chunks/chunk-FZWJ2A7V.js +0 -3093
  75. package/dist/safe-bash/chunks/chunk-G2VCIF2J.js +0 -22
  76. package/dist/safe-bash/chunks/chunk-GVKBUQDX.js +0 -2649
  77. package/dist/safe-bash/chunks/chunk-IO2OGW3E.js +0 -28051
  78. package/dist/safe-bash/chunks/chunk-ISCZG7WA.js +0 -2648
  79. package/dist/safe-bash/chunks/chunk-JCN3FXLP.js +0 -38983
  80. package/dist/safe-bash/chunks/chunk-KJHDD4A2.js +0 -759
  81. package/dist/safe-bash/chunks/chunk-LB6HVRXS.js +0 -857
  82. package/dist/safe-bash/chunks/chunk-LLWAJOZH.js +0 -15
  83. package/dist/safe-bash/chunks/chunk-LMUKYZIJ.js +0 -708
  84. package/dist/safe-bash/chunks/chunk-M5SCNKIK.js +0 -2012
  85. package/dist/safe-bash/chunks/chunk-MJPFHANT.js +0 -3350
  86. package/dist/safe-bash/chunks/chunk-MZQW2DOL.js +0 -82
  87. package/dist/safe-bash/chunks/chunk-NB2V7EOY.js +0 -1348
  88. package/dist/safe-bash/chunks/chunk-NJVGOIYN.js +0 -17
  89. package/dist/safe-bash/chunks/chunk-OLNZHDIQ.js +0 -5141
  90. package/dist/safe-bash/chunks/chunk-OSUXMC43.js +0 -2317
  91. package/dist/safe-bash/chunks/chunk-OUUVROTM.js +0 -38
  92. package/dist/safe-bash/chunks/chunk-PA6GYKBQ.js +0 -151
  93. package/dist/safe-bash/chunks/chunk-PEFHZ226.js +0 -6957
  94. package/dist/safe-bash/chunks/chunk-QBB5P5KW.js +0 -4839
  95. package/dist/safe-bash/chunks/chunk-RSAWYAEH.js +0 -973
  96. package/dist/safe-bash/chunks/chunk-UWLYRWT4.js +0 -739
  97. package/dist/safe-bash/chunks/chunk-V463NBQH.js +0 -13
  98. package/dist/safe-bash/chunks/chunk-WPUALYUS.js +0 -843
  99. package/dist/safe-bash/chunks/chunk-XHKFSRGU.js +0 -5747
  100. package/dist/safe-bash/chunks/chunk-XHRCLZ3N.js +0 -13391
  101. package/dist/safe-bash/chunks/chunk-XPF5XHLY.js +0 -15
  102. package/dist/safe-bash/chunks/chunk-ZBFOWARG.js +0 -305
  103. package/dist/safe-bash/chunks/chunk-ZG7GWQ5P.js +0 -1859
  104. package/dist/safe-bash/chunks/model-store-EIY3ZQLZ.js +0 -10
  105. package/dist/safe-bash/chunks/pdf-renderer-CMF3CSVU.js +0 -22
  106. package/dist/safe-bash/chunks/pptx-ZL6L7KP2-O425BFIU.js +0 -30658
  107. package/dist/safe-bash/chunks/src-HHEPGR7U.js +0 -18969
  108. package/dist/safe-bash/chunks/src-MXIKQCIC.js +0 -187
  109. package/dist/safe-bash/chunks/usage-6TGVA2OM.js +0 -35
  110. package/dist/safe-bash/chunks/xz-EGQGQUEI.js +0 -8
  111. package/dist/safe-bash/chunks/xz-K2E2WLM6.js +0 -9
  112. package/dist/safe-bash/chunks/zstd-6JBLP5EF.js +0 -8
  113. package/dist/safe-bash/git_rust-C3QYOAZL.wasm +0 -0
@@ -1,2813 +0,0 @@
1
- import {
2
- init_platform
3
- } from "./chunk-ZG7GWQ5P.js";
4
-
5
- // packages/safe-bash-regex-engine/src/text/budget.ts
6
- init_platform();
7
- import { PublicDiagnostic } from "../../safe-bash-contracts/public-diagnostic.js";
8
- import { hasYieldCheckpoint, monotonicNow, yieldTurn } from "../../safe-bash-contracts/yield.js";
9
- var defaultPerfNow = performance.now;
10
- var validatedTextProgramOptions = /* @__PURE__ */ new WeakSet();
11
- var DUMMY_ABORT_SIGNAL = Object.freeze({
12
- aborted: false,
13
- reason: void 0,
14
- onabort: null,
15
- throwIfAborted() {
16
- },
17
- addEventListener() {
18
- },
19
- removeEventListener() {
20
- },
21
- dispatchEvent() {
22
- return true;
23
- }
24
- });
25
- var DUMMY_COMMAND_CONTEXT = { signal: DUMMY_ABORT_SIGNAL };
26
- var pooledBudgetA;
27
- var pooledBudgetB;
28
- var pooledBudgetToggle = 0;
29
- var ProgramError = class extends PublicDiagnostic {
30
- };
31
- var Budget = class _Budget {
32
- constructor(context, options) {
33
- this.context = context;
34
- this.options = options;
35
- const rem = options.maxSteps ?? Infinity;
36
- this.unlimited = rem === Infinity;
37
- this.remainingNum = this.unlimited ? 0 : rem;
38
- this.remainingSmi = !this.unlimited && rem <= 1073741823 ? rem | 0 : 1073741823;
39
- this.signal = context.signal;
40
- this.hasExtYield = hasYieldCheckpoint(context.signal);
41
- this.yieldTimes[0] = performance.now !== defaultPerfNow || this.hasExtYield ? monotonicNow() : -1;
42
- this.maxBufferBytes = options.maxBufferBytes ?? Infinity;
43
- if (context.signal.aborted) context.signal.throwIfAborted();
44
- if (!validatedTextProgramOptions.has(options)) {
45
- for (const [key, value] of Object.entries(options)) {
46
- if (!key.startsWith("max")) continue;
47
- if (value !== void 0 && (typeof value !== "number" || value !== Infinity && !Number.isSafeInteger(value) || value < 1)) throw new ProgramError("limits must be positive safe integers");
48
- }
49
- validatedTextProgramOptions.add(options);
50
- }
51
- }
52
- context;
53
- options;
54
- maxBufferBytes;
55
- stepsUsed = 0;
56
- inUse = false;
57
- remainingSmi;
58
- remainingNum;
59
- unlimited;
60
- signal;
61
- checkpoints = 0;
62
- hasExtYield = false;
63
- yieldTimes = new Float64Array(1);
64
- static acquire(context, options) {
65
- if (!pooledBudgetA) {
66
- pooledBudgetA = new _Budget(DUMMY_COMMAND_CONTEXT, options);
67
- }
68
- if (!pooledBudgetB) {
69
- pooledBudgetB = new _Budget(DUMMY_COMMAND_CONTEXT, options);
70
- }
71
- const first = (pooledBudgetToggle++ & 1) === 0 ? pooledBudgetA : pooledBudgetB;
72
- const second = first === pooledBudgetA ? pooledBudgetB : pooledBudgetA;
73
- if (!first.inUse) {
74
- first.inUse = true;
75
- first.resetForRun(context, options);
76
- return first;
77
- }
78
- if (!second.inUse) {
79
- second.inUse = true;
80
- second.resetForRun(context, options);
81
- return second;
82
- }
83
- return new _Budget(context, options);
84
- }
85
- static release(budget) {
86
- if (budget === pooledBudgetA || budget === pooledBudgetB) {
87
- budget.inUse = false;
88
- budget.context = DUMMY_COMMAND_CONTEXT;
89
- budget.signal = DUMMY_ABORT_SIGNAL;
90
- }
91
- }
92
- resetForRun(context, options) {
93
- if (context.signal.aborted) context.signal.throwIfAborted();
94
- const rem = options.maxSteps ?? Infinity;
95
- this.context = context;
96
- this.options = options;
97
- this.stepsUsed = 0;
98
- this.unlimited = rem === Infinity;
99
- this.remainingNum = this.unlimited ? 0 : rem;
100
- this.remainingSmi = !this.unlimited && rem <= 1073741823 ? rem | 0 : 1073741823;
101
- this.signal = context.signal;
102
- this.checkpoints = 0;
103
- this.hasExtYield = hasYieldCheckpoint(context.signal);
104
- this.yieldTimes[0] = performance.now !== defaultPerfNow || this.hasExtYield ? monotonicNow() : -1;
105
- const nextMaxBuf = options.maxBufferBytes ?? Infinity;
106
- if (this.maxBufferBytes !== nextMaxBuf) this.maxBufferBytes = nextMaxBuf;
107
- }
108
- step(count = 1) {
109
- if (this.signal.aborted) this.signal.throwIfAborted();
110
- const nextSteps = this.stepsUsed + count;
111
- this.stepsUsed = nextSteps;
112
- if (this.unlimited) return;
113
- if ((count | 0) === count && count >= 0 && count <= this.remainingSmi) {
114
- this.remainingSmi = this.remainingSmi - (count | 0) | 0;
115
- this.remainingNum -= count;
116
- return;
117
- }
118
- if (count > this.remainingNum) throw new ProgramError("execution step limit exceeded");
119
- this.remainingNum -= count;
120
- this.remainingSmi = this.remainingNum <= 1073741823 ? this.remainingNum | 0 : 1073741823;
121
- }
122
- check(text) {
123
- if (text.length > this.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
124
- return text;
125
- }
126
- async checkpoint() {
127
- const p = this.checkpointSync();
128
- if (p) await p;
129
- }
130
- checkpointSync() {
131
- if (this.signal.aborted) this.signal.throwIfAborted();
132
- const count = ++this.checkpoints;
133
- if ((count & 255) === 0) {
134
- return this.yieldCheckpointAsync();
135
- }
136
- if (performance.now !== defaultPerfNow || this.hasExtYield || (count & 63) === 0) {
137
- const now = monotonicNow();
138
- if (this.yieldTimes[0] < 0) {
139
- this.yieldTimes[0] = now;
140
- } else if (now - this.yieldTimes[0] >= 25) {
141
- return this.yieldCheckpointAsync();
142
- }
143
- }
144
- return void 0;
145
- }
146
- async yieldCheckpointAsync() {
147
- await yieldTurn(this.signal);
148
- this.yieldTimes[0] = monotonicNow();
149
- this.signal.throwIfAborted();
150
- }
151
- };
152
-
153
- // packages/safe-bash-regex-engine/src/text/rust-syntax.ts
154
- init_platform();
155
- var RustPatternError = class extends ProgramError {
156
- constructor(message, offset, compilation = false) {
157
- super(message);
158
- this.offset = offset;
159
- this.compilation = compilation;
160
- }
161
- offset;
162
- compilation;
163
- };
164
- function simpleCaseFold(text) {
165
- let result = "";
166
- for (const char of text) {
167
- const lower = char.toLowerCase(), upper = lower.toUpperCase();
168
- result += char === "\u0131" || [...lower].length !== 1 ? char : [...upper].length === 1 ? upper.toLowerCase() : lower;
169
- }
170
- return result;
171
- }
172
- var word = (char) => /^[\p{Alphabetic}\p{M}\p{Nd}\p{Pc}\p{Join_Control}]$/u.test(char);
173
- var asciiWord = (char) => /^[A-Za-z0-9_]$/u.test(char);
174
- function property(name, insensitive) {
175
- if (!name || [...name].some((c) => !" _-=0123456789".includes(c) && !(c >= "A" && c <= "Z") && !(c >= "a" && c <= "z"))) throw new ProgramError("invalid Unicode character class");
176
- const clean = name.split(" ").join("").split("-").join("_");
177
- const equals = clean.indexOf("="), key = equals < 0 ? "" : clean.slice(0, equals), value = equals < 0 ? clean : clean.slice(equals + 1);
178
- const title = value.split("_").map((part) => part[0]?.toUpperCase() + part.slice(1).toLowerCase()).join("_");
179
- const keys = { sc: "Script", script: "Script", scx: "Script_Extensions", scriptextensions: "Script_Extensions", script_extensions: "Script_Extensions", gc: "General_Category", generalcategory: "General_Category", general_category: "General_Category" };
180
- const prefix = key ? (keys[key.toLowerCase()] ?? key) + "=" : "";
181
- const candidates = [prefix + value, prefix + title];
182
- if (!key) candidates.push("Script=" + value, "Script=" + title);
183
- if (clean.toLowerCase() === "any") return () => true;
184
- if (clean.toLowerCase() === "ascii") return (char) => char.codePointAt(0) <= 127;
185
- for (const candidate of candidates) {
186
- try {
187
- const pattern = new RegExp(`^\\p{${candidate}}$`, insensitive ? "iu" : "u");
188
- return (char) => pattern.test(char);
189
- } catch {
190
- }
191
- }
192
- throw new ProgramError(`Unicode property not found: ${name}`);
193
- }
194
- function parseRustPattern(source, ignoreCase, maximumDepth = Infinity) {
195
- let at = 0, depth = 0, groupCount = 0, peakDepth = 0;
196
- let flags = new Set(ignoreCase ? ["u", "i"] : ["u"]);
197
- const groupNames = /* @__PURE__ */ new Map(), references = /* @__PURE__ */ new Set();
198
- let numberedReferences = false;
199
- function fail(message, offset = at, compilation = false) {
200
- throw new RustPatternError(message, offset, compilation);
201
- }
202
- const enter = () => {
203
- peakDepth = Math.max(peakDepth, ++depth);
204
- if (depth > maximumDepth) throw new ProgramError("rust regular expression depth limit exceeded");
205
- };
206
- const skip = () => {
207
- if (!flags.has("x")) return;
208
- while (at < source.length) {
209
- if (" \n\r\f\v".includes(source[at])) {
210
- at++;
211
- continue;
212
- }
213
- if (source[at] !== "#") break;
214
- while (at < source.length && source[at] !== "\n") at++;
215
- }
216
- };
217
- const scalar = () => {
218
- if (at >= source.length) throw new ProgramError("unexpected end of regular expression");
219
- const char = String.fromCodePoint(source.codePointAt(at));
220
- at += char.length;
221
- return char;
222
- };
223
- const literal = (char) => {
224
- const insensitive = flags.has("i"), folded = simpleCaseFold(char);
225
- return { type: "character", ...insensitive ? {} : { literal: char }, accepts: (candidate) => insensitive ? simpleCaseFold(candidate) === folded : candidate === char };
226
- };
227
- const classEscape = () => {
228
- const char = source[at];
229
- if (char === "p" || char === "P") {
230
- at++;
231
- let name;
232
- if (source[at] === "{") {
233
- const end = source.indexOf("}", ++at);
234
- if (end < 0) throw new ProgramError("Unicode escape not closed");
235
- name = source.slice(at, end);
236
- at = end + 1;
237
- } else name = scalar();
238
- let accepts2;
239
- try {
240
- accepts2 = property(name, flags.has("i"));
241
- } catch {
242
- return fail("Regex error: error parsing pattern 0", at, true);
243
- }
244
- return char === "p" ? accepts2 : (value) => !accepts2(value);
245
- }
246
- if (char === void 0 || !"dDsSwWhH".includes(char)) return;
247
- at++;
248
- const unicode = flags.has("u"), lower = char.toLowerCase();
249
- const accepts = lower === "h" ? (value) => /^[0-9A-Fa-f]$/u.test(value) : lower === "w" ? unicode ? word : asciiWord : lower === "d" ? unicode ? (value) => /^\p{Nd}$/u.test(value) : (value) => value >= "0" && value <= "9" : unicode ? (value) => /^\p{White_Space}$/u.test(value) : (value) => " \n\r\f\v".includes(value);
250
- return char === lower ? accepts : (value) => !accepts(value);
251
- };
252
- const escaped = () => {
253
- const char = scalar();
254
- const controls = { a: "\x07", b: "\b", f: "\f", n: "\n", r: "\r", t: " ", v: "\v", e: "\x1B" };
255
- if (controls[char] !== void 0) return controls[char];
256
- if (char === "x" || char === "u" || char === "U") {
257
- const escapeStart = at;
258
- const braced = source[at] === "{";
259
- if (braced) at++;
260
- const begin = at, count = char === "x" ? 2 : char === "u" ? 4 : 8;
261
- while (at < source.length && "0123456789abcdefABCDEF".includes(source[at]) && (braced || at - begin < count)) at++;
262
- const hex = source.slice(begin, at), value = Number.parseInt(hex, 16);
263
- if (!hex || braced && source[at++] !== "}" || !braced && hex.length !== count || value > 1114111 || value >= 55296 && value <= 57343) fail("Invalid hex escape", escapeStart);
264
- return String.fromCodePoint(value);
265
- }
266
- if (char >= "A" && char <= "Z" || char >= "a" && char <= "z") fail(`Invalid escape: \\${char}`, at - 2);
267
- return char;
268
- };
269
- const bracket = () => {
270
- enter();
271
- skip();
272
- const negate = source[at] === "^";
273
- if (negate) at++;
274
- const insensitive = flags.has("i");
275
- const token = () => {
276
- skip();
277
- if (source[at] === "[") {
278
- if (source[at + 1] === ":") {
279
- const end = source.indexOf(":]", at + 2), name = source.slice(at + 2, end);
280
- const classes2 = {
281
- alnum: (c) => /^[A-Za-z0-9]$/u.test(c),
282
- alpha: (c) => /^[A-Za-z]$/u.test(c),
283
- ascii: (c) => c.codePointAt(0) <= 127,
284
- blank: (c) => c === " " || c === " ",
285
- cntrl: (c) => c.codePointAt(0) <= 31 || c === "\x7F",
286
- digit: (c) => /^[0-9]$/u.test(c),
287
- graph: (c) => /^[!-~]$/u.test(c),
288
- lower: (c) => /^[a-z]$/u.test(c),
289
- print: (c) => /^[ -~]$/u.test(c),
290
- punct: (c) => /^[!-/:-@[-`{-~]$/u.test(c),
291
- space: (c) => " \n\r\f\v".includes(c),
292
- upper: (c) => /^[A-Z]$/u.test(c),
293
- word: asciiWord,
294
- xdigit: (c) => /^[A-Fa-f0-9]$/u.test(c)
295
- };
296
- const negative = name.startsWith("^"), accepts2 = classes2[negative ? name.slice(1) : name];
297
- if (end < 0 || !accepts2) throw new ProgramError("invalid ASCII character class");
298
- at = end + 2;
299
- return { accepts: negative ? (c) => !accepts2(c) : accepts2 };
300
- }
301
- at++;
302
- const nested = bracket();
303
- return { accepts: nested.accepts };
304
- }
305
- let char;
306
- if (source[at] === "\\") {
307
- at++;
308
- const accepts2 = classEscape();
309
- if (accepts2) return { accepts: accepts2 };
310
- char = escaped();
311
- } else char = scalar();
312
- return { accepts: (candidate) => candidate === char, scalar: char };
313
- };
314
- const union = () => {
315
- const terms = [];
316
- while (at < source.length) {
317
- skip();
318
- if (source[at] === "]" && terms.length || ["&&", "--", "~~"].some((op) => source.startsWith(op, at))) break;
319
- const start = token();
320
- skip();
321
- if (start.scalar !== void 0 && source[at] === "-" && source[at + 1] !== "]" && source[at + 1] !== "-") {
322
- at++;
323
- const end = token();
324
- if (end.scalar === void 0 || start.scalar.codePointAt(0) > end.scalar.codePointAt(0)) fail("Regex error: error parsing pattern 0", at, true);
325
- const low = start.scalar.codePointAt(0), high = end.scalar.codePointAt(0);
326
- terms.push((char) => [...char].length === 1 && char.codePointAt(0) >= low && char.codePointAt(0) <= high);
327
- } else terms.push(start.accepts);
328
- }
329
- return (char) => terms.some((accepts2) => accepts2(char));
330
- };
331
- let accepts = union();
332
- while (at < source.length && source[at] !== "]") {
333
- const op = source.slice(at, at + 2);
334
- at += 2;
335
- if (!["&&", "--", "~~"].includes(op)) throw new ProgramError("invalid character class operation");
336
- const left = accepts, right = union();
337
- accepts = op === "&&" ? (char) => left(char) && right(char) : op === "--" ? (char) => left(char) && !right(char) : (char) => left(char) !== right(char);
338
- }
339
- if (source[at] !== "]") fail("Invalid character class", at);
340
- at++;
341
- depth--;
342
- return { type: "character", accepts: (char) => {
343
- const lower = char.toLowerCase(), upper = char.toUpperCase();
344
- const found = accepts(char) || insensitive && (accepts(simpleCaseFold(char)) || char !== "\u0131" && [...upper].length === 1 && accepts(upper) || [...lower].length === 1 && accepts(lower));
345
- return negate ? !found : found;
346
- } };
347
- };
348
- const atom = () => {
349
- skip();
350
- const atomStart = at, char = scalar();
351
- if (char === "(") {
352
- enter();
353
- const outer = new Set(flags);
354
- let capturing = true, atomic = false, name, assertion;
355
- if (source[at] === "?") {
356
- at++;
357
- const kind = source[at];
358
- if (kind === "#") {
359
- const close = source.indexOf(")", ++at);
360
- if (close < 0) fail("Opening parenthesis without closing parenthesis", at);
361
- at = close + 1;
362
- depth--;
363
- return { type: "empty" };
364
- }
365
- if (source.startsWith("P=", at)) {
366
- at += 2;
367
- const end = source.indexOf(")", at), name2 = source.slice(at, end), index2 = groupNames.get(name2);
368
- if (end < 0) fail("Could not parse group name", at);
369
- if (index2 === void 0) fail("Invalid group name in back reference: " + name2, at);
370
- at = end + 1;
371
- depth--;
372
- return { type: "backreference", index: index2, ignoreCase: flags.has("i"), fold: simpleCaseFold };
373
- }
374
- if (kind === "(") {
375
- at++;
376
- let condition;
377
- const end = source.indexOf(")", at), token = source.slice(at, end);
378
- const stripped = token.startsWith("<") && token.endsWith(">") || token.startsWith("'") && token.endsWith("'") ? token.slice(1, -1) : token;
379
- const numeric = stripped.length > 0 && [...stripped].every((c) => c >= "0" && c <= "9"), index2 = numeric ? Number(stripped) : groupNames.get(stripped);
380
- if (index2 !== void 0) {
381
- if (numeric) {
382
- references.add(index2);
383
- numberedReferences = true;
384
- }
385
- condition = { type: "captureSet", index: index2 };
386
- at = end;
387
- } else if (stripped !== token) fail("Invalid group name in back reference: " + stripped, at);
388
- else condition = alternate();
389
- if (source[at++] !== ")") fail("Opening parenthesis without closing parenthesis", at);
390
- const yes = sequence();
391
- let no = { type: "empty" };
392
- if (source[at] === "|") {
393
- at++;
394
- no = sequence();
395
- }
396
- if (source[at++] !== ")") fail("Opening parenthesis without closing parenthesis", at);
397
- flags = outer;
398
- depth--;
399
- return { type: "conditional", condition, yes, no };
400
- }
401
- if (kind === ":" || kind === ">") {
402
- at++;
403
- capturing = false;
404
- atomic = kind === ">";
405
- } else if (kind === "=" || kind === "!") {
406
- at++;
407
- capturing = false;
408
- assertion = { positive: kind === "=", behind: false };
409
- } else if (kind === "<" && "=!".includes(source[at + 1] ?? "\0")) {
410
- at++;
411
- capturing = false;
412
- assertion = { positive: source[at++] === "=", behind: true };
413
- } else if (kind === "<" || source.startsWith("P<", at)) {
414
- at += kind === "<" ? 1 : 2;
415
- const end = source.indexOf(">", at);
416
- if (end < 0) throw new ProgramError("invalid named capture");
417
- name = source.slice(at, end);
418
- at = end + 1;
419
- if (!name || groupNames.has(name) || !/^[\p{L}_][\p{L}\p{N}_]*$/u.test(name)) fail("Could not parse group name", at);
420
- } else {
421
- let enabled = true, changed = false;
422
- while (at < source.length && source[at] !== ")" && source[at] !== ":") {
423
- const flag = source[at++];
424
- if (flag === "-") {
425
- enabled = false;
426
- continue;
427
- }
428
- if (flag === "u" && !enabled) fail("Disabling Unicode not supported", at - 1);
429
- if (!"imsxUu".includes(flag)) fail(`Unknown group flag: ${source.slice(atomStart, at)}`, atomStart + 2);
430
- changed = true;
431
- if (enabled) flags.add(flag);
432
- else flags.delete(flag);
433
- }
434
- if (!changed) throw new ProgramError("invalid regular expression group");
435
- if (source[at] === ")") {
436
- at++;
437
- depth--;
438
- return { type: "empty" };
439
- }
440
- if (source[at++] !== ":") throw new ProgramError("unclosed regular expression group");
441
- capturing = false;
442
- }
443
- }
444
- const index = capturing ? ++groupCount : 0;
445
- if (name !== void 0) groupNames.set(name, index);
446
- const node = alternate();
447
- skip();
448
- if (source[at] !== ")") fail("Opening parenthesis without closing parenthesis", at);
449
- at++;
450
- flags = outer;
451
- depth--;
452
- return atomic ? { type: "atomic", node } : assertion ? { type: "assertion", node, ...assertion } : capturing ? { type: "group", node, index, lastCapture: groupCount } : node;
453
- }
454
- if (char === "[") return bracket();
455
- if (char === "\\") {
456
- const accepts = classEscape();
457
- if (accepts) return { type: "character", accepts };
458
- const escapedChar = source[at];
459
- if (escapedChar === "b" || escapedChar === "B" || escapedChar === "<" || escapedChar === ">") {
460
- at++;
461
- return { type: "boundary", accepts: word, positive: escapedChar !== "B", ...escapedChar === "<" ? { edge: "start" } : escapedChar === ">" ? { edge: "end" } : {} };
462
- }
463
- if (escapedChar === "A" || escapedChar === "z" || escapedChar === "Z") {
464
- at++;
465
- return { type: escapedChar === "A" ? "begin" : "end", strict: true, ...escapedChar === "Z" ? { trailingNewlines: true } : {} };
466
- }
467
- if (escapedChar === "G" || escapedChar === "K") {
468
- at++;
469
- return { type: escapedChar === "G" ? "continue" : "reset" };
470
- }
471
- if (escapedChar && escapedChar >= "0" && escapedChar <= "9") {
472
- const begin = at++;
473
- while (source[at] && source[at] >= "0" && source[at] <= "9") at++;
474
- const index = Number(source.slice(begin, at));
475
- if (source[begin] === "0" && index !== 0) fail("Invalid back reference", begin);
476
- references.add(index);
477
- numberedReferences = true;
478
- return { type: "backreference", index, ignoreCase: flags.has("i"), fold: simpleCaseFold };
479
- }
480
- if (escapedChar === "k" || escapedChar === "g") {
481
- const open = source[at + 1], close = open === "'" ? "'" : ">", end = source.indexOf(close, at + 2);
482
- if (open !== "<" && open !== "'" || end < 0) fail("Could not parse group name", at + 1);
483
- if (escapedChar === "g") fail("Regex uses currently unimplemented feature: Subroutine Call", at, true);
484
- const name = source.slice(at + 2, end), number = Number(name);
485
- const numeric = name.length > 0 && Number.isInteger(number);
486
- const index = numeric ? name.startsWith("-") ? groupCount + number + 1 : name.startsWith("+") ? groupCount + number : number : groupNames.get(name);
487
- if (index === void 0) fail("Invalid group name in back reference: " + name, at + 1);
488
- if (numeric) {
489
- references.add(index);
490
- numberedReferences = true;
491
- }
492
- at = end + 1;
493
- return { type: "backreference", index, ignoreCase: flags.has("i"), fold: simpleCaseFold };
494
- }
495
- return literal(escaped());
496
- }
497
- if (char === ".") {
498
- const all = flags.has("s");
499
- return { type: "character", accepts: (value) => all || value !== "\n" };
500
- }
501
- if (char === "^" || char === "$") return { type: char === "^" ? "begin" : "end", multiline: flags.has("m"), strict: true };
502
- if ("*+?".includes(char)) fail("Target of repeat operator is invalid", atomStart);
503
- return literal(char);
504
- };
505
- const repeated = () => {
506
- let node = atom();
507
- skip();
508
- const quantifier = source[at], quantifierStart = at;
509
- if (quantifier === "*" || quantifier === "+" || quantifier === "?") {
510
- if (node.type === "empty") fail("Target of repeat operator is invalid", at);
511
- at++;
512
- node = { type: "repeat", node, minimum: quantifier === "+" ? 1 : 0, maximum: quantifier === "?" ? 1 : Infinity };
513
- } else if (quantifier === "{") {
514
- at++;
515
- const begin = at;
516
- while (source[at] && source[at] >= "0" && source[at] <= "9") at++;
517
- const hasMinimum = begin !== at, minimum = Number(source.slice(begin, at));
518
- let maximum = minimum;
519
- if (source[at] === ",") {
520
- const begin2 = ++at;
521
- while (source[at] && source[at] >= "0" && source[at] <= "9") at++;
522
- maximum = begin2 === at ? Infinity : Number(source.slice(begin2, at));
523
- }
524
- if (source[at] !== "}" || !hasMinimum && maximum === minimum) {
525
- at = quantifierStart;
526
- return node;
527
- }
528
- at++;
529
- if (!Number.isSafeInteger(minimum) || maximum !== Infinity && !Number.isSafeInteger(maximum) || maximum < minimum) fail("Regex error: error parsing pattern 0", at, true);
530
- if (node.type === "empty") fail("Target of repeat operator is invalid", quantifierStart);
531
- node = { type: "repeat", node, minimum, maximum };
532
- }
533
- if (node.type === "repeat") {
534
- node.lazy = flags.has("U");
535
- if (source[at] === "?") {
536
- node.lazy = !node.lazy;
537
- at++;
538
- } else if (source[at] === "+") {
539
- node = { type: "atomic", node };
540
- at++;
541
- }
542
- }
543
- if (source[at] && "*+?".includes(source[at])) fail("Target of repeat operator is invalid", at);
544
- return node;
545
- };
546
- const sequence = () => {
547
- const nodes = [];
548
- while (at < source.length) {
549
- skip();
550
- if (at === source.length || source[at] === ")" || source[at] === "|") break;
551
- nodes.push(repeated());
552
- }
553
- return nodes.length ? { type: "sequence", nodes } : { type: "empty" };
554
- };
555
- const alternate = () => {
556
- const nodes = [sequence()];
557
- while (source[at] === "|") {
558
- at++;
559
- nodes.push(sequence());
560
- }
561
- return nodes.length === 1 ? nodes[0] : { type: "alternate", nodes };
562
- };
563
- const root = alternate();
564
- if (at !== source.length) fail("General parsing error: end of string not reached", at);
565
- for (const index of references) if (index <= 0 || index > groupCount) fail(`Invalid back reference to group ${index}`, at, true);
566
- if (numberedReferences && groupNames.size) fail("Numbered backref/call not allowed because named group was used, use a named backref instead", at, true);
567
- return { root, groupCount, groupNames, depth: peakDepth };
568
- }
569
-
570
- // packages/safe-bash-regex-engine/src/text/regex.ts
571
- init_platform();
572
-
573
- // packages/safe-bash-regex-engine/src/text/replacement-buffer.ts
574
- init_platform();
575
- var ReplacementBuffer = class {
576
- constructor(budget) {
577
- this.budget = budget;
578
- }
579
- budget;
580
- #segments = [];
581
- #size = 0;
582
- #allocated = 0;
583
- #unboundedText = "";
584
- get remaining() {
585
- return this.budget.maxBufferBytes - this.#size;
586
- }
587
- admit(length) {
588
- this.budget.step(0);
589
- if (!Number.isSafeInteger(length) || length < 0 || length > this.remaining) throw new ProgramError("text buffer limit exceeded");
590
- }
591
- async append(source, start = 0, end = source.length) {
592
- this.admit(end - start);
593
- if (this.budget.maxBufferBytes === Infinity) {
594
- let offset2 = start;
595
- while (offset2 < end) {
596
- await this.budget.checkpoint();
597
- const length = Math.min(end - offset2, 1024);
598
- this.budget.step(length);
599
- this.budget.step();
600
- this.#unboundedText += offset2 === 0 && length === source.length ? source : source.slice(offset2, offset2 + length);
601
- this.#size += length;
602
- offset2 += length;
603
- }
604
- return;
605
- }
606
- let offset = start;
607
- while (offset < end) {
608
- await this.budget.checkpoint();
609
- this.budget.step();
610
- const width = source.charCodeAt(offset) <= 255 ? 1 : 2;
611
- let length = 1;
612
- while (length < 1024 && offset + length < end) {
613
- this.budget.step();
614
- if ((source.charCodeAt(offset + length) <= 255 ? 1 : 2) !== width) break;
615
- length++;
616
- }
617
- const bytes = length * width;
618
- if (bytes > this.budget.maxBufferBytes - this.#allocated) throw new ProgramError("text buffer limit exceeded");
619
- this.budget.step(length + 1);
620
- const segment = width === 1 ? new Uint8Array(length) : new Uint16Array(length);
621
- for (let index = 0; index < length; index++) segment[index] = source.charCodeAt(offset + index);
622
- this.#segments.push(segment);
623
- this.#allocated += segment.byteLength;
624
- this.#size += length;
625
- offset += length;
626
- }
627
- }
628
- async finish() {
629
- this.budget.step(0);
630
- if (!this.#size) return "";
631
- this.budget.step(this.#size);
632
- await this.budget.checkpoint();
633
- this.budget.step(0);
634
- if (this.budget.maxBufferBytes === Infinity) {
635
- const text = this.#unboundedText;
636
- this.clear();
637
- return text;
638
- }
639
- if (this.#segments.length === 1) {
640
- const text = String.fromCharCode(...this.#segments[0].subarray(0, this.#size));
641
- this.clear();
642
- return text;
643
- }
644
- this.budget.step(this.#size);
645
- if (this.#allocated > this.budget.maxBufferBytes || this.#size > this.budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
646
- const parts = [];
647
- let offset = 0;
648
- for (const segment of this.#segments) {
649
- await this.budget.checkpoint();
650
- this.budget.step(0);
651
- const length = Math.min(segment.length, this.#size - offset);
652
- parts.push(String.fromCharCode(...segment.subarray(0, length)));
653
- offset += length;
654
- }
655
- this.clear();
656
- await this.budget.checkpoint();
657
- this.budget.step(0);
658
- return parts.join("");
659
- }
660
- clear() {
661
- this.#segments = [];
662
- this.#size = 0;
663
- this.#allocated = 0;
664
- this.#unboundedText = "";
665
- }
666
- };
667
-
668
- // packages/safe-bash-regex-engine/src/text/regex.ts
669
- function isWordChar(ch) {
670
- if (ch === void 0) return false;
671
- const code = ch.charCodeAt(0);
672
- return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || code === 95;
673
- }
674
- function matchesBoundary(instruction, text, position) {
675
- const before = position > 0 && instruction.accepts(text[position - 1]);
676
- const after = position < text.length && instruction.accepts(text[position]);
677
- const boundary = instruction.edge === "start" ? !before && after : instruction.edge === "end" ? before && !after : before !== after;
678
- return boundary === instruction.positive;
679
- }
680
- function instructionCounts(root) {
681
- const counts = /* @__PURE__ */ new Map();
682
- const pending = [{ node: root, visited: false }];
683
- while (pending.length) {
684
- const { node, visited } = pending.pop();
685
- if (!visited) {
686
- pending.push({ node, visited: true });
687
- if (node.type === "group" || node.type === "assertion" || node.type === "repeat" || node.type === "atomic")
688
- pending.push({ node: node.node, visited: false });
689
- else if (node.type === "conditional") {
690
- pending.push({ node: node.no, visited: false }, { node: node.yes, visited: false }, { node: node.condition, visited: false });
691
- } else if (node.type === "sequence" || node.type === "alternate")
692
- for (let index = node.nodes.length - 1; index >= 0; index--)
693
- pending.push({ node: node.nodes[index], visited: false });
694
- continue;
695
- }
696
- let size;
697
- if (node.type === "empty") size = 0;
698
- else if (node.type === "group" || node.type === "assertion" || node.type === "atomic") size = 2 + counts.get(node.node);
699
- else if (node.type === "conditional") size = 3 + counts.get(node.condition) + counts.get(node.yes) + counts.get(node.no);
700
- else if (node.type === "sequence" || node.type === "alternate") {
701
- size = node.type === "alternate" ? 2 * (node.nodes.length - 1) : 0;
702
- for (const child of node.nodes) size += counts.get(child);
703
- if (node.type === "sequence") node.nodes = node.nodes.filter((child) => counts.get(child) > 0);
704
- } else if (node.type === "repeat") {
705
- const child = counts.get(node.node);
706
- size = node.maximum === 0 ? 0 : node.maximum === Infinity ? child * (node.minimum + 1) + 2 : child * node.maximum + node.maximum - node.minimum;
707
- } else size = 1;
708
- counts.set(node, Number.isSafeInteger(size) ? size : Infinity);
709
- }
710
- return counts;
711
- }
712
- function* compileProgram(root, counts, ignoreCase) {
713
- const code = [];
714
- const emit = (instruction) => code.push(instruction) - 1;
715
- const pending = [{ node: root, index: 0 }];
716
- while (pending.length) {
717
- const frame = pending[pending.length - 1];
718
- const node = frame.node;
719
- if (counts.get(node) === 0) {
720
- pending.pop();
721
- continue;
722
- }
723
- yield;
724
- if (node.type === "sequence") {
725
- if (frame.index < node.nodes.length) pending.push({ node: node.nodes[frame.index++], index: 0 });
726
- else pending.pop();
727
- } else if (node.type === "group") {
728
- if (frame.index++ === 0) {
729
- emit({
730
- kind: "save",
731
- slot: node.index * 2,
732
- ...node.lastCapture > node.index ? { clearUntil: (node.lastCapture + 1) * 2 } : {}
733
- });
734
- pending.push({ node: node.node, index: 0 });
735
- } else {
736
- emit({ kind: "save", slot: node.index * 2 + 1 });
737
- pending.pop();
738
- }
739
- } else if (node.type === "conditional") {
740
- if (frame.index === 0) {
741
- frame.start = emit({ kind: "conditional", first: code.length + 1, yes: 0, no: 0 });
742
- frame.index = 1;
743
- pending.push({ node: node.condition, index: 0 });
744
- } else if (frame.index === 1) {
745
- emit({ kind: "match" });
746
- code[frame.start].yes = code.length;
747
- frame.index = 2;
748
- pending.push({ node: node.yes, index: 0 });
749
- } else if (frame.index === 2) {
750
- frame.jump = emit({ kind: "jump", target: 0 });
751
- code[frame.start].no = code.length;
752
- frame.index = 3;
753
- pending.push({ node: node.no, index: 0 });
754
- } else {
755
- code[frame.jump].target = code.length;
756
- pending.pop();
757
- }
758
- } else if (node.type === "assertion" || node.type === "atomic") {
759
- if (frame.index++ === 0) {
760
- frame.start = emit(node.type === "assertion" ? { kind: "assertion", first: code.length + 1, next: 0, positive: node.positive, behind: node.behind } : { kind: "atomic", first: code.length + 1, next: 0 });
761
- pending.push({ node: node.node, index: 0 });
762
- } else {
763
- emit({ kind: "match" });
764
- code[frame.start].next = code.length;
765
- pending.pop();
766
- }
767
- } else if (node.type === "alternate") {
768
- if (frame.awaiting) {
769
- if (frame.index < node.nodes.length) {
770
- (frame.jumps ??= []).push(emit({ kind: "jump", target: 0 }));
771
- code[frame.start].second = code.length;
772
- }
773
- frame.awaiting = false;
774
- }
775
- if (frame.index === node.nodes.length) {
776
- for (const jump of frame.jumps ?? []) code[jump].target = code.length;
777
- pending.pop();
778
- } else {
779
- if (frame.index < node.nodes.length - 1) frame.start = emit({ kind: "split", first: code.length + 1, second: 0 });
780
- frame.awaiting = true;
781
- pending.push({ node: node.nodes[frame.index++], index: 0 });
782
- }
783
- } else if (node.type === "repeat") {
784
- if (frame.start !== void 0) {
785
- if (node.maximum === Infinity) emit({ kind: "jump", target: frame.start });
786
- const split = code[frame.start];
787
- split.second = code.length;
788
- if (node.lazy) [split.first, split.second] = [split.second, split.first];
789
- frame.start = void 0;
790
- if (node.maximum === Infinity) {
791
- pending.pop();
792
- continue;
793
- }
794
- }
795
- if (counts.get(node.node) === 0) frame.index = Math.max(frame.index, node.minimum);
796
- if (frame.index < node.minimum) {
797
- frame.index++;
798
- pending.push({ node: node.node, index: 0 });
799
- } else if (frame.index < node.maximum) {
800
- frame.index++;
801
- frame.start = emit({ kind: "split", first: code.length + 1, second: 0 });
802
- pending.push({ node: node.node, index: 0 });
803
- } else pending.pop();
804
- } else {
805
- if (node.type === "character") emit({ kind: "character", ...node.literal !== void 0 ? { literal: node.literal } : {}, accepts: node.accepts });
806
- else if (node.type === "backreference") emit({ kind: "backreference", index: node.index, ignoreCase: node.ignoreCase ?? ignoreCase, ...node.fold ? { fold: node.fold } : {} });
807
- else if (node.type === "boundary") emit({ kind: "boundary", accepts: node.accepts, positive: node.positive, ...node.edge ? { edge: node.edge } : {} });
808
- else if (node.type === "continue") emit({ kind: "continue" });
809
- else if (node.type === "reset") emit({ kind: "save", slot: 0 });
810
- else if (node.type === "captureSet") emit({ kind: "captureSet", index: node.index });
811
- else if (node.type === "begin" || node.type === "end") emit({ kind: node.type, ...node.multiline === void 0 ? {} : { multiline: node.multiline }, ...node.strict === void 0 ? {} : { strict: node.strict }, ...node.trailingNewlines ? { trailingNewlines: true } : {} });
812
- else throw new ProgramError("invalid internal regular expression node");
813
- pending.pop();
814
- }
815
- }
816
- emit({ kind: "match" });
817
- return code;
818
- }
819
- var classes = {
820
- alpha: (character) => /^[A-Za-z]$/u.test(character),
821
- alnum: (character) => /^[A-Za-z0-9]$/u.test(character),
822
- digit: (character) => /^[0-9]$/u.test(character),
823
- lower: (character) => /^[a-z]$/u.test(character),
824
- upper: (character) => /^[A-Z]$/u.test(character),
825
- xdigit: (character) => /^[A-Fa-f0-9]$/u.test(character),
826
- space: (character) => /^[ \t\n\r\v\f]$/u.test(character),
827
- blank: (character) => character === " " || character === " ",
828
- cntrl: (character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127,
829
- graph: (character) => character.charCodeAt(0) >= 33 && character.charCodeAt(0) <= 126,
830
- print: (character) => character.charCodeAt(0) >= 32 && character.charCodeAt(0) <= 126,
831
- punct: (character) => /^[!-/:-@[-`{-~]$/u.test(character)
832
- };
833
- function extendedSource(source) {
834
- let result = "";
835
- let bracket = false;
836
- let bracketFirst = false;
837
- for (let offset = 0; offset < source.length; offset++) {
838
- const character = source[offset];
839
- if (!bracket && character === "\\" && offset + 1 < source.length) {
840
- const next = source[++offset];
841
- result += "()|+?{}".includes(next) ? next : `\\${next}`;
842
- } else if (bracket) {
843
- if (bracketFirst && character === "^") {
844
- result += character;
845
- continue;
846
- }
847
- if (bracketFirst && character === "]") {
848
- result += character;
849
- bracketFirst = false;
850
- continue;
851
- }
852
- bracketFirst = false;
853
- if (character === "[" && (source[offset + 1] === ":" || source[offset + 1] === "." || source[offset + 1] === "=")) {
854
- const kind = source[offset + 1];
855
- const close = source.indexOf(`${kind}]`, offset + 2);
856
- if (close >= 0) {
857
- result += source.slice(offset, close + 2);
858
- offset = close + 1;
859
- continue;
860
- }
861
- }
862
- if (character === "]") bracket = false;
863
- result += character;
864
- } else {
865
- if (character === "[") {
866
- bracket = true;
867
- bracketFirst = true;
868
- }
869
- result += "()|+?{}".includes(character) ? `\\${character}` : character;
870
- }
871
- }
872
- return result;
873
- }
874
- function makeAsciiTable(accepts) {
875
- const ascii = new Uint8Array(128);
876
- for (let c = 0; c < 128; c++) {
877
- if (accepts(String.fromCharCode(c))) ascii[c] = 1;
878
- }
879
- return ascii;
880
- }
881
- function buildChainMatch(root, groupCount) {
882
- if (root.type !== "sequence" || groupCount > 9) return void 0;
883
- let startIdx = 0;
884
- let endIdx = root.nodes.length;
885
- let anchoredStart = false;
886
- let anchoredEnd = false;
887
- if (startIdx < endIdx && root.nodes[startIdx]?.type === "begin") {
888
- anchoredStart = true;
889
- startIdx++;
890
- }
891
- if (startIdx < endIdx && root.nodes[endIdx - 1]?.type === "end") {
892
- anchoredEnd = true;
893
- endIdx--;
894
- }
895
- if (startIdx >= endIdx) return void 0;
896
- const steps = [];
897
- let hasRepeat = false;
898
- for (let i = startIdx; i < endIdx; i++) {
899
- let n = root.nodes[i];
900
- let group = 0;
901
- if (n.type === "group") {
902
- group = n.index;
903
- n = n.node.type === "sequence" && n.node.nodes.length === 1 ? n.node.nodes[0] : n.node;
904
- }
905
- if (n.type === "character") {
906
- if (n.literal !== void 0) {
907
- const prev = steps[steps.length - 1];
908
- if (group === 0 && prev && prev.kind === "literal" && prev.group === 0) {
909
- prev.value += n.literal;
910
- } else {
911
- steps.push({ kind: "literal", value: n.literal, group });
912
- }
913
- } else {
914
- steps.push({ kind: "char", accepts: n.accepts, ascii: makeAsciiTable(n.accepts), group });
915
- }
916
- } else if (n.type === "repeat" && n.minimum >= 0 && n.maximum === Infinity && !n.lazy && n.node.type === "character") {
917
- hasRepeat = true;
918
- steps.push({ kind: "repeat", minimum: n.minimum, accepts: n.node.accepts, ascii: makeAsciiTable(n.node.accepts), group });
919
- } else {
920
- return void 0;
921
- }
922
- }
923
- const first = steps[0];
924
- if (!first) return void 0;
925
- const hasLiteralPrefix = first.kind === "literal" && first.value.length > 0;
926
- const hasRepeatHead = first.kind === "repeat" && first.minimum >= 1;
927
- if (!hasLiteralPrefix && !hasRepeatHead) return void 0;
928
- for (let s = 0; s < steps.length; s++) {
929
- const step = steps[s];
930
- if (step.kind === "repeat") {
931
- if (s < steps.length - 1) {
932
- const next = steps[s + 1];
933
- if (next.kind !== "literal" || next.value.length === 0 || step.accepts(next.value[0])) return void 0;
934
- }
935
- if (!anchoredStart && hasLiteralPrefix) {
936
- for (let k = 0; k < first.value.length; k++) {
937
- if (step.accepts(first.value[k])) return void 0;
938
- }
939
- }
940
- }
941
- }
942
- if (!hasRepeat && steps.length < 2) return void 0;
943
- return { prefix: hasLiteralPrefix ? first.value : "", anchoredStart, anchoredEnd, steps };
944
- }
945
- function matchChainAt(steps, prefixLen, anchoredEnd, text, startPos, outOffsets, groupCount, textEnd = text.length, startStep = 1) {
946
- for (let g = 1; g <= groupCount; g++) {
947
- outOffsets[g * 2] = -1;
948
- outOffsets[g * 2 + 1] = -1;
949
- }
950
- let cursor = startStep === 1 ? startPos + prefixLen : startPos;
951
- for (let s = startStep; s < steps.length; s++) {
952
- const step = steps[s];
953
- const stepStart = cursor;
954
- if (step.kind === "literal") {
955
- const val = step.value;
956
- if (cursor + val.length > textEnd) return -1;
957
- for (let k = 0; k < val.length; k++) {
958
- if (text.charCodeAt(cursor + k) !== val.charCodeAt(k)) return -1;
959
- }
960
- cursor += val.length;
961
- } else if (step.kind === "char") {
962
- if (cursor >= textEnd) return -1;
963
- const code = text.charCodeAt(cursor);
964
- if (code < 128 ? step.ascii[code] === 0 : !step.accepts(text[cursor])) return -1;
965
- cursor++;
966
- } else {
967
- while (cursor < textEnd) {
968
- const code = text.charCodeAt(cursor);
969
- if (code < 128 ? step.ascii[code] === 0 : !step.accepts(text[cursor])) break;
970
- cursor++;
971
- }
972
- if (cursor - stepStart < step.minimum) return -1;
973
- }
974
- if (step.group > 0) {
975
- outOffsets[step.group * 2] = stepStart;
976
- outOffsets[step.group * 2 + 1] = cursor;
977
- }
978
- }
979
- if (anchoredEnd && cursor !== textEnd) return -1;
980
- outOffsets[0] = startPos;
981
- outOffsets[1] = cursor;
982
- return cursor;
983
- }
984
- var NfaStorage = class {
985
- constructor(budget) {
986
- this.budget = budget;
987
- }
988
- budget;
989
- used = 0;
990
- reserve(bytes) {
991
- this.budget.step(0);
992
- if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > this.budget.maxBufferBytes - this.used) {
993
- throw new ProgramError("regular expression state buffer limit exceeded");
994
- }
995
- this.used += bytes;
996
- }
997
- release(bytes) {
998
- if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > this.used) throw new ProgramError("invalid regular expression state accounting");
999
- this.used -= bytes;
1000
- }
1001
- clear() {
1002
- this.used = 0;
1003
- }
1004
- };
1005
- var Pattern = class {
1006
- constructor(source, extended = true, ignoreCase = false, dialect = "sed", modifiers = "", limits = {}) {
1007
- this.ignoreCase = ignoreCase;
1008
- this.dialect = dialect;
1009
- this.modifiers = modifiers;
1010
- this.sourceLength = source.length;
1011
- const prefix = dialect === "jq" || dialect === "rust" ? dialect + " " : "";
1012
- const maximumInstructions = limits.maxPatternInstructions ?? Infinity;
1013
- if ([maximumInstructions, limits.maxPatternSource ?? Infinity, limits.maxPatternDepth ?? Infinity].some((value) => value !== Infinity && (!Number.isSafeInteger(value) || value < 1))) throw new ProgramError("limits must be positive safe integers");
1014
- if (source.length > (limits.maxPatternSource ?? Infinity)) throw new ProgramError(`${prefix}regular expression source limit exceeded`);
1015
- if (dialect === "rust") {
1016
- const parsed = parseRustPattern(source, ignoreCase, limits.maxPatternDepth), counts2 = instructionCounts(parsed.root);
1017
- if (!Number.isSafeInteger(counts2.get(parsed.root) + 1) || counts2.get(parsed.root) + 1 > maximumInstructions) throw new ProgramError(`${prefix}regular expression program limit exceeded`);
1018
- this.patternDepth = parsed.depth;
1019
- this.instructionCount = counts2.get(parsed.root) + 1;
1020
- this.groupCount = parsed.groupCount;
1021
- for (const [name, index] of parsed.groupNames) this.groupNames.set(name, index);
1022
- this.anchored = false;
1023
- this.parsed = { root: parsed.root, counts: counts2 };
1024
- return;
1025
- }
1026
- if (!extended) source = extendedSource(source);
1027
- let offset = 0;
1028
- let groups = 0;
1029
- const closedGroups = /* @__PURE__ */ new Set();
1030
- const characterNode = (character) => ({
1031
- type: "character",
1032
- ...ignoreCase ? {} : { literal: character },
1033
- accepts: (candidate) => ignoreCase ? candidate.toLowerCase() === character.toLowerCase() : candidate === character
1034
- });
1035
- const escaped = () => {
1036
- const character = source[offset++];
1037
- if (character === void 0) throw new ProgramError("trailing backslash in regular expression");
1038
- if (dialect === "awk") {
1039
- const octal = "01234567".includes(character);
1040
- if (octal || character === "x") {
1041
- let digits = octal ? character : "";
1042
- const alphabet = octal ? "01234567" : "0123456789abcdefABCDEF";
1043
- while (digits.length < (octal ? 3 : 2) && offset < source.length && alphabet.includes(source[offset])) digits += source[offset++];
1044
- return digits ? String.fromCharCode(parseInt(digits, octal ? 8 : 16) & 255) : character;
1045
- }
1046
- if (character === "b") return "\b";
1047
- }
1048
- if (dialect === "sed" && /^[1-9]$/u.test(character)) throw new ProgramError("pattern backreferences are not supported");
1049
- const control = { n: "\n", t: " ", r: "\r", f: "\f", v: "\v", a: "\x07" };
1050
- return control[character] ?? character;
1051
- };
1052
- const bracket = () => {
1053
- const negate = source[offset] === "^";
1054
- if (negate) offset++;
1055
- const tests = [];
1056
- let first = true;
1057
- while (offset < source.length && (source[offset] !== "]" || first)) {
1058
- first = false;
1059
- if (source.startsWith("[:", offset)) {
1060
- const end = source.indexOf(":]", offset + 2);
1061
- const name = end < 0 ? "" : source.slice(offset + 2, end);
1062
- if (!classes[name]) throw new ProgramError(`unsupported character class '${name}'`);
1063
- tests.push(classes[name]);
1064
- offset = end + 2;
1065
- continue;
1066
- }
1067
- if (source.startsWith("[.", offset) || source.startsWith("[=", offset)) throw new ProgramError("collating and equivalence classes are not supported");
1068
- const readBracketChar = () => {
1069
- const ch = source[offset++];
1070
- if (ch !== "\\") return ch;
1071
- if (dialect === "sed") {
1072
- const next = source[offset];
1073
- if (next !== void 0 && "ntrfva".includes(next)) return escaped();
1074
- return "\\";
1075
- }
1076
- if (dialect === "awk" && source[offset] !== void 0 && /^[1-9]$/u.test(source[offset])) {
1077
- return escaped();
1078
- }
1079
- return escaped();
1080
- };
1081
- const start = readBracketChar();
1082
- if (source[offset] === "-" && source[offset + 1] !== "]" && source[offset + 1] !== void 0) {
1083
- offset++;
1084
- const end = readBracketChar();
1085
- if (start > end) throw new ProgramError("reversed character range");
1086
- tests.push((character) => character >= start && character <= end);
1087
- } else tests.push((character) => character === start);
1088
- }
1089
- if (source[offset++] !== "]") throw new ProgramError("unterminated bracket expression");
1090
- return { type: "character", accepts: (character) => {
1091
- const accepted = tests.some((test) => test(character) || ignoreCase && (test(character.toLowerCase()) || test(character.toUpperCase())));
1092
- return negate ? !accepted : accepted;
1093
- } };
1094
- };
1095
- const atom = (atStart, afterBegin) => {
1096
- const token = dialect === "jq" && offset < source.length ? String.fromCodePoint(source.codePointAt(offset)) : source[offset];
1097
- offset += token?.length ?? 1;
1098
- if (token === "[") return bracket();
1099
- if (token === "\\") {
1100
- const reference = source[offset];
1101
- if ((dialect === "sed" || dialect === "jq") && reference !== void 0 && /^[1-9]$/u.test(reference)) {
1102
- const index = Number(reference);
1103
- if (!closedGroups.has(index)) throw new ProgramError("pattern references an undefined or open capture group");
1104
- offset++;
1105
- return { type: "backreference", index };
1106
- }
1107
- if (reference !== void 0 && "bByY<>".includes(reference)) {
1108
- offset++;
1109
- if (dialect === "awk" && reference === "b") {
1110
- return characterNode("\b");
1111
- }
1112
- return {
1113
- type: "boundary",
1114
- accepts: isWordChar,
1115
- positive: reference !== "B" && reference !== "Y",
1116
- ...reference === "<" ? { edge: "start" } : reference === ">" ? { edge: "end" } : {}
1117
- };
1118
- }
1119
- if ((dialect === "jq" || dialect === "sed" || dialect === "awk") && reference !== void 0 && "dDsSwW".includes(reference)) {
1120
- offset++;
1121
- const alphabet = reference.toLowerCase();
1122
- return { type: "character", accepts: (character) => {
1123
- const accepted = alphabet === "d" ? character >= "0" && character <= "9" : alphabet === "s" ? " \n\r\f\v".includes(character) : character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character >= "0" && character <= "9" || character === "_";
1124
- return reference === alphabet ? accepted : !accepted;
1125
- } };
1126
- }
1127
- return characterNode(escaped());
1128
- }
1129
- if (token === ".") return { type: "character", accepts: (character) => dialect !== "jq" || modifiers.includes("m") || character !== "\n" };
1130
- if (token === "^") return extended || atStart ? { type: "begin" } : characterNode(token);
1131
- if (token === "$") return extended || offset === source.length || source[offset] === ")" || source[offset] === "|" ? { type: "end" } : characterNode(token);
1132
- if (token === "*" && !extended && (atStart || afterBegin)) return characterNode(token);
1133
- if (token === void 0 || "*+?{}".includes(token)) throw new ProgramError("quantifier without an expression");
1134
- return characterNode(token);
1135
- };
1136
- const repeated = (original) => {
1137
- let node = original;
1138
- if (!extended && (node.type === "begin" || node.type === "end")) return node;
1139
- const quantifier = source[offset];
1140
- if (quantifier === "*" || quantifier === "+" || quantifier === "?") {
1141
- offset++;
1142
- node = { type: "repeat", node, minimum: quantifier === "+" ? 1 : 0, maximum: quantifier === "?" ? 1 : Infinity };
1143
- } else if (quantifier === "{") {
1144
- const match = /^\{([0-9]+)(?:,([0-9]*))?\}/u.exec(source.slice(offset));
1145
- if (!match) throw new ProgramError("invalid repetition interval");
1146
- const minimum = Number(match[1]);
1147
- const maximum = match[2] === void 0 ? minimum : match[2] === "" ? Infinity : Number(match[2]);
1148
- if (!Number.isSafeInteger(minimum) || maximum !== Infinity && !Number.isSafeInteger(maximum) || maximum < minimum) throw new ProgramError("invalid or excessive repetition interval");
1149
- offset += match[0].length;
1150
- node = { type: "repeat", node, minimum, maximum };
1151
- }
1152
- if (dialect === "jq" && node.type === "repeat" && source[offset] === "?") {
1153
- node.lazy = true;
1154
- offset++;
1155
- }
1156
- if (source[offset] !== void 0 && "*+?{".includes(source[offset])) throw new ProgramError("nested quantifier is not supported");
1157
- return node;
1158
- };
1159
- const frames = [{ nodes: [], alternatives: [], index: 0 }];
1160
- const sequence = (nodes) => nodes.length ? { type: "sequence", nodes } : { type: "empty" };
1161
- const finish = (frame) => {
1162
- frame.alternatives.push(sequence(frame.nodes));
1163
- return frame.alternatives.length === 1 ? frame.alternatives[0] : { type: "alternate", nodes: frame.alternatives };
1164
- };
1165
- while (offset < source.length) {
1166
- const frame = frames[frames.length - 1];
1167
- if (source[offset] === "|") {
1168
- offset++;
1169
- frame.alternatives.push(sequence(frame.nodes));
1170
- frame.nodes = [];
1171
- } else if (source[offset] === ")") {
1172
- if (frames.length === 1) throw new ProgramError("unmatched ')' in regular expression");
1173
- offset++;
1174
- const inner = finish(frame);
1175
- frames.pop();
1176
- closedGroups.add(frame.index);
1177
- const node = frame.assertion ? { type: "assertion", node: inner, ...frame.assertion } : frame.index ? { type: "group", index: frame.index, lastCapture: groups, node: inner } : inner;
1178
- frames[frames.length - 1].nodes.push(repeated(node));
1179
- } else if (source[offset] === "(") {
1180
- if (frames.length > (limits.maxPatternDepth ?? Infinity)) throw new ProgramError(`${prefix}regular expression depth limit exceeded`);
1181
- this.patternDepth = Math.max(this.patternDepth, frames.length);
1182
- offset++;
1183
- let name;
1184
- let capturing = true;
1185
- let assertion;
1186
- if (source[offset] === "?" && source[offset + 1] === ":") {
1187
- offset += 2;
1188
- capturing = false;
1189
- } else if (dialect === "jq" && source[offset] === "?") {
1190
- offset++;
1191
- if (source[offset] === ":") {
1192
- offset++;
1193
- capturing = false;
1194
- } else if (source[offset] === "=" || source[offset] === "!") {
1195
- assertion = { positive: source[offset++] === "=", behind: false };
1196
- capturing = false;
1197
- } else if (source[offset] === "<" && "=!".includes(source[offset + 1] ?? "")) {
1198
- offset++;
1199
- assertion = { positive: source[offset++] === "=", behind: true };
1200
- capturing = false;
1201
- } else if (source[offset] === "<" && !"=!".includes(source[offset + 1] ?? "")) {
1202
- const end = source.indexOf(">", ++offset);
1203
- if (end < 0) throw new ProgramError("invalid named capture");
1204
- name = source.slice(offset, end);
1205
- offset = end + 1;
1206
- } else throw new ProgramError("unsupported jq regular expression group");
1207
- }
1208
- const index = capturing ? ++groups : 0;
1209
- if (name !== void 0) this.groupNames.set(name, index);
1210
- frames.push({ nodes: [], alternatives: [], index, assertion });
1211
- } else {
1212
- frame.nodes.push(repeated(atom(frame.nodes.length === 0, frame.nodes.length === 1 && frame.nodes[0].type === "begin")));
1213
- }
1214
- }
1215
- if (frames.length !== 1) throw new ProgramError("unmatched '(' in regular expression");
1216
- const root = finish(frames[0]);
1217
- this.groupCount = groups;
1218
- this.anchored = root.type === "sequence" && root.nodes[0]?.type === "begin";
1219
- const counts = instructionCounts(root);
1220
- if (!Number.isSafeInteger(counts.get(root) + 1)) throw new ProgramError(`${prefix}regular expression program size is not representable`);
1221
- if (counts.get(root) + 1 > maximumInstructions) throw new ProgramError(`${prefix}regular expression program limit exceeded`);
1222
- this.instructionCount = counts.get(root) + 1;
1223
- this.parsed = { root, counts };
1224
- if (counts.get(root) <= 64) {
1225
- this.compileFromParsedSync();
1226
- }
1227
- }
1228
- ignoreCase;
1229
- dialect;
1230
- modifiers;
1231
- groupCount;
1232
- groupNames = /* @__PURE__ */ new Map();
1233
- code = [];
1234
- compiledSteps = 0;
1235
- sourceLength = 0;
1236
- patternDepth = 0;
1237
- instructionCount;
1238
- budgetPrepared = false;
1239
- parsed;
1240
- anchored;
1241
- linear = false;
1242
- literalMatch;
1243
- simpleRepeatMatch;
1244
- chainMatch;
1245
- backreferences = false;
1246
- trailingNewlineAnchor = false;
1247
- fastPrefixInfo;
1248
- assertInstructionLimit(budget) {
1249
- if (this.sourceLength > (budget.options?.maxPatternSource ?? Infinity)) throw new ProgramError("regular expression source limit exceeded");
1250
- if (this.patternDepth > (budget.options?.maxPatternDepth ?? Infinity)) throw new ProgramError("regular expression depth limit exceeded");
1251
- if (this.instructionCount > (budget.options?.maxPatternInstructions ?? Infinity)) throw new ProgramError(`${this.dialect === "jq" ? "jq " : ""}regular expression program limit exceeded`);
1252
- }
1253
- compileFromParsedSync() {
1254
- if (!this.parsed) return;
1255
- const { root, counts } = this.parsed;
1256
- this.compiledSteps = counts.get(root) + 1;
1257
- const compilation = compileProgram(root, counts, this.ignoreCase);
1258
- let result = compilation.next();
1259
- while (!result.done) result = compilation.next();
1260
- this.finalizeCompiledCode(result.value, root);
1261
- }
1262
- async prepare(budget) {
1263
- this.assertInstructionLimit(budget);
1264
- if (!this.parsed) {
1265
- if (!this.budgetPrepared && this.compiledSteps > 0) {
1266
- budget.step(this.compiledSteps);
1267
- const pending = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1268
- if (pending) await pending;
1269
- this.budgetPrepared = true;
1270
- }
1271
- return;
1272
- }
1273
- const { root, counts } = this.parsed;
1274
- budget.step(counts.get(root) + 1);
1275
- await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
1276
- const compilation = compileProgram(root, counts, this.ignoreCase);
1277
- let result = compilation.next();
1278
- let work = 0;
1279
- while (!result.done) {
1280
- if (++work % 64 === 0) {
1281
- await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
1282
- budget.step(0);
1283
- }
1284
- result = compilation.next();
1285
- }
1286
- await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
1287
- budget.step(0);
1288
- this.budgetPrepared = true;
1289
- this.finalizeCompiledCode(result.value, root);
1290
- }
1291
- finalizeCompiledCode(code, root) {
1292
- this.linear = code.every((instruction) => instruction.kind === "character" || instruction.kind === "begin" || instruction.kind === "end" || instruction.kind === "match");
1293
- if (this.linear && !this.ignoreCase && this.dialect !== "jq" && this.dialect !== "rust") {
1294
- let validLiteral = true;
1295
- let anchoredStart = false;
1296
- let anchoredEnd = false;
1297
- let literalValue = "";
1298
- for (let i = 0; i < code.length - 1; i++) {
1299
- const inst = code[i];
1300
- if (inst.kind === "begin") {
1301
- if (i === 0) anchoredStart = true;
1302
- else {
1303
- validLiteral = false;
1304
- break;
1305
- }
1306
- } else if (inst.kind === "end") {
1307
- if (i === code.length - 2) anchoredEnd = true;
1308
- else {
1309
- validLiteral = false;
1310
- break;
1311
- }
1312
- } else if (inst.kind === "character" && inst.literal !== void 0) {
1313
- literalValue += inst.literal;
1314
- } else {
1315
- validLiteral = false;
1316
- break;
1317
- }
1318
- }
1319
- if (validLiteral) {
1320
- this.literalMatch = { value: literalValue, anchoredStart, anchoredEnd, groups: [literalValue] };
1321
- this.fastPrefixInfo = { anchoredStart, anchoredEnd, prefix: literalValue };
1322
- }
1323
- } else if (!this.ignoreCase && this.dialect !== "jq" && this.dialect !== "rust" && root.type === "sequence" && this.groupCount <= 1) {
1324
- let startIdx = 0;
1325
- let endIdx = root.nodes.length;
1326
- let anchoredStart = false;
1327
- let anchoredEnd = false;
1328
- if (startIdx < endIdx && root.nodes[startIdx]?.type === "begin") {
1329
- anchoredStart = true;
1330
- startIdx++;
1331
- }
1332
- if (startIdx < endIdx && root.nodes[endIdx - 1]?.type === "end") {
1333
- anchoredEnd = true;
1334
- endIdx--;
1335
- }
1336
- if (startIdx < endIdx) {
1337
- let prefix = "";
1338
- let prefixValid = true;
1339
- for (let i = startIdx; i < endIdx - 1; i++) {
1340
- const n = root.nodes[i];
1341
- if (n.type === "character" && n.literal !== void 0) {
1342
- prefix += n.literal;
1343
- } else {
1344
- prefixValid = false;
1345
- break;
1346
- }
1347
- }
1348
- const tail = root.nodes[endIdx - 1];
1349
- const captured = tail.type === "group" && tail.index === 1 && this.groupCount === 1;
1350
- const rawInner = captured ? tail.node : this.groupCount === 0 ? tail : void 0;
1351
- const repeatNode = rawInner?.type === "sequence" && rawInner.nodes.length === 1 ? rawInner.nodes[0] : rawInner;
1352
- if (prefixValid && repeatNode?.type === "repeat" && (repeatNode.minimum >= 1 || prefix.length > 0 || anchoredStart) && repeatNode.maximum === Infinity && !repeatNode.lazy && repeatNode.node.type === "character") {
1353
- const acceptsFn = repeatNode.node.accepts;
1354
- const ascii = new Uint8Array(128);
1355
- for (let c = 0; c < 128; c++) {
1356
- if (acceptsFn(String.fromCharCode(c))) ascii[c] = 1;
1357
- }
1358
- this.simpleRepeatMatch = {
1359
- prefix,
1360
- anchoredStart,
1361
- anchoredEnd,
1362
- captured,
1363
- minimum: repeatNode.minimum,
1364
- accepts: acceptsFn,
1365
- ascii
1366
- };
1367
- if (anchoredStart || prefix.length > 0) {
1368
- this.fastPrefixInfo = { anchoredStart, anchoredEnd, prefix };
1369
- }
1370
- }
1371
- }
1372
- }
1373
- if (!this.ignoreCase && this.dialect !== "jq" && this.dialect !== "rust" && !this.literalMatch && !this.simpleRepeatMatch) {
1374
- const cm = buildChainMatch(root, this.groupCount);
1375
- if (cm) {
1376
- this.chainMatch = cm;
1377
- this.fastPrefixInfo = { anchoredStart: cm.anchoredStart, anchoredEnd: cm.anchoredEnd, prefix: cm.prefix };
1378
- }
1379
- }
1380
- this.backreferences = code.some((instruction) => instruction.kind === "backreference");
1381
- this.trailingNewlineAnchor = code.some((instruction) => instruction.kind === "end" && instruction.trailingNewlines);
1382
- this.code = code;
1383
- this.parsed = void 0;
1384
- }
1385
- async findJq(text, budget, from, options = { pc: 0 }) {
1386
- const continuation = options.continuation ?? from;
1387
- let trailingStart = text.length;
1388
- if (this.trailingNewlineAnchor) while (trailingStart > 0 && text[trailingStart - 1] === "\n") {
1389
- budget.step();
1390
- trailingStart--;
1391
- if (trailingStart % 64 === 0) await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
1392
- }
1393
- for (let start = from; start <= (options.end ?? text.length) && (!options.exact || start === from); start += (text.codePointAt(start) ?? 0) > 65535 ? 2 : 1) {
1394
- const pending = [{ pc: options.pc, position: start, captures: options.captures ?? [] }];
1395
- const visited = /* @__PURE__ */ new Set();
1396
- let storage = 0;
1397
- let checkpoints = 0;
1398
- while (pending.length) {
1399
- if (++checkpoints % 64 === 1) await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
1400
- budget.step();
1401
- const state = pending.pop();
1402
- if (options.end !== void 0 && state.position > options.end) continue;
1403
- const key = `${state.pc}:${state.position}:${state.captures.join(",")}`;
1404
- if (visited.has(key)) continue;
1405
- storage += key.length * 2 + 64;
1406
- if (storage > budget.maxBufferBytes) throw new ProgramError("regular expression state buffer limit exceeded");
1407
- visited.add(key);
1408
- const instruction = this.code[state.pc];
1409
- const { position, captures } = state;
1410
- const push = (pc, next = position, saved = captures) => {
1411
- if ((pending.length + 1) * (64 + (this.groupCount + 1) * 16) + storage > budget.maxBufferBytes) throw new ProgramError("regular expression state buffer limit exceeded");
1412
- pending.push({ pc, position: next, captures: saved });
1413
- };
1414
- if (instruction.kind === "match") {
1415
- if (options.end !== void 0 && position !== options.end) continue;
1416
- if (this.modifiers.includes("n") && position === start) continue;
1417
- const matchStart = captures[0] ?? start;
1418
- const groups = [text.slice(matchStart, position)];
1419
- for (let index = 1; index <= this.groupCount; index++) {
1420
- budget.step();
1421
- groups.push(captures[index * 2] === void 0 ? void 0 : text.slice(captures[index * 2], captures[index * 2 + 1]));
1422
- }
1423
- return { match: { start: matchStart, end: position, groups }, captures };
1424
- }
1425
- if (instruction.kind === "conditional") {
1426
- const result = await this.findJq(text, budget, position, { pc: instruction.first, exact: true, captures, continuation });
1427
- if (result) push(instruction.yes, result.match.end, result.captures);
1428
- else push(instruction.no);
1429
- } else if (instruction.kind === "atomic") {
1430
- const result = await this.findJq(text, budget, position, { pc: instruction.first, exact: true, captures, continuation });
1431
- if (result) push(instruction.next, result.match.end, result.captures);
1432
- } else if (instruction.kind === "assertion") {
1433
- const result = await this.findJq(
1434
- text,
1435
- budget,
1436
- instruction.behind ? 0 : position,
1437
- instruction.behind ? { pc: instruction.first, end: position, captures, continuation } : { pc: instruction.first, exact: true, captures, continuation }
1438
- );
1439
- if (Boolean(result) === instruction.positive) push(instruction.next, position, result?.captures ?? captures);
1440
- } else if (instruction.kind === "jump") push(instruction.target);
1441
- else if (instruction.kind === "split") {
1442
- push(instruction.second);
1443
- push(instruction.first);
1444
- } else if (instruction.kind === "save") {
1445
- const saved = [...captures];
1446
- for (let slot = instruction.slot + 2; slot < Math.min(instruction.clearUntil ?? 0, saved.length); slot++) delete saved[slot];
1447
- saved[instruction.slot] = position;
1448
- push(state.pc + 1, position, saved);
1449
- } else if (instruction.kind === "continue") {
1450
- if (position === continuation) push(state.pc + 1);
1451
- } else if (instruction.kind === "captureSet") {
1452
- if (captures[instruction.index * 2] !== void 0) push(state.pc + 1);
1453
- } else if (instruction.kind === "begin") {
1454
- if (position === 0 || instruction.multiline && text[position - 1] === "\n") push(state.pc + 1);
1455
- } else if (instruction.kind === "end") {
1456
- if (position === text.length || instruction.trailingNewlines && position >= trailingStart || (instruction.multiline || !instruction.strict && position === text.length - 1) && text[position] === "\n") push(state.pc + 1);
1457
- } else if (instruction.kind === "boundary") {
1458
- const previous = position > 1 && text.codePointAt(position - 2) > 65535 ? text.slice(position - 2, position) : text.slice(position - 1, position);
1459
- const next = text.codePointAt(position), current = next === void 0 ? "" : String.fromCodePoint(next);
1460
- const before = position > 0 && instruction.accepts(previous), after = Boolean(current) && instruction.accepts(current);
1461
- const boundary = instruction.edge === "start" ? !before && after : instruction.edge === "end" ? before && !after : before !== after;
1462
- if (boundary === instruction.positive) push(state.pc + 1);
1463
- } else if (instruction.kind === "character") {
1464
- const code = text.codePointAt(position);
1465
- if (code !== void 0) {
1466
- const character = String.fromCodePoint(code);
1467
- if (instruction.accepts(character)) push(state.pc + 1, position + character.length);
1468
- }
1469
- } else if (instruction.kind === "backreference") {
1470
- const begin = captures[instruction.index * 2];
1471
- const end = captures[instruction.index * 2 + 1];
1472
- if (begin !== void 0 && end !== void 0) {
1473
- const length = end - begin;
1474
- budget.step(length);
1475
- const expected = text.slice(begin, end);
1476
- const actual = text.slice(position, position + length);
1477
- if (instruction.ignoreCase ? instruction.fold ? instruction.fold(expected) === instruction.fold(actual) : expected.toLowerCase() === actual.toLowerCase() : expected === actual) push(state.pc + 1, position + length);
1478
- }
1479
- } else throw new ProgramError("unsupported jq regular expression instruction");
1480
- }
1481
- }
1482
- return void 0;
1483
- }
1484
- canFindSync() {
1485
- return this.code.length > 0 && this.dialect !== "jq" && this.dialect !== "rust" && Boolean(this.literalMatch || this.simpleRepeatMatch || this.chainMatch);
1486
- }
1487
- getFastPrefixInfo() {
1488
- return this.fastPrefixInfo;
1489
- }
1490
- getLiteralMatchInfo() {
1491
- return this.literalMatch;
1492
- }
1493
- findSyncFastInto(text, budget, from, outOffsets, textEnd = text.length, textStart = 0) {
1494
- this.assertInstructionLimit(budget);
1495
- if (this.chainMatch) {
1496
- const { prefix, anchoredStart: anchoredStart2, anchoredEnd: anchoredEnd2, steps } = this.chainMatch;
1497
- if (from > textEnd || anchoredStart2 && from > textStart) return false;
1498
- const first = steps[0];
1499
- const startStep = prefix.length > 0 && first.group === 0 ? 1 : 0;
1500
- let found2 = -1;
1501
- let matchEnd = -1;
1502
- if (anchoredStart2) {
1503
- if (prefix.length === 0 || textStart + prefix.length <= textEnd && text.startsWith(prefix, textStart)) {
1504
- matchEnd = matchChainAt(steps, prefix.length, anchoredEnd2, text, textStart, outOffsets, this.groupCount, textEnd, startStep);
1505
- if (matchEnd >= 0) found2 = textStart;
1506
- }
1507
- } else if (prefix.length > 0) {
1508
- let searchFrom = from;
1509
- while (searchFrom <= textEnd - prefix.length) {
1510
- const idx = text.indexOf(prefix, searchFrom);
1511
- if (idx < 0 || idx > textEnd - prefix.length) break;
1512
- const end = matchChainAt(steps, prefix.length, anchoredEnd2, text, idx, outOffsets, this.groupCount, textEnd, startStep);
1513
- if (end >= 0) {
1514
- found2 = idx;
1515
- matchEnd = end;
1516
- break;
1517
- }
1518
- searchFrom = idx + 1;
1519
- }
1520
- } else {
1521
- const head = first;
1522
- const headAscii = head.ascii;
1523
- const headAccepts = head.accepts;
1524
- const headMin = head.minimum;
1525
- let searchFrom = from;
1526
- while (searchFrom < textEnd) {
1527
- while (searchFrom < textEnd) {
1528
- const c = text.charCodeAt(searchFrom);
1529
- if (c < 128 ? headAscii[c] !== 0 : headAccepts(text[searchFrom])) break;
1530
- searchFrom++;
1531
- }
1532
- if (searchFrom >= textEnd) break;
1533
- let runEnd = searchFrom + 1;
1534
- while (runEnd < textEnd) {
1535
- const c = text.charCodeAt(runEnd);
1536
- if (c < 128 ? headAscii[c] === 0 : !headAccepts(text[runEnd])) break;
1537
- runEnd++;
1538
- }
1539
- if (runEnd - searchFrom >= headMin) {
1540
- const end = matchChainAt(steps, 0, anchoredEnd2, text, searchFrom, outOffsets, this.groupCount, textEnd, 0);
1541
- if (end >= 0) {
1542
- found2 = searchFrom;
1543
- matchEnd = end;
1544
- break;
1545
- }
1546
- }
1547
- searchFrom = runEnd + 1;
1548
- }
1549
- }
1550
- const positionsTried2 = anchoredStart2 ? 1 : found2 >= 0 ? found2 - from + 1 : textEnd - from + 1;
1551
- const len2 = found2 >= 0 ? matchEnd - found2 : 0;
1552
- budget.step(positionsTried2 * 2 + (found2 >= 0 ? this.code.length * 2 + len2 : 0));
1553
- if (found2 < 0) return false;
1554
- if (len2 > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1555
- return true;
1556
- }
1557
- if (this.simpleRepeatMatch) {
1558
- const { prefix, anchoredStart: anchoredStart2, anchoredEnd: anchoredEnd2, captured, minimum, accepts, ascii } = this.simpleRepeatMatch;
1559
- if (from > textEnd || anchoredStart2 && from > textStart) return false;
1560
- let found2 = -1;
1561
- let matchEnd = -1;
1562
- let groupStart = -1;
1563
- let groupEnd = -1;
1564
- if (anchoredStart2) {
1565
- if (textStart + prefix.length <= textEnd && text.startsWith(prefix, textStart)) {
1566
- const pos = textStart + prefix.length;
1567
- let cursor = pos;
1568
- while (cursor < textEnd) {
1569
- const code = text.charCodeAt(cursor);
1570
- if (code < 128 ? ascii[code] === 0 : !accepts(text[cursor])) break;
1571
- cursor++;
1572
- }
1573
- if (cursor - pos >= minimum && (!anchoredEnd2 || cursor === textEnd)) {
1574
- found2 = textStart;
1575
- matchEnd = cursor;
1576
- groupStart = pos;
1577
- groupEnd = cursor;
1578
- }
1579
- }
1580
- } else if (prefix.length === 0) {
1581
- let searchFrom = from;
1582
- const maxStart = textEnd - minimum;
1583
- while (searchFrom <= maxStart) {
1584
- const c0 = text.charCodeAt(searchFrom);
1585
- if (c0 < 128 ? ascii[c0] === 0 : !accepts(text[searchFrom])) {
1586
- searchFrom++;
1587
- continue;
1588
- }
1589
- const idx = searchFrom;
1590
- let cursor = idx + 1;
1591
- while (cursor < textEnd) {
1592
- const code = text.charCodeAt(cursor);
1593
- if (code < 128 ? ascii[code] === 0 : !accepts(text[cursor])) break;
1594
- cursor++;
1595
- }
1596
- if (cursor - idx >= minimum && (!anchoredEnd2 || cursor === textEnd)) {
1597
- found2 = idx;
1598
- matchEnd = cursor;
1599
- groupStart = idx;
1600
- groupEnd = cursor;
1601
- break;
1602
- }
1603
- searchFrom = cursor + 1;
1604
- }
1605
- } else {
1606
- let searchFrom = from;
1607
- while (searchFrom <= textEnd - prefix.length) {
1608
- const idx = text.indexOf(prefix, searchFrom);
1609
- if (idx < 0 || idx > textEnd - prefix.length) break;
1610
- const pos = idx + prefix.length;
1611
- let cursor = pos;
1612
- while (cursor < textEnd) {
1613
- const code = text.charCodeAt(cursor);
1614
- if (code < 128 ? ascii[code] === 0 : !accepts(text[cursor])) break;
1615
- cursor++;
1616
- }
1617
- if (cursor - pos >= minimum && (!anchoredEnd2 || cursor === textEnd)) {
1618
- found2 = idx;
1619
- matchEnd = cursor;
1620
- groupStart = pos;
1621
- groupEnd = cursor;
1622
- break;
1623
- }
1624
- searchFrom = idx + 1;
1625
- }
1626
- }
1627
- const positionsTried2 = anchoredStart2 ? 1 : found2 >= 0 ? found2 - from + 1 : textEnd - from + 1;
1628
- const len2 = found2 >= 0 ? matchEnd - found2 : 0;
1629
- budget.step(positionsTried2 * 2 + (found2 >= 0 ? this.code.length * 2 + len2 : 0));
1630
- if (found2 < 0) return false;
1631
- if (len2 > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1632
- outOffsets[0] = found2;
1633
- outOffsets[1] = matchEnd;
1634
- outOffsets[2] = captured ? groupStart : -1;
1635
- outOffsets[3] = captured ? groupEnd : -1;
1636
- return true;
1637
- }
1638
- const { value, anchoredStart, anchoredEnd } = this.literalMatch;
1639
- const len = value.length;
1640
- if (from > textEnd || anchoredStart && from > textStart) return false;
1641
- let found = -1;
1642
- if (anchoredStart && anchoredEnd) {
1643
- if (from === textStart && textEnd - textStart === len && text.startsWith(value, textStart)) found = textStart;
1644
- } else if (anchoredStart) {
1645
- if (from === textStart && textStart + len <= textEnd && text.startsWith(value, textStart)) found = textStart;
1646
- } else if (anchoredEnd) {
1647
- const candidate = textEnd - len;
1648
- if (candidate >= from && text.startsWith(value, candidate)) found = candidate;
1649
- } else {
1650
- const maxStart = textEnd - len;
1651
- if (from <= maxStart) {
1652
- if (textEnd === text.length || maxStart - from > 64) {
1653
- const idx = text.indexOf(value, from);
1654
- if (idx >= 0 && idx <= maxStart) found = idx;
1655
- } else {
1656
- const c0 = value.charCodeAt(0);
1657
- const c1 = len > 1 ? value.charCodeAt(1) : -1;
1658
- for (let i = from; i <= maxStart; i++) {
1659
- if (text.charCodeAt(i) === c0 && (len === 1 || text.charCodeAt(i + 1) === c1 && (len === 2 || text.startsWith(value, i)))) {
1660
- found = i;
1661
- break;
1662
- }
1663
- }
1664
- }
1665
- }
1666
- }
1667
- const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : textEnd - from + 1;
1668
- budget.step(positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0));
1669
- if (found < 0) return false;
1670
- if (len > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1671
- outOffsets[0] = found;
1672
- outOffsets[1] = found + len;
1673
- outOffsets[2] = -1;
1674
- outOffsets[3] = -1;
1675
- return true;
1676
- }
1677
- findAfterCheck(check, text, budget, from) {
1678
- return check.then(() => this.find(text, budget, from));
1679
- }
1680
- finishLiteralAfterCheck(check, found, len, maxBufferBytes, groups) {
1681
- if (found < 0) return check.then(RETURN_UNDEFINED);
1682
- return check.then(() => {
1683
- if (len > maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1684
- return { start: found, end: found + len, groups };
1685
- });
1686
- }
1687
- tryFindSync(text, budget, from = 0) {
1688
- this.assertInstructionLimit(budget);
1689
- if (this.code.length && this.chainMatch && this.dialect !== "jq" && this.dialect !== "rust") {
1690
- const initialCheck2 = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1691
- if (initialCheck2) return this.findAfterCheck(initialCheck2, text, budget, from);
1692
- if (!this.findSyncFastInto(text, budget, from, FAST_MATCH_OFFSETS)) return void 0;
1693
- const start = FAST_MATCH_OFFSETS[0];
1694
- const end = FAST_MATCH_OFFSETS[1];
1695
- const groups2 = new Array(this.groupCount + 1);
1696
- groups2[0] = text.slice(start, end);
1697
- for (let g = 1; g <= this.groupCount; g++) {
1698
- const gs = FAST_MATCH_OFFSETS[g * 2];
1699
- const ge = FAST_MATCH_OFFSETS[g * 2 + 1];
1700
- groups2[g] = gs >= 0 ? text.slice(gs, ge) : void 0;
1701
- }
1702
- return { start, end, groups: groups2 };
1703
- }
1704
- if (this.code.length && this.simpleRepeatMatch && this.dialect !== "jq" && this.dialect !== "rust") {
1705
- const initialCheck2 = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1706
- if (initialCheck2) return this.findAfterCheck(initialCheck2, text, budget, from);
1707
- return this.execSimpleRepeat(text, budget, from);
1708
- }
1709
- if (!this.code.length || !this.literalMatch || this.dialect === "jq" || this.dialect === "rust") {
1710
- return this.find(text, budget, from);
1711
- }
1712
- const initialCheck = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1713
- if (initialCheck) return this.findAfterCheck(initialCheck, text, budget, from);
1714
- const { value, anchoredStart, anchoredEnd, groups } = this.literalMatch;
1715
- const len = value.length;
1716
- if (from > text.length || anchoredStart && from > 0) return void 0;
1717
- let found = -1;
1718
- if (anchoredStart && anchoredEnd) {
1719
- if (from === 0 && text.length === len && text === value) found = 0;
1720
- } else if (anchoredStart) {
1721
- if (from === 0 && text.startsWith(value)) found = 0;
1722
- } else if (anchoredEnd) {
1723
- const candidate = text.length - len;
1724
- if (candidate >= from && text.endsWith(value)) found = candidate;
1725
- } else {
1726
- found = text.indexOf(value, from);
1727
- }
1728
- const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : text.length - from + 1;
1729
- const stepCount = positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0);
1730
- budget.step(stepCount);
1731
- if (stepCount >= 64) {
1732
- const midCheck = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1733
- if (midCheck) return this.finishLiteralAfterCheck(midCheck, found, len, budget.maxBufferBytes, groups);
1734
- }
1735
- if (found < 0) return void 0;
1736
- if (len > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1737
- return { start: found, end: found + len, groups };
1738
- }
1739
- tryTestSync(text, budget, textStart = 0, textEnd = text.length) {
1740
- if (this.canFindSync()) {
1741
- const initialCheck = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1742
- if (!initialCheck) {
1743
- return this.findSyncFastInto(text, budget, textStart, FAST_MATCH_OFFSETS, textEnd, textStart);
1744
- }
1745
- return initialCheck.then(() => this.findSyncFastInto(text, budget, textStart, FAST_MATCH_OFFSETS, textEnd, textStart));
1746
- }
1747
- const sub = textStart === 0 && textEnd === text.length ? text : text.slice(textStart, textEnd);
1748
- const found = this.tryFindSync(sub, budget, 0);
1749
- if (found instanceof Promise) return found.then((res) => res !== void 0);
1750
- return found !== void 0;
1751
- }
1752
- execSimpleRepeat(text, budget, from) {
1753
- const { prefix, anchoredStart, anchoredEnd, captured, minimum, accepts, ascii } = this.simpleRepeatMatch;
1754
- if (from > text.length || anchoredStart && from > 0) return void 0;
1755
- let found = -1;
1756
- let matchEnd = -1;
1757
- let groupStart = -1;
1758
- let groupEnd = -1;
1759
- if (anchoredStart) {
1760
- if (text.startsWith(prefix)) {
1761
- const pos = prefix.length;
1762
- let cursor = pos;
1763
- while (cursor < text.length) {
1764
- const code = text.charCodeAt(cursor);
1765
- if (code < 128 ? ascii[code] === 0 : !accepts(text[cursor])) break;
1766
- cursor++;
1767
- }
1768
- if (cursor - pos >= minimum && (!anchoredEnd || cursor === text.length)) {
1769
- found = 0;
1770
- matchEnd = cursor;
1771
- groupStart = pos;
1772
- groupEnd = cursor;
1773
- }
1774
- }
1775
- } else {
1776
- let searchFrom = from;
1777
- while (searchFrom <= text.length - prefix.length) {
1778
- const idx = text.indexOf(prefix, searchFrom);
1779
- if (idx < 0) break;
1780
- const pos = idx + prefix.length;
1781
- let cursor = pos;
1782
- while (cursor < text.length) {
1783
- const code = text.charCodeAt(cursor);
1784
- if (code < 128 ? ascii[code] === 0 : !accepts(text[cursor])) break;
1785
- cursor++;
1786
- }
1787
- if (cursor - pos >= minimum && (!anchoredEnd || cursor === text.length)) {
1788
- found = idx;
1789
- matchEnd = cursor;
1790
- groupStart = pos;
1791
- groupEnd = cursor;
1792
- break;
1793
- }
1794
- searchFrom = idx + 1;
1795
- }
1796
- }
1797
- const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : text.length - from + 1;
1798
- const len = found >= 0 ? matchEnd - found : 0;
1799
- const stepCount = positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0);
1800
- budget.step(stepCount);
1801
- if (stepCount >= 64) {
1802
- const midCheck = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1803
- if (midCheck) {
1804
- return midCheck.then(() => {
1805
- if (found < 0) return void 0;
1806
- if (len > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1807
- const full2 = text.slice(found, matchEnd);
1808
- const groups2 = captured ? [full2, text.slice(groupStart, groupEnd)] : [full2];
1809
- return { start: found, end: matchEnd, groups: groups2 };
1810
- });
1811
- }
1812
- }
1813
- if (found < 0) return void 0;
1814
- if (len > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1815
- const full = text.slice(found, matchEnd);
1816
- const groups = captured ? [full, text.slice(groupStart, groupEnd)] : [full];
1817
- return { start: found, end: matchEnd, groups };
1818
- }
1819
- async find(text, budget, from = 0, continuation = from) {
1820
- this.assertInstructionLimit(budget);
1821
- if (!this.code.length) await this.prepare(budget);
1822
- if (this.dialect === "jq" || this.dialect === "rust") return (await this.findJq(text, budget, from, { pc: 0, continuation }))?.match;
1823
- if (this.simpleRepeatMatch) {
1824
- const initialCheck2 = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1825
- if (initialCheck2) await initialCheck2;
1826
- return await this.execSimpleRepeat(text, budget, from);
1827
- }
1828
- const initialCheck = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1829
- if (initialCheck) await initialCheck;
1830
- if (this.literalMatch) {
1831
- const { value, anchoredStart, anchoredEnd, groups } = this.literalMatch;
1832
- const len = value.length;
1833
- if (from > text.length || anchoredStart && from > 0) return void 0;
1834
- let found = -1;
1835
- if (anchoredStart && anchoredEnd) {
1836
- if (from === 0 && text.length === len && text === value) found = 0;
1837
- } else if (anchoredStart) {
1838
- if (from === 0 && text.startsWith(value)) found = 0;
1839
- } else if (anchoredEnd) {
1840
- const candidate = text.length - len;
1841
- if (candidate >= from && text.endsWith(value)) found = candidate;
1842
- } else {
1843
- found = text.indexOf(value, from);
1844
- }
1845
- const positionsTried = anchoredStart ? 1 : found >= 0 ? found - from + 1 : text.length - from + 1;
1846
- const stepCount = positionsTried * 2 + (found >= 0 ? this.code.length * 2 + len : 0);
1847
- budget.step(stepCount);
1848
- if (stepCount >= 64) {
1849
- const midCheck = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1850
- if (midCheck) await midCheck;
1851
- }
1852
- if (found < 0) return void 0;
1853
- if (len > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1854
- const endCheck = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1855
- if (endCheck) await endCheck;
1856
- return { start: found, end: found + len, groups };
1857
- }
1858
- let units = 0;
1859
- const work = (count = 1) => {
1860
- budget.step(count);
1861
- units += count;
1862
- if (units < 64) return void 0;
1863
- units %= 64;
1864
- return budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
1865
- };
1866
- if (this.linear) {
1867
- for (let start = from; start <= text.length && (!this.anchored || start === 0); start++) {
1868
- let position = start;
1869
- for (const instruction of this.code) {
1870
- const paused = work(2);
1871
- if (paused) await paused;
1872
- if (instruction.kind === "character") {
1873
- if (position >= text.length || !instruction.accepts(text[position])) break;
1874
- position++;
1875
- } else if (instruction.kind === "begin" && position !== 0 || instruction.kind === "end" && position !== text.length) break;
1876
- else if (instruction.kind === "match") {
1877
- if (position - start > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
1878
- const copied = work(position - start);
1879
- if (copied) await copied;
1880
- const match = { start, end: position, groups: [text.slice(start, position)] };
1881
- await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
1882
- return match;
1883
- }
1884
- }
1885
- }
1886
- return void 0;
1887
- }
1888
- const storage = new NfaStorage(budget);
1889
- const positionDigits = String(text.length).length;
1890
- const instructionDigits = String(this.code.length).length;
1891
- if (from > text.length || this.anchored && from !== 0) return void 0;
1892
- storage.reserve(128);
1893
- const positions = /* @__PURE__ */ new Map();
1894
- let earliestStarts;
1895
- let nextStart = from;
1896
- let bestStart;
1897
- let bestEnd;
1898
- let bestCaptures = [];
1899
- let bestBytes = 0;
1900
- try {
1901
- if (this.groupCount && !this.backreferences && !this.anchored) {
1902
- storage.reserve(64);
1903
- earliestStarts = /* @__PURE__ */ new Map();
1904
- }
1905
- let position = from;
1906
- while (position <= text.length) {
1907
- const advanced = work();
1908
- if (advanced) await advanced;
1909
- let pending = positions.get(position);
1910
- if (bestStart === void 0 && (!this.anchored || position === 0) && (!this.backreferences || position === nextStart)) {
1911
- storage.reserve(72 + (pending ? 0 : 64));
1912
- pending ??= [];
1913
- pending.push({ pc: 0, start: position, captures: [], bytes: 72 });
1914
- }
1915
- if (!pending && !positions.size) break;
1916
- if (!pending) {
1917
- position++;
1918
- continue;
1919
- }
1920
- const reversed = work(pending.length);
1921
- if (reversed) await reversed;
1922
- pending.reverse();
1923
- positions.delete(position);
1924
- const visited = /* @__PURE__ */ new Map();
1925
- let stateBytes = 0;
1926
- const enqueue = (destination, pc, start, captures, saveSlot, clearUntil) => {
1927
- const length = saveSlot === void 0 ? captures.length : Math.max(captures.length, saveSlot + 1);
1928
- const bytes = 72 + length * 8;
1929
- const waiting = destination === position ? pending : positions.get(destination);
1930
- storage.reserve(bytes + (waiting ? 0 : 64));
1931
- const saved = saveSlot === void 0 ? captures : [...captures];
1932
- if (saveSlot !== void 0) {
1933
- for (let slot = saveSlot + 2; slot < Math.min(clearUntil ?? 0, saved.length); slot++) delete saved[slot];
1934
- saved[saveSlot] = position;
1935
- }
1936
- const thread = { pc, start, captures: saved, bytes };
1937
- if (waiting) waiting.push(thread);
1938
- else positions.set(destination, [thread]);
1939
- };
1940
- while (pending.length) {
1941
- const paused = work();
1942
- if (paused) await paused;
1943
- const thread = pending.pop();
1944
- try {
1945
- if (bestStart !== void 0 && thread.start > bestStart) continue;
1946
- if (earliestStarts) {
1947
- const earliest = earliestStarts.get(thread.pc);
1948
- if (earliest !== void 0 && earliest < thread.start) continue;
1949
- if (earliest === void 0) {
1950
- storage.reserve(40);
1951
- stateBytes += 40;
1952
- }
1953
- earliestStarts.set(thread.pc, thread.start);
1954
- }
1955
- let state = thread.pc;
1956
- let bytes = 40;
1957
- if (this.groupCount) {
1958
- const joinedLength = Math.max(0, thread.captures.length - 1) + thread.captures.length * positionDigits;
1959
- const stateLength = instructionDigits + 1 + joinedLength;
1960
- const serialized = work(stateLength);
1961
- if (serialized) await serialized;
1962
- const reserved = 32 + joinedLength * 2 + 72 + stateLength * 2;
1963
- storage.reserve(reserved);
1964
- state = `${thread.pc}:${thread.captures.join(",")}`;
1965
- bytes = 72 + state.length * 2;
1966
- storage.release(reserved - bytes);
1967
- } else storage.reserve(bytes);
1968
- const priorStart = visited.get(state);
1969
- if (priorStart !== void 0) {
1970
- storage.release(bytes);
1971
- if (priorStart <= thread.start) continue;
1972
- } else stateBytes += bytes;
1973
- visited.set(state, thread.start);
1974
- const instruction = this.code[thread.pc];
1975
- if (instruction.kind === "character") {
1976
- if (position < text.length && instruction.accepts(text[position])) enqueue(position + 1, thread.pc + 1, thread.start, thread.captures);
1977
- } else if (instruction.kind === "backreference") {
1978
- const begin = thread.captures[instruction.index * 2];
1979
- const end = thread.captures[instruction.index * 2 + 1];
1980
- if (begin === void 0 || end === void 0 || position + end - begin > text.length) continue;
1981
- let matches = true;
1982
- for (let offset = 0; offset < end - begin; offset++) {
1983
- const compared = work();
1984
- if (compared) await compared;
1985
- const expected = text[begin + offset];
1986
- const actual = text[position + offset];
1987
- if (instruction.ignoreCase ? expected.toLowerCase() !== actual.toLowerCase() : expected !== actual) {
1988
- matches = false;
1989
- break;
1990
- }
1991
- }
1992
- if (matches) enqueue(position + end - begin, thread.pc + 1, thread.start, thread.captures);
1993
- } else if (instruction.kind === "match") {
1994
- let preferred = bestStart === void 0 || thread.start < bestStart || thread.start === bestStart && position > bestEnd;
1995
- if (thread.start === bestStart && position === bestEnd) for (let index = 1; index <= this.groupCount; index++) {
1996
- const compared = work();
1997
- if (compared) await compared;
1998
- const begin = thread.captures[index * 2];
1999
- const end = thread.captures[index * 2 + 1];
2000
- const priorBegin = bestCaptures[index * 2];
2001
- const priorEnd = bestCaptures[index * 2 + 1];
2002
- const length = begin === void 0 || end === void 0 ? -1 : end - begin;
2003
- const priorLength = priorBegin === void 0 || priorEnd === void 0 ? -1 : priorEnd - priorBegin;
2004
- if (length !== priorLength) {
2005
- preferred = length > priorLength;
2006
- break;
2007
- }
2008
- }
2009
- if (preferred) {
2010
- const retained = 32 + thread.captures.length * 8;
2011
- storage.reserve(retained);
2012
- bestStart = thread.start;
2013
- bestEnd = position;
2014
- bestCaptures = thread.captures;
2015
- storage.release(bestBytes);
2016
- bestBytes = retained;
2017
- }
2018
- } else if (instruction.kind === "split") {
2019
- enqueue(position, instruction.second, thread.start, thread.captures);
2020
- enqueue(position, instruction.first, thread.start, thread.captures);
2021
- } else if (instruction.kind === "jump") enqueue(position, instruction.target, thread.start, thread.captures);
2022
- else if (instruction.kind === "save") {
2023
- const copied = work(Math.max(thread.captures.length, instruction.slot + 1));
2024
- if (copied) await copied;
2025
- enqueue(position, thread.pc + 1, thread.start, thread.captures, instruction.slot, instruction.clearUntil);
2026
- } else if (instruction.kind === "boundary") {
2027
- if (matchesBoundary(instruction, text, position)) enqueue(position, thread.pc + 1, thread.start, thread.captures);
2028
- } else if (instruction.kind === "begin" ? position === 0 : position === text.length) enqueue(position, thread.pc + 1, thread.start, thread.captures);
2029
- } finally {
2030
- storage.release(thread.bytes);
2031
- }
2032
- }
2033
- visited.clear();
2034
- earliestStarts?.clear();
2035
- storage.release(stateBytes + 64);
2036
- if (this.backreferences && !positions.size) {
2037
- if (bestStart !== void 0 || this.anchored) break;
2038
- position = ++nextStart;
2039
- } else position++;
2040
- }
2041
- if (bestStart !== void 0 && bestEnd !== void 0) {
2042
- let characters = bestEnd - bestStart;
2043
- for (let index = 1; index <= this.groupCount; index++) {
2044
- const counted = work();
2045
- if (counted) await counted;
2046
- const begin = bestCaptures[index * 2];
2047
- const end = bestCaptures[index * 2 + 1];
2048
- if (begin !== void 0 && end !== void 0) characters += end - begin;
2049
- }
2050
- const copied = work(characters);
2051
- if (copied) await copied;
2052
- storage.reserve(64 + (this.groupCount + 1) * 40 + characters * 2);
2053
- const groups = [text.slice(bestStart, bestEnd)];
2054
- for (let index = 1; index <= this.groupCount; index++) {
2055
- const materialized = work();
2056
- if (materialized) await materialized;
2057
- const begin = bestCaptures[index * 2];
2058
- const end = bestCaptures[index * 2 + 1];
2059
- groups.push(begin === void 0 || end === void 0 ? void 0 : text.slice(begin, end));
2060
- }
2061
- await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
2062
- return { start: bestStart, end: bestEnd, groups };
2063
- }
2064
- return void 0;
2065
- } finally {
2066
- positions.clear();
2067
- earliestStarts?.clear();
2068
- storage.clear();
2069
- }
2070
- }
2071
- };
2072
- async function replacementLength(replacement, match, budget, available, syntax) {
2073
- let length = 0;
2074
- let tokens = 0;
2075
- for (let index = 0; index < replacement.length; index++) {
2076
- if (tokens++ % 256 === 0) await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
2077
- budget.step();
2078
- const character = replacement[index];
2079
- let size = 1;
2080
- if (character === "&") {
2081
- budget.step();
2082
- size = match.groups[0]?.length ?? 0;
2083
- } else if (character === "\\" && index + 1 < replacement.length) {
2084
- budget.step();
2085
- const next = replacement[++index];
2086
- if (syntax === "awk") {
2087
- size = next === "&" || next === "\\" ? 1 : 2;
2088
- } else if (next >= "0" && next <= "9") {
2089
- budget.step();
2090
- size = match.groups[Number(next)]?.length ?? 0;
2091
- }
2092
- }
2093
- if (size > available - length) throw new ProgramError("text buffer limit exceeded");
2094
- length += size;
2095
- }
2096
- return length;
2097
- }
2098
- async function replacementText(replacement, match, buffer, budget, syntax) {
2099
- let literal = 0;
2100
- let tokens = 0;
2101
- for (let index = 0; index < replacement.length; index++) {
2102
- if (tokens++ % 256 === 0) await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
2103
- budget.step();
2104
- const character = replacement[index];
2105
- if (character !== "&" && (character !== "\\" || index + 1 === replacement.length)) continue;
2106
- await buffer.append(replacement, literal, index);
2107
- if (character === "&") {
2108
- budget.step();
2109
- await buffer.append(match.groups[0] ?? "");
2110
- } else {
2111
- budget.step();
2112
- const next = replacement[++index];
2113
- if (syntax === "awk") {
2114
- await buffer.append(replacement, next === "&" || next === "\\" ? index : index - 1, index + 1);
2115
- } else if (next >= "0" && next <= "9") {
2116
- budget.step();
2117
- await buffer.append(match.groups[Number(next)] ?? "");
2118
- } else await buffer.append(next === "n" ? "\n" : next === "t" ? " " : next);
2119
- }
2120
- literal = index + 1;
2121
- }
2122
- await buffer.append(replacement, literal);
2123
- }
2124
- var RETURN_UNDEFINED = () => void 0;
2125
- var FAST_MATCH_OFFSETS = new Int32Array(20);
2126
- var SYNC_SUB_RESULT = { text: "", count: 0 };
2127
- var SIMPLE_REPLACEMENT_CACHE = /* @__PURE__ */ new Map();
2128
- function getSimpleReplacement(replacement, syntax) {
2129
- const key = syntax === "sed" ? replacement : `awk:${replacement}`;
2130
- const cached = SIMPLE_REPLACEMENT_CACHE.get(key);
2131
- if (cached !== void 0) return cached;
2132
- if (SIMPLE_REPLACEMENT_CACHE.size >= 128) SIMPLE_REPLACEMENT_CACHE.clear();
2133
- if (!replacement.includes("&") && !replacement.includes("\\")) {
2134
- const res = { kind: "literal", prefix: replacement, group: -1, mid: "", group2: -1, suffix: "", stepsPerExpansion: replacement.length * 2 + 1, smallInts: [] };
2135
- SIMPLE_REPLACEMENT_CACHE.set(key, res);
2136
- return res;
2137
- }
2138
- if (syntax === "sed") {
2139
- let prefix = "";
2140
- let mid = "";
2141
- let suffix = "";
2142
- let group = -1;
2143
- let group2 = -1;
2144
- let steps = 1;
2145
- for (let i = 0; i < replacement.length; i++) {
2146
- steps++;
2147
- const ch = replacement[i];
2148
- if (ch === "&") {
2149
- if (group2 !== -1) {
2150
- SIMPLE_REPLACEMENT_CACHE.set(key, null);
2151
- return null;
2152
- }
2153
- steps++;
2154
- if (group === -1) group = 0;
2155
- else group2 = 0;
2156
- } else if (ch === "\\" && i + 1 < replacement.length) {
2157
- steps++;
2158
- const next = replacement[++i];
2159
- if (next >= "0" && next <= "9") {
2160
- if (group2 !== -1) {
2161
- SIMPLE_REPLACEMENT_CACHE.set(key, null);
2162
- return null;
2163
- }
2164
- steps++;
2165
- if (group === -1) group = next.charCodeAt(0) - 48;
2166
- else group2 = next.charCodeAt(0) - 48;
2167
- } else {
2168
- const decoded = next === "n" ? "\n" : next === "t" ? " " : next;
2169
- if (group === -1) prefix += decoded;
2170
- else if (group2 === -1) mid += decoded;
2171
- else suffix += decoded;
2172
- }
2173
- } else {
2174
- if (group === -1) prefix += ch;
2175
- else if (group2 === -1) mid += ch;
2176
- else suffix += ch;
2177
- }
2178
- }
2179
- const res = group === -1 ? { kind: "literal", prefix, group: -1, mid: "", group2: -1, suffix: "", stepsPerExpansion: steps + prefix.length, smallInts: [] } : group2 === -1 ? { kind: "singleRef", prefix, group, mid: "", group2: -1, suffix: mid, stepsPerExpansion: steps + prefix.length + mid.length, smallInts: new Array(100) } : { kind: "twoRefs", prefix, group, mid, group2, suffix, stepsPerExpansion: steps + prefix.length + mid.length + suffix.length, smallInts: [] };
2180
- SIMPLE_REPLACEMENT_CACHE.set(key, res);
2181
- return res;
2182
- }
2183
- SIMPLE_REPLACEMENT_CACHE.set(key, null);
2184
- return null;
2185
- }
2186
- function appendReplacementFromOffsetsSync(out, replacement, text, matchStart, matchEnd, group1Start, group1End, budget, maxBufferBytes, syntax, simpleRep = getSimpleReplacement(replacement, syntax)) {
2187
- if (simpleRep !== null) {
2188
- if (simpleRep.kind === "literal") {
2189
- budget.step(simpleRep.stepsPerExpansion);
2190
- if (out.length + simpleRep.prefix.length > maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2191
- return out ? out + simpleRep.prefix : simpleRep.prefix;
2192
- }
2193
- if (simpleRep.kind === "twoRefs") {
2194
- const g1Start = simpleRep.group === 0 ? matchStart : simpleRep.group === 1 ? group1Start : FAST_MATCH_OFFSETS[simpleRep.group * 2];
2195
- const g1End = simpleRep.group === 0 ? matchEnd : simpleRep.group === 1 ? group1End : FAST_MATCH_OFFSETS[simpleRep.group * 2 + 1];
2196
- const g2Start = simpleRep.group2 === 0 ? matchStart : simpleRep.group2 === 1 ? group1Start : FAST_MATCH_OFFSETS[simpleRep.group2 * 2];
2197
- const g2End = simpleRep.group2 === 0 ? matchEnd : simpleRep.group2 === 1 ? group1End : FAST_MATCH_OFFSETS[simpleRep.group2 * 2 + 1];
2198
- const g1Len = g1Start >= 0 && g1End > g1Start ? g1End - g1Start : 0;
2199
- const g2Len = g2Start >= 0 && g2End > g2Start ? g2End - g2Start : 0;
2200
- const addedLen2 = simpleRep.prefix.length + g1Len + simpleRep.mid.length + g2Len + simpleRep.suffix.length;
2201
- budget.step(simpleRep.stepsPerExpansion + g1Len + g2Len);
2202
- if (out.length + addedLen2 > maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2203
- const g1Str = g1Len > 0 ? text.slice(g1Start, g1End) : "";
2204
- const g2Str = g2Len > 0 ? text.slice(g2Start, g2End) : "";
2205
- const expanded2 = simpleRep.suffix ? simpleRep.prefix + g1Str + simpleRep.mid + g2Str + simpleRep.suffix : simpleRep.prefix + g1Str + simpleRep.mid + g2Str;
2206
- return out ? out + expanded2 : expanded2;
2207
- }
2208
- const gStart = simpleRep.group === 0 ? matchStart : simpleRep.group === 1 ? group1Start : FAST_MATCH_OFFSETS[simpleRep.group * 2];
2209
- const gEnd = simpleRep.group === 0 ? matchEnd : simpleRep.group === 1 ? group1End : FAST_MATCH_OFFSETS[simpleRep.group * 2 + 1];
2210
- const gLen = gStart >= 0 && gEnd > gStart ? gEnd - gStart : 0;
2211
- const addedLen = simpleRep.prefix.length + gLen + simpleRep.suffix.length;
2212
- budget.step(simpleRep.stepsPerExpansion + gLen);
2213
- if (out.length + addedLen > maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2214
- let expanded;
2215
- if (gLen === 1) {
2216
- const c0 = text.charCodeAt(gStart) - 48;
2217
- if (c0 >= 0 && c0 <= 9) {
2218
- expanded = simpleRep.smallInts[c0] ??= simpleRep.suffix ? simpleRep.prefix + String.fromCharCode(c0 + 48) + simpleRep.suffix : simpleRep.prefix + String.fromCharCode(c0 + 48);
2219
- }
2220
- } else if (gLen === 2) {
2221
- const c0 = text.charCodeAt(gStart) - 48;
2222
- const c1 = text.charCodeAt(gStart + 1) - 48;
2223
- if (c0 >= 1 && c0 <= 9 && c1 >= 0 && c1 <= 9) {
2224
- const num = c0 * 10 + c1;
2225
- expanded = simpleRep.smallInts[num] ??= simpleRep.suffix ? simpleRep.prefix + String(num) + simpleRep.suffix : simpleRep.prefix + String(num);
2226
- }
2227
- }
2228
- if (expanded === void 0) {
2229
- const gStr = gLen > 0 ? text.slice(gStart, gEnd) : "";
2230
- expanded = simpleRep.suffix ? simpleRep.prefix + gStr + simpleRep.suffix : simpleRep.prefix + gStr;
2231
- }
2232
- return out ? out + expanded : expanded;
2233
- }
2234
- const initialOutLen = out.length;
2235
- let literalStart = 0;
2236
- for (let index = 0; index < replacement.length; index++) {
2237
- budget.step();
2238
- const character = replacement[index];
2239
- if (character !== "&" && (character !== "\\" || index + 1 >= replacement.length)) continue;
2240
- if (index > literalStart) {
2241
- const litLen = index - literalStart;
2242
- if (out.length + litLen > maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2243
- const span = literalStart === 0 && index === replacement.length ? replacement : replacement.slice(literalStart, index);
2244
- out = out ? out + span : span;
2245
- }
2246
- let piece = "";
2247
- if (character === "&") {
2248
- budget.step();
2249
- piece = matchEnd > matchStart ? text.slice(matchStart, matchEnd) : "";
2250
- } else {
2251
- budget.step();
2252
- const next = replacement[++index];
2253
- if (syntax === "awk") {
2254
- piece = next === "&" || next === "\\" ? next : `\\${next}`;
2255
- } else if (next >= "0" && next <= "9") {
2256
- budget.step();
2257
- const g = next.charCodeAt(0) - 48;
2258
- if (g === 0) piece = matchEnd > matchStart ? text.slice(matchStart, matchEnd) : "";
2259
- else if (g === 1 && group1Start >= 0) piece = group1End > group1Start ? text.slice(group1Start, group1End) : "";
2260
- else if (g > 1) {
2261
- const gs = FAST_MATCH_OFFSETS[g * 2];
2262
- const ge = FAST_MATCH_OFFSETS[g * 2 + 1];
2263
- if (gs >= 0 && ge > gs) piece = text.slice(gs, ge);
2264
- }
2265
- } else {
2266
- piece = next === "n" ? "\n" : next === "t" ? " " : next;
2267
- }
2268
- }
2269
- if (out.length + piece.length > maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2270
- if (piece) out = out ? out + piece : piece;
2271
- literalStart = index + 1;
2272
- }
2273
- if (literalStart < replacement.length) {
2274
- const tailLen = replacement.length - literalStart;
2275
- if (out.length + tailLen > maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2276
- const span = literalStart === 0 ? replacement : replacement.slice(literalStart);
2277
- out = out ? out + span : span;
2278
- }
2279
- budget.step(out.length - initialOutLen + 1);
2280
- return out;
2281
- }
2282
- function trySubstituteSync(text, pattern, replacement, budget, global, occurrence = 1, syntax = "sed") {
2283
- if (pattern.canFindSync() && text.length <= 4096 && replacement.length <= 256) {
2284
- let search = 0;
2285
- let consumed = 0;
2286
- let previousEnd = -1;
2287
- let encountered = 0;
2288
- let count = 0;
2289
- let out = "";
2290
- while (search <= text.length) {
2291
- budget.step();
2292
- if (!pattern.findSyncFastInto(text, budget, search, FAST_MATCH_OFFSETS)) break;
2293
- const matchStart = FAST_MATCH_OFFSETS[0];
2294
- const matchEnd = FAST_MATCH_OFFSETS[1];
2295
- const group1Start = FAST_MATCH_OFFSETS[2];
2296
- const group1End = FAST_MATCH_OFFSETS[3];
2297
- if (matchStart === matchEnd && matchStart === previousEnd) {
2298
- search = matchEnd + 1;
2299
- continue;
2300
- }
2301
- encountered++;
2302
- if (encountered >= occurrence) {
2303
- const prefixLen = matchStart - consumed;
2304
- if (out.length + prefixLen > budget.maxBufferBytes) {
2305
- throw new ProgramError("text buffer limit exceeded");
2306
- }
2307
- if (prefixLen > 0) {
2308
- const pref = text.slice(consumed, matchStart);
2309
- out = out ? out + pref : pref;
2310
- }
2311
- out = appendReplacementFromOffsetsSync(out, replacement, text, matchStart, matchEnd, group1Start, group1End, budget, budget.maxBufferBytes, syntax);
2312
- consumed = matchEnd;
2313
- count++;
2314
- if (!global || pattern.getFastPrefixInfo()?.anchoredStart) break;
2315
- }
2316
- previousEnd = matchEnd;
2317
- search = matchEnd === matchStart ? matchEnd + 1 : matchEnd;
2318
- }
2319
- if (count > 0) {
2320
- const tailLen = text.length - consumed;
2321
- if (out.length + tailLen > budget.maxBufferBytes) {
2322
- throw new ProgramError("text buffer limit exceeded");
2323
- }
2324
- if (tailLen > 0) {
2325
- const tail = consumed === 0 ? text : text.slice(consumed);
2326
- out = out ? out + tail : tail;
2327
- }
2328
- } else {
2329
- out = budget.check(text);
2330
- }
2331
- SYNC_SUB_RESULT.text = out;
2332
- SYNC_SUB_RESULT.count = count;
2333
- return SYNC_SUB_RESULT;
2334
- }
2335
- if (!global && occurrence === 1 && !replacement.includes("&") && !replacement.includes("\\")) {
2336
- budget.step();
2337
- const matchOrPromise = pattern.tryFindSync(text, budget, 0);
2338
- if (matchOrPromise instanceof Promise) {
2339
- return matchOrPromise.then((match2) => {
2340
- if (!match2) {
2341
- budget.step(0);
2342
- return { text: budget.check(text), count: 0 };
2343
- }
2344
- const newLen2 = text.length - (match2.end - match2.start) + replacement.length;
2345
- if (newLen2 > budget.maxBufferBytes || match2.start + replacement.length > budget.maxBufferBytes) {
2346
- throw new ProgramError("text buffer limit exceeded");
2347
- }
2348
- budget.step(replacement.length * 2 + 1);
2349
- const out2 = (match2.start === 0 ? "" : text.slice(0, match2.start)) + replacement + (match2.end === text.length ? "" : text.slice(match2.end));
2350
- return { text: budget.check(out2), count: 1 };
2351
- });
2352
- }
2353
- const match = matchOrPromise;
2354
- if (!match) {
2355
- budget.step(0);
2356
- return { text: budget.check(text), count: 0 };
2357
- }
2358
- const newLen = text.length - (match.end - match.start) + replacement.length;
2359
- if (newLen > budget.maxBufferBytes || match.start + replacement.length > budget.maxBufferBytes) {
2360
- throw new ProgramError("text buffer limit exceeded");
2361
- }
2362
- budget.step(replacement.length * 2 + 1);
2363
- const out = (match.start === 0 ? "" : text.slice(0, match.start)) + replacement + (match.end === text.length ? "" : text.slice(match.end));
2364
- return { text: budget.check(out), count: 1 };
2365
- }
2366
- return substitute(text, pattern, replacement, budget, global, occurrence, syntax);
2367
- }
2368
- async function substitute(text, pattern, replacement, budget, global, occurrence = 1, syntax = "sed") {
2369
- if (!global && occurrence === 1 && !replacement.includes("&") && !replacement.includes("\\")) {
2370
- const check = budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint();
2371
- if (check) await check;
2372
- budget.step();
2373
- const match = await pattern.find(text, budget, 0);
2374
- if (!match) {
2375
- budget.step(0);
2376
- return { text: budget.check(text), count: 0 };
2377
- }
2378
- const newLen = text.length - (match.end - match.start) + replacement.length;
2379
- if (newLen > budget.maxBufferBytes || match.start + replacement.length > budget.maxBufferBytes) {
2380
- throw new ProgramError("text buffer limit exceeded");
2381
- }
2382
- budget.step(replacement.length * 2 + 1);
2383
- const out = (match.start === 0 ? "" : text.slice(0, match.start)) + replacement + (match.end === text.length ? "" : text.slice(match.end));
2384
- return { text: budget.check(out), count: 1 };
2385
- }
2386
- let search = 0;
2387
- let consumed = 0;
2388
- let previousEnd = -1;
2389
- let encountered = 0;
2390
- let count = 0;
2391
- const result = new ReplacementBuffer(budget);
2392
- try {
2393
- while (search <= text.length) {
2394
- await (budget.checkpointSync ? budget.checkpointSync() : budget.checkpoint());
2395
- budget.step();
2396
- const match = await pattern.find(text, budget, search);
2397
- if (!match) break;
2398
- if (match.start === match.end && match.start === previousEnd) {
2399
- search = match.end + 1;
2400
- continue;
2401
- }
2402
- encountered++;
2403
- if (encountered >= occurrence) {
2404
- const prefix = match.start - consumed;
2405
- result.admit(prefix);
2406
- const length = await replacementLength(replacement, match, budget, result.remaining - prefix, syntax);
2407
- result.admit(prefix + length);
2408
- await result.append(text, consumed, match.start);
2409
- await replacementText(replacement, match, result, budget, syntax);
2410
- consumed = match.end;
2411
- count++;
2412
- if (!global) break;
2413
- }
2414
- previousEnd = match.end > match.start ? match.end : -1;
2415
- search = match.end > match.start ? match.end : match.end + 1;
2416
- }
2417
- budget.step(0);
2418
- if (!count) return { text: budget.check(text), count };
2419
- await result.append(text, consumed);
2420
- return { text: await result.finish(), count };
2421
- } finally {
2422
- result.clear();
2423
- }
2424
- }
2425
- var PAIR_OFFSETS_1 = new Int32Array(4);
2426
- var PAIR_OFFSETS_2 = new Int32Array(4);
2427
- var SYNC_PAIR_RESULT = { text: "", substituted: false };
2428
- function expandSimpleFromOffsets(simpleRep, text, matchStart, matchEnd, group1Start, group1End, budget) {
2429
- if (simpleRep.kind === "literal") {
2430
- budget.step(simpleRep.stepsPerExpansion);
2431
- return simpleRep.prefix;
2432
- }
2433
- const gStart = simpleRep.group === 0 ? matchStart : simpleRep.group === 1 ? group1Start : -1;
2434
- const gEnd = simpleRep.group === 0 ? matchEnd : simpleRep.group === 1 ? group1End : -1;
2435
- const gLen = gStart >= 0 && gEnd > gStart ? gEnd - gStart : 0;
2436
- budget.step(simpleRep.stepsPerExpansion + gLen);
2437
- if (gLen === 1) {
2438
- const c0 = text.charCodeAt(gStart) - 48;
2439
- if (c0 >= 0 && c0 <= 9) {
2440
- return simpleRep.smallInts[c0] ??= simpleRep.suffix ? simpleRep.prefix + String.fromCharCode(c0 + 48) + simpleRep.suffix : simpleRep.prefix + String.fromCharCode(c0 + 48);
2441
- }
2442
- } else if (gLen === 2) {
2443
- const c0 = text.charCodeAt(gStart) - 48;
2444
- const c1 = text.charCodeAt(gStart + 1) - 48;
2445
- if (c0 >= 1 && c0 <= 9 && c1 >= 0 && c1 <= 9) {
2446
- const num = c0 * 10 + c1;
2447
- return simpleRep.smallInts[num] ??= simpleRep.suffix ? simpleRep.prefix + String(num) + simpleRep.suffix : simpleRep.prefix + String(num);
2448
- }
2449
- }
2450
- const gStr = gLen > 0 ? text.slice(gStart, gEnd) : "";
2451
- return simpleRep.suffix ? simpleRep.prefix + gStr + simpleRep.suffix : simpleRep.prefix + gStr;
2452
- }
2453
- function trySubstitutePairSync(text, pat1, rep1, global1, occ1, pat2, rep2, global2, occ2, budget) {
2454
- if (occ1 !== 1 || occ2 !== 1 || text.length > 4096) return void 0;
2455
- if (!pat1.canFindSync() || !pat2.canFindSync()) return void 0;
2456
- const info1 = pat1.getFastPrefixInfo();
2457
- const info2 = pat2.getFastPrefixInfo();
2458
- if (!info1 || !info2 || !info1.anchoredStart || info2.anchoredStart || info2.prefix.length === 0) return void 0;
2459
- const sr1 = getSimpleReplacement(rep1, "sed");
2460
- const sr2 = getSimpleReplacement(rep2, "sed");
2461
- if (!sr1 || !sr2) return void 0;
2462
- budget.step();
2463
- let effectiveE1 = 0;
2464
- let exp1 = "";
2465
- let effectiveExp1Len = 0;
2466
- let matched1 = false;
2467
- if (pat1.findSyncFastInto(text, budget, 0, PAIR_OFFSETS_1)) {
2468
- const e1 = PAIR_OFFSETS_1[1];
2469
- if (e1 === 0) return void 0;
2470
- matched1 = true;
2471
- exp1 = expandSimpleFromOffsets(sr1, text, 0, e1, PAIR_OFFSETS_1[2], PAIR_OFFSETS_1[3], budget);
2472
- let commonSuffix = 0;
2473
- const maxSuffix = Math.min(exp1.length, e1);
2474
- while (commonSuffix < maxSuffix && exp1.charCodeAt(exp1.length - 1 - commonSuffix) === text.charCodeAt(e1 - 1 - commonSuffix)) {
2475
- commonSuffix++;
2476
- }
2477
- effectiveExp1Len = exp1.length - commonSuffix;
2478
- effectiveE1 = e1 - commonSuffix;
2479
- const firstChar2 = info2.prefix.charCodeAt(0);
2480
- for (let i = 0; i < effectiveExp1Len; i++) {
2481
- if (exp1.charCodeAt(i) === firstChar2) return void 0;
2482
- }
2483
- }
2484
- budget.step();
2485
- if (!pat2.findSyncFastInto(text, budget, effectiveE1, PAIR_OFFSETS_2)) {
2486
- if (!matched1) {
2487
- SYNC_PAIR_RESULT.text = budget.check(text);
2488
- SYNC_PAIR_RESULT.substituted = false;
2489
- return SYNC_PAIR_RESULT;
2490
- }
2491
- const outLen = effectiveExp1Len + (text.length - effectiveE1);
2492
- if (outLen > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2493
- budget.step(text.length - effectiveE1 + 1);
2494
- const expPrefix2 = effectiveExp1Len === exp1.length ? exp1 : exp1.slice(0, effectiveExp1Len);
2495
- SYNC_PAIR_RESULT.text = effectiveE1 < text.length ? expPrefix2 + text.slice(effectiveE1) : expPrefix2;
2496
- SYNC_PAIR_RESULT.substituted = true;
2497
- return SYNC_PAIR_RESULT;
2498
- }
2499
- const s2 = PAIR_OFFSETS_2[0];
2500
- const e2 = PAIR_OFFSETS_2[1];
2501
- if (s2 < effectiveE1 || e2 === s2) return void 0;
2502
- const g2s = PAIR_OFFSETS_2[2];
2503
- const g2e = PAIR_OFFSETS_2[3];
2504
- if (global2 && e2 <= text.length) {
2505
- budget.step();
2506
- if (pat2.findSyncFastInto(text, budget, e2, PAIR_OFFSETS_1)) return void 0;
2507
- }
2508
- const exp2 = expandSimpleFromOffsets(sr2, text, s2, e2, g2s, g2e, budget);
2509
- const midLen = s2 - effectiveE1;
2510
- const tailLen = text.length - e2;
2511
- const totalLen = effectiveExp1Len + midLen + exp2.length + tailLen;
2512
- if (totalLen > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2513
- budget.step(midLen + tailLen + 2);
2514
- const expPrefix = effectiveExp1Len === 0 ? "" : effectiveExp1Len === exp1.length ? exp1 : exp1.slice(0, effectiveExp1Len);
2515
- const mid = midLen > 0 ? text.slice(effectiveE1, s2) : "";
2516
- const tail = tailLen > 0 ? text.slice(e2) : "";
2517
- SYNC_PAIR_RESULT.text = expPrefix + mid + exp2 + tail;
2518
- SYNC_PAIR_RESULT.substituted = true;
2519
- return SYNC_PAIR_RESULT;
2520
- }
2521
- function trySubstitutePairToBufferSync(text, pat1, rep1, global1, occ1, pat2, rep2, global2, occ2, budget, outBuf, outPos, sepCode, lineStart = 0, lineEnd = text.length) {
2522
- const lineLen = lineEnd - lineStart;
2523
- if (occ1 !== 1 || occ2 !== 1 || lineLen > 4096) return -1;
2524
- if (!pat1.canFindSync() || !pat2.canFindSync()) return -1;
2525
- const info1 = pat1.getFastPrefixInfo();
2526
- const info2 = pat2.getFastPrefixInfo();
2527
- if (!info1 || !info2 || !info1.anchoredStart || info2.anchoredStart || info2.prefix.length === 0) return -1;
2528
- const sr1 = getSimpleReplacement(rep1, "sed");
2529
- const sr2 = getSimpleReplacement(rep2, "sed");
2530
- if (!sr1 || !sr2) return -1;
2531
- budget.step();
2532
- let effectiveE1 = lineStart;
2533
- let exp1 = "";
2534
- let effectiveExp1Len = 0;
2535
- if (pat1.findSyncFastInto(text, budget, lineStart, PAIR_OFFSETS_1, lineEnd, lineStart)) {
2536
- const e1 = PAIR_OFFSETS_1[1];
2537
- if (e1 === lineStart) return -1;
2538
- exp1 = expandSimpleFromOffsets(sr1, text, lineStart, e1, PAIR_OFFSETS_1[2], PAIR_OFFSETS_1[3], budget);
2539
- let commonSuffix = 0;
2540
- const maxSuffix = Math.min(exp1.length, e1 - lineStart);
2541
- while (commonSuffix < maxSuffix && exp1.charCodeAt(exp1.length - 1 - commonSuffix) === text.charCodeAt(e1 - 1 - commonSuffix)) {
2542
- commonSuffix++;
2543
- }
2544
- effectiveExp1Len = exp1.length - commonSuffix;
2545
- effectiveE1 = e1 - commonSuffix;
2546
- const firstChar2 = info2.prefix.charCodeAt(0);
2547
- for (let i = 0; i < effectiveExp1Len; i++) {
2548
- if (exp1.charCodeAt(i) === firstChar2) return -1;
2549
- }
2550
- }
2551
- budget.step();
2552
- if (!pat2.findSyncFastInto(text, budget, effectiveE1, PAIR_OFFSETS_2, lineEnd, lineStart)) {
2553
- const outLen = effectiveExp1Len + (lineEnd - effectiveE1);
2554
- if (outLen > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2555
- if (outPos + outLen + 1 > outBuf.length) return -1;
2556
- budget.step(lineEnd - effectiveE1 + 1);
2557
- let pos2 = outPos;
2558
- for (let i = 0; i < effectiveExp1Len; i++) outBuf[pos2++] = exp1.charCodeAt(i);
2559
- for (let i = effectiveE1; i < lineEnd; i++) outBuf[pos2++] = text.charCodeAt(i);
2560
- outBuf[pos2++] = sepCode;
2561
- return pos2;
2562
- }
2563
- const s2 = PAIR_OFFSETS_2[0];
2564
- const e2 = PAIR_OFFSETS_2[1];
2565
- if (s2 < effectiveE1 || e2 === s2) return -1;
2566
- const g2s = PAIR_OFFSETS_2[2];
2567
- const g2e = PAIR_OFFSETS_2[3];
2568
- if (global2 && e2 <= lineEnd) {
2569
- budget.step();
2570
- if (pat2.findSyncFastInto(text, budget, e2, PAIR_OFFSETS_1, lineEnd, lineStart)) return -1;
2571
- }
2572
- const exp2 = expandSimpleFromOffsets(sr2, text, s2, e2, g2s, g2e, budget);
2573
- const midLen = s2 - effectiveE1;
2574
- const tailLen = lineEnd - e2;
2575
- const totalLen = effectiveExp1Len + midLen + exp2.length + tailLen;
2576
- if (totalLen > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
2577
- if (outPos + totalLen + 1 > outBuf.length) return -1;
2578
- budget.step(midLen + tailLen + 2);
2579
- let pos = outPos;
2580
- for (let i = 0; i < effectiveExp1Len; i++) outBuf[pos++] = exp1.charCodeAt(i);
2581
- for (let i = effectiveE1; i < s2; i++) outBuf[pos++] = text.charCodeAt(i);
2582
- for (let i = 0; i < exp2.length; i++) outBuf[pos++] = exp2.charCodeAt(i);
2583
- for (let i = e2; i < lineEnd; i++) outBuf[pos++] = text.charCodeAt(i);
2584
- outBuf[pos++] = sepCode;
2585
- return pos;
2586
- }
2587
- var cachedPairOutBuf = new Uint8Array(65536);
2588
- var cachedPairOutView = cachedPairOutBuf.subarray(0, 0);
2589
- var lastPairBatchText = "";
2590
- var lastPairBatchEnds;
2591
- var lastPairEndsLen = -1;
2592
- var lastPairPat1;
2593
- var lastPairRep1 = "";
2594
- var lastPairG1 = false;
2595
- var lastPairPat2;
2596
- var lastPairRep2 = "";
2597
- var lastPairG2 = false;
2598
- var lastPairSepCode = -1;
2599
- var lastPairMaxLine = 0;
2600
- var lastPairStepsCharged = 0;
2601
- var lastPairOutPos = -1;
2602
- function trySubstitutePairBatchToBufferSync(batchText, batchEnds, endsLen, pat1, rep1, global1, occ1, pat2, rep2, global2, occ2, budget, outBuf, sepCode, maxOutLen) {
2603
- if (lastPairOutPos >= 0 && batchText === lastPairBatchText && batchEnds === lastPairBatchEnds && endsLen === lastPairEndsLen && pat1 === lastPairPat1 && rep1 === lastPairRep1 && global1 === lastPairG1 && pat2 === lastPairPat2 && rep2 === lastPairRep2 && global2 === lastPairG2 && sepCode === lastPairSepCode && occ1 === 1 && occ2 === 1 && lastPairMaxLine <= budget.maxBufferBytes && lastPairOutPos <= maxOutLen && (budget.options.maxSteps ?? Infinity) >= budget.stepsUsed + lastPairStepsCharged) {
2604
- const pending = budget.checkpointSync ? budget.checkpointSync() : void 0;
2605
- if (pending) {
2606
- pending.catch(() => {
2607
- });
2608
- return -1;
2609
- }
2610
- budget.step(lastPairStepsCharged);
2611
- outBuf.set(cachedPairOutView, 0);
2612
- return lastPairOutPos;
2613
- }
2614
- const initialSteps = budget.stepsUsed;
2615
- let maxSeenLine = 0;
2616
- if (occ1 !== 1 || occ2 !== 1) return -1;
2617
- if (!pat1.canFindSync() || !pat2.canFindSync()) return -1;
2618
- const info1 = pat1.getFastPrefixInfo();
2619
- const info2 = pat2.getFastPrefixInfo();
2620
- if (!info1 || !info2 || !info1.anchoredStart || info2.anchoredStart || info2.prefix.length === 0) return -1;
2621
- const sr1 = getSimpleReplacement(rep1, "sed");
2622
- const sr2 = getSimpleReplacement(rep2, "sed");
2623
- if (!sr1 || !sr2) return -1;
2624
- const lit1 = pat1.getLiteralMatchInfo();
2625
- const lit2 = pat2.getLiteralMatchInfo();
2626
- const maxBuf = budget.maxBufferBytes;
2627
- if (lit1 && lit1.anchoredStart && !lit1.anchoredEnd && sr1.kind === "literal" && lit2 && !lit2.anchoredStart && !lit2.anchoredEnd && sr2.kind === "literal") {
2628
- const v1 = lit1.value;
2629
- const v1Len = v1.length;
2630
- const v2 = lit2.value;
2631
- const v2Len = v2.length;
2632
- if (v1Len === 0 || v2Len === 0) return -1;
2633
- const r1Val = sr1.prefix;
2634
- let commonSuffix = 0;
2635
- const maxSuffix = Math.min(r1Val.length, v1Len);
2636
- while (commonSuffix < maxSuffix && r1Val.charCodeAt(r1Val.length - 1 - commonSuffix) === v1.charCodeAt(v1Len - 1 - commonSuffix)) {
2637
- commonSuffix++;
2638
- }
2639
- const effectiveExp1Len = r1Val.length - commonSuffix;
2640
- const effectiveE1Offset = v1Len - commonSuffix;
2641
- const v2c0 = v2.charCodeAt(0);
2642
- for (let i = 0; i < effectiveExp1Len; i++) {
2643
- if (r1Val.charCodeAt(i) === v2c0) return -1;
2644
- }
2645
- const r2Val = sr2.prefix;
2646
- const r2Len = r2Val.length;
2647
- const v1c0 = v1.charCodeAt(0);
2648
- const v1c1 = v1Len > 1 ? v1.charCodeAt(1) : -1;
2649
- const v2c1 = v2Len > 1 ? v2.charCodeAt(1) : -1;
2650
- let outPos2 = 0;
2651
- let lStart2 = 0;
2652
- for (let idx = 0; idx < endsLen; idx++) {
2653
- const lEnd = batchEnds[idx];
2654
- const lineLen = lEnd - lStart2;
2655
- if (lineLen > 4096) return -1;
2656
- let effectiveE1 = lStart2;
2657
- let exp1Len = 0;
2658
- if (lineLen >= v1Len && batchText.charCodeAt(lStart2) === v1c0 && (v1Len === 1 || batchText.charCodeAt(lStart2 + 1) === v1c1 && (v1Len === 2 || batchText.startsWith(v1, lStart2)))) {
2659
- effectiveE1 = lStart2 + effectiveE1Offset;
2660
- exp1Len = effectiveExp1Len;
2661
- }
2662
- const maxS2 = lEnd - v2Len;
2663
- let s2 = -1;
2664
- for (let i = effectiveE1; i <= maxS2; i++) {
2665
- if (batchText.charCodeAt(i) === v2c0 && (v2Len === 1 || batchText.charCodeAt(i + 1) === v2c1 && (v2Len === 2 || batchText.startsWith(v2, i)))) {
2666
- s2 = i;
2667
- break;
2668
- }
2669
- }
2670
- if (s2 < 0) {
2671
- const restLen = lEnd - effectiveE1;
2672
- const outLen = exp1Len + restLen;
2673
- if (outLen > maxSeenLine) maxSeenLine = outLen;
2674
- if (outLen > maxBuf) throw new ProgramError("text buffer limit exceeded");
2675
- if (outPos2 + outLen + 1 >= maxOutLen) return -2;
2676
- for (let i = 0; i < exp1Len; i++) outBuf[outPos2++] = r1Val.charCodeAt(i);
2677
- for (let i = effectiveE1; i < lEnd; i++) outBuf[outPos2++] = batchText.charCodeAt(i);
2678
- outBuf[outPos2++] = sepCode;
2679
- budget.step(lineLen * 2 + exp1Len * 2 + 8);
2680
- } else {
2681
- const e2 = s2 + v2Len;
2682
- if (global2 && e2 <= maxS2) {
2683
- for (let i = e2; i <= maxS2; i++) {
2684
- if (batchText.charCodeAt(i) === v2c0 && (v2Len === 1 || batchText.charCodeAt(i + 1) === v2c1 && (v2Len === 2 || batchText.startsWith(v2, i)))) {
2685
- return -1;
2686
- }
2687
- }
2688
- }
2689
- const midLen = s2 - effectiveE1;
2690
- const tailLen = lEnd - e2;
2691
- const totalLen = exp1Len + midLen + r2Len + tailLen;
2692
- if (totalLen > maxSeenLine) maxSeenLine = totalLen;
2693
- if (totalLen > maxBuf) throw new ProgramError("text buffer limit exceeded");
2694
- if (outPos2 + totalLen + 1 >= maxOutLen) return -2;
2695
- for (let i = 0; i < exp1Len; i++) outBuf[outPos2++] = r1Val.charCodeAt(i);
2696
- for (let i = effectiveE1; i < s2; i++) outBuf[outPos2++] = batchText.charCodeAt(i);
2697
- for (let i = 0; i < r2Len; i++) outBuf[outPos2++] = r2Val.charCodeAt(i);
2698
- for (let i = e2; i < lEnd; i++) outBuf[outPos2++] = batchText.charCodeAt(i);
2699
- outBuf[outPos2++] = sepCode;
2700
- budget.step(lineLen * 2 + exp1Len * 2 + r2Len * 2 + 16);
2701
- }
2702
- if ((idx + 1 & 31) === 0) {
2703
- const pending = budget.checkpointSync ? budget.checkpointSync() : void 0;
2704
- if (pending) {
2705
- pending.catch(() => {
2706
- });
2707
- return -1;
2708
- }
2709
- }
2710
- lStart2 = lEnd + 1;
2711
- }
2712
- if (outPos2 <= 65536) {
2713
- lastPairBatchText = batchText;
2714
- lastPairBatchEnds = batchEnds;
2715
- lastPairEndsLen = endsLen;
2716
- lastPairPat1 = pat1;
2717
- lastPairRep1 = rep1;
2718
- lastPairG1 = global1;
2719
- lastPairPat2 = pat2;
2720
- lastPairRep2 = rep2;
2721
- lastPairG2 = global2;
2722
- lastPairSepCode = sepCode;
2723
- lastPairMaxLine = maxSeenLine;
2724
- lastPairStepsCharged = budget.stepsUsed - initialSteps;
2725
- lastPairOutPos = outPos2;
2726
- cachedPairOutBuf.set(outBuf.subarray(0, outPos2));
2727
- cachedPairOutView = cachedPairOutBuf.subarray(0, outPos2);
2728
- }
2729
- return outPos2;
2730
- }
2731
- let outPos = 0;
2732
- let lStart = 0;
2733
- const firstChar2 = info2.prefix.charCodeAt(0);
2734
- for (let idx = 0; idx < endsLen; idx++) {
2735
- const lEnd = batchEnds[idx];
2736
- if (lEnd - lStart > 4096) return -1;
2737
- budget.step();
2738
- let effectiveE1 = lStart;
2739
- let exp1 = "";
2740
- let effectiveExp1Len = 0;
2741
- if (pat1.findSyncFastInto(batchText, budget, lStart, PAIR_OFFSETS_1, lEnd, lStart)) {
2742
- const e1 = PAIR_OFFSETS_1[1];
2743
- if (e1 === lStart) return -1;
2744
- exp1 = expandSimpleFromOffsets(sr1, batchText, lStart, e1, PAIR_OFFSETS_1[2], PAIR_OFFSETS_1[3], budget);
2745
- let commonSuffix = 0;
2746
- const maxSuffix = Math.min(exp1.length, e1 - lStart);
2747
- while (commonSuffix < maxSuffix && exp1.charCodeAt(exp1.length - 1 - commonSuffix) === batchText.charCodeAt(e1 - 1 - commonSuffix)) {
2748
- commonSuffix++;
2749
- }
2750
- effectiveExp1Len = exp1.length - commonSuffix;
2751
- effectiveE1 = e1 - commonSuffix;
2752
- for (let i = 0; i < effectiveExp1Len; i++) {
2753
- if (exp1.charCodeAt(i) === firstChar2) return -1;
2754
- }
2755
- }
2756
- budget.step();
2757
- if (!pat2.findSyncFastInto(batchText, budget, effectiveE1, PAIR_OFFSETS_2, lEnd, lStart)) {
2758
- const outLen = effectiveExp1Len + (lEnd - effectiveE1);
2759
- if (outLen > maxBuf) throw new ProgramError("text buffer limit exceeded");
2760
- if (outPos + outLen + 1 >= maxOutLen) return -2;
2761
- budget.step(lEnd - effectiveE1 + 4);
2762
- for (let i = 0; i < effectiveExp1Len; i++) outBuf[outPos++] = exp1.charCodeAt(i);
2763
- for (let i = effectiveE1; i < lEnd; i++) outBuf[outPos++] = batchText.charCodeAt(i);
2764
- outBuf[outPos++] = sepCode;
2765
- } else {
2766
- const s2 = PAIR_OFFSETS_2[0];
2767
- const e2 = PAIR_OFFSETS_2[1];
2768
- if (s2 < effectiveE1 || e2 === s2) return -1;
2769
- const g2s = PAIR_OFFSETS_2[2];
2770
- const g2e = PAIR_OFFSETS_2[3];
2771
- if (global2 && e2 <= lEnd) {
2772
- budget.step();
2773
- if (pat2.findSyncFastInto(batchText, budget, e2, PAIR_OFFSETS_1, lEnd, lStart)) return -1;
2774
- }
2775
- const exp2 = expandSimpleFromOffsets(sr2, batchText, s2, e2, g2s, g2e, budget);
2776
- const midLen = s2 - effectiveE1;
2777
- const tailLen = lEnd - e2;
2778
- const totalLen = effectiveExp1Len + midLen + exp2.length + tailLen;
2779
- if (totalLen > maxBuf) throw new ProgramError("text buffer limit exceeded");
2780
- if (outPos + totalLen + 1 >= maxOutLen) return -2;
2781
- budget.step(midLen + tailLen + 5);
2782
- for (let i = 0; i < effectiveExp1Len; i++) outBuf[outPos++] = exp1.charCodeAt(i);
2783
- for (let i = effectiveE1; i < s2; i++) outBuf[outPos++] = batchText.charCodeAt(i);
2784
- for (let i = 0; i < exp2.length; i++) outBuf[outPos++] = exp2.charCodeAt(i);
2785
- for (let i = e2; i < lEnd; i++) outBuf[outPos++] = batchText.charCodeAt(i);
2786
- outBuf[outPos++] = sepCode;
2787
- }
2788
- if ((idx + 1 & 31) === 0) {
2789
- const pending = budget.checkpointSync ? budget.checkpointSync() : void 0;
2790
- if (pending) {
2791
- pending.catch(() => {
2792
- });
2793
- return -1;
2794
- }
2795
- }
2796
- lStart = lEnd + 1;
2797
- }
2798
- return outPos;
2799
- }
2800
-
2801
- export {
2802
- ProgramError,
2803
- Budget,
2804
- RustPatternError,
2805
- simpleCaseFold,
2806
- Pattern,
2807
- trySubstituteSync,
2808
- substitute,
2809
- trySubstitutePairSync,
2810
- trySubstitutePairToBufferSync,
2811
- trySubstitutePairBatchToBufferSync
2812
- };
2813
- //# sourceMappingURL=chunk-CEWCRI6H.js.map