@patterkit/cli 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +1038 -401
  2. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -12,11 +12,20 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
12
12
  if (typeof require !== "undefined") return require.apply(this, arguments);
13
13
  throw Error('Dynamic require of "' + x + '" is not supported');
14
14
  });
15
- var __esm = (fn, res) => function __init() {
16
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
+ var __esm = (fn, res, err) => function __init() {
16
+ if (err) throw err[0];
17
+ try {
18
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
19
+ } catch (e) {
20
+ throw err = [e], e;
21
+ }
17
22
  };
18
23
  var __commonJS = (cb, mod) => function __require3() {
19
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
24
+ try {
25
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
26
+ } catch (e) {
27
+ throw mod = 0, e;
28
+ }
20
29
  };
21
30
  var __export = (target, all) => {
22
31
  for (var name in all)
@@ -3600,7 +3609,7 @@ var require_worksheet = __commonJS({
3600
3609
  // =========================================================================
3601
3610
  // Worksheet Protection
3602
3611
  protect(password, options) {
3603
- return new Promise((resolve5) => {
3612
+ return new Promise((resolve6) => {
3604
3613
  this.sheetProtection = {
3605
3614
  sheet: true
3606
3615
  };
@@ -3624,7 +3633,7 @@ var require_worksheet = __commonJS({
3624
3633
  delete this.sheetProtection.spinCount;
3625
3634
  }
3626
3635
  }
3627
- resolve5();
3636
+ resolve6();
3628
3637
  });
3629
3638
  }
3630
3639
  unprotect() {
@@ -6321,8 +6330,8 @@ var require_lib2 = __commonJS({
6321
6330
  return this;
6322
6331
  }
6323
6332
  var p = this.constructor;
6324
- return this.then(resolve6, reject3);
6325
- function resolve6(value) {
6333
+ return this.then(resolve7, reject3);
6334
+ function resolve7(value) {
6326
6335
  function yes() {
6327
6336
  return value;
6328
6337
  }
@@ -6475,8 +6484,8 @@ var require_lib2 = __commonJS({
6475
6484
  }
6476
6485
  return out;
6477
6486
  }
6478
- Promise2.resolve = resolve5;
6479
- function resolve5(value) {
6487
+ Promise2.resolve = resolve6;
6488
+ function resolve6(value) {
6480
6489
  if (value instanceof this) {
6481
6490
  return value;
6482
6491
  }
@@ -7008,10 +7017,10 @@ var require_utils = __commonJS({
7008
7017
  var promise = external.Promise.resolve(inputData).then(function(data) {
7009
7018
  var isBlob = support.blob && (data instanceof Blob || ["[object File]", "[object Blob]"].indexOf(Object.prototype.toString.call(data)) !== -1);
7010
7019
  if (isBlob && typeof FileReader !== "undefined") {
7011
- return new external.Promise(function(resolve5, reject2) {
7020
+ return new external.Promise(function(resolve6, reject2) {
7012
7021
  var reader = new FileReader();
7013
7022
  reader.onload = function(e) {
7014
- resolve5(e.target.result);
7023
+ resolve6(e.target.result);
7015
7024
  };
7016
7025
  reader.onerror = function(e) {
7017
7026
  reject2(e.target.error);
@@ -7566,7 +7575,7 @@ var require_StreamHelper = __commonJS({
7566
7575
  }
7567
7576
  }
7568
7577
  function accumulate(helper, updateCallback) {
7569
- return new external.Promise(function(resolve5, reject2) {
7578
+ return new external.Promise(function(resolve6, reject2) {
7570
7579
  var dataArray = [];
7571
7580
  var chunkType = helper._internalType, resultType = helper._outputType, mimeType = helper._mimeType;
7572
7581
  helper.on("data", function(data, meta) {
@@ -7580,7 +7589,7 @@ var require_StreamHelper = __commonJS({
7580
7589
  }).on("end", function() {
7581
7590
  try {
7582
7591
  var result = transformZipOutput(resultType, concat2(chunkType, dataArray), mimeType);
7583
- resolve5(result);
7592
+ resolve6(result);
7584
7593
  } catch (e) {
7585
7594
  reject2(e);
7586
7595
  }
@@ -13693,7 +13702,7 @@ var require_load = __commonJS({
13693
13702
  var Crc32Probe = require_Crc32Probe();
13694
13703
  var nodejsUtils = require_nodejsUtils();
13695
13704
  function checkEntryCRC32(zipEntry) {
13696
- return new external.Promise(function(resolve5, reject2) {
13705
+ return new external.Promise(function(resolve6, reject2) {
13697
13706
  var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());
13698
13707
  worker.on("error", function(e) {
13699
13708
  reject2(e);
@@ -13701,7 +13710,7 @@ var require_load = __commonJS({
13701
13710
  if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {
13702
13711
  reject2(new Error("Corrupted zip : CRC32 mismatch"));
13703
13712
  } else {
13704
- resolve5();
13713
+ resolve6();
13705
13714
  }
13706
13715
  }).resume();
13707
13716
  });
@@ -14958,14 +14967,14 @@ var require_async_iterator = __commonJS({
14958
14967
  };
14959
14968
  }
14960
14969
  function readAndResolve(iter) {
14961
- var resolve5 = iter[kLastResolve];
14962
- if (resolve5 !== null) {
14970
+ var resolve6 = iter[kLastResolve];
14971
+ if (resolve6 !== null) {
14963
14972
  var data = iter[kStream].read();
14964
14973
  if (data !== null) {
14965
14974
  iter[kLastPromise] = null;
14966
14975
  iter[kLastResolve] = null;
14967
14976
  iter[kLastReject] = null;
14968
- resolve5(createIterResult(data, false));
14977
+ resolve6(createIterResult(data, false));
14969
14978
  }
14970
14979
  }
14971
14980
  }
@@ -14973,13 +14982,13 @@ var require_async_iterator = __commonJS({
14973
14982
  process.nextTick(readAndResolve, iter);
14974
14983
  }
14975
14984
  function wrapForNext(lastPromise, iter) {
14976
- return function(resolve5, reject2) {
14985
+ return function(resolve6, reject2) {
14977
14986
  lastPromise.then(function() {
14978
14987
  if (iter[kEnded]) {
14979
- resolve5(createIterResult(void 0, true));
14988
+ resolve6(createIterResult(void 0, true));
14980
14989
  return;
14981
14990
  }
14982
- iter[kHandlePromise](resolve5, reject2);
14991
+ iter[kHandlePromise](resolve6, reject2);
14983
14992
  }, reject2);
14984
14993
  };
14985
14994
  }
@@ -14999,12 +15008,12 @@ var require_async_iterator = __commonJS({
14999
15008
  return Promise.resolve(createIterResult(void 0, true));
15000
15009
  }
15001
15010
  if (this[kStream].destroyed) {
15002
- return new Promise(function(resolve5, reject2) {
15011
+ return new Promise(function(resolve6, reject2) {
15003
15012
  process.nextTick(function() {
15004
15013
  if (_this[kError]) {
15005
15014
  reject2(_this[kError]);
15006
15015
  } else {
15007
- resolve5(createIterResult(void 0, true));
15016
+ resolve6(createIterResult(void 0, true));
15008
15017
  }
15009
15018
  });
15010
15019
  });
@@ -15027,13 +15036,13 @@ var require_async_iterator = __commonJS({
15027
15036
  return this;
15028
15037
  }), _defineProperty2(_Object$setPrototypeO, "return", function _return() {
15029
15038
  var _this2 = this;
15030
- return new Promise(function(resolve5, reject2) {
15039
+ return new Promise(function(resolve6, reject2) {
15031
15040
  _this2[kStream].destroy(null, function(err) {
15032
15041
  if (err) {
15033
15042
  reject2(err);
15034
15043
  return;
15035
15044
  }
15036
- resolve5(createIterResult(void 0, true));
15045
+ resolve6(createIterResult(void 0, true));
15037
15046
  });
15038
15047
  });
15039
15048
  }), _Object$setPrototypeO), AsyncIteratorPrototype);
@@ -15055,15 +15064,15 @@ var require_async_iterator = __commonJS({
15055
15064
  value: stream2._readableState.endEmitted,
15056
15065
  writable: true
15057
15066
  }), _defineProperty2(_Object$create, kHandlePromise, {
15058
- value: function value(resolve5, reject2) {
15067
+ value: function value(resolve6, reject2) {
15059
15068
  var data = iterator[kStream].read();
15060
15069
  if (data) {
15061
15070
  iterator[kLastPromise] = null;
15062
15071
  iterator[kLastResolve] = null;
15063
15072
  iterator[kLastReject] = null;
15064
- resolve5(createIterResult(data, false));
15073
+ resolve6(createIterResult(data, false));
15065
15074
  } else {
15066
- iterator[kLastResolve] = resolve5;
15075
+ iterator[kLastResolve] = resolve6;
15067
15076
  iterator[kLastReject] = reject2;
15068
15077
  }
15069
15078
  },
@@ -15082,12 +15091,12 @@ var require_async_iterator = __commonJS({
15082
15091
  iterator[kError] = err;
15083
15092
  return;
15084
15093
  }
15085
- var resolve5 = iterator[kLastResolve];
15086
- if (resolve5 !== null) {
15094
+ var resolve6 = iterator[kLastResolve];
15095
+ if (resolve6 !== null) {
15087
15096
  iterator[kLastPromise] = null;
15088
15097
  iterator[kLastResolve] = null;
15089
15098
  iterator[kLastReject] = null;
15090
- resolve5(createIterResult(void 0, true));
15099
+ resolve6(createIterResult(void 0, true));
15091
15100
  }
15092
15101
  iterator[kEnded] = true;
15093
15102
  });
@@ -15102,7 +15111,7 @@ var require_async_iterator = __commonJS({
15102
15111
  var require_from = __commonJS({
15103
15112
  "../../node_modules/readable-stream/lib/internal/streams/from.js"(exports2, module2) {
15104
15113
  "use strict";
15105
- function asyncGeneratorStep2(gen, resolve5, reject2, _next, _throw, key2, arg) {
15114
+ function asyncGeneratorStep2(gen, resolve6, reject2, _next, _throw, key2, arg) {
15106
15115
  try {
15107
15116
  var info = gen[key2](arg);
15108
15117
  var value = info.value;
@@ -15111,7 +15120,7 @@ var require_from = __commonJS({
15111
15120
  return;
15112
15121
  }
15113
15122
  if (info.done) {
15114
- resolve5(value);
15123
+ resolve6(value);
15115
15124
  } else {
15116
15125
  Promise.resolve(value).then(_next, _throw);
15117
15126
  }
@@ -15119,13 +15128,13 @@ var require_from = __commonJS({
15119
15128
  function _asyncToGenerator2(fn) {
15120
15129
  return function() {
15121
15130
  var self2 = this, args = arguments;
15122
- return new Promise(function(resolve5, reject2) {
15131
+ return new Promise(function(resolve6, reject2) {
15123
15132
  var gen = fn.apply(self2, args);
15124
15133
  function _next(value) {
15125
- asyncGeneratorStep2(gen, resolve5, reject2, _next, _throw, "next", value);
15134
+ asyncGeneratorStep2(gen, resolve6, reject2, _next, _throw, "next", value);
15126
15135
  }
15127
15136
  function _throw(err) {
15128
- asyncGeneratorStep2(gen, resolve5, reject2, _next, _throw, "throw", err);
15137
+ asyncGeneratorStep2(gen, resolve6, reject2, _next, _throw, "throw", err);
15129
15138
  }
15130
15139
  _next(void 0);
15131
15140
  });
@@ -16214,14 +16223,14 @@ var require_utils2 = __commonJS({
16214
16223
  nop() {
16215
16224
  },
16216
16225
  promiseImmediate(value) {
16217
- return new Promise((resolve5) => {
16226
+ return new Promise((resolve6) => {
16218
16227
  if (global.setImmediate) {
16219
16228
  setImmediate(() => {
16220
- resolve5(value);
16229
+ resolve6(value);
16221
16230
  });
16222
16231
  } else {
16223
16232
  setTimeout(() => {
16224
- resolve5(value);
16233
+ resolve6(value);
16225
16234
  }, 1);
16226
16235
  }
16227
16236
  });
@@ -16321,9 +16330,9 @@ var require_utils2 = __commonJS({
16321
16330
  },
16322
16331
  fs: {
16323
16332
  exists(path) {
16324
- return new Promise((resolve5) => {
16333
+ return new Promise((resolve6) => {
16325
16334
  fs4.access(path, fs4.constants.F_OK, (err) => {
16326
- resolve5(!err);
16335
+ resolve6(!err);
16327
16336
  });
16328
16337
  });
16329
16338
  }
@@ -16548,9 +16557,9 @@ var require_stream_buf = __commonJS({
16548
16557
  },
16549
16558
  async _pipe(chunk) {
16550
16559
  const write2 = function(pipe) {
16551
- return new Promise((resolve5) => {
16560
+ return new Promise((resolve6) => {
16552
16561
  pipe.write(chunk.toBuffer(), () => {
16553
- resolve5();
16562
+ resolve6();
16554
16563
  });
16555
16564
  });
16556
16565
  };
@@ -28560,12 +28569,12 @@ var require_xlsx = __commonJS({
28560
28569
  var VmlNotesXform = require_vml_notes_xform();
28561
28570
  var theme1Xml = require_theme1();
28562
28571
  function fsReadFileAsync(filename, options) {
28563
- return new Promise((resolve5, reject2) => {
28572
+ return new Promise((resolve6, reject2) => {
28564
28573
  fs4.readFile(filename, options, (error, data) => {
28565
28574
  if (error) {
28566
28575
  reject2(error);
28567
28576
  } else {
28568
- resolve5(data);
28577
+ resolve6(data);
28569
28578
  }
28570
28579
  });
28571
28580
  });
@@ -28692,7 +28701,7 @@ var require_xlsx = __commonJS({
28692
28701
  if (lastDot >= 1) {
28693
28702
  const extension = filename.substr(lastDot + 1);
28694
28703
  const name = filename.substr(0, lastDot);
28695
- await new Promise((resolve5, reject2) => {
28704
+ await new Promise((resolve6, reject2) => {
28696
28705
  const streamBuf = new StreamBuf();
28697
28706
  streamBuf.on("finish", () => {
28698
28707
  model.mediaIndex[filename] = model.media.length;
@@ -28704,7 +28713,7 @@ var require_xlsx = __commonJS({
28704
28713
  buffer: streamBuf.toBuffer()
28705
28714
  };
28706
28715
  model.media.push(medium);
28707
- resolve5();
28716
+ resolve6();
28708
28717
  });
28709
28718
  entry.on("error", (error) => {
28710
28719
  reject2(error);
@@ -28729,13 +28738,13 @@ var require_xlsx = __commonJS({
28729
28738
  model.vmlDrawings[`../drawings/${name}.vml`] = vmlDrawing;
28730
28739
  }
28731
28740
  async _processThemeEntry(entry, model, name) {
28732
- await new Promise((resolve5, reject2) => {
28741
+ await new Promise((resolve6, reject2) => {
28733
28742
  const stream2 = new StreamBuf();
28734
28743
  entry.on("error", reject2);
28735
28744
  stream2.on("error", reject2);
28736
28745
  stream2.on("finish", () => {
28737
28746
  model.themes[name] = stream2.read().toString();
28738
- resolve5();
28747
+ resolve6();
28739
28748
  });
28740
28749
  entry.pipe(stream2);
28741
28750
  });
@@ -29043,9 +29052,9 @@ var require_xlsx = __commonJS({
29043
29052
  });
29044
29053
  }
29045
29054
  _finalize(zip) {
29046
- return new Promise((resolve5, reject2) => {
29055
+ return new Promise((resolve6, reject2) => {
29047
29056
  zip.on("finish", () => {
29048
- resolve5(this);
29057
+ resolve6(this);
29049
29058
  });
29050
29059
  zip.on("error", reject2);
29051
29060
  zip.finalize();
@@ -29105,9 +29114,9 @@ var require_xlsx = __commonJS({
29105
29114
  }
29106
29115
  writeFile(filename, options) {
29107
29116
  const stream2 = fs4.createWriteStream(filename);
29108
- return new Promise((resolve5, reject2) => {
29117
+ return new Promise((resolve6, reject2) => {
29109
29118
  stream2.on("finish", () => {
29110
- resolve5();
29119
+ resolve6();
29111
29120
  });
29112
29121
  stream2.on("error", (error) => {
29113
29122
  reject2(error);
@@ -33244,7 +33253,7 @@ var require_csv = __commonJS({
33244
33253
  }
33245
33254
  read(stream2, options) {
33246
33255
  options = options || {};
33247
- return new Promise((resolve5, reject2) => {
33256
+ return new Promise((resolve6, reject2) => {
33248
33257
  const worksheet = this.workbook.addWorksheet(options.sheetName);
33249
33258
  const dateFormats = options.dateFormats || [
33250
33259
  "YYYY-MM-DD[T]HH:mm:ssZ",
@@ -33284,7 +33293,7 @@ var require_csv = __commonJS({
33284
33293
  }).on("end", () => {
33285
33294
  csvStream.emit("worksheet", worksheet);
33286
33295
  });
33287
- csvStream.on("worksheet", resolve5).on("error", reject2);
33296
+ csvStream.on("worksheet", resolve6).on("error", reject2);
33288
33297
  stream2.pipe(csvStream);
33289
33298
  });
33290
33299
  }
@@ -33297,12 +33306,12 @@ var require_csv = __commonJS({
33297
33306
  );
33298
33307
  }
33299
33308
  write(stream2, options) {
33300
- return new Promise((resolve5, reject2) => {
33309
+ return new Promise((resolve6, reject2) => {
33301
33310
  options = options || {};
33302
33311
  const worksheet = this.workbook.getWorksheet(options.sheetName || options.sheetId);
33303
33312
  const csvStream = fastCsv.format(options.formatterOptions);
33304
33313
  stream2.on("finish", () => {
33305
- resolve5();
33314
+ resolve6();
33306
33315
  });
33307
33316
  csvStream.on("error", reject2);
33308
33317
  csvStream.pipe(stream2);
@@ -33651,6 +33660,8 @@ var require_brace_expansion = __commonJS({
33651
33660
  var escClose = "\0CLOSE" + Math.random() + "\0";
33652
33661
  var escComma = "\0COMMA" + Math.random() + "\0";
33653
33662
  var escPeriod = "\0PERIOD" + Math.random() + "\0";
33663
+ var EXPANSION_MAX = 1e5;
33664
+ var EXPANSION_MAX_LENGTH = 4e6;
33654
33665
  function numeric(str) {
33655
33666
  return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
33656
33667
  }
@@ -33684,11 +33695,12 @@ var require_brace_expansion = __commonJS({
33684
33695
  if (!str)
33685
33696
  return [];
33686
33697
  options = options || {};
33687
- var max = options.max == null ? Infinity : options.max;
33698
+ var max = options.max == null ? EXPANSION_MAX : options.max;
33699
+ var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH : options.maxLength;
33688
33700
  if (str.substr(0, 2) === "{}") {
33689
33701
  str = "\\{\\}" + str.substr(2);
33690
33702
  }
33691
- return expand(escapeBraces(str), max, true).map(unescapeBraces);
33703
+ return expand(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
33692
33704
  }
33693
33705
  function embrace(str) {
33694
33706
  return "{" + str + "}";
@@ -33702,18 +33714,90 @@ var require_brace_expansion = __commonJS({
33702
33714
  function gte(i, y) {
33703
33715
  return i >= y;
33704
33716
  }
33705
- function expand(str, max, isTop) {
33706
- var expansions = [];
33707
- var m = balanced("{", "}", str);
33708
- if (!m) return [str];
33709
- var pre = m.pre;
33710
- var post = m.post.length ? expand(m.post, max, false) : [""];
33711
- if (/\$$/.test(m.pre)) {
33712
- for (var k = 0; k < post.length && k < max; k++) {
33713
- var expansion = pre + "{" + m.body + "}" + post[k];
33714
- expansions.push(expansion);
33717
+ function combine(acc, pre, values, max, maxLength, dropEmpties) {
33718
+ var out = [];
33719
+ var length = 0;
33720
+ for (var a = 0; a < acc.length; a++) {
33721
+ for (var v = 0; v < values.length; v++) {
33722
+ if (out.length >= max) return out;
33723
+ var expansion = acc[a] + pre + values[v];
33724
+ if (dropEmpties && !expansion) continue;
33725
+ if (length + expansion.length > maxLength) return out;
33726
+ out.push(expansion);
33727
+ length += expansion.length;
33728
+ }
33729
+ }
33730
+ return out;
33731
+ }
33732
+ function expandSequence(body, isAlphaSequence, max, maxLength) {
33733
+ var n = body.split(/\.\./);
33734
+ var N = [];
33735
+ if (n[0] === void 0 || n[1] === void 0) {
33736
+ return N;
33737
+ }
33738
+ var x = numeric(n[0]);
33739
+ var y = numeric(n[1]);
33740
+ var width = Math.max(n[0].length, n[1].length);
33741
+ var incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
33742
+ var test = lte;
33743
+ var reverse = y < x;
33744
+ if (reverse) {
33745
+ incr *= -1;
33746
+ test = gte;
33747
+ }
33748
+ var pad2 = n.some(isPadded);
33749
+ var length = 0;
33750
+ for (var i = x; test(i, y) && N.length < max; i += incr) {
33751
+ var c2;
33752
+ if (isAlphaSequence) {
33753
+ c2 = String.fromCharCode(i);
33754
+ if (c2 === "\\") {
33755
+ c2 = "";
33756
+ }
33757
+ } else {
33758
+ c2 = String(i);
33759
+ if (pad2) {
33760
+ var need = width - c2.length;
33761
+ if (need > 0) {
33762
+ var z = new Array(need + 1).join("0");
33763
+ if (i < 0) {
33764
+ c2 = "-" + z + c2.slice(1);
33765
+ } else {
33766
+ c2 = z + c2;
33767
+ }
33768
+ }
33769
+ }
33770
+ }
33771
+ if (length + c2.length > maxLength) break;
33772
+ N.push(c2);
33773
+ length += c2.length;
33774
+ }
33775
+ return N;
33776
+ }
33777
+ function expand(str, max, maxLength, isTop) {
33778
+ var acc = [""];
33779
+ var dropEmpties = false;
33780
+ var firstGroup = true;
33781
+ for (; ; ) {
33782
+ const m = balanced("{", "}", str);
33783
+ if (!m) {
33784
+ return combine(acc, str, [""], max, maxLength, dropEmpties);
33785
+ }
33786
+ const pre = m.pre;
33787
+ if (/\$$/.test(pre)) {
33788
+ acc = combine(
33789
+ acc,
33790
+ pre + "{" + m.body + "}",
33791
+ [""],
33792
+ max,
33793
+ maxLength,
33794
+ dropEmpties && !m.post.length
33795
+ );
33796
+ firstGroup = false;
33797
+ if (!m.post.length) break;
33798
+ str = m.post;
33799
+ continue;
33715
33800
  }
33716
- } else {
33717
33801
  var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
33718
33802
  var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
33719
33803
  var isSequence = isNumericSequence || isAlphaSequence;
@@ -33721,74 +33805,69 @@ var require_brace_expansion = __commonJS({
33721
33805
  if (!isSequence && !isOptions) {
33722
33806
  if (m.post.match(/,(?!,).*\}/)) {
33723
33807
  str = m.pre + "{" + m.body + escClose + m.post;
33724
- return expand(str, max, true);
33808
+ isTop = true;
33809
+ continue;
33725
33810
  }
33726
- return [str];
33811
+ return combine(
33812
+ acc,
33813
+ pre + "{" + m.body + "}" + m.post,
33814
+ [""],
33815
+ max,
33816
+ maxLength,
33817
+ dropEmpties
33818
+ );
33819
+ }
33820
+ if (firstGroup) {
33821
+ dropEmpties = isTop && !isSequence;
33822
+ firstGroup = false;
33727
33823
  }
33728
- var n;
33824
+ var values;
33729
33825
  if (isSequence) {
33730
- n = m.body.split(/\.\./);
33826
+ values = expandSequence(m.body, isAlphaSequence, max, maxLength);
33731
33827
  } else {
33732
- n = parseCommaParts(m.body);
33733
- if (n.length === 1) {
33734
- n = expand(n[0], max, false).map(embrace);
33828
+ var n = parseCommaParts(m.body);
33829
+ if (n.length === 1 && n[0] !== void 0) {
33830
+ n = expand(n[0], max, maxLength, false).map(embrace);
33735
33831
  if (n.length === 1) {
33736
- return post.map(function(p) {
33737
- return m.pre + n[0] + p;
33738
- });
33832
+ acc = combine(
33833
+ acc,
33834
+ pre + n[0],
33835
+ [""],
33836
+ max,
33837
+ maxLength,
33838
+ dropEmpties && !m.post.length
33839
+ );
33840
+ if (!m.post.length) break;
33841
+ str = m.post;
33842
+ continue;
33739
33843
  }
33740
33844
  }
33741
- }
33742
- var N;
33743
- if (isSequence) {
33744
- var x = numeric(n[0]);
33745
- var y = numeric(n[1]);
33746
- var width = Math.max(n[0].length, n[1].length);
33747
- var incr = n.length == 3 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
33748
- var test = lte;
33749
- var reverse = y < x;
33750
- if (reverse) {
33751
- incr *= -1;
33752
- test = gte;
33753
- }
33754
- var pad2 = n.some(isPadded);
33755
- N = [];
33756
- for (var i = x; test(i, y) && N.length < max; i += incr) {
33757
- var c2;
33758
- if (isAlphaSequence) {
33759
- c2 = String.fromCharCode(i);
33760
- if (c2 === "\\")
33761
- c2 = "";
33762
- } else {
33763
- c2 = String(i);
33764
- if (pad2) {
33765
- var need = width - c2.length;
33766
- if (need > 0) {
33767
- var z = new Array(need + 1).join("0");
33768
- if (i < 0)
33769
- c2 = "-" + z + c2.slice(1);
33770
- else
33771
- c2 = z + c2;
33772
- }
33773
- }
33845
+ var dropsEmpties = dropEmpties && !m.post.length && !pre;
33846
+ for (var d = 0; dropsEmpties && d < acc.length; d++) {
33847
+ if (acc[d]) {
33848
+ dropsEmpties = false;
33774
33849
  }
33775
- N.push(c2);
33776
- }
33777
- } else {
33778
- N = [];
33779
- for (var j = 0; j < n.length; j++) {
33780
- N.push.apply(N, expand(n[j], max, false));
33781
33850
  }
33782
- }
33783
- for (var j = 0; j < N.length; j++) {
33784
- for (var k = 0; k < post.length && expansions.length < max; k++) {
33785
- var expansion = pre + N[j] + post[k];
33786
- if (!isTop || isSequence || expansion)
33787
- expansions.push(expansion);
33851
+ values = [];
33852
+ var valuesLength = 0;
33853
+ outer: for (var j = 0; j < n.length; j++) {
33854
+ var expanded = expand(n[j], max, maxLength, false);
33855
+ for (var k = 0; k < expanded.length; k++) {
33856
+ var v = expanded[k];
33857
+ if (dropsEmpties && !v) continue;
33858
+ if (values.length >= max || valuesLength + v.length > maxLength) {
33859
+ break outer;
33860
+ }
33861
+ values.push(v);
33862
+ valuesLength += v.length;
33863
+ }
33788
33864
  }
33789
33865
  }
33866
+ acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
33867
+ if (!m.post.length) break;
33868
+ str = m.post;
33790
33869
  }
33791
- return expansions;
33870
+ return acc;
33792
33871
  }
33793
33872
  }
33794
33873
  });
@@ -34455,9 +34534,9 @@ var require_readdir_glob = __commonJS({
34455
34534
  var fs4 = __require("fs");
34456
34535
  var { EventEmitter } = __require("events");
34457
34536
  var { Minimatch } = require_minimatch();
34458
- var { resolve: resolve5 } = __require("path");
34537
+ var { resolve: resolve6 } = __require("path");
34459
34538
  function readdir(dir2, strict) {
34460
- return new Promise((resolve6, reject2) => {
34539
+ return new Promise((resolve7, reject2) => {
34461
34540
  fs4.readdir(dir2, { withFileTypes: true }, (err, files) => {
34462
34541
  if (err) {
34463
34542
  switch (err.code) {
@@ -34465,7 +34544,7 @@ var require_readdir_glob = __commonJS({
34465
34544
  if (strict) {
34466
34545
  reject2(err);
34467
34546
  } else {
34468
- resolve6([]);
34547
+ resolve7([]);
34469
34548
  }
34470
34549
  break;
34471
34550
  case "ENOTSUP":
@@ -34475,7 +34554,7 @@ var require_readdir_glob = __commonJS({
34475
34554
  case "ENAMETOOLONG":
34476
34555
  // Filename too long
34477
34556
  case "UNKNOWN":
34478
- resolve6([]);
34557
+ resolve7([]);
34479
34558
  break;
34480
34559
  case "ELOOP":
34481
34560
  // Too many levels of symbolic links
@@ -34484,30 +34563,30 @@ var require_readdir_glob = __commonJS({
34484
34563
  break;
34485
34564
  }
34486
34565
  } else {
34487
- resolve6(files);
34566
+ resolve7(files);
34488
34567
  }
34489
34568
  });
34490
34569
  });
34491
34570
  }
34492
34571
  function stat(file, followSymlinks) {
34493
- return new Promise((resolve6, reject2) => {
34572
+ return new Promise((resolve7, reject2) => {
34494
34573
  const statFunc = followSymlinks ? fs4.stat : fs4.lstat;
34495
34574
  statFunc(file, (err, stats) => {
34496
34575
  if (err) {
34497
34576
  switch (err.code) {
34498
34577
  case "ENOENT":
34499
34578
  if (followSymlinks) {
34500
- resolve6(stat(file, false));
34579
+ resolve7(stat(file, false));
34501
34580
  } else {
34502
- resolve6(null);
34581
+ resolve7(null);
34503
34582
  }
34504
34583
  break;
34505
34584
  default:
34506
- resolve6(null);
34585
+ resolve7(null);
34507
34586
  break;
34508
34587
  }
34509
34588
  } else {
34510
- resolve6(stats);
34589
+ resolve7(stats);
34511
34590
  }
34512
34591
  });
34513
34592
  });
@@ -34597,7 +34676,7 @@ var require_readdir_glob = __commonJS({
34597
34676
  (skip) => new Minimatch(skip, { dot: true })
34598
34677
  );
34599
34678
  }
34600
- this.iterator = explore(resolve5(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
34679
+ this.iterator = explore(resolve6(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
34601
34680
  this.paused = false;
34602
34681
  this.inactive = false;
34603
34682
  this.aborted = false;
@@ -34851,10 +34930,10 @@ function awaitify(asyncFn, arity) {
34851
34930
  if (typeof args[arity - 1] === "function") {
34852
34931
  return asyncFn.apply(this, args);
34853
34932
  }
34854
- return new Promise((resolve5, reject2) => {
34933
+ return new Promise((resolve6, reject2) => {
34855
34934
  args[arity - 1] = (err, ...cbArgs) => {
34856
34935
  if (err) return reject2(err);
34857
- resolve5(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
34936
+ resolve6(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
34858
34937
  };
34859
34938
  asyncFn.apply(this, args);
34860
34939
  });
@@ -35036,13 +35115,13 @@ function mapSeries(coll, iteratee, callback) {
35036
35115
  return _asyncMap(eachOfSeries$1, coll, iteratee, callback);
35037
35116
  }
35038
35117
  function promiseCallback() {
35039
- let resolve5, reject2;
35118
+ let resolve6, reject2;
35040
35119
  function callback(err, ...args) {
35041
35120
  if (err) return reject2(err);
35042
- resolve5(args.length > 1 ? args : args[0]);
35121
+ resolve6(args.length > 1 ? args : args[0]);
35043
35122
  }
35044
35123
  callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
35045
- resolve5 = res, reject2 = rej;
35124
+ resolve6 = res, reject2 = rej;
35046
35125
  });
35047
35126
  return callback;
35048
35127
  }
@@ -35315,8 +35394,8 @@ function queue$1(worker, concurrency, payload) {
35315
35394
  });
35316
35395
  }
35317
35396
  if (rejectOnError || !callback) {
35318
- return new Promise((resolve5, reject2) => {
35319
- res = resolve5;
35397
+ return new Promise((resolve6, reject2) => {
35398
+ res = resolve6;
35320
35399
  rej = reject2;
35321
35400
  });
35322
35401
  }
@@ -35355,10 +35434,10 @@ function queue$1(worker, concurrency, payload) {
35355
35434
  }
35356
35435
  const eventMethod = (name) => (handler) => {
35357
35436
  if (!handler) {
35358
- return new Promise((resolve5, reject2) => {
35437
+ return new Promise((resolve6, reject2) => {
35359
35438
  once2(name, (err, data) => {
35360
35439
  if (err) return reject2(err);
35361
- resolve5(data);
35440
+ resolve6(data);
35362
35441
  });
35363
35442
  });
35364
35443
  }
@@ -41797,6 +41876,8 @@ var require_brace_expansion2 = __commonJS({
41797
41876
  var escClose = "\0CLOSE" + Math.random() + "\0";
41798
41877
  var escComma = "\0COMMA" + Math.random() + "\0";
41799
41878
  var escPeriod = "\0PERIOD" + Math.random() + "\0";
41879
+ var EXPANSION_MAX = 1e5;
41880
+ var EXPANSION_MAX_LENGTH = 4e6;
41800
41881
  function numeric(str) {
41801
41882
  return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
41802
41883
  }
@@ -41830,11 +41911,12 @@ var require_brace_expansion2 = __commonJS({
41830
41911
  if (!str)
41831
41912
  return [];
41832
41913
  options = options || {};
41833
- var max = options.max == null ? Infinity : options.max;
41914
+ var max = options.max == null ? EXPANSION_MAX : options.max;
41915
+ var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH : options.maxLength;
41834
41916
  if (str.substr(0, 2) === "{}") {
41835
41917
  str = "\\{\\}" + str.substr(2);
41836
41918
  }
41837
- return expand(escapeBraces(str), max, true).map(unescapeBraces);
41919
+ return expand(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
41838
41920
  }
41839
41921
  function embrace(str) {
41840
41922
  return "{" + str + "}";
@@ -41848,86 +41930,175 @@ var require_brace_expansion2 = __commonJS({
41848
41930
  function gte(i, y) {
41849
41931
  return i >= y;
41850
41932
  }
41851
- function expand(str, max, isTop) {
41852
- var expansions = [];
41853
- var m = balanced("{", "}", str);
41854
- if (!m || /\$$/.test(m.pre)) return [str];
41855
- var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
41856
- var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
41857
- var isSequence = isNumericSequence || isAlphaSequence;
41858
- var isOptions = m.body.indexOf(",") >= 0;
41859
- if (!isSequence && !isOptions) {
41860
- if (m.post.match(/,(?!,).*\}/)) {
41861
- str = m.pre + "{" + m.body + escClose + m.post;
41862
- return expand(str, max, true);
41863
- }
41864
- return [str];
41865
- }
41866
- var n;
41867
- if (isSequence) {
41868
- n = m.body.split(/\.\./);
41869
- } else {
41870
- n = parseCommaParts(m.body);
41871
- if (n.length === 1) {
41872
- n = expand(n[0], max, false).map(embrace);
41873
- if (n.length === 1) {
41874
- var post = m.post.length ? expand(m.post, max, false) : [""];
41875
- return post.map(function(p) {
41876
- return m.pre + n[0] + p;
41877
- });
41878
- }
41933
+ function combine(acc, base, pre, values, max, maxLength, dropEmpties, outBase) {
41934
+ var out = [];
41935
+ var length = 0;
41936
+ for (var a = 0; a < acc.length; a++) {
41937
+ for (var v = 0; v < values.length; v++) {
41938
+ if (out.length >= max) return out;
41939
+ var expansion = acc[a] + pre + values[v];
41940
+ if (dropEmpties && expansion.length === base[a]) continue;
41941
+ if (length + expansion.length > maxLength) return out;
41942
+ out.push(expansion);
41943
+ outBase.push(base[a]);
41944
+ length += expansion.length;
41879
41945
  }
41880
41946
  }
41881
- var pre = m.pre;
41882
- var post = m.post.length ? expand(m.post, max, false) : [""];
41883
- var N;
41884
- if (isSequence) {
41885
- var x = numeric(n[0]);
41886
- var y = numeric(n[1]);
41887
- var width = Math.max(n[0].length, n[1].length);
41888
- var incr = n.length == 3 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
41889
- var test = lte;
41890
- var reverse = y < x;
41891
- if (reverse) {
41892
- incr *= -1;
41893
- test = gte;
41894
- }
41895
- var pad2 = n.some(isPadded);
41896
- N = [];
41897
- for (var i = x; test(i, y) && N.length < max; i += incr) {
41898
- var c2;
41899
- if (isAlphaSequence) {
41900
- c2 = String.fromCharCode(i);
41901
- if (c2 === "\\")
41902
- c2 = "";
41903
- } else {
41904
- c2 = String(i);
41905
- if (pad2) {
41906
- var need = width - c2.length;
41907
- if (need > 0) {
41908
- var z = new Array(need + 1).join("0");
41909
- if (i < 0)
41910
- c2 = "-" + z + c2.slice(1);
41911
- else
41912
- c2 = z + c2;
41947
+ return out;
41948
+ }
41949
+ function expandSequence(body, isAlphaSequence, max, maxLength) {
41950
+ var n = body.split(/\.\./);
41951
+ var N = [];
41952
+ if (n[0] === void 0 || n[1] === void 0) {
41953
+ return N;
41954
+ }
41955
+ var x = numeric(n[0]);
41956
+ var y = numeric(n[1]);
41957
+ var width = Math.max(n[0].length, n[1].length);
41958
+ var incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
41959
+ var test = lte;
41960
+ var reverse = y < x;
41961
+ if (reverse) {
41962
+ incr *= -1;
41963
+ test = gte;
41964
+ }
41965
+ var pad2 = n.some(isPadded);
41966
+ var length = 0;
41967
+ for (var i = x; test(i, y) && N.length < max; i += incr) {
41968
+ var c2;
41969
+ if (isAlphaSequence) {
41970
+ c2 = String.fromCharCode(i);
41971
+ if (c2 === "\\") {
41972
+ c2 = "";
41973
+ }
41974
+ } else {
41975
+ c2 = String(i);
41976
+ if (pad2) {
41977
+ var need = width - c2.length;
41978
+ if (need > 0) {
41979
+ var z = new Array(need + 1).join("0");
41980
+ if (i < 0) {
41981
+ c2 = "-" + z + c2.slice(1);
41982
+ } else {
41983
+ c2 = z + c2;
41913
41984
  }
41914
41985
  }
41915
41986
  }
41916
- N.push(c2);
41917
41987
  }
41918
- } else {
41919
- N = concatMap(n, function(el) {
41920
- return expand(el, max, false);
41921
- });
41988
+ if (length + c2.length > maxLength) break;
41989
+ N.push(c2);
41990
+ length += c2.length;
41922
41991
  }
41923
- for (var j = 0; j < N.length; j++) {
41924
- for (var k = 0; k < post.length && expansions.length < max; k++) {
41925
- var expansion = pre + N[j] + post[k];
41926
- if (!isTop || isSequence || expansion)
41927
- expansions.push(expansion);
41992
+ return N;
41993
+ }
41994
+ function expand(str, max, maxLength, isTop) {
41995
+ var acc = [""];
41996
+ var accBase = [0];
41997
+ var dropEmpties = false;
41998
+ var firstGroup = true;
41999
+ var nextBase;
42000
+ for (; ; ) {
42001
+ var m = balanced("{", "}", str);
42002
+ if (!m) {
42003
+ return combine(acc, accBase, str, [""], max, maxLength, dropEmpties, []);
42004
+ }
42005
+ var pre = m.pre;
42006
+ if (/\$$/.test(pre)) {
42007
+ return combine(acc, accBase, str, [""], max, maxLength, dropEmpties, []);
42008
+ }
42009
+ var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
42010
+ var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
42011
+ var isSequence = isNumericSequence || isAlphaSequence;
42012
+ var isOptions = m.body.indexOf(",") >= 0;
42013
+ if (!isSequence && !isOptions) {
42014
+ if (m.post.match(/,(?!,).*\}/)) {
42015
+ str = m.pre + "{" + m.body + escClose + m.post;
42016
+ isTop = true;
42017
+ firstGroup = true;
42018
+ dropEmpties = false;
42019
+ accBase = [];
42020
+ for (var b = 0; b < acc.length; b++) {
42021
+ accBase.push(acc[b].length);
42022
+ }
42023
+ continue;
42024
+ }
42025
+ return combine(
42026
+ acc,
42027
+ accBase,
42028
+ pre + "{" + m.body + "}" + m.post,
42029
+ [""],
42030
+ max,
42031
+ maxLength,
42032
+ dropEmpties,
42033
+ []
42034
+ );
41928
42035
  }
42036
+ if (firstGroup) {
42037
+ dropEmpties = isTop && !isSequence;
42038
+ firstGroup = false;
42039
+ }
42040
+ var values;
42041
+ if (isSequence) {
42042
+ values = expandSequence(m.body, isAlphaSequence, max, maxLength);
42043
+ } else {
42044
+ var n = parseCommaParts(m.body);
42045
+ if (n.length === 1 && n[0] !== void 0) {
42046
+ n = expand(n[0], max, maxLength, false).map(embrace);
42047
+ if (n.length === 1) {
42048
+ nextBase = [];
42049
+ acc = combine(
42050
+ acc,
42051
+ accBase,
42052
+ pre + n[0],
42053
+ [""],
42054
+ max,
42055
+ maxLength,
42056
+ dropEmpties && !m.post.length,
42057
+ nextBase
42058
+ );
42059
+ accBase = nextBase;
42060
+ if (!m.post.length) break;
42061
+ str = m.post;
42062
+ continue;
42063
+ }
42064
+ }
42065
+ var dropsEmpties = dropEmpties && !m.post.length && !pre;
42066
+ for (var d = 0; dropsEmpties && d < acc.length; d++) {
42067
+ if (acc[d].length !== accBase[d]) {
42068
+ dropsEmpties = false;
42069
+ }
42070
+ }
42071
+ values = [];
42072
+ var valuesLength = 0;
42073
+ outer: for (var j = 0; j < n.length; j++) {
42074
+ var expanded = expand(n[j], max, maxLength, false);
42075
+ for (var k = 0; k < expanded.length; k++) {
42076
+ var v = expanded[k];
42077
+ if (dropsEmpties && !v) continue;
42078
+ if (values.length >= max || valuesLength + v.length > maxLength) {
42079
+ break outer;
42080
+ }
42081
+ values.push(v);
42082
+ valuesLength += v.length;
42083
+ }
42084
+ }
42085
+ }
42086
+ nextBase = [];
42087
+ acc = combine(
42088
+ acc,
42089
+ accBase,
42090
+ pre,
42091
+ values,
42092
+ max,
42093
+ maxLength,
42094
+ dropEmpties && !m.post.length,
42095
+ nextBase
42096
+ );
42097
+ accBase = nextBase;
42098
+ if (!m.post.length) break;
42099
+ str = m.post;
41929
42100
  }
41930
- return expansions;
42101
+ return acc;
41931
42102
  }
41932
42103
  }
41933
42104
  });
@@ -44622,11 +44793,11 @@ var require_core = __commonJS({
44622
44793
  this._finalize();
44623
44794
  }
44624
44795
  var self2 = this;
44625
- return new Promise(function(resolve5, reject2) {
44796
+ return new Promise(function(resolve6, reject2) {
44626
44797
  var errored;
44627
44798
  self2._module.on("end", function() {
44628
44799
  if (!errored) {
44629
- resolve5();
44800
+ resolve6();
44630
44801
  }
44631
44802
  });
44632
44803
  self2._module.on("error", function(err) {
@@ -48397,7 +48568,7 @@ var require_worksheet_writer = __commonJS({
48397
48568
  // =========================================================================
48398
48569
  // Worksheet Protection
48399
48570
  protect(password, options) {
48400
- return new Promise((resolve5) => {
48571
+ return new Promise((resolve6) => {
48401
48572
  this.sheetProtection = {
48402
48573
  sheet: true
48403
48574
  };
@@ -48421,7 +48592,7 @@ var require_worksheet_writer = __commonJS({
48421
48592
  delete this.sheetProtection.spinCount;
48422
48593
  }
48423
48594
  }
48424
- resolve5();
48595
+ resolve6();
48425
48596
  });
48426
48597
  }
48427
48598
  unprotect() {
@@ -48640,9 +48811,9 @@ var require_workbook_writer = __commonJS({
48640
48811
  _commitWorksheets() {
48641
48812
  const commitWorksheet = function(worksheet) {
48642
48813
  if (!worksheet.committed) {
48643
- return new Promise((resolve5) => {
48814
+ return new Promise((resolve6) => {
48644
48815
  worksheet.stream.on("zipped", () => {
48645
- resolve5();
48816
+ resolve6();
48646
48817
  });
48647
48818
  worksheet.commit();
48648
48819
  });
@@ -48730,19 +48901,19 @@ var require_workbook_writer = __commonJS({
48730
48901
  return void 0;
48731
48902
  }
48732
48903
  addStyles() {
48733
- return new Promise((resolve5) => {
48904
+ return new Promise((resolve6) => {
48734
48905
  this.zip.append(this.styles.xml, { name: "xl/styles.xml" });
48735
- resolve5();
48906
+ resolve6();
48736
48907
  });
48737
48908
  }
48738
48909
  addThemes() {
48739
- return new Promise((resolve5) => {
48910
+ return new Promise((resolve6) => {
48740
48911
  this.zip.append(theme1Xml, { name: "xl/theme/theme1.xml" });
48741
- resolve5();
48912
+ resolve6();
48742
48913
  });
48743
48914
  }
48744
48915
  addOfficeRels() {
48745
- return new Promise((resolve5) => {
48916
+ return new Promise((resolve6) => {
48746
48917
  const xform = new RelationshipsXform();
48747
48918
  const xml = xform.toXml([
48748
48919
  { Id: "rId1", Type: RelType.OfficeDocument, Target: "xl/workbook.xml" },
@@ -48750,11 +48921,11 @@ var require_workbook_writer = __commonJS({
48750
48921
  { Id: "rId3", Type: RelType.ExtenderProperties, Target: "docProps/app.xml" }
48751
48922
  ]);
48752
48923
  this.zip.append(xml, { name: "/_rels/.rels" });
48753
- resolve5();
48924
+ resolve6();
48754
48925
  });
48755
48926
  }
48756
48927
  addContentTypes() {
48757
- return new Promise((resolve5) => {
48928
+ return new Promise((resolve6) => {
48758
48929
  const model = {
48759
48930
  worksheets: this._worksheets.filter(Boolean),
48760
48931
  sharedStrings: this.sharedStrings,
@@ -48764,7 +48935,7 @@ var require_workbook_writer = __commonJS({
48764
48935
  const xform = new ContentTypesXform();
48765
48936
  const xml = xform.toXml(model);
48766
48937
  this.zip.append(xml, { name: "[Content_Types].xml" });
48767
- resolve5();
48938
+ resolve6();
48768
48939
  });
48769
48940
  }
48770
48941
  addMedia() {
@@ -48789,31 +48960,31 @@ var require_workbook_writer = __commonJS({
48789
48960
  );
48790
48961
  }
48791
48962
  addApp() {
48792
- return new Promise((resolve5) => {
48963
+ return new Promise((resolve6) => {
48793
48964
  const model = {
48794
48965
  worksheets: this._worksheets.filter(Boolean)
48795
48966
  };
48796
48967
  const xform = new AppXform();
48797
48968
  const xml = xform.toXml(model);
48798
48969
  this.zip.append(xml, { name: "docProps/app.xml" });
48799
- resolve5();
48970
+ resolve6();
48800
48971
  });
48801
48972
  }
48802
48973
  addCore() {
48803
- return new Promise((resolve5) => {
48974
+ return new Promise((resolve6) => {
48804
48975
  const coreXform = new CoreXform();
48805
48976
  const xml = coreXform.toXml(this);
48806
48977
  this.zip.append(xml, { name: "docProps/core.xml" });
48807
- resolve5();
48978
+ resolve6();
48808
48979
  });
48809
48980
  }
48810
48981
  addSharedStrings() {
48811
48982
  if (this.sharedStrings.count) {
48812
- return new Promise((resolve5) => {
48983
+ return new Promise((resolve6) => {
48813
48984
  const sharedStringsXform = new SharedStringsXform();
48814
48985
  const xml = sharedStringsXform.toXml(this.sharedStrings);
48815
48986
  this.zip.append(xml, { name: "/xl/sharedStrings.xml" });
48816
- resolve5();
48987
+ resolve6();
48817
48988
  });
48818
48989
  }
48819
48990
  return Promise.resolve();
@@ -48841,11 +49012,11 @@ var require_workbook_writer = __commonJS({
48841
49012
  });
48842
49013
  }
48843
49014
  });
48844
- return new Promise((resolve5) => {
49015
+ return new Promise((resolve6) => {
48845
49016
  const xform = new RelationshipsXform();
48846
49017
  const xml = xform.toXml(relationships);
48847
49018
  this.zip.append(xml, { name: "/xl/_rels/workbook.xml.rels" });
48848
- resolve5();
49019
+ resolve6();
48849
49020
  });
48850
49021
  }
48851
49022
  addWorkbook() {
@@ -48857,18 +49028,18 @@ var require_workbook_writer = __commonJS({
48857
49028
  properties: {},
48858
49029
  calcProperties: {}
48859
49030
  };
48860
- return new Promise((resolve5) => {
49031
+ return new Promise((resolve6) => {
48861
49032
  const xform = new WorkbookXform();
48862
49033
  xform.prepare(model);
48863
49034
  zip.append(xform.toXml(model), { name: "/xl/workbook.xml" });
48864
- resolve5();
49035
+ resolve6();
48865
49036
  });
48866
49037
  }
48867
49038
  _finalize() {
48868
- return new Promise((resolve5, reject2) => {
49039
+ return new Promise((resolve6, reject2) => {
48869
49040
  this.stream.on("error", reject2);
48870
49041
  this.stream.on("finish", () => {
48871
- resolve5(this);
49042
+ resolve6(this);
48872
49043
  });
48873
49044
  this.zip.on("error", reject2);
48874
49045
  this.zip.finalize();
@@ -50802,13 +50973,13 @@ var require_thenables = __commonJS({
50802
50973
  promise._captureStackTrace();
50803
50974
  if (context) context._popContext();
50804
50975
  var synchronous = true;
50805
- var result = util2.tryCatch(then).call(x, resolve5, reject2);
50976
+ var result = util2.tryCatch(then).call(x, resolve6, reject2);
50806
50977
  synchronous = false;
50807
50978
  if (promise && result === errorObj2) {
50808
50979
  promise._rejectCallback(result.e, true, true);
50809
50980
  promise = null;
50810
50981
  }
50811
- function resolve5(value) {
50982
+ function resolve6(value) {
50812
50983
  if (!promise) return;
50813
50984
  promise._resolveCallback(value);
50814
50985
  promise = null;
@@ -51343,9 +51514,9 @@ var require_debuggability = __commonJS({
51343
51514
  return false;
51344
51515
  }
51345
51516
  Promise2.prototype._fireEvent = defaultFireEvent;
51346
- Promise2.prototype._execute = function(executor, resolve5, reject2) {
51517
+ Promise2.prototype._execute = function(executor, resolve6, reject2) {
51347
51518
  try {
51348
- executor(resolve5, reject2);
51519
+ executor(resolve6, reject2);
51349
51520
  } catch (e) {
51350
51521
  return e;
51351
51522
  }
@@ -51368,10 +51539,10 @@ var require_debuggability = __commonJS({
51368
51539
  ;
51369
51540
  ;
51370
51541
  };
51371
- function cancellationExecute(executor, resolve5, reject2) {
51542
+ function cancellationExecute(executor, resolve6, reject2) {
51372
51543
  var promise = this;
51373
51544
  try {
51374
- executor(resolve5, reject2, function(onCancel) {
51545
+ executor(resolve6, reject2, function(onCancel) {
51375
51546
  if (typeof onCancel !== "function") {
51376
51547
  throw new TypeError("onCancel must be a function, got: " + util2.toString(onCancel));
51377
51548
  }
@@ -56625,7 +56796,7 @@ var require_PullStream = __commonJS({
56625
56796
  };
56626
56797
  var rejectHandler;
56627
56798
  var pullStreamRejectHandler;
56628
- return new Promise2(function(resolve5, reject2) {
56799
+ return new Promise2(function(resolve6, reject2) {
56629
56800
  rejectHandler = reject2;
56630
56801
  pullStreamRejectHandler = function(e) {
56631
56802
  self2.__emittedError = e;
@@ -56635,7 +56806,7 @@ var require_PullStream = __commonJS({
56635
56806
  return reject2(new Error("FILE_ENDED"));
56636
56807
  self2.once("error", pullStreamRejectHandler);
56637
56808
  self2.stream(eof, includeEof).on("error", reject2).pipe(concatStream).on("finish", function() {
56638
- resolve5(buffer2);
56809
+ resolve6(buffer2);
56639
56810
  }).on("error", reject2);
56640
56811
  }).finally(function() {
56641
56812
  self2.removeListener("error", rejectHandler);
@@ -56680,10 +56851,10 @@ var require_BufferStream = __commonJS({
56680
56851
  if (!Stream.Writable || !Stream.Writable.prototype.destroy)
56681
56852
  Stream = require_readable5();
56682
56853
  module2.exports = function(entry) {
56683
- return new Promise2(function(resolve5, reject2) {
56854
+ return new Promise2(function(resolve6, reject2) {
56684
56855
  var chunks = [];
56685
56856
  var bufferStream = Stream.Transform().on("finish", function() {
56686
- resolve5(Buffer2.concat(chunks));
56857
+ resolve6(Buffer2.concat(chunks));
56687
56858
  }).on("error", reject2);
56688
56859
  bufferStream._transform = function(d, e, cb) {
56689
56860
  chunks.push(d);
@@ -56825,8 +56996,8 @@ var require_parse = __commonJS({
56825
56996
  __autodraining = true;
56826
56997
  var draining2 = entry.pipe(NoopStream());
56827
56998
  draining2.promise = function() {
56828
- return new Promise2(function(resolve5, reject2) {
56829
- draining2.on("finish", resolve5);
56999
+ return new Promise2(function(resolve6, reject2) {
57000
+ draining2.on("finish", resolve6);
56830
57001
  draining2.on("error", reject2);
56831
57002
  });
56832
57003
  };
@@ -56881,11 +57052,11 @@ var require_parse = __commonJS({
56881
57052
  eof = Buffer2.alloc(4);
56882
57053
  eof.writeUInt32LE(134695760, 0);
56883
57054
  }
56884
- return new Promise2(function(resolve5, reject2) {
57055
+ return new Promise2(function(resolve6, reject2) {
56885
57056
  self2.stream(eof).pipe(inflater).on("error", function(err) {
56886
57057
  self2.emit("error", err);
56887
57058
  }).pipe(entry).on("finish", function() {
56888
- return fileSizeKnown ? self2._readRecord().then(resolve5).catch(reject2) : self2._processDataDescriptor(entry).then(resolve5).catch(reject2);
57059
+ return fileSizeKnown ? self2._readRecord().then(resolve6).catch(reject2) : self2._processDataDescriptor(entry).then(resolve6).catch(reject2);
56889
57060
  });
56890
57061
  });
56891
57062
  });
@@ -56927,8 +57098,8 @@ var require_parse = __commonJS({
56927
57098
  };
56928
57099
  Parse.prototype.promise = function() {
56929
57100
  var self2 = this;
56930
- return new Promise2(function(resolve5, reject2) {
56931
- self2.on("finish", resolve5);
57101
+ return new Promise2(function(resolve6, reject2) {
57102
+ self2.on("finish", resolve6);
56932
57103
  self2.on("error", reject2);
56933
57104
  });
56934
57105
  };
@@ -60439,8 +60610,8 @@ var require_extract2 = __commonJS({
60439
60610
  extract.emit("close");
60440
60611
  });
60441
60612
  extract.promise = function() {
60442
- return new Promise2(function(resolve5, reject2) {
60443
- extract.on("close", resolve5);
60613
+ return new Promise2(function(resolve6, reject2) {
60614
+ extract.on("close", resolve6);
60444
60615
  extract.on("error", reject2);
60445
60616
  });
60446
60617
  };
@@ -61951,8 +62122,8 @@ var require_directory = __commonJS({
61951
62122
  return;
61952
62123
  }
61953
62124
  var writer = opts.getWriter ? opts.getWriter({ path: extractPath }) : Writer({ path: extractPath });
61954
- return new Promise2(function(resolve5, reject2) {
61955
- entry.stream(opts.password).on("error", reject2).pipe(writer).on("close", resolve5).on("error", reject2);
62125
+ return new Promise2(function(resolve6, reject2) {
62126
+ entry.stream(opts.password).on("error", reject2).pipe(writer).on("close", resolve6).on("error", reject2);
61956
62127
  });
61957
62128
  }, { concurrency: opts.concurrency > 1 ? opts.concurrency : 1 });
61958
62129
  });
@@ -62019,12 +62190,12 @@ var require_Open = __commonJS({
62019
62190
  return fs4.createReadStream(filename, { start: offset, end: length && offset + length });
62020
62191
  },
62021
62192
  size: function() {
62022
- return new Promise2(function(resolve5, reject2) {
62193
+ return new Promise2(function(resolve6, reject2) {
62023
62194
  fs4.stat(filename, function(err, d) {
62024
62195
  if (err)
62025
62196
  reject2(err);
62026
62197
  else
62027
- resolve5(d.size);
62198
+ resolve6(d.size);
62028
62199
  });
62029
62200
  });
62030
62201
  }
@@ -62045,14 +62216,14 @@ var require_Open = __commonJS({
62045
62216
  return request(options2);
62046
62217
  },
62047
62218
  size: function() {
62048
- return new Promise2(function(resolve5, reject2) {
62219
+ return new Promise2(function(resolve6, reject2) {
62049
62220
  var req = request(params);
62050
62221
  req.on("response", function(d) {
62051
62222
  req.abort();
62052
62223
  if (!d.headers["content-length"])
62053
62224
  reject2(new Error("Missing content length header"));
62054
62225
  else
62055
- resolve5(d.headers["content-length"]);
62226
+ resolve6(d.headers["content-length"]);
62056
62227
  }).on("error", reject2);
62057
62228
  });
62058
62229
  }
@@ -62062,12 +62233,12 @@ var require_Open = __commonJS({
62062
62233
  s3: function(client, params, options) {
62063
62234
  var source2 = {
62064
62235
  size: function() {
62065
- return new Promise2(function(resolve5, reject2) {
62236
+ return new Promise2(function(resolve6, reject2) {
62066
62237
  client.headObject(params, function(err, d) {
62067
62238
  if (err)
62068
62239
  reject2(err);
62069
62240
  else
62070
- resolve5(d.ContentLength);
62241
+ resolve6(d.ContentLength);
62071
62242
  });
62072
62243
  });
62073
62244
  },
@@ -62485,7 +62656,7 @@ var require_iterate_stream = __commonJS({
62485
62656
  const contents = [];
62486
62657
  stream2.on("data", (data) => contents.push(data));
62487
62658
  let resolveStreamEndedPromise;
62488
- const streamEndedPromise = new Promise((resolve5) => resolveStreamEndedPromise = resolve5);
62659
+ const streamEndedPromise = new Promise((resolve6) => resolveStreamEndedPromise = resolve6);
62489
62660
  let ended = false;
62490
62661
  stream2.on("end", () => {
62491
62662
  ended = true;
@@ -62510,13 +62681,13 @@ var require_iterate_stream = __commonJS({
62510
62681
  resolveStreamEndedPromise();
62511
62682
  };
62512
62683
  function once2(eventEmitter, type) {
62513
- return new Promise((resolve5) => {
62684
+ return new Promise((resolve6) => {
62514
62685
  let fired = false;
62515
62686
  const handler = () => {
62516
62687
  if (!fired) {
62517
62688
  fired = true;
62518
62689
  eventEmitter.removeListener(type, handler);
62519
- resolve5();
62690
+ resolve6();
62520
62691
  }
62521
62692
  };
62522
62693
  eventEmitter.addListener(type, handler);
@@ -63043,7 +63214,7 @@ var require_workbook_reader = __commonJS({
63043
63214
  if (this.sharedStrings && this.workbookRels) {
63044
63215
  yield* this._parseWorksheet(iterateStream(entry), sheetNo);
63045
63216
  } else {
63046
- await new Promise((resolve5, reject2) => {
63217
+ await new Promise((resolve6, reject2) => {
63047
63218
  tmp.file((err, path, fd, tempFileCleanupCallback) => {
63048
63219
  if (err) {
63049
63220
  return reject2(err);
@@ -63053,7 +63224,7 @@ var require_workbook_reader = __commonJS({
63053
63224
  tempStream.on("error", reject2);
63054
63225
  entry.pipe(tempStream);
63055
63226
  return tempStream.on("finish", () => {
63056
- return resolve5();
63227
+ return resolve6();
63057
63228
  });
63058
63229
  });
63059
63230
  });
@@ -64432,9 +64603,9 @@ var require_clone2 = __commonJS({
64432
64603
  } else if (_instanceof(parent3, nativeSet)) {
64433
64604
  child = new nativeSet();
64434
64605
  } else if (_instanceof(parent3, nativePromise)) {
64435
- child = new nativePromise(function(resolve5, reject2) {
64606
+ child = new nativePromise(function(resolve6, reject2) {
64436
64607
  parent3.then(function(value) {
64437
- resolve5(_clone(value, depth2 - 1));
64608
+ resolve6(_clone(value, depth2 - 1));
64438
64609
  }, function(err) {
64439
64610
  reject2(_clone(err, depth2 - 1));
64440
64611
  });
@@ -193557,7 +193728,7 @@ function stripCaptions(text, open, close) {
193557
193728
  }
193558
193729
  return removed ? collapseCaptionWs(out) : text;
193559
193730
  }
193560
- function interpolate(text, resolve5) {
193731
+ function interpolate(text, resolve6) {
193561
193732
  if (text.indexOf("{") < 0) return text;
193562
193733
  let out = "";
193563
193734
  for (const tok of tokenise2(text)) {
@@ -193569,7 +193740,7 @@ function interpolate(text, resolve5) {
193569
193740
  out += tok.raw;
193570
193741
  continue;
193571
193742
  }
193572
- const v = resolve5(tok.ref);
193743
+ const v = resolve6(tok.ref);
193573
193744
  out += v === void 0 ? "" : renderSlotValue(v);
193574
193745
  }
193575
193746
  return out;
@@ -194028,7 +194199,7 @@ function bundleOutputPath(loaded) {
194028
194199
  }
194029
194200
 
194030
194201
  // ../ops/src/playable-runtime.ts
194031
- var PLAYABLE_RUNTIME_JS = '"use strict";var Patterplay=(()=>{var P=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var de=Object.prototype.hasOwnProperty;var ue=(s,e)=>{for(var t in e)P(s,t,{get:e[t],enumerable:!0})},ge=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of pe(e))!de.call(s,n)&&n!==t&&P(s,n,{get:()=>e[n],enumerable:!(r=le(e,n))||r.enumerable});return s};var fe=s=>ge(P({},"__esModule",{value:!0}),s);var De={};ue(De,{Engine:()=>B,Flow:()=>v,buildTagIndex:()=>O,effectiveGameData:()=>oe,gameDataFields:()=>ie,gameDataValue:()=>j});function S(s){switch(s[0]){case"b":return{kind:"bool",value:s[1]};case"n":return{kind:"number",value:s[1]};case"s":return{kind:"string",value:s[1]};case"sv":return{kind:"scopedvar",scope:s[1],name:s[2]};case"u":return{kind:"unary",op:s[1],operand:S(s[2])};case"bin":return{kind:"binary",op:s[1],left:S(s[2]),right:S(s[3])};case"call":{let e=s.slice(2).map(S);return{kind:"call",name:s[1],args:e}}case"fd":return{kind:"flagdelta",sign:s[1],name:s[2]}}}var p=class extends Error{constructor(e){super(e),this.name="EvalError"}};function E(s,e,t){let r=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),n=i=>{switch(i.kind){case"bool":return i.value;case"number":return i.value;case"string":return i.value;case"scopedvar":{let o=e.scopes[i.scope];if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):o[i.name];if(a===void 0){if(r.get(i.scope)==="throw")throw new p(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{let o=t.functions[i.name];if(!o)throw new p(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:n,ctx:e})}case"flagdelta":throw new p("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=n(i.operand);if(typeof a!="boolean")throw new p(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=n(i.operand);if(typeof o!="number")throw new p(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let l=n(i.left);if(typeof l!="boolean")throw new p(`\'and\' requires boolean operands, left is ${typeof l}`);if(!l)return!1;let c=n(i.right);if(typeof c!="boolean")throw new p(`\'and\' requires boolean operands, right is ${typeof c}`);return c}if(i.op==="or"){let l=n(i.left);if(typeof l!="boolean")throw new p(`\'or\' requires boolean operands, left is ${typeof l}`);if(l)return!0;let c=n(i.right);if(typeof c!="boolean")throw new p(`\'or\' requires boolean operands, right is ${typeof c}`);return c}let o=n(i.left),a=n(i.right);switch(i.op){case"==":return U(o,a);case"!=":return!U(o,a);case">":return y(o,a,">"),o>a;case">=":return y(o,a,">="),o>=a;case"<":return y(o,a,"<"),o<a;case"<=":return y(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new p(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return y(o,a,"-"),o-a;case"*":return y(o,a,"*"),o*a;case"/":if(y(o,a,"/"),a===0)throw new p("division by zero");return o/a}}}};return n(s)}function U(s,e){if(Array.isArray(s)||Array.isArray(e)){if(!Array.isArray(s)||!Array.isArray(e)||s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]!==e[t])return!1;return!0}return s===e}function y(s,e,t){if(typeof s!="number"||typeof e!="number")throw new p(`\'${t}\' requires numeric operands, got ${typeof s} and ${typeof e}`)}var he={name:"check_flags",count:s=>Math.max(1,s.args.length-1)},me=[he];function W(s,e,t){let r=t?.countingCalls??me;return C(s,t?.want??!0,e,r)}function C(s,e,t,r){if(s.kind==="binary"&&(s.op==="and"||s.op==="or")){let n=C(s.left,e,t,r),i=C(s.right,e,t,r);return s.op==="and"===e?n>0&&i>0?n+i:0:Math.max(n,i)}if(s.kind==="unary"&&s.op==="not")return C(s.operand,!e,t,r);if(s.kind==="call"){let n=r.find(i=>i.name===s.name);if(n){let i=n.count(s),o=t(s);return e?o?i:0:o?0:1}}return t(s)===e?1:0}var w=class{scopes=new Map;defineOwned(e,t){this.assertFree(e);let r={},n=new Map;for(let i of t){let o=i.name.toLowerCase();n.set(o,i),r[o]=i.default??K(i)}return this.scopes.set(e,{kind:"owned",bag:r,decls:n}),this}reseedOwned(e,t){let r=this.scopes.get(e);if(!r||r.kind!=="owned")throw new Error(`\'@${e}\' is not an owned scope`);for(let n of Object.keys(r.bag))delete r.bag[n];r.decls.clear();for(let n of t){let i=n.name.toLowerCase();r.decls.set(i,n),r.bag[i]=n.default??K(n)}return this}defineForeign(e,t,r=[],n=!0){this.assertFree(e);let i=new Map;for(let o of r)i.set(o.name.toLowerCase(),o);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:i,scopeWritable:n}),this}has(e){return this.scopes.has(e)}get(e,t){let r=this.scopes.get(e);if(!r)return;let n=t.toLowerCase();return r.kind==="owned"?r.bag[n]:r.resolver.get(n)}set(e,t,r){let n=this.scopes.get(e);if(!n)throw new Error(`unknown scope \'@${e}\'`);let i=t.toLowerCase();if(!this.writable(n,i))throw new Error(`\'@${e}.${t}\' is read-only`);n.kind==="owned"?n.bag[i]=r:n.resolver.set(i,r)}writable(e,t){return e.kind==="owned"?e.decls.get(t)?.writable??!0:e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}toEvalContext(e){let t={};for(let[r,n]of this.scopes)t[r]=n.kind==="owned"?n.bag:n.resolver;return{scopes:t,host:e}}toSchema(){let e=new Map;for(let[t,r]of this.scopes){if(r.decls.size===0)continue;let n=new Map;for(let[i,o]of r.decls)n.set(i,{type:o.type,enumValues:o.values});e.set(t,n)}return{properties:e}}save(){let e={};for(let[t,r]of this.scopes)r.kind==="owned"&&(e[t]={...r.bag});return e}load(e){for(let[t,r]of Object.entries(e)){let n=this.scopes.get(t);n?.kind==="owned"&&Object.assign(n.bag,r)}}assertFree(e){if(this.scopes.has(e))throw new Error(`scope \'@${e}\' is already registered`)}};function K(s){if(s.default!==void 0)return s.default;switch(s.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"enum":return s.values?.[0]??"";case"flags":return[]}}function x(s){return s.ctx.host??{}}var T={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(s,e){if(s.length!==2)throw new p("random(a, b) requires exactly 2 arguments");let t=x(e).nextRandom;if(!t)throw new p("random() called without a PRNG in context");let r=e.evaluate(s[0]),n=e.evaluate(s[1]);if(typeof r!="number"||typeof n!="number")throw new p("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(n))throw new p("random(a, b) arguments must be integers");let i=Math.min(r,n),o=Math.max(r,n);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:z("check_flags"),eval(s,e){let t=J(s[0],e,"check_flags");for(let r=1;r<s.length;r++){let n=s[r];if(n.kind!=="flagdelta")throw new p("check_flags() flag args must be +flagName or -flagName");if(n.sign==="+"?!t.includes(n.name):t.includes(n.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:z("set_flags"),eval(s,e){let t=[...J(s[0],e,"set_flags")];for(let r=1;r<s.length;r++){let n=s[r];if(n.kind!=="flagdelta")throw new p("set_flags() flag args must be +flagName or -flagName");if(n.sign==="+")t.includes(n.name)||t.push(n.name);else{let i=t.indexOf(n.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:I("visits"),eval:(s,e)=>x(e).visits?.(D(s,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:I("seen"),eval:(s,e)=>(x(e).visits?.(D(s,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:I("patter_visits"),eval:(s,e)=>x(e).patterVisits?.(D(s,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:I("patter_seen"),eval:(s,e)=>(x(e).patterVisits?.(D(s,e,"patter_seen"))??0)>0}}};function F(s,e){let t=s.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function D(s,e,t){let r=e.evaluate(s[0]);if(typeof r!="string")throw new p(`${t}(id) requires a string node id`);return r}function I(s){return(e,t)=>{let r=e[0];r&&r.kind!=="string"&&t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${s}(id): the argument must be a string id literal (a scene / block / node id)`})}}function J(s,e,t){if(!s)throw new p(`${t}() requires at least one argument (the flags variable)`);let r=e.evaluate(s);if(Array.isArray(r))return r;if(r===!1||r===null||r===void 0)return[];throw new p(`${t}() first argument must be a flags property`)}function z(s){return(e,t)=>{if(e.length===0)return;let r=e[0];if(r.kind!=="scopedvar"){t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${s}(): first argument must be a flags property reference (@name or @scope.name)`});return}let n=t.schema.properties.get(r.scope)?.get(r.name);if(n&&n.type!=="flags"){let i=r.scope===t.defaultScope?r.name:`${r.scope}.${r.name}`;t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${s}(): \'@${i}\' is not a flags property (got ${n.type})`});return}for(let i=1;i<e.length;i++){let o=e[i];o.kind!=="flagdelta"?t.report({path:[...t.path,"args",i],kind:"wrong-arg-type",severity:"error",message:`${s}(): argument ${i+1} must be +flagName or -flagName`}):n?.type==="flags"&&n.enumValues&&!n.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${s}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var Se=/^@[A-Za-z0-9_.]+$/;function*ye(s){let e="",t=0;for(;t<s.length;){let r=s[t];if(r==="{"&&s[t+1]==="{"){e+="{",t+=2;continue}if(r==="}"&&s[t+1]==="}"){e+="}",t+=2;continue}if(r==="{"){let n=s.indexOf("}",t+1);if(n!==-1){let i=s.slice(t,n+1),o=s.slice(t+1,n).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:Se.test(o)?o:void 0},t=n+1;continue}e+=i,t=n+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function be(s){return Array.isArray(s)?s.join(", "):typeof s=="boolean"?s?"true":"false":String(s)}function ve(s){return s===" "||s===" "||s===`\n`||s==="\\r"||s==="\\f"||s==="\\v"}function we(s){let e="",t=!1;for(let r of s){if(ve(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function X(s,e,t){if(e.length===0||s.indexOf(e)<0)return s;let r="",n=0,i=!1;for(;n<s.length;){if(s.startsWith(e,n)){let o=s.indexOf(t,n+e.length);if(o>=0){n=o+t.length,i=!0;continue}r+=s.slice(n);break}r+=s[n],n+=1}return i?we(r):s}function Z(s,e){if(s.indexOf("{")<0)return s;let t="";for(let r of ye(s)){if(r.kind==="text"){t+=r.value;continue}if(!r.ref){t+=r.raw;continue}let n=e(r.ref);t+=n===void 0?"":be(n)}return t}function k(s,e){for(let t of s){e(t);let r=t.children;r&&k(r,e)}}function xe(s){return s.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function h(s){let e=s.gameId?.trim();return e||xe(s.name)}function V(s){return`cast:${s}`}var G={open:"[",close:"]"},Q="SFX";function R(s){let e=new Set,t=[];for(let r of s)e.has(r)||(e.add(r),t.push(r));return t}function O(s){let e=new Map,t=(r,n)=>{let i=R([...n,...r.tags??[]]);if(e.set(r.id,i),r.type==="group")for(let o of r.children)t(o,i);else for(let o of r.beats??[])e.set(o.id,R([...i,...o.tags??[]]))};for(let r of Object.values(s.scenes)){let n=R(r.tags??[]);e.set(r.id,n);for(let i of r.blocks){let o=R([...n,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var Y=new WeakMap,B=class s{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;constructor(e,t={}){this.creationOptions=t;let r=t.locale??e.locales.default,n=e.strings;this.allStrings=n,this.currentLocale=r;let i=n[r]??{},o=n[e.locales.default]??{},a=e.localisation,l=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let c=new Map;for(let d of e.cast??[])d.displayName&&c.set(d.name,d.displayName);this.defaultSeed=(t.seed??2654435769)>>>0;let u=new Map,g=new Map,L=new Map;for(let[d,m]of Object.entries(e.scenes)){this.sceneGameIdToId.set(h(m),d);let b=new Map;for(let f of m.blocks)g.set(f.id,{sceneId:d}),L.set(f.id,f),b.set(h(f),f.id),k(f.children,q=>u.set(q.id,q));this.blockGameIdToId.set(d,b)}let $=e.properties??[],N=$.filter(d=>d.shared??!0).map(ee),ae=$.filter(d=>!(d.shared??!0)).map(ee),ce=new Set(N.map(d=>d.name.toLowerCase())),A=new w().defineOwned("patter",N),_=new Set;if(t.world){let d=e.scopeRegistry?.scopes.find(b=>b.token==="world"),m=(d?.declarations??[]).map(te);A.defineForeign("world",t.world,m,d?.writable??!0),_.add("world")}for(let d of e.scopeRegistry?.scopes??[]){if(_.has(d.token))continue;let m=(d.declarations??[]).map(te);A.defineForeign(d.token,Ce(d.declarations??[]),m,d.writable??!0)}let H=new Map;for(let[d,m]of Object.entries(e.scenes)){let b=new Set((m.sceneProps??[]).filter(f=>f.shared??!1).map(f=>f.name.toLowerCase()));H.set(d,b)}this.host={bundle:e,emitIds:l,strings:i,defaultStrings:o,castDisplay:c,nodeIndex:u,blockIndex:g,blockById:L,tagIndex:O(e),shared:A,patterSharedDecls:N,patterLocalDecls:ae,patterSharedNames:ce,sceneSharedNames:H,sharedVisits:new Map,sharedSelectors:new Map,stageBags:new Map,customRng:t.rng,onDryChoice:t.onDryChoice,replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??G).open,captionClose:(e.closedCaptions??G).close,captionCharacter:e.closedCaptions?.character||Q,refSplitCache:new Map}}get locale(){return this.currentLocale}get isSourceDebug(){return this.sourceDebug}setLocale(e){this.currentLocale=e,this.host.strings=this.allStrings[e]??{}}replaceStrings(e){this.allStrings=e.strings,this.host.strings=this.allStrings[this.currentLocale]??{},this.host.defaultStrings=this.allStrings[this.host.bundle.locales.default]??{}}hotSwap(e){let t=this.saveGame(),r=i=>(i.setLocale(this.currentLocale),i.setClosedCaptions(this.host.captionsOn),i),n=new s(e,this.creationOptions);try{return n.loadGame(t),r(n)}catch{let i=new s(e,this.creationOptions);for(let[o,a]of Object.entries(t.flows)){let l=a.cursor.currentSceneId;try{i.openFlow(o,l!==null?{scene:l}:{})}catch{}}return r(i)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){let r=this.resolveSceneRef(t.scene),n=this.resolveBlockRef(r,t.block),i=new v(e,this.host,t.seed??this.defaultSeed);return this.flowsById.set(e,i),i.start(r,n),i}resolveSceneRef(e){if(e!=null)return this.host.bundle.scenes[e]?e:this.sceneGameIdToId.get(e)??e}resolveBlockRef(e,t){if(t!=null){if(this.host.blockById.has(t))return t;if(e!=null){let r=this.blockGameIdToId.get(e)?.get(t);if(r)return r}return t}}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?h(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?h(t):void 0}tagsForBeat(e){return this.host.tagIndex.get(e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?this.host.tagIndex.get(t):void 0)??[]}tagsForBlock(e,t){let r=this.resolveSceneRef(e),n=this.resolveBlockRef(r,t);return(n!=null?this.host.tagIndex.get(n):void 0)??[]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...h(e)?{gameId:h(e)}:{},name:e.name,...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...h(t)?{gameId:h(t)}:{},name:t.name,...this.tagsField(t.id),children:t.children.map(r=>this.outlineNode(r))}))}))}getBeatSequence(){let e=[];for(let t of Object.values(this.host.bundle.scenes))for(let r of t.blocks)k(r.children,n=>{if(n.type==="snippet")for(let i of n.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:n.id,beat:this.beatInfo(i)})});return e}outlineNode(e){return e.type==="group"?{type:"group",id:e.id,...this.tagsField(e.id),...e.selector?{selector:e.selector}:{},...e.prompt?{prompt:this.beatInfo(e.prompt)}:{},children:e.children.map(t=>this.outlineNode(t))}:{type:"snippet",id:e.id,...this.tagsField(e.id),beats:(e.beats??[]).map(t=>this.beatInfo(t)),...e.jump?{jumpTo:e.jump.to,...e.jump.mode?{jumpMode:e.jump.mode}:{}}:{}}}beatInfo(e){let t=this.host.tagIndex.get(e.id),r={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){r.character=e.character;let n=this.host.defaultStrings[V(e.character)]??this.host.castDisplay.get(e.character);n!==void 0&&(r.characterName=n)}e.direction!==void 0&&(r.direction=e.direction)}if(e.kind==="line"||e.kind==="text"){let n=this.host.defaultStrings[e.id];n!==void 0&&(r.text=n)}return e.gameData&&Object.keys(e.gameData).length&&(r.gameData=e.gameData),t&&t.length&&(r.tags=t),r}tagsField(e){let t=this.host.tagIndex.get(e);return t&&t.length?{tags:t}:{}}getFlow(e){return this.flowsById.get(e)}flows(){return[...this.flowsById.values()]}closeFlow(e){this.flowsById.delete(e)}reset(){this.flowsById.clear(),this.host.shared.reseedOwned("patter",this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear(),this.host.stageBags.clear()}getProperty(e){let{scope:t,name:r}=this.splitShared(e);return this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:n}=this.splitShared(e);this.host.shared.set(r,n,t)}listProperties(){return this.host.patterSharedDecls.map(e=>({ref:`@${e.name}`,type:e.type,values:e.values,value:this.getProperty(`@${e.name}`),default:ke(e)}))}splitShared(e){let t=this.host.refSplitCache.get(e);if(t||(t=F(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t.scope==="scene")throw new Error(`\'${e}\': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);return t}save(){return this.host.shared.save()}load(e){this.host.shared.load(e)}saveGame(){let e={};for(let[t,r]of this.flowsById)e[t]=r.snapshot();return{version:2,shared:this.host.shared.save(),sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:ne(this.host.sharedSelectors),stageBags:Object.fromEntries([...this.host.stageBags].map(([t,r])=>[t,{...r}])),flows:e}}loadGame(e){if(e.version!==2)throw new Error(`unsupported save version: ${e.version}`);this.host.shared.load(e.shared),this.host.sharedVisits.clear();for(let[t,r]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(t,r);this.host.sharedSelectors.clear();for(let[t,r]of se(e.sharedSelectors))this.host.sharedSelectors.set(t,r);this.host.stageBags.clear();for(let[t,r]of Object.entries(e.stageBags??{}))this.host.stageBags.set(t,{...r});this.flowsById.clear();for(let[t,r]of Object.entries(e.flows)){let n=new v(t,this.host,this.defaultSeed);n.restore(r),this.flowsById.set(t,n)}}},v=class{id;host;local;rngState;started=!1;flowEnded=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPromptBeat=null;pendingPromptOwnerId=null;selectors=new Map;visitCounts=new Map;sceneBags=new Map;patterResolver={get:e=>this.host.patterSharedNames.has(e)?this.host.shared.get("patter",e):this.local.get("patter",e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.shared.set("patter",e,t):this.local.set("patter",e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;return t===null?void 0:(this.host.sceneSharedNames.get(t)?.has(e)?this.host.stageBags.get(t):this.sceneBags.get(t))?.[e]},set:(e,t)=>{let r=this.currentSceneId;if(r===null)return;let n=this.host.sceneSharedNames.get(r)?.has(e)?this.host.stageBags.get(r):this.sceneBags.get(r);n&&(n[e]=t)}};evalCtx;constructor(e,t,r){this.id=e,this.host=t,this.rngState=r>>>0,this.local=this.freshLocal();let n={...t.shared.toEvalContext().scopes};n.patter=this.patterResolver,n.scene=this.sceneResolver,this.evalCtx={scopes:n,host:{nextRandom:this.rng,visits:i=>this.visitCounts.get(i)??0,patterVisits:i=>this.host.sharedVisits.get(i)??0}}}start(e,t){if(this.sceneBags.clear(),this.local=this.freshLocal(),this.selectors.clear(),this.visitCounts.clear(),this.stack=[],this.currentSceneId=null,this.flowEnded=!1,this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.started=!0,t){let r=this.host.blockIndex.get(t);if(!r)throw new Error(`unknown block: ${t}`);this.enterSceneSetup(r.sceneId),this.stack=[{sceneId:r.sceneId,containerId:t,index:0}],this.enter(t)}else{let r=e??Object.keys(this.host.bundle.scenes)[0],n=r?this.host.bundle.scenes[r]:void 0;if(!n)throw new Error(r?`unknown scene: ${r}`:"no scenes in bundle");this.enterSceneSetup(r);let i=n.blocks[0];i&&(this.stack=[{sceneId:r,containerId:i.id,index:0}],this.enter(i.id))}this.settle()}reset(e,t){this.start(e,t)}get currentScene(){return this.currentSceneId}advance(){if(!this.started)throw new Error("flow has not been started");if(this.pendingPromptBeat){let e=this.pendingPromptBeat;return this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.beatResult(e)}return this.settle(),this.flowEnded?{type:"end"}:this.pendingChoice?{type:"choice",groupId:this.pendingChoice.groupId,options:this.pendingChoice.options}:this.activeSnippet?this.beatResult(this.activeSnippet.beats[this.beatIndex++]):(this.flowEnded=!0,{type:"end"})}advanceToStop(){let e=[];for(;;){let t=this.advance();if(t.type==="choice"||t.type==="end")return{played:e,stop:t};e.push(t)}}settle(){let e=0;for(;;){if(++e>1e4)throw new Error("flow did not settle after 10000 transitions - likely a jump cycle with no deliverable content");if(this.flowEnded||this.pendingChoice)return;if(this.activeSnippet){if(this.beatIndex<(this.activeSnippet.beats?.length??0))return;this.runEffects(this.activeSnippet.onExit);let n=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(n);continue}let t=this.stack[this.stack.length-1];if(!t){this.flowEnded=!0;return}t.sceneId!==this.currentSceneId&&(this.currentSceneId=t.sceneId);let r=this.childrenOf(t.containerId);if(!r){this.stack.pop();continue}for(;t.index<r.length&&!this.eligible(r[t.index]);)t.index++;if(t.index>=r.length){this.stack.pop();continue}this.enterChild(r[t.index++])}}getChoices(){return this.pendingChoice?.options??[]}choose(e){let t=this.pendingChoice;if(!t)throw new Error("no choice is pending");let r=t.options.find(i=>i.id===e);if(!r)throw new Error(`unknown choice option: ${e}`);if(!r.eligible)throw new Error(`choice option is not eligible: ${e}`);let n=t.byId.get(e);this.pendingChoice=null,this.pendingPromptBeat=this.host.replayPromptOnChoose?this.promptBeatOf(n)??null:null,this.pendingPromptOwnerId=this.pendingPromptBeat?n.id:null,this.enterChild(n)}isEnded(){return this.flowEnded}getProperty(e){let{scope:t,name:r}=this.splitRef(e);return t==="patter"?this.patterResolver.get(r):t==="scene"?this.sceneResolver.get(r):this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:n}=this.splitRef(e);if(r==="patter")this.patterResolver.set(n,t);else if(r==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);this.sceneResolver.set(n,t)}else this.host.shared.set(r,n,t)}snapshot(){return{scopes:this.local.save(),sceneBags:Object.fromEntries([...this.sceneBags].map(([e,t])=>[e,{...t}])),rngState:this.rngState,visits:Object.fromEntries(this.visitCounts),cursor:{flowEnded:this.flowEnded,currentSceneId:this.currentSceneId,stack:this.stack.map(e=>{let t=this.childrenOf(e.containerId)?.[e.index];return t?{...e,nextId:t.id}:{...e}}),activeSnippetId:this.activeSnippet?.id??null,beatIndex:this.beatIndex,pendingChoice:this.pendingChoice?{groupId:this.pendingChoice.groupId,options:this.pendingChoice.options.map(e=>({...e}))}:null,pendingPromptOwnerId:this.pendingPromptOwnerId,selectors:ne(this.selectors)}}}restore(e){this.rngState=e.rngState>>>0,this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;if(this.started=!0,this.flowEnded=t.flowEnded,this.beatIndex=t.beatIndex,this.currentSceneId=t.currentSceneId,this.stack=t.stack.map(r=>{let{nextId:n,...i}=r;if(n!==void 0){let o=this.childrenOf(i.containerId)?.findIndex(a=>a.id===n)??-1;if(o>=0)return{...i,index:o}}return{...i}}),this.sceneBags=new Map(Object.entries(e.sceneBags??{}).map(([r,n])=>[r,{...n}])),this.local=this.freshLocal(),this.local.load(e.scopes),this.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=se(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,n=[];for(let i of t.pendingChoice.options){let o=this.host.nodeIndex.get(i.id);o&&(r.set(i.id,o),n.push({...i}))}n.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:n,byId:r})}if(this.pendingPromptBeat=null,this.pendingPromptOwnerId=t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let r=this.host.nodeIndex.get(this.pendingPromptOwnerId);this.pendingPromptBeat=r?this.promptBeatOf(r)??null:null,this.pendingPromptBeat||(this.pendingPromptOwnerId=null)}}enterSceneSetup(e){let t=this.host.bundle.scenes[e];if(!t)throw new Error(`unknown scene: ${e}`);this.currentSceneId=e,this.enter(e),this.seedScene(t),this.runEffects(t.onEntry)}enterChild(e){if(this.enter(e.id),e.type==="snippet"){this.beginSnippet(e);return}let t=e.selector??"run";if(t==="run"){this.stack.push({sceneId:this.currentSceneId,containerId:e.id,index:0});return}if(t==="choice"){this.setupChoice(e);return}let r=this.selectChild(e);r&&this.enterChild(r)}childrenOf(e){let t=this.host.blockById.get(e);if(t)return t.children;let r=this.host.nodeIndex.get(e);if(r&&r.type==="group")return r.children}beginSnippet(e){this.runEffects(e.onEnter),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],r=new Map,n=[];for(let o of e.children){if(o.fallback===!0){n.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),l=o.secretUntilEligible===!0;!a&&l||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.length>0){this.pendingChoice={groupId:e.id,options:t,byId:r};return}let i=n.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.host.onDryChoice?.(e.id)}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(e==="END"){this.flowEnded=!0,this.stack=[];return}let r,n,i=this.host.bundle.scenes[e];if(i){this.enterSceneSetup(e);let a=i.blocks[0];if(!a){t==="jump"&&(this.stack=[]);return}r=e,n=a.id}else{let a=this.host.blockIndex.get(e);if(!a)throw new Error(`jump target not found: ${e}`);a.sceneId!==this.currentSceneId&&this.enterSceneSetup(a.sceneId),r=a.sceneId,n=e}this.enter(n);let o={sceneId:r,containerId:n,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.filter(n=>this.eligible(n));if(t.length===0)return null;let r=this.selectorState(e);switch(e.selector){case"branch":return t[0];case"sequence":{let n=e.options?.order??"sequential",i=e.options?.exhaust??"once";return n==="shuffle"?this.pickShuffle(t,i,r):n==="specificity"?this.pickSpecificity(t,i,r):this.pickSequential(t,i,r)}default:return null}}pickSequential(e,t,r){let n=e.length,i=r.seq??0;return r.seq=i+1,t==="repeat"?e[i%n]:i<n?e[i]:t==="stick"?e[n-1]:null}pickShuffle(e,t,r){let n=e.length,i=t==="stick",o=()=>(i?e.slice(0,n-1):e).map(g=>g.id);if(r.bag===void 0&&(r.bag=o()),r.bag.length===0){if(t==="once")return null;if(i){let g=e[n-1];return r.last=g.id,g}r.bag=o()}let a=r.bag,l=r.last!==void 0&&a.length>1?a.indexOf(r.last):-1,c=Math.floor(this.rng()*(l>=0?a.length-1:a.length));l>=0&&c>=l&&c++;let u=a[c];return a.splice(c,1),r.last=u,e.find(g=>g.id===u)}pickSpecificity(e,t,r){let n=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(u=>u.id));let c=new Set(r.bag);if(n=e.filter(u=>c.has(u.id)),n.length===0)return t==="stick"&&r.last!==void 0?e.find(u=>u.id===r.last)??null:null}let i=-1,a=n.map(c=>{let u=this.specScore(c);return u>i&&(i=u),{c,s:u}}).filter(c=>c.s===i).map(c=>c.c),l;if(a.length===1)l=a[0];else{let c=r.last!==void 0?a.findIndex(g=>g.id===r.last):-1,u=Math.floor(this.rng()*(c>=0?a.length-1:a.length));c>=0&&u>=c&&u++,l=a[u]}return t!=="repeat"&&(r.bag=r.bag.filter(c=>c!==l.id)),r.last=l.id,l}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0):0}matchedSpec(e,t){return W(e,n=>re(E(n,this.evalCtx,T)),{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,r=t.get(e.id);return r||(r={},t.set(e.id,r)),r}runEffects(e){for(let t of e??[])this.setProperty(t.target,this.evalExpr(t.value))}eligible(e){return e.condition?re(this.evalExpr(e.condition)):!0}evalExpr(e){return E(this.conditionAst(e),this.evalCtx,T)}conditionAst(e){let t=Y.get(e);return t||(t=S(e.ast),Y.set(e,t)),t}enter(e){this.visitCounts.set(e,(this.visitCounts.get(e)??0)+1),this.host.sharedVisits.set(e,(this.host.sharedVisits.get(e)??0)+1)}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=this.rngState+1831565813|0;this.rngState=e;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296};beatResult(e){let t=this.host.tagIndex.get(e.id),r=t&&t.length?{tags:t}:{};switch(e.kind){case"gameEvent":return{type:"gameEvent",id:e.id,gameData:e.gameData,...r};case"text":return{type:"text",id:e.id,text:this.interpolate(this.resolveString(e.id)),gameData:e.gameData,...r};case"line":{let n=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?n:this.interpolate(n)),l=i&&a.length===0;return{type:"line",id:e.id,text:a,character:l?void 0:e.character,characterName:l?void 0:this.resolveCharacterName(e.character),direction:l?void 0:e.direction,gameData:e.gameData,...r}}}}interpolate(e){return Z(e,t=>this.getProperty(t))}stripCaptions(e){return X(e,this.host.captionOpen,this.host.captionClose)}captionLine(e){return this.host.captionsOn?e:this.stripCaptions(e)}promptFor(e){let t=this.promptBeatOf(e);if(!t)return;let r=this.interpolate(this.resolveString(t.id));return t.kind==="line"?{kind:"line",text:this.captionLine(r),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction}:{kind:"text",text:r}}promptBeatOf(e){return e.type==="group"&&e.prompt?e.prompt:((e.type==="snippet"?e:this.firstTextSnippetIn(e.children))?.beats??[]).find(r=>r.kind==="line"||r.kind==="text")}firstTextSnippetIn(e){let t;return k(e,r=>{!t&&r.type==="snippet"&&(r.beats??[]).some(n=>n.kind==="line"||n.kind==="text")&&(t=r)}),t}resolveString(e){if(this.host.emitIds)return e;let t=this.host.strings[e];if(t!==void 0)return t;let r=this.host.defaultStrings[e];return r!==void 0?`<Untranslated: ${e}> ${r}`:e}resolveCharacterName(e){if(e===void 0||this.host.emitIds)return;let t=V(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}splitRef(e){let t=this.host.refSplitCache.get(e);return t||(t=F(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t}freshLocal(){return new w().defineOwned("patter",this.host.patterLocalDecls)}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set;if(!this.sceneBags.has(e.id)){let r={};for(let n of e.sceneProps??[]){let i=n.name.toLowerCase();t.has(i)||(r[i]=M(n))}this.sceneBags.set(e.id,r)}if(!this.host.stageBags.has(e.id)){let r={};for(let n of e.sceneProps??[]){let i=n.name.toLowerCase();t.has(i)&&(r[i]=M(n))}this.host.stageBags.set(e.id,r)}for(let r of e.sceneProps??[]){if(!r.temporary)continue;let n=r.name.toLowerCase(),i=t.has(n)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);i&&(i[n]=M(r))}}};function ne(s){let e={};for(let[t,r]of s){let n={};r.seq!==void 0&&(n.seq=r.seq),r.bag&&(n.bag=[...r.bag]),r.last!==void 0&&(n.last=r.last),e[t]=n}return e}function se(s){let e=new Map;for(let[t,r]of Object.entries(s??{})){let n={};r.seq!==void 0&&(n.seq=r.seq),r.bag&&(n.bag=[...r.bag]),r.last!==void 0&&(n.last=r.last),e.set(t,n)}return e}function ee(s){return{name:s.name,type:s.type,values:s.values,default:s.default}}function ke(s){if(s.default!==void 0)return s.default;switch(s.type){case"number":return 0;case"string":return"";case"flags":return[];case"enum":return s.values?.[0]??"";default:return!1}}function te(s){return{name:s.name,type:s.type,values:s.values,default:s.default,writable:s.writable}}function Ee(s){if(s.default!==void 0)return s.default;switch(s.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"flags":return[];case"enum":return s.values?.[0]??""}}function Ce(s){let e=new Map;for(let t of s)e.set(t.name,Ee(t));return{get:t=>e.get(t),set:(t,r)=>{e.set(t,r)}}}function M(s){if(s.default!==void 0)return s.default;switch(s.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"flags":return[];case"enum":return s.values?.[0]??""}}function re(s){return typeof s=="boolean"?s:typeof s=="number"?s!==0:typeof s=="string"?s!=="":s.length>0}function ie(s,e){return s.gameDataFields?.[e]??[]}function j(s,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:s.find(r=>r.name===t)?.default}function oe(s,e){let t={};for(let r of s){let n=j(s,e,r.name);n!==void 0&&(t[r.name]=n)}for(let[r,n]of Object.entries(e??{}))r in t||(t[r]=n);return t}return fe(De);})();\n//# sourceMappingURL=patterplay.min.js.map';
194202
+ var PLAYABLE_RUNTIME_JS = '"use strict";var Patterplay=(()=>{var A=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var he=Object.prototype.hasOwnProperty;var fe=(s,e)=>{for(var t in e)A(s,t,{get:e[t],enumerable:!0})},me=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ge(e))!he.call(s,n)&&n!==t&&A(s,n,{get:()=>e[n],enumerable:!(r=ue(e,n))||r.enumerable});return s};var Se=s=>me(A({},"__esModule",{value:!0}),s);var Oe={};fe(Oe,{Engine:()=>B,Flow:()=>b,buildTagIndex:()=>O,effectiveGameData:()=>le,gameDataFields:()=>ce,gameDataValue:()=>$});function S(s){switch(s[0]){case"b":return{kind:"bool",value:s[1]};case"n":return{kind:"number",value:s[1]};case"s":return{kind:"string",value:s[1]};case"sv":return{kind:"scopedvar",scope:s[1],name:s[2]};case"u":return{kind:"unary",op:s[1],operand:S(s[2])};case"bin":return{kind:"binary",op:s[1],left:S(s[2]),right:S(s[3])};case"call":{let e=s.slice(2).map(S);return{kind:"call",name:s[1],args:e}}case"fd":return{kind:"flagdelta",sign:s[1],name:s[2]}}}var p=class extends Error{constructor(e){super(e),this.name="EvalError"}};function C(s,e,t){let r=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),n=i=>{switch(i.kind){case"bool":return i.value;case"number":return i.value;case"string":return i.value;case"scopedvar":{let o=e.scopes[i.scope];if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):o[i.name];if(a===void 0){if(r.get(i.scope)==="throw")throw new p(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{let o=t.functions[i.name];if(!o)throw new p(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:n,ctx:e})}case"flagdelta":throw new p("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=n(i.operand);if(typeof a!="boolean")throw new p(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=n(i.operand);if(typeof o!="number")throw new p(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let l=n(i.left);if(typeof l!="boolean")throw new p(`\'and\' requires boolean operands, left is ${typeof l}`);if(!l)return!1;let c=n(i.right);if(typeof c!="boolean")throw new p(`\'and\' requires boolean operands, right is ${typeof c}`);return c}if(i.op==="or"){let l=n(i.left);if(typeof l!="boolean")throw new p(`\'or\' requires boolean operands, left is ${typeof l}`);if(l)return!0;let c=n(i.right);if(typeof c!="boolean")throw new p(`\'or\' requires boolean operands, right is ${typeof c}`);return c}let o=n(i.left),a=n(i.right);switch(i.op){case"==":return K(o,a);case"!=":return!K(o,a);case">":return y(o,a,">"),o>a;case">=":return y(o,a,">="),o>=a;case"<":return y(o,a,"<"),o<a;case"<=":return y(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new p(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return y(o,a,"-"),o-a;case"*":return y(o,a,"*"),o*a;case"/":if(y(o,a,"/"),a===0)throw new p("division by zero");return o/a}}}};return n(s)}function K(s,e){if(Array.isArray(s)||Array.isArray(e)){if(!Array.isArray(s)||!Array.isArray(e)||s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]!==e[t])return!1;return!0}return s===e}function y(s,e,t){if(typeof s!="number"||typeof e!="number")throw new p(`\'${t}\' requires numeric operands, got ${typeof s} and ${typeof e}`)}var ye={name:"check_flags",count:s=>Math.max(1,s.args.length-1)},ve=[ye];function J(s,e,t){let r=t?.countingCalls??ve;return E(s,t?.want??!0,e,r)}function E(s,e,t,r){if(s.kind==="binary"&&(s.op==="and"||s.op==="or")){let n=E(s.left,e,t,r),i=E(s.right,e,t,r);return s.op==="and"===e?n>0&&i>0?n+i:0:Math.max(n,i)}if(s.kind==="unary"&&s.op==="not")return E(s.operand,!e,t,r);if(s.kind==="call"){let n=r.find(i=>i.name===s.name);if(n){let i=n.count(s),o=t(s);return e?o?i:0:o?0:1}}return t(s)===e?1:0}var F=class s{values={};decls=new Map;subscribers=new Set;auditors=new Set;norm;constructor(e=[],t){this.norm=t?.normalise??(r=>r.toLowerCase()),this.seed(e)}seed(e){for(let t of e){let r=this.norm(t.name);this.decls.set(r,t),this.values[r]=structuredClone(t.default??X(t))}}get(e){return this.values[this.norm(e)]}set(e,t,r){let n=this.norm(e);if(this.decls.get(n)?.writable===!1)throw new Error(`\'${e}\' is read-only`);let i={name:n,prev:this.values[n],next:t,silent:r?.silent??!1,reason:r?.reason};this.values[n]=t;for(let o of this.auditors)o(i);if(!i.silent)for(let o of this.subscribers)o(i);return i}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}onAudit(e){return this.auditors.add(e),()=>this.auditors.delete(e)}rows(){return[...this.decls.entries()].map(([e,t])=>z(t,this.get(e),void 0,e))}declarations(){return[...this.decls.values()]}clone(){let e=new s([],{normalise:this.norm});return e.decls=new Map(this.decls),Object.assign(e.values,structuredClone(this.values)),e}reseed(e){for(let t of Object.keys(this.values))delete this.values[t];this.decls.clear(),this.seed(e)}save(){return structuredClone(this.values)}load(e){for(let[t,r]of Object.entries(e))this.values[this.norm(t)]=r}};function z(s,e,t,r){return{name:r??s.name.toLowerCase(),type:s.type,value:e,default:s.default??X(s),...s.values!==void 0?{values:s.values}:{},writable:t??s.writable??!0}}var T=1,w=class{scopes=new Map;defineOwned(e,t){return this.mountOwned(e,new F(t))}mountOwned(e,t){return this.assertFree(e),this.scopes.set(e,{kind:"owned",bag:t}),this}ownedBag(e){let t=this.scopes.get(e);if(!t||t.kind!=="owned")throw new Error(`\'@${e}\' is not an owned scope`);return t.bag}reseedOwned(e,t){return this.ownedBag(e).reseed(t),this}defineForeign(e,t,r=[],n=!0){this.assertFree(e);let i=new Map;for(let o of r)i.set(o.name.toLowerCase(),o);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:i,scopeWritable:n}),this}has(e){return this.scopes.has(e)}get(e,t){let r=this.scopes.get(e);if(r)return r.kind==="owned"?r.bag.get(t):r.resolver.get(t.toLowerCase())}set(e,t,r){let n=this.scopes.get(e);if(!n)throw new Error(`unknown scope \'@${e}\'`);if(n.kind==="owned"){try{n.bag.set(t,r)}catch{throw new Error(`\'@${e}.${t}\' is read-only`)}return}let i=t.toLowerCase();if(!this.foreignWritable(n,i))throw new Error(`\'@${e}.${t}\' is read-only`);n.resolver.set(i,r)}foreignWritable(e,t){return e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}listProperties(){let e=[];for(let[t,r]of this.scopes)if(r.kind==="owned")for(let n of r.bag.rows())e.push({scope:t,...n});else for(let n of r.decls.values())e.push({scope:t,...z(n,r.resolver.get(n.name.toLowerCase()),this.foreignWritable(r,n.name.toLowerCase()))});return e}toEvalContext(e){let t={};for(let[r,n]of this.scopes)t[r]=n.kind==="owned"?n.bag.values:n.resolver;return{scopes:t,host:e}}toSchema(){let e=new Map;for(let[t,r]of this.scopes){let n=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];if(n.length===0)continue;let i=new Map;for(let o of n)i.set(o.name.toLowerCase(),{type:o.type,enumValues:o.values});e.set(t,i)}return{properties:e}}save(){let e={};for(let[t,r]of this.scopes)r.kind==="owned"&&(e[t]=r.bag.save());return e}load(e){for(let[t,r]of Object.entries(e)){let n=this.scopes.get(t);n?.kind==="owned"&&n.bag.load(r)}}saveFragment(){return{version:T,scopes:this.save()}}loadFragment(e){if(e.version!==T)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${T})`);this.load(e.scopes)}assertFree(e){if(this.scopes.has(e))throw new Error(`scope \'@${e}\' is already registered`)}};function X(s){if(s.default!==void 0)return s.default;switch(s.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"enum":return s.values?.[0]??"";case"flags":return[]}}function x(s){return s.ctx.host??{}}var V={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(s,e){if(s.length!==2)throw new p("random(a, b) requires exactly 2 arguments");let t=x(e).nextRandom;if(!t)throw new p("random() called without a PRNG in context");let r=e.evaluate(s[0]),n=e.evaluate(s[1]);if(typeof r!="number"||typeof n!="number")throw new p("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(n))throw new p("random(a, b) arguments must be integers");let i=Math.min(r,n),o=Math.max(r,n);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:Q("check_flags"),eval(s,e){let t=Z(s[0],e,"check_flags");for(let r=1;r<s.length;r++){let n=s[r];if(n.kind!=="flagdelta")throw new p("check_flags() flag args must be +flagName or -flagName");if(n.sign==="+"?!t.includes(n.name):t.includes(n.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:Q("set_flags"),eval(s,e){let t=[...Z(s[0],e,"set_flags")];for(let r=1;r<s.length;r++){let n=s[r];if(n.kind!=="flagdelta")throw new p("set_flags() flag args must be +flagName or -flagName");if(n.sign==="+")t.includes(n.name)||t.push(n.name);else{let i=t.indexOf(n.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:D("visits"),eval:(s,e)=>x(e).visits?.(I(s,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:D("seen"),eval:(s,e)=>(x(e).visits?.(I(s,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:D("patter_visits"),eval:(s,e)=>x(e).patterVisits?.(I(s,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:D("patter_seen"),eval:(s,e)=>(x(e).patterVisits?.(I(s,e,"patter_seen"))??0)>0}}};function G(s,e){let t=s.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function I(s,e,t){let r=e.evaluate(s[0]);if(typeof r!="string")throw new p(`${t}(id) requires a string node id`);return r}function D(s){return(e,t)=>{let r=e[0];r&&r.kind!=="string"&&t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${s}(id): the argument must be a string id literal (a scene / block / node id)`})}}function Z(s,e,t){if(!s)throw new p(`${t}() requires at least one argument (the flags variable)`);let r=e.evaluate(s);if(Array.isArray(r))return r;if(r===!1||r===null||r===void 0)return[];throw new p(`${t}() first argument must be a flags property`)}function Q(s){return(e,t)=>{if(e.length===0)return;let r=e[0];if(r.kind!=="scopedvar"){t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${s}(): first argument must be a flags property reference (@name or @scope.name)`});return}let n=t.schema.properties.get(r.scope)?.get(r.name);if(n&&n.type!=="flags"){let i=r.scope===t.defaultScope?r.name:`${r.scope}.${r.name}`;t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${s}(): \'@${i}\' is not a flags property (got ${n.type})`});return}for(let i=1;i<e.length;i++){let o=e[i];o.kind!=="flagdelta"?t.report({path:[...t.path,"args",i],kind:"wrong-arg-type",severity:"error",message:`${s}(): argument ${i+1} must be +flagName or -flagName`}):n?.type==="flags"&&n.enumValues&&!n.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${s}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var be=/^@[A-Za-z0-9_.]+$/;function*we(s){let e="",t=0;for(;t<s.length;){let r=s[t];if(r==="{"&&s[t+1]==="{"){e+="{",t+=2;continue}if(r==="}"&&s[t+1]==="}"){e+="}",t+=2;continue}if(r==="{"){let n=s.indexOf("}",t+1);if(n!==-1){let i=s.slice(t,n+1),o=s.slice(t+1,n).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:be.test(o)?o:void 0},t=n+1;continue}e+=i,t=n+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function xe(s){return Array.isArray(s)?s.join(", "):typeof s=="boolean"?s?"true":"false":String(s)}function ke(s){return s===" "||s===" "||s===`\n`||s==="\\r"||s==="\\f"||s==="\\v"}function Ce(s){let e="",t=!1;for(let r of s){if(ke(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function Y(s,e,t){if(e.length===0||s.indexOf(e)<0)return s;let r="",n=0,i=!1;for(;n<s.length;){if(s.startsWith(e,n)){let o=s.indexOf(t,n+e.length);if(o>=0){n=o+t.length,i=!0;continue}r+=s.slice(n);break}r+=s[n],n+=1}return i?Ce(r):s}function ee(s,e){if(s.indexOf("{")<0)return s;let t="";for(let r of we(s)){if(r.kind==="text"){t+=r.value;continue}if(!r.ref){t+=r.raw;continue}let n=e(r.ref);t+=n===void 0?"":xe(n)}return t}function k(s,e){for(let t of s){e(t);let r=t.children;r&&k(r,e)}}function Ee(s){return s.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function f(s){let e=s.gameId?.trim();return e||Ee(s.name)}function M(s){return`cast:${s}`}var j={open:"[",close:"]"},te="SFX";function R(s){let e=new Set,t=[];for(let r of s)e.has(r)||(e.add(r),t.push(r));return t}function O(s){let e=new Map,t=(r,n)=>{let i=R([...n,...r.tags??[]]);if(e.set(r.id,i),r.type==="group")for(let o of r.children)t(o,i);else for(let o of r.beats??[])e.set(o.id,R([...i,...o.tags??[]]))};for(let r of Object.values(s.scenes)){let n=R(r.tags??[]);e.set(r.id,n);for(let i of r.blocks){let o=R([...n,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var re=new WeakMap,B=class s{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;constructor(e,t={}){this.creationOptions=t;let r=t.locale??e.locales.default,n=e.strings;this.allStrings=n,this.currentLocale=r;let i=n[r]??{},o=n[e.locales.default]??{},a=e.localisation,l=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let c=new Map;for(let d of e.cast??[])d.displayName&&c.set(d.name,d.displayName);this.defaultSeed=(t.seed??2654435769)>>>0;let u=new Map,g=new Map,_=new Map;for(let[d,m]of Object.entries(e.scenes)){this.sceneGameIdToId.set(f(m),d);let v=new Map;for(let h of m.blocks)g.set(h.id,{sceneId:d}),_.set(h.id,h),v.set(f(h),h.id),k(h.children,W=>u.set(W.id,W));this.blockGameIdToId.set(d,v)}let H=e.properties??[],N=H.filter(d=>d.shared??!0).map(ne),pe=H.filter(d=>!(d.shared??!0)).map(ne),de=new Set(N.map(d=>d.name.toLowerCase())),P=new w().defineOwned("patter",N),q=new Set;if(t.world){let d=e.scopeRegistry?.scopes.find(v=>v.token==="world"),m=(d?.declarations??[]).map(se);P.defineForeign("world",t.world,m,d?.writable??!0),q.add("world")}for(let d of e.scopeRegistry?.scopes??[]){if(q.has(d.token))continue;let m=(d.declarations??[]).map(se);P.defineForeign(d.token,Re(d.declarations??[]),m,d.writable??!0)}let U=new Map;for(let[d,m]of Object.entries(e.scenes)){let v=new Set((m.sceneProps??[]).filter(h=>h.shared??!1).map(h=>h.name.toLowerCase()));U.set(d,v)}this.host={bundle:e,emitIds:l,strings:i,defaultStrings:o,castDisplay:c,nodeIndex:u,blockIndex:g,blockById:_,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:O(e),shared:P,patterSharedDecls:N,patterLocalDecls:pe,patterSharedNames:de,sceneSharedNames:U,sharedVisits:new Map,sharedSelectors:new Map,stageBags:new Map,customRng:t.rng,onDryChoice:t.onDryChoice,replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??j).open,captionClose:(e.closedCaptions??j).close,captionCharacter:e.closedCaptions?.character||te,refSplitCache:new Map}}get locale(){return this.currentLocale}get isSourceDebug(){return this.sourceDebug}setLocale(e){this.currentLocale=e,this.host.strings=this.allStrings[e]??{}}replaceStrings(e){this.allStrings=e.strings,this.host.strings=this.allStrings[this.currentLocale]??{},this.host.defaultStrings=this.allStrings[this.host.bundle.locales.default]??{}}hotSwap(e){let t=this.saveGame(),r=i=>(i.setLocale(this.currentLocale),i.setClosedCaptions(this.host.captionsOn),i),n=new s(e,this.creationOptions);try{return n.loadGame(t),r(n)}catch{let i=new s(e,this.creationOptions);for(let[o,a]of Object.entries(t.flows)){let l=a.cursor.currentSceneId;try{i.openFlow(o,l!==null?{scene:l}:{})}catch{}}return r(i)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){let r=this.resolveSceneRef(t.scene),n=this.resolveBlockRef(r,t.block);this.flowsById.get(e)?.close();let i=new b(e,this.host,t.seed??this.defaultSeed);return this.flowsById.set(e,i),i.start(r,n),i}runFlow(e,t,r){let n=this.flowsById.get(e);if(!n)return this.openFlow(e,{scene:t,block:r}).advanceToStop().played;if(!n.goto(t,r))throw new Error(`runFlow: address not found: ${t}${r===void 0?"":` / ${r}`}`);return n.advanceToStop().played}resolveSceneRef(e){if(e!=null)return this.host.bundle.scenes[e]?e:this.sceneGameIdToId.get(e)??e}resolveBlockRef(e,t){if(t!=null){if(this.host.blockById.has(t))return t;if(e!=null){let r=this.blockGameIdToId.get(e)?.get(t);if(r)return r}return t}}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?f(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?f(t):void 0}tagsForBeat(e){return this.host.tagIndex.get(e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?this.host.tagIndex.get(t):void 0)??[]}tagsForBlock(e,t){let r=this.resolveSceneRef(e),n=this.resolveBlockRef(r,t);return(n!=null?this.host.tagIndex.get(n):void 0)??[]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...f(e)?{gameId:f(e)}:{},name:e.name,...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...f(t)?{gameId:f(t)}:{},name:t.name,...this.tagsField(t.id),children:t.children.map(r=>this.outlineNode(r))}))}))}getBeatSequence(){let e=[];for(let t of Object.values(this.host.bundle.scenes))for(let r of t.blocks)k(r.children,n=>{if(n.type==="snippet")for(let i of n.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:n.id,beat:this.beatInfo(i)})});return e}outlineNode(e){return e.type==="group"?{type:"group",id:e.id,...this.tagsField(e.id),...e.selector?{selector:e.selector}:{},...e.prompt?{prompt:this.beatInfo(e.prompt)}:{},children:e.children.map(t=>this.outlineNode(t))}:{type:"snippet",id:e.id,...this.tagsField(e.id),beats:(e.beats??[]).map(t=>this.beatInfo(t)),...e.jump?{jumpTo:e.jump.to,...e.jump.mode?{jumpMode:e.jump.mode}:{}}:{}}}beatInfo(e){let t=this.host.tagIndex.get(e.id),r={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){r.character=e.character;let n=this.host.defaultStrings[M(e.character)]??this.host.castDisplay.get(e.character);n!==void 0&&(r.characterName=n)}e.direction!==void 0&&(r.direction=e.direction)}if(e.kind==="line"||e.kind==="text"){let n=this.host.defaultStrings[e.id];n!==void 0&&(r.text=n)}return e.gameData&&Object.keys(e.gameData).length&&(r.gameData=e.gameData),t&&t.length&&(r.tags=t),r}tagsField(e){let t=this.host.tagIndex.get(e);return t&&t.length?{tags:t}:{}}getFlow(e){return this.flowsById.get(e)}flows(){return[...this.flowsById.values()]}closeFlow(e){this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){for(let e of this.flowsById.values())e.close();this.flowsById.clear(),this.host.shared.reseedOwned("patter",this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear(),this.host.stageBags.clear()}getProperty(e){let{scope:t,name:r}=this.splitShared(e);return this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:n}=this.splitShared(e);this.host.shared.set(r,n,t)}listProperties(){return this.host.patterSharedDecls.map(e=>({ref:`@${e.name}`,type:e.type,values:e.values,value:this.getProperty(`@${e.name}`),default:Ie(e)}))}splitShared(e){let t=this.host.refSplitCache.get(e);if(t||(t=G(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t.scope==="scene")throw new Error(`\'${e}\': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);return t}save(){return this.host.shared.save()}load(e){this.host.shared.load(e)}saveGame(){let e={};for(let[t,r]of this.flowsById)e[t]=r.snapshot();return{version:2,shared:this.host.shared.save(),sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:oe(this.host.sharedSelectors),stageBags:Object.fromEntries([...this.host.stageBags].map(([t,r])=>[t,{...r}])),flows:e}}loadGame(e){if(e.version!==2)throw new Error(`unsupported save version: ${e.version}`);this.host.shared.load(e.shared),this.host.sharedVisits.clear();for(let[t,r]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(t,r);this.host.sharedSelectors.clear();for(let[t,r]of ae(e.sharedSelectors))this.host.sharedSelectors.set(t,r);this.host.stageBags.clear();for(let[t,r]of Object.entries(e.stageBags??{}))this.host.stageBags.set(t,{...r});this.flowsById.clear();for(let[t,r]of Object.entries(e.flows)){let n=new b(t,this.host,this.defaultSeed);n.restore(r),this.flowsById.set(t,n)}}},b=class{id;host;local;rngState;started=!1;flowEnded=!1;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPromptBeat=null;pendingPromptOwnerId=null;selectors=new Map;visitCounts=new Map;sceneBags=new Map;patterResolver={get:e=>this.host.patterSharedNames.has(e)?this.host.shared.get("patter",e):this.local.get("patter",e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.shared.set("patter",e,t):this.local.set("patter",e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;return t===null?void 0:(this.host.sceneSharedNames.get(t)?.has(e)?this.host.stageBags.get(t):this.sceneBags.get(t))?.[e]},set:(e,t)=>{let r=this.currentSceneId;if(r===null)return;let n=this.host.sceneSharedNames.get(r)?.has(e)?this.host.stageBags.get(r):this.sceneBags.get(r);n&&(n[e]=t)}};evalCtx;constructor(e,t,r){this.id=e,this.host=t,this.rngState=r>>>0,this.local=this.freshLocal();let n={...t.shared.toEvalContext().scopes};n.patter=this.patterResolver,n.scene=this.sceneResolver,this.evalCtx={scopes:n,host:{nextRandom:this.rng,visits:i=>this.visitCounts.get(i)??0,patterVisits:i=>this.host.sharedVisits.get(i)??0}}}start(e,t){if(this.sceneBags.clear(),this.local=this.freshLocal(),this.selectors.clear(),this.visitCounts.clear(),this.stack=[],this.currentSceneId=null,this.flowEnded=!1,this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.started=!0,t){let r=this.host.blockIndex.get(t);if(!r)throw new Error(`unknown block: ${t}`);this.enterSceneSetup(r.sceneId),this.stack=[{sceneId:r.sceneId,containerId:t,index:0}],this.enter(t)}else{let r=e??Object.keys(this.host.bundle.scenes)[0],n=r?this.host.bundle.scenes[r]:void 0;if(!n)throw new Error(r?`unknown scene: ${r}`:"no scenes in bundle");this.enterSceneSetup(r);let i=n.blocks[0];i&&(this.stack=[{sceneId:r,containerId:i.id,index:0}],this.enter(i.id))}this.settle()}reset(e,t){this.start(e,t)}goto(e,t){if(this.closed)return!1;if(e==="END")return this.started=!0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],!0;let r=this.host.sceneGameIdToId.get(e)??(this.host.bundle.scenes[e]?e:void 0);if(r===void 0)return!1;let n;return t!==void 0&&(n=this.host.blockGameIdToId.get(r)?.get(t)??(this.host.blockIndex.get(t)?.sceneId===r?t:void 0),n===void 0)?!1:this.started?(this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.enterTarget(n??r,"jump"),this.settle(),!0):(this.start(r,n),!0)}close(){this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null}get isClosed(){return this.closed}get currentScene(){return this.currentSceneId}advance(){if(this.closed)return{type:"end"};if(!this.started)throw new Error("flow has not been started");if(this.pendingPromptBeat){let e=this.pendingPromptBeat;return this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.beatResult(e)}return this.settle(),this.flowEnded?{type:"end"}:this.pendingChoice?{type:"choice",groupId:this.pendingChoice.groupId,options:this.pendingChoice.options}:this.activeSnippet?this.beatResult(this.activeSnippet.beats[this.beatIndex++]):(this.flowEnded=!0,{type:"end"})}advanceToStop(){let e=[];for(;;){let t=this.advance();if(t.type==="choice"||t.type==="end")return{played:e,stop:t};e.push(t)}}settle(){let e=0;for(;;){if(++e>1e4)throw new Error("flow did not settle after 10000 transitions - likely a jump cycle with no deliverable content");if(this.flowEnded||this.pendingChoice)return;if(this.activeSnippet){if(this.beatIndex<(this.activeSnippet.beats?.length??0))return;this.runEffects(this.activeSnippet.onExit);let n=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(n);continue}let t=this.stack[this.stack.length-1];if(!t){this.flowEnded=!0;return}t.sceneId!==this.currentSceneId&&(this.currentSceneId=t.sceneId);let r=this.childrenOf(t.containerId);if(!r){this.stack.pop();continue}for(;t.index<r.length&&!this.eligible(r[t.index]);)t.index++;if(t.index>=r.length){this.stack.pop();continue}this.enterChild(r[t.index++])}}getChoices(){return this.pendingChoice?.options??[]}choose(e){let t=this.pendingChoice;if(!t)throw new Error("no choice is pending");let r=t.options.find(i=>i.id===e);if(!r)throw new Error(`unknown choice option: ${e}`);if(!r.eligible)throw new Error(`choice option is not eligible: ${e}`);let n=t.byId.get(e);this.pendingChoice=null,this.pendingPromptBeat=this.host.replayPromptOnChoose?this.promptBeatOf(n)??null:null,this.pendingPromptOwnerId=this.pendingPromptBeat?n.id:null,this.enterChild(n)}isEnded(){return this.flowEnded}getProperty(e){let{scope:t,name:r}=this.splitRef(e);return t==="patter"?this.patterResolver.get(r):t==="scene"?this.sceneResolver.get(r):this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:n}=this.splitRef(e);if(r==="patter")this.patterResolver.set(n,t);else if(r==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);this.sceneResolver.set(n,t)}else this.host.shared.set(r,n,t)}snapshot(){return{scopes:this.local.save(),sceneBags:Object.fromEntries([...this.sceneBags].map(([e,t])=>[e,{...t}])),rngState:this.rngState,visits:Object.fromEntries(this.visitCounts),cursor:{flowEnded:this.flowEnded,currentSceneId:this.currentSceneId,stack:this.stack.map(e=>{let t=this.childrenOf(e.containerId)?.[e.index];return t?{...e,nextId:t.id}:{...e}}),activeSnippetId:this.activeSnippet?.id??null,beatIndex:this.beatIndex,pendingChoice:this.pendingChoice?{groupId:this.pendingChoice.groupId,options:this.pendingChoice.options.map(e=>({...e}))}:null,pendingPromptOwnerId:this.pendingPromptOwnerId,selectors:oe(this.selectors)}}}restore(e){this.rngState=e.rngState>>>0,this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;if(this.started=!0,this.flowEnded=t.flowEnded,this.beatIndex=t.beatIndex,this.currentSceneId=t.currentSceneId,this.stack=t.stack.map(r=>{let{nextId:n,...i}=r;if(n!==void 0){let o=this.childrenOf(i.containerId)?.findIndex(a=>a.id===n)??-1;if(o>=0)return{...i,index:o}}return{...i}}),this.sceneBags=new Map(Object.entries(e.sceneBags??{}).map(([r,n])=>[r,{...n}])),this.local=this.freshLocal(),this.local.load(e.scopes),this.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=ae(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,n=[];for(let i of t.pendingChoice.options){let o=this.host.nodeIndex.get(i.id);o&&(r.set(i.id,o),n.push({...i}))}n.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:n,byId:r})}if(this.pendingPromptBeat=null,this.pendingPromptOwnerId=t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let r=this.host.nodeIndex.get(this.pendingPromptOwnerId);this.pendingPromptBeat=r?this.promptBeatOf(r)??null:null,this.pendingPromptBeat||(this.pendingPromptOwnerId=null)}}enterSceneSetup(e){let t=this.host.bundle.scenes[e];if(!t)throw new Error(`unknown scene: ${e}`);this.currentSceneId=e,this.enter(e),this.seedScene(t),this.runEffects(t.onEntry)}enterChild(e){if(this.enter(e.id),e.type==="snippet"){this.beginSnippet(e);return}let t=e.selector??"run";if(t==="run"){this.stack.push({sceneId:this.currentSceneId,containerId:e.id,index:0});return}if(t==="choice"){this.setupChoice(e);return}let r=this.selectChild(e);r&&this.enterChild(r)}childrenOf(e){let t=this.host.blockById.get(e);if(t)return t.children;let r=this.host.nodeIndex.get(e);if(r&&r.type==="group")return r.children}beginSnippet(e){this.runEffects(e.onEnter),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],r=new Map,n=[];for(let o of e.children){if(o.fallback===!0){n.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),l=o.secretUntilEligible===!0;!a&&l||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.length>0){this.pendingChoice={groupId:e.id,options:t,byId:r};return}let i=n.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.host.onDryChoice?.(e.id)}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(e==="END"){this.flowEnded=!0,this.stack=[];return}let r,n,i=this.host.bundle.scenes[e];if(i){this.enterSceneSetup(e);let a=i.blocks[0];if(!a){t==="jump"&&(this.stack=[]);return}r=e,n=a.id}else{let a=this.host.blockIndex.get(e);if(!a)throw new Error(`jump target not found: ${e}`);a.sceneId!==this.currentSceneId&&this.enterSceneSetup(a.sceneId),r=a.sceneId,n=e}this.enter(n);let o={sceneId:r,containerId:n,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.filter(n=>this.eligible(n));if(t.length===0)return null;let r=this.selectorState(e);switch(e.selector){case"branch":return t[0];case"sequence":{let n=e.options?.order??"sequential",i=e.options?.exhaust??"once";return n==="shuffle"?this.pickShuffle(t,i,r):n==="specificity"?this.pickSpecificity(t,i,r):this.pickSequential(t,i,r)}default:return null}}pickSequential(e,t,r){let n=e.length,i=r.seq??0;return r.seq=i+1,t==="repeat"?e[i%n]:i<n?e[i]:t==="stick"?e[n-1]:null}pickShuffle(e,t,r){let n=e.length,i=t==="stick",o=()=>(i?e.slice(0,n-1):e).map(g=>g.id);if(r.bag===void 0&&(r.bag=o()),r.bag.length===0){if(t==="once")return null;if(i){let g=e[n-1];return r.last=g.id,g}r.bag=o()}let a=r.bag,l=r.last!==void 0&&a.length>1?a.indexOf(r.last):-1,c=Math.floor(this.rng()*(l>=0?a.length-1:a.length));l>=0&&c>=l&&c++;let u=a[c];return a.splice(c,1),r.last=u,e.find(g=>g.id===u)}pickSpecificity(e,t,r){let n=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(u=>u.id));let c=new Set(r.bag);if(n=e.filter(u=>c.has(u.id)),n.length===0)return t==="stick"&&r.last!==void 0?e.find(u=>u.id===r.last)??null:null}let i=-1,a=n.map(c=>{let u=this.specScore(c);return u>i&&(i=u),{c,s:u}}).filter(c=>c.s===i).map(c=>c.c),l;if(a.length===1)l=a[0];else{let c=r.last!==void 0?a.findIndex(g=>g.id===r.last):-1,u=Math.floor(this.rng()*(c>=0?a.length-1:a.length));c>=0&&u>=c&&u++,l=a[u]}return t!=="repeat"&&(r.bag=r.bag.filter(c=>c!==l.id)),r.last=l.id,l}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0):0}matchedSpec(e,t){return J(e,n=>ie(C(n,this.evalCtx,V)),{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,r=t.get(e.id);return r||(r={},t.set(e.id,r)),r}runEffects(e){for(let t of e??[])this.setProperty(t.target,this.evalExpr(t.value))}eligible(e){return e.condition?ie(this.evalExpr(e.condition)):!0}evalExpr(e){return C(this.conditionAst(e),this.evalCtx,V)}conditionAst(e){let t=re.get(e);return t||(t=S(e.ast),re.set(e,t)),t}enter(e){this.visitCounts.set(e,(this.visitCounts.get(e)??0)+1),this.host.sharedVisits.set(e,(this.host.sharedVisits.get(e)??0)+1)}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=this.rngState+1831565813|0;this.rngState=e;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296};beatResult(e){let t=this.host.tagIndex.get(e.id),r=t&&t.length?{tags:t}:{};switch(e.kind){case"gameEvent":return{type:"gameEvent",id:e.id,gameData:e.gameData,...r};case"text":return{type:"text",id:e.id,text:this.interpolate(this.resolveString(e.id)),gameData:e.gameData,...r};case"line":{let n=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?n:this.interpolate(n)),l=i&&a.length===0;return{type:"line",id:e.id,text:a,character:l?void 0:e.character,characterName:l?void 0:this.resolveCharacterName(e.character),direction:l?void 0:e.direction,gameData:e.gameData,...r}}}}interpolate(e){return ee(e,t=>this.getProperty(t))}stripCaptions(e){return Y(e,this.host.captionOpen,this.host.captionClose)}captionLine(e){return this.host.captionsOn?e:this.stripCaptions(e)}promptFor(e){let t=this.promptBeatOf(e);if(!t)return;let r=this.interpolate(this.resolveString(t.id));return t.kind==="line"?{kind:"line",text:this.captionLine(r),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction}:{kind:"text",text:r}}promptBeatOf(e){return e.type==="group"&&e.prompt?e.prompt:((e.type==="snippet"?e:this.firstTextSnippetIn(e.children))?.beats??[]).find(r=>r.kind==="line"||r.kind==="text")}firstTextSnippetIn(e){let t;return k(e,r=>{!t&&r.type==="snippet"&&(r.beats??[]).some(n=>n.kind==="line"||n.kind==="text")&&(t=r)}),t}resolveString(e){if(this.host.emitIds)return e;let t=this.host.strings[e];if(t!==void 0)return t;let r=this.host.defaultStrings[e];return r!==void 0?`<Untranslated: ${e}> ${r}`:e}resolveCharacterName(e){if(e===void 0||this.host.emitIds)return;let t=M(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}splitRef(e){let t=this.host.refSplitCache.get(e);return t||(t=G(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t}freshLocal(){return new w().defineOwned("patter",this.host.patterLocalDecls)}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set;if(!this.sceneBags.has(e.id)){let r={};for(let n of e.sceneProps??[]){let i=n.name.toLowerCase();t.has(i)||(r[i]=L(n))}this.sceneBags.set(e.id,r)}if(!this.host.stageBags.has(e.id)){let r={};for(let n of e.sceneProps??[]){let i=n.name.toLowerCase();t.has(i)&&(r[i]=L(n))}this.host.stageBags.set(e.id,r)}for(let r of e.sceneProps??[]){if(!r.temporary)continue;let n=r.name.toLowerCase(),i=t.has(n)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);i&&(i[n]=L(r))}}};function oe(s){let e={};for(let[t,r]of s){let n={};r.seq!==void 0&&(n.seq=r.seq),r.bag&&(n.bag=[...r.bag]),r.last!==void 0&&(n.last=r.last),e[t]=n}return e}function ae(s){let e=new Map;for(let[t,r]of Object.entries(s??{})){let n={};r.seq!==void 0&&(n.seq=r.seq),r.bag&&(n.bag=[...r.bag]),r.last!==void 0&&(n.last=r.last),e.set(t,n)}return e}function ne(s){return{name:s.name,type:s.type,values:s.values,default:s.default}}function Ie(s){if(s.default!==void 0)return s.default;switch(s.type){case"number":return 0;case"string":return"";case"flags":return[];case"enum":return s.values?.[0]??"";default:return!1}}function se(s){return{name:s.name,type:s.type,values:s.values,default:s.default,writable:s.writable}}function De(s){if(s.default!==void 0)return s.default;switch(s.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"flags":return[];case"enum":return s.values?.[0]??""}}function Re(s){let e=new Map;for(let t of s)e.set(t.name,De(t));return{get:t=>e.get(t),set:(t,r)=>{e.set(t,r)}}}function L(s){if(s.default!==void 0)return s.default;switch(s.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"flags":return[];case"enum":return s.values?.[0]??""}}function ie(s){return typeof s=="boolean"?s:typeof s=="number"?s!==0:typeof s=="string"?s!=="":s.length>0}function ce(s,e){return s.gameDataFields?.[e]??[]}function $(s,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:s.find(r=>r.name===t)?.default}function le(s,e){let t={};for(let r of s){let n=$(s,e,r.name);n!==void 0&&(t[r.name]=n)}for(let[r,n]of Object.entries(e??{}))r in t||(t[r]=n);return t}return Se(Oe);})();\n//# sourceMappingURL=patterplay.min.js.map';
194032
194203
 
194033
194204
  // ../ops/src/export-html.ts
194034
194205
  var esc = (s) => s.replace(/[&<>]/g, (c2) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;" })[c2]);
@@ -194265,6 +194436,106 @@ function walk(node, want, evalTruthy, countingCalls) {
194265
194436
  }
194266
194437
 
194267
194438
  // ../../../expr/packages/scoperegistry/src/index.ts
194439
+ var PropertyBag = class _PropertyBag {
194440
+ /** The live values record (stable identity across reseed, so an
194441
+ * EvalContext built over it stays valid). Read-path for evaluation;
194442
+ * writes go through `set` so the firing rule applies. */
194443
+ values = {};
194444
+ decls = /* @__PURE__ */ new Map();
194445
+ subscribers = /* @__PURE__ */ new Set();
194446
+ auditors = /* @__PURE__ */ new Set();
194447
+ /** Name normalisation policy: lowercase by default (the registry's
194448
+ * long-standing contract); a product whose names are case-significant
194449
+ * passes identity. */
194450
+ norm;
194451
+ constructor(declarations = [], opts) {
194452
+ this.norm = opts?.normalise ?? ((n) => n.toLowerCase());
194453
+ this.seed(declarations);
194454
+ }
194455
+ seed(declarations) {
194456
+ for (const d of declarations) {
194457
+ const name = this.norm(d.name);
194458
+ this.decls.set(name, d);
194459
+ this.values[name] = structuredClone(d.default ?? defaultFor(d));
194460
+ }
194461
+ }
194462
+ get(name) {
194463
+ return this.values[this.norm(name)];
194464
+ }
194465
+ /** Write a property. Engine writes (the default) notify subscribers;
194466
+ * pass `silent: true` for a host write, which reaches only the audit
194467
+ * hook. Throws on a read-only property. Returns the change. */
194468
+ set(name, value, opts) {
194469
+ const n = this.norm(name);
194470
+ if (this.decls.get(n)?.writable === false) throw new Error(`'${name}' is read-only`);
194471
+ const change = {
194472
+ name: n,
194473
+ prev: this.values[n],
194474
+ next: value,
194475
+ silent: opts?.silent ?? false,
194476
+ reason: opts?.reason
194477
+ };
194478
+ this.values[n] = value;
194479
+ for (const audit of this.auditors) audit(change);
194480
+ if (!change.silent) for (const fn of this.subscribers) fn(change);
194481
+ return change;
194482
+ }
194483
+ /** Notified of engine (non-silent) writes. Returns the unsubscribe. */
194484
+ subscribe(fn) {
194485
+ this.subscribers.add(fn);
194486
+ return () => this.subscribers.delete(fn);
194487
+ }
194488
+ /** Notified of EVERY write, silent or not. Returns the unsubscribe. */
194489
+ onAudit(fn) {
194490
+ this.auditors.add(fn);
194491
+ return () => this.auditors.delete(fn);
194492
+ }
194493
+ /** Examiner rows: the declared surface only (stray values are storage,
194494
+ * not surface). */
194495
+ rows() {
194496
+ return [...this.decls.entries()].map(([name, d]) => rowFor(d, this.get(name), void 0, name));
194497
+ }
194498
+ declarations() {
194499
+ return [...this.decls.values()];
194500
+ }
194501
+ /** The one sanctioned copy door: values deep-copied, declarations
194502
+ * duplicated, the normalisation policy carried, subscriptions NOT
194503
+ * carried. */
194504
+ clone() {
194505
+ const c2 = new _PropertyBag([], { normalise: this.norm });
194506
+ c2.decls = new Map(this.decls);
194507
+ Object.assign(c2.values, structuredClone(this.values));
194508
+ return c2;
194509
+ }
194510
+ /** Clear and re-seed from new declarations, in place (the values record
194511
+ * keeps its identity, so contexts built over it stay valid). */
194512
+ reseed(declarations) {
194513
+ for (const k of Object.keys(this.values)) delete this.values[k];
194514
+ this.decls.clear();
194515
+ this.seed(declarations);
194516
+ }
194517
+ /** Bare values, ready to embed in a product's save. */
194518
+ save() {
194519
+ return structuredClone(this.values);
194520
+ }
194521
+ /** Lay saved values over the current ones (call after a fresh seed:
194522
+ * orphans land as strays, new declarations keep their defaults; the
194523
+ * product decides whether to prune). Does not fire events. */
194524
+ load(values) {
194525
+ for (const [k, v] of Object.entries(values)) this.values[this.norm(k)] = v;
194526
+ }
194527
+ };
194528
+ function rowFor(d, value, writable, name) {
194529
+ return {
194530
+ name: name ?? d.name.toLowerCase(),
194531
+ type: d.type,
194532
+ value,
194533
+ default: d.default ?? defaultFor(d),
194534
+ ...d.values !== void 0 ? { values: d.values } : {},
194535
+ writable: writable ?? d.writable ?? true
194536
+ };
194537
+ }
194538
+ var SAVE_FRAGMENT_VERSION = 1;
194268
194539
  var ScopeRegistry = class {
194269
194540
  scopes = /* @__PURE__ */ new Map();
194270
194541
  /**
@@ -194273,17 +194544,24 @@ var ScopeRegistry = class {
194273
194544
  * type-checked (declarations) and serialized by `save`/`load`.
194274
194545
  */
194275
194546
  defineOwned(token2, declarations) {
194547
+ return this.mountOwned(token2, new PropertyBag(declarations));
194548
+ }
194549
+ /**
194550
+ * Attach an EXISTING bag as an owned scope - the shared-container move: a
194551
+ * host (or the other product) holds the bag; this registry reads, writes
194552
+ * and lists it like its own, but the holder saves it.
194553
+ */
194554
+ mountOwned(token2, bag) {
194276
194555
  this.assertFree(token2);
194277
- const bag = {};
194278
- const decls = /* @__PURE__ */ new Map();
194279
- for (const d of declarations) {
194280
- const name = d.name.toLowerCase();
194281
- decls.set(name, d);
194282
- bag[name] = d.default ?? defaultFor(d);
194283
- }
194284
- this.scopes.set(token2, { kind: "owned", bag, decls });
194556
+ this.scopes.set(token2, { kind: "owned", bag });
194285
194557
  return this;
194286
194558
  }
194559
+ /** An owned scope's bag (subscribe, audit, rows live there). */
194560
+ ownedBag(token2) {
194561
+ const e = this.scopes.get(token2);
194562
+ if (!e || e.kind !== "owned") throw new Error(`'@${token2}' is not an owned scope`);
194563
+ return e.bag;
194564
+ }
194287
194565
  /**
194288
194566
  * Re-initialise an existing **owned** scope's bag from new declarations,
194289
194567
  * clearing its current values. For scope-local state that resets on a context
@@ -194292,15 +194570,7 @@ var ScopeRegistry = class {
194292
194570
  * registry stays valid.
194293
194571
  */
194294
194572
  reseedOwned(token2, declarations) {
194295
- const e = this.scopes.get(token2);
194296
- if (!e || e.kind !== "owned") throw new Error(`'@${token2}' is not an owned scope`);
194297
- for (const k of Object.keys(e.bag)) delete e.bag[k];
194298
- e.decls.clear();
194299
- for (const d of declarations) {
194300
- const name = d.name.toLowerCase();
194301
- e.decls.set(name, d);
194302
- e.bag[name] = d.default ?? defaultFor(d);
194303
- }
194573
+ this.ownedBag(token2).reseed(declarations);
194304
194574
  return this;
194305
194575
  }
194306
194576
  /**
@@ -194323,23 +194593,49 @@ var ScopeRegistry = class {
194323
194593
  get(scope, name) {
194324
194594
  const e = this.scopes.get(scope);
194325
194595
  if (!e) return void 0;
194326
- const n = name.toLowerCase();
194327
- return e.kind === "owned" ? e.bag[n] : e.resolver.get(n);
194596
+ return e.kind === "owned" ? e.bag.get(name) : e.resolver.get(name.toLowerCase());
194328
194597
  }
194329
- /** Write a property. Throws on an unknown or read-only scope/property. */
194598
+ /** Write a property (an ENGINE write: the bag's subscribers fire; use
194599
+ * the bag directly for silent host writes). Throws on an unknown or
194600
+ * read-only scope/property. */
194330
194601
  set(scope, name, value) {
194331
194602
  const e = this.scopes.get(scope);
194332
194603
  if (!e) throw new Error(`unknown scope '@${scope}'`);
194604
+ if (e.kind === "owned") {
194605
+ try {
194606
+ e.bag.set(name, value);
194607
+ } catch {
194608
+ throw new Error(`'@${scope}.${name}' is read-only`);
194609
+ }
194610
+ return;
194611
+ }
194333
194612
  const n = name.toLowerCase();
194334
- if (!this.writable(e, n)) throw new Error(`'@${scope}.${name}' is read-only`);
194335
- if (e.kind === "owned") e.bag[n] = value;
194336
- else e.resolver.set(n, value);
194613
+ if (!this.foreignWritable(e, n)) throw new Error(`'@${scope}.${name}' is read-only`);
194614
+ e.resolver.set(n, value);
194337
194615
  }
194338
- writable(e, name) {
194339
- if (e.kind === "owned") return e.decls.get(name)?.writable ?? true;
194616
+ foreignWritable(e, name) {
194340
194617
  if (!e.resolver.set) return false;
194341
194618
  return e.decls.get(name)?.writable ?? e.scopeWritable;
194342
194619
  }
194620
+ /** Examiner rows across every scope with a declared surface: owned bags
194621
+ * first, then declared foreign scopes (values read through, writability
194622
+ * reflecting the resolver). Opaque foreign scopes are not listed. */
194623
+ listProperties() {
194624
+ const out = [];
194625
+ for (const [token2, e] of this.scopes) {
194626
+ if (e.kind === "owned") {
194627
+ for (const row of e.bag.rows()) out.push({ scope: token2, ...row });
194628
+ } else {
194629
+ for (const d of e.decls.values()) {
194630
+ out.push({
194631
+ scope: token2,
194632
+ ...rowFor(d, e.resolver.get(d.name.toLowerCase()), this.foreignWritable(e, d.name.toLowerCase()))
194633
+ });
194634
+ }
194635
+ }
194636
+ }
194637
+ return out;
194638
+ }
194343
194639
  /**
194344
194640
  * Build the `EvalContext` expr's `evaluate` consumes: owned scopes as static
194345
194641
  * bags, foreign scopes as their resolvers. `host` carries dialect-function
@@ -194348,7 +194644,7 @@ var ScopeRegistry = class {
194348
194644
  toEvalContext(host2) {
194349
194645
  const scopes = {};
194350
194646
  for (const [token2, e] of this.scopes) {
194351
- scopes[token2] = e.kind === "owned" ? e.bag : e.resolver;
194647
+ scopes[token2] = e.kind === "owned" ? e.bag.values : e.resolver;
194352
194648
  }
194353
194649
  return { scopes, host: host2 };
194354
194650
  }
@@ -194360,26 +194656,44 @@ var ScopeRegistry = class {
194360
194656
  toSchema() {
194361
194657
  const properties = /* @__PURE__ */ new Map();
194362
194658
  for (const [token2, e] of this.scopes) {
194363
- if (e.decls.size === 0) continue;
194659
+ const decls = e.kind === "owned" ? e.bag.declarations() : [...e.decls.values()];
194660
+ if (decls.length === 0) continue;
194364
194661
  const m = /* @__PURE__ */ new Map();
194365
- for (const [name, d] of e.decls) m.set(name, { type: d.type, enumValues: d.values });
194662
+ for (const d of decls) m.set(d.name.toLowerCase(), { type: d.type, enumValues: d.values });
194366
194663
  properties.set(token2, m);
194367
194664
  }
194368
194665
  return { properties };
194369
194666
  }
194370
- /** Serialize **owned** scopes only (foreign scopes are host-owned, host-saved). */
194667
+ /** Serialize **owned** scopes only (foreign scopes are host-owned,
194668
+ * host-saved), as bare bags - the 0.1.x shape, kept stable so existing
194669
+ * consumers' save formats are untouched. A product embedding the
194670
+ * versioned cross-product shape uses `saveFragment`. */
194371
194671
  save() {
194372
194672
  const out = {};
194373
- for (const [token2, e] of this.scopes) if (e.kind === "owned") out[token2] = { ...e.bag };
194673
+ for (const [token2, e] of this.scopes) if (e.kind === "owned") out[token2] = e.bag.save();
194374
194674
  return out;
194375
194675
  }
194376
- /** Restore owned-scope values from a `save` blob. Unknown/foreign scopes are ignored. */
194676
+ /** Restore owned-scope values from a `save` blob. Unknown/foreign scopes
194677
+ * are ignored. */
194377
194678
  load(blob) {
194378
194679
  for (const [token2, vals] of Object.entries(blob)) {
194379
194680
  const e = this.scopes.get(token2);
194380
- if (e?.kind === "owned") Object.assign(e.bag, vals);
194681
+ if (e?.kind === "owned") e.bag.load(vals);
194381
194682
  }
194382
194683
  }
194684
+ /** The versioned owned-state fragment (the one serialisation shape both
194685
+ * product families' save envelopes embed when they adopt the kernel;
194686
+ * design/engine-runtimes.md 3.1). `save()` wrapped with a version stamp. */
194687
+ saveFragment() {
194688
+ return { version: SAVE_FRAGMENT_VERSION, scopes: this.save() };
194689
+ }
194690
+ /** Restore from a versioned fragment; an unsupported version throws. */
194691
+ loadFragment(fragment) {
194692
+ if (fragment.version !== SAVE_FRAGMENT_VERSION) {
194693
+ throw new Error(`unsupported owned-state fragment version ${fragment.version} (supported: ${SAVE_FRAGMENT_VERSION})`);
194694
+ }
194695
+ this.load(fragment.scopes);
194696
+ }
194383
194697
  assertFree(token2) {
194384
194698
  if (this.scopes.has(token2)) throw new Error(`scope '@${token2}' is already registered`);
194385
194699
  }
@@ -194517,6 +194831,9 @@ var Engine = class _Engine {
194517
194831
  nodeIndex,
194518
194832
  blockIndex,
194519
194833
  blockById,
194834
+ sceneGameIdToId: this.sceneGameIdToId,
194835
+ blockGameIdToId: this.blockGameIdToId,
194836
+ // same instances the engine resolves with
194520
194837
  tagIndex: buildTagIndex(bundle),
194521
194838
  shared,
194522
194839
  patterSharedDecls,
@@ -194625,16 +194942,56 @@ var Engine = class _Engine {
194625
194942
  /**
194626
194943
  * Open (and start) a named flow. Each flow has its own cursor, PRNG, and per-flow
194627
194944
  * half of the scopes (not-shared `@patter`/`@scene`); all flows share the shared
194628
- * half. Re-opening an existing id replaces it with a fresh flow.
194945
+ * half.
194946
+ *
194947
+ * Re-opening an existing id REPLACES it with a fresh flow, and CLOSES the old one
194948
+ * ({@link Flow.close}) so a host still holding it cannot keep driving the shared world. Replacing is
194949
+ * therefore a reset: that name's cursor, visit counts, selector cursors (so any shuffle / once-each
194950
+ * position) and per-flow properties all start over.
194951
+ *
194952
+ * Contrast {@link runFlow}, which REUSES a flow of the same name instead of replacing it - that is the
194953
+ * call to reach for when you want a speaker's variation state to carry on.
194629
194954
  */
194630
194955
  openFlow(id, opts = {}) {
194631
194956
  const sceneId = this.resolveSceneRef(opts.scene);
194632
194957
  const blockId = this.resolveBlockRef(sceneId, opts.block);
194958
+ this.flowsById.get(id)?.close();
194633
194959
  const flow = new Flow(id, this.host, opts.seed ?? this.defaultSeed);
194634
194960
  this.flowsById.set(id, flow);
194635
194961
  flow.start(sceneId, blockId);
194636
194962
  return flow;
194637
194963
  }
194964
+ /**
194965
+ * "Play this address and give me everything it produced" - the one-call form of the bark / one-shot
194966
+ * pattern. The NAMED flow is reused if it already exists (moved with {@link Flow.goto}) and opened at
194967
+ * the address if not, then run to its next stop, returning every beat it played.
194968
+ *
194969
+ * Calling it again with the SAME NAME does NOT replace the flow - it reuses it, and that is the whole
194970
+ * point. A flow owns its selector cursors, visit counts and per-flow properties, so reusing one lets a
194971
+ * **shuffle keep its bag** and an **"once each" list keep its place**: successive calls give the next
194972
+ * variation instead of replaying the first forever. (A fresh flow each time would reset all of it,
194973
+ * unless every such group happened to be authored `shared`.) Use one name per independent speaker;
194974
+ * different names never share per-flow state.
194975
+ *
194976
+ * This is exactly where it differs from {@link openFlow}, which REPLACES a flow of the same name and
194977
+ * so resets that variation state. Never mix the two on one name unless you mean to start over.
194978
+ *
194979
+ * Returns the played beats in order - `[]` means the address had nothing left to give (an exhausted
194980
+ * variation list, say), which is the signal to fall back to other content. It THROWS on an address
194981
+ * that does not resolve: unlike `goto` (a navigation primitive, where probing is legitimate), naming a
194982
+ * location here asserts it exists, and keeping `[]` unambiguous is worth more than a soft failure.
194983
+ *
194984
+ * A run that stops at a CHOICE returns the beats up to it and leaves the choice pending on the flow -
194985
+ * fetch it with `engine.getFlow(name)?.getChoices()`.
194986
+ */
194987
+ runFlow(flow, scene, block) {
194988
+ const existing = this.flowsById.get(flow);
194989
+ if (!existing) return this.openFlow(flow, { scene, block }).advanceToStop().played;
194990
+ if (!existing.goto(scene, block)) {
194991
+ throw new Error(`runFlow: address not found: ${scene}${block === void 0 ? "" : ` / ${block}`}`);
194992
+ }
194993
+ return existing.advanceToStop().played;
194994
+ }
194638
194995
  /** Resolve a scene reference (a gameId address OR an internal id) to its internal id. */
194639
194996
  resolveSceneRef(ref) {
194640
194997
  if (ref == null) return void 0;
@@ -194772,8 +195129,10 @@ var Engine = class _Engine {
194772
195129
  flows() {
194773
195130
  return [...this.flowsById.values()];
194774
195131
  }
194775
- /** Close (remove) a flow. */
195132
+ /** Close (remove) a flow. The flow object is FINISHED, not merely unregistered, so a host still
195133
+ * holding it cannot keep advancing it into the shared world (see {@link Flow.close}). */
194776
195134
  closeFlow(id) {
195135
+ this.flowsById.get(id)?.close();
194777
195136
  this.flowsById.delete(id);
194778
195137
  }
194779
195138
  /**
@@ -194783,6 +195142,7 @@ var Engine = class _Engine {
194783
195142
  * After reset, open fresh flows with `openFlow`.
194784
195143
  */
194785
195144
  reset() {
195145
+ for (const flow of this.flowsById.values()) flow.close();
194786
195146
  this.flowsById.clear();
194787
195147
  this.host.shared.reseedOwned("patter", this.host.patterSharedDecls);
194788
195148
  this.host.sharedVisits.clear();
@@ -194874,6 +195234,9 @@ var Flow = class {
194874
195234
  // `activeSnippet`/`beatIndex`.
194875
195235
  started = false;
194876
195236
  flowEnded = false;
195237
+ /** Closed by the engine (see `close()`). Terminal, and distinct from `flowEnded`: an ENDED flow is
195238
+ * merely out of content and `goto` revives it; a CLOSED one is finished for good. */
195239
+ closed = false;
194877
195240
  currentSceneId = null;
194878
195241
  stack = [];
194879
195242
  activeSnippet = null;
@@ -194980,6 +195343,81 @@ var Flow = class {
194980
195343
  reset(sceneId, blockId) {
194981
195344
  this.start(sceneId, blockId);
194982
195345
  }
195346
+ /**
195347
+ * Send this flow's cursor to an ADDRESS, exactly as an authored `go` jump would: the target scene's
195348
+ * `onEntry` effects run, entering counts as a visit, and the callstack is REPLACED - any pending
195349
+ * `call` returns are discarded, just as a goto inside a call does.
195350
+ *
195351
+ * `scene` and `block` are host-facing gameIds (spec §6) or internal ids; `block` is scene-scoped, so
195352
+ * it is looked up within `scene`. `"END"` ends the flow. To move within the current scene, pass the
195353
+ * current scene's address again (`flow.currentScene` -> `engine.sceneAddress`).
195354
+ *
195355
+ * This is HOST navigation, not authoring, and it takes effect IMMEDIATELY: any beats left in the
195356
+ * snippet being delivered are abandoned, and a pending choice is dropped. The format stops an AUTHOR
195357
+ * writing a divert into the middle of a snippet; a host teleport is out-of-band, like `reset()` or
195358
+ * `loadGame()`. A flow that never started starts here; one that already ended resumes here.
195359
+ *
195360
+ * Returns false - leaving the cursor exactly where it was - if the address does not resolve. Per-flow
195361
+ * state (properties, visit counts, selector cursors) is untouched either way: this MOVES, never resets.
195362
+ */
195363
+ goto(scene, block) {
195364
+ if (this.closed) return false;
195365
+ if (scene === "END") {
195366
+ this.started = true;
195367
+ this.pendingChoice = null;
195368
+ this.pendingPromptBeat = null;
195369
+ this.pendingPromptOwnerId = null;
195370
+ this.activeSnippet = null;
195371
+ this.beatIndex = 0;
195372
+ this.flowEnded = true;
195373
+ this.stack = [];
195374
+ return true;
195375
+ }
195376
+ const sceneId = this.host.sceneGameIdToId.get(scene) ?? (this.host.bundle.scenes[scene] ? scene : void 0);
195377
+ if (sceneId === void 0) return false;
195378
+ let blockId;
195379
+ if (block !== void 0) {
195380
+ blockId = this.host.blockGameIdToId.get(sceneId)?.get(block) ?? (this.host.blockIndex.get(block)?.sceneId === sceneId ? block : void 0);
195381
+ if (blockId === void 0) return false;
195382
+ }
195383
+ if (!this.started) {
195384
+ this.start(sceneId, blockId);
195385
+ return true;
195386
+ }
195387
+ this.pendingChoice = null;
195388
+ this.pendingPromptBeat = null;
195389
+ this.pendingPromptOwnerId = null;
195390
+ this.activeSnippet = null;
195391
+ this.beatIndex = 0;
195392
+ this.flowEnded = false;
195393
+ this.enterTarget(blockId ?? sceneId, "jump");
195394
+ this.settle();
195395
+ return true;
195396
+ }
195397
+ /**
195398
+ * Finish this flow for good. Engine-managed: `engine.closeFlow(id)`, `engine.reset()`, and re-opening
195399
+ * a name with `engine.openFlow` all call it on the flow being dropped.
195400
+ *
195401
+ * A dropped flow used to stay fully live: unregistered and invisible to `engine.flows()`, but a host
195402
+ * still holding the object could keep advancing it, and every scene `onEntry`, shared property, world
195403
+ * visit count and shared selector cursor it touched still landed on the engine. Closing makes that
195404
+ * stale reference inert - `advance()` reports the end and `goto()` refuses - so a forgotten reference
195405
+ * cannot quietly mutate the world. Terminal: unlike ending, a close is never revived.
195406
+ */
195407
+ close() {
195408
+ this.closed = true;
195409
+ this.flowEnded = true;
195410
+ this.stack = [];
195411
+ this.activeSnippet = null;
195412
+ this.beatIndex = 0;
195413
+ this.pendingChoice = null;
195414
+ this.pendingPromptBeat = null;
195415
+ this.pendingPromptOwnerId = null;
195416
+ }
195417
+ /** True once the engine has closed this flow (closed, dropped by `reset()`, or replaced by name). */
195418
+ get isClosed() {
195419
+ return this.closed;
195420
+ }
194983
195421
  /** The scene the cursor is currently in - set on entry and whenever a jump crosses scenes. Read
194984
195422
  * right after `advance()` to know which scene the just-played beat lives in (tooling that mirrors
194985
195423
  * the playhead, e.g. an editor following a cross-scene jump). `null` before the flow has started. */
@@ -194988,6 +195426,7 @@ var Flow = class {
194988
195426
  }
194989
195427
  /** Run until the next line, game event, choice, or the end of the flow. */
194990
195428
  advance() {
195429
+ if (this.closed) return { type: "end" };
194991
195430
  if (!this.started) throw new Error("flow has not been started");
194992
195431
  if (this.pendingPromptBeat) {
194993
195432
  const b = this.pendingPromptBeat;
@@ -195901,8 +196340,9 @@ function sortValues(values) {
195901
196340
  return String(a).localeCompare(String(b));
195902
196341
  });
195903
196342
  }
195904
- function runCoverage(loaded, options = {}, hooks = {}) {
195905
- const runs = options.runs ?? 5e3;
196343
+ var DEFAULT_RUNS = 5e3;
196344
+ function* sweep(loaded, options = {}, hooks = {}) {
196345
+ const runs = options.runs ?? DEFAULT_RUNS;
195906
196346
  const maxSteps = options.maxSteps ?? 200;
195907
196347
  const seed = options.seed ?? 0;
195908
196348
  const start = resolveStart(loaded, options);
@@ -195993,6 +196433,7 @@ function runCoverage(loaded, options = {}, hooks = {}) {
195993
196433
  termination[term]++;
195994
196434
  executed++;
195995
196435
  if ((run2 & 255) === 0) hooks.onProgress?.(executed, runs);
196436
+ yield executed;
195996
196437
  }
195997
196438
  hooks.onProgress?.(executed, runs);
195998
196439
  const unwrittenInputs = /* @__PURE__ */ new Set();
@@ -196036,6 +196477,12 @@ function runCoverage(loaded, options = {}, hooks = {}) {
196036
196477
  cancelled
196037
196478
  };
196038
196479
  }
196480
+ function runCoverage(loaded, options = {}, hooks = {}) {
196481
+ const it = sweep(loaded, options, hooks);
196482
+ let step = it.next();
196483
+ while (!step.done) step = it.next();
196484
+ return step.value;
196485
+ }
196039
196486
  function renderCoverageText(report, sceneName = (id) => id) {
196040
196487
  const out = [];
196041
196488
  const t = report.totals;
@@ -197668,14 +198115,14 @@ var require_events = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
197668
198115
  return ret2;
197669
198116
  }
197670
198117
  function once2(emitter, name) {
197671
- return new Promise(function(resolve5, reject2) {
198118
+ return new Promise(function(resolve6, reject2) {
197672
198119
  function errorListener(err) {
197673
198120
  emitter.removeListener(name, resolver);
197674
198121
  reject2(err);
197675
198122
  }
197676
198123
  function resolver() {
197677
198124
  if (typeof emitter.removeListener === "function") emitter.removeListener("error", errorListener);
197678
- resolve5([].slice.call(arguments));
198125
+ resolve6([].slice.call(arguments));
197679
198126
  }
197680
198127
  eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
197681
198128
  if (name !== "error") addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
@@ -200577,8 +201024,8 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
200577
201024
  }
200578
201025
  function fn() {
200579
201026
  var promiseResolve, promiseReject;
200580
- var promise = new Promise(function(resolve5, reject2) {
200581
- promiseResolve = resolve5;
201027
+ var promise = new Promise(function(resolve6, reject2) {
201028
+ promiseResolve = resolve6;
200582
201029
  promiseReject = reject2;
200583
201030
  });
200584
201031
  var args = [];
@@ -201944,14 +202391,14 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
201944
202391
  };
201945
202392
  }
201946
202393
  function readAndResolve(iter) {
201947
- var resolve5 = iter[kLastResolve];
201948
- if (resolve5 !== null) {
202394
+ var resolve6 = iter[kLastResolve];
202395
+ if (resolve6 !== null) {
201949
202396
  var data = iter[kStream].read();
201950
202397
  if (data !== null) {
201951
202398
  iter[kLastPromise] = null;
201952
202399
  iter[kLastResolve] = null;
201953
202400
  iter[kLastReject] = null;
201954
- resolve5(createIterResult(data, false));
202401
+ resolve6(createIterResult(data, false));
201955
202402
  }
201956
202403
  }
201957
202404
  }
@@ -201959,13 +202406,13 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
201959
202406
  process$1.nextTick(readAndResolve, iter);
201960
202407
  }
201961
202408
  function wrapForNext(lastPromise, iter) {
201962
- return function(resolve5, reject2) {
202409
+ return function(resolve6, reject2) {
201963
202410
  lastPromise.then(function() {
201964
202411
  if (iter[kEnded]) {
201965
- resolve5(createIterResult(void 0, true));
202412
+ resolve6(createIterResult(void 0, true));
201966
202413
  return;
201967
202414
  }
201968
- iter[kHandlePromise](resolve5, reject2);
202415
+ iter[kHandlePromise](resolve6, reject2);
201969
202416
  }, reject2);
201970
202417
  };
201971
202418
  }
@@ -201980,10 +202427,10 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
201980
202427
  var error = this[kError];
201981
202428
  if (error !== null) return Promise.reject(error);
201982
202429
  if (this[kEnded]) return Promise.resolve(createIterResult(void 0, true));
201983
- if (this[kStream].destroyed) return new Promise(function(resolve5, reject2) {
202430
+ if (this[kStream].destroyed) return new Promise(function(resolve6, reject2) {
201984
202431
  process$1.nextTick(function() {
201985
202432
  if (_this[kError]) reject2(_this[kError]);
201986
- else resolve5(createIterResult(void 0, true));
202433
+ else resolve6(createIterResult(void 0, true));
201987
202434
  });
201988
202435
  });
201989
202436
  var lastPromise = this[kLastPromise];
@@ -202001,13 +202448,13 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
202001
202448
  return this;
202002
202449
  }), _defineProperty2(_Object$setPrototypeO, "return", function _return() {
202003
202450
  var _this2 = this;
202004
- return new Promise(function(resolve5, reject2) {
202451
+ return new Promise(function(resolve6, reject2) {
202005
202452
  _this2[kStream].destroy(null, function(err) {
202006
202453
  if (err) {
202007
202454
  reject2(err);
202008
202455
  return;
202009
202456
  }
202010
- resolve5(createIterResult(void 0, true));
202457
+ resolve6(createIterResult(void 0, true));
202011
202458
  });
202012
202459
  });
202013
202460
  }), _Object$setPrototypeO), AsyncIteratorPrototype);
@@ -202029,15 +202476,15 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
202029
202476
  value: stream2._readableState.endEmitted,
202030
202477
  writable: true
202031
202478
  }), _defineProperty2(_Object$create, kHandlePromise, {
202032
- value: function value(resolve5, reject2) {
202479
+ value: function value(resolve6, reject2) {
202033
202480
  var data = iterator[kStream].read();
202034
202481
  if (data) {
202035
202482
  iterator[kLastPromise] = null;
202036
202483
  iterator[kLastResolve] = null;
202037
202484
  iterator[kLastReject] = null;
202038
- resolve5(createIterResult(data, false));
202485
+ resolve6(createIterResult(data, false));
202039
202486
  } else {
202040
- iterator[kLastResolve] = resolve5;
202487
+ iterator[kLastResolve] = resolve6;
202041
202488
  iterator[kLastReject] = reject2;
202042
202489
  }
202043
202490
  },
@@ -202056,12 +202503,12 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
202056
202503
  iterator[kError] = err;
202057
202504
  return;
202058
202505
  }
202059
- var resolve5 = iterator[kLastResolve];
202060
- if (resolve5 !== null) {
202506
+ var resolve6 = iterator[kLastResolve];
202507
+ if (resolve6 !== null) {
202061
202508
  iterator[kLastPromise] = null;
202062
202509
  iterator[kLastResolve] = null;
202063
202510
  iterator[kLastReject] = null;
202064
- resolve5(createIterResult(void 0, true));
202511
+ resolve6(createIterResult(void 0, true));
202065
202512
  }
202066
202513
  iterator[kEnded] = true;
202067
202514
  });
@@ -213427,7 +213874,7 @@ var require_xml = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
213427
213874
  }
213428
213875
  }
213429
213876
  function add(value, last2) {
213430
- format(append, resolve5(value, indent, indent ? 1 : 0), last2);
213877
+ format(append, resolve6(value, indent, indent ? 1 : 0), last2);
213431
213878
  }
213432
213879
  function end() {
213433
213880
  if (stream2) {
@@ -213466,12 +213913,12 @@ var require_xml = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
213466
213913
  return output;
213467
213914
  }
213468
213915
  function element() {
213469
- var self2 = { _elem: resolve5(Array.prototype.slice.call(arguments)) };
213916
+ var self2 = { _elem: resolve6(Array.prototype.slice.call(arguments)) };
213470
213917
  self2.push = function(input) {
213471
213918
  if (!this.append) throw new Error("not assigned to a parent!");
213472
213919
  var that = this;
213473
213920
  var indent = this._elem.indent;
213474
- format(this.append, resolve5(input, indent, this._elem.icount + (indent ? 1 : 0)), function() {
213921
+ format(this.append, resolve6(input, indent, this._elem.icount + (indent ? 1 : 0)), function() {
213475
213922
  that.append(true);
213476
213923
  });
213477
213924
  };
@@ -213484,7 +213931,7 @@ var require_xml = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
213484
213931
  function create_indent(character, count) {
213485
213932
  return new Array(count || 0).join(character || "");
213486
213933
  }
213487
- function resolve5(data, indent, indent_count) {
213934
+ function resolve6(data, indent, indent_count) {
213488
213935
  indent_count = indent_count || 0;
213489
213936
  var indent_spaces = create_indent(indent, indent_count);
213490
213937
  var name;
@@ -213519,7 +213966,7 @@ var require_xml = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
213519
213966
  content.push("");
213520
213967
  values.forEach(function(value) {
213521
213968
  if (typeof value == "object") if (Object.keys(value)[0] == "_attr") get_attributes(value._attr);
213522
- else content.push(resolve5(value, indent, indent_count + 1));
213969
+ else content.push(resolve6(value, indent, indent_count + 1));
213523
213970
  else {
213524
213971
  content.pop();
213525
213972
  isStringContent = true;
@@ -232328,14 +232775,14 @@ var runners = {
232328
232775
  }
232329
232776
  };
232330
232777
  var solveArc = function(doc, x, y, coords) {
232331
- const [rx, ry, rot, large, sweep, ex, ey] = coords;
232332
- const segs = arcToSegments(ex, ey, rx, ry, large, sweep, rot, x, y);
232778
+ const [rx, ry, rot, large, sweep2, ex, ey] = coords;
232779
+ const segs = arcToSegments(ex, ey, rx, ry, large, sweep2, rot, x, y);
232333
232780
  for (let seg of segs) {
232334
232781
  const bez = segmentToBezier(...seg);
232335
232782
  doc.bezierCurveTo(...bez);
232336
232783
  }
232337
232784
  };
232338
- var arcToSegments = function(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
232785
+ var arcToSegments = function(x, y, rx, ry, large, sweep2, rotateX, ox, oy) {
232339
232786
  const th = rotateX * (Math.PI / 180);
232340
232787
  const sin_th = Math.sin(th);
232341
232788
  const cos_th = Math.cos(th);
@@ -232363,7 +232810,7 @@ var arcToSegments = function(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
232363
232810
  sfactor_sq = 0;
232364
232811
  }
232365
232812
  let sfactor = Math.sqrt(sfactor_sq);
232366
- if (sweep === large) {
232813
+ if (sweep2 === large) {
232367
232814
  sfactor = -sfactor;
232368
232815
  }
232369
232816
  const xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
@@ -232371,9 +232818,9 @@ var arcToSegments = function(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
232371
232818
  const th0 = Math.atan2(y0 - yc, x0 - xc);
232372
232819
  const th1 = Math.atan2(y1 - yc, x1 - xc);
232373
232820
  let th_arc = th1 - th0;
232374
- if (th_arc < 0 && sweep === 1) {
232821
+ if (th_arc < 0 && sweep2 === 1) {
232375
232822
  th_arc += 2 * Math.PI;
232376
- } else if (th_arc > 0 && sweep === 0) {
232823
+ } else if (th_arc > 0 && sweep2 === 0) {
232377
232824
  th_arc -= 2 * Math.PI;
232378
232825
  }
232379
232826
  const segments = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 1e-3)));
@@ -236809,7 +237256,7 @@ var SERIF2 = (bold, italic) => bold && italic ? "Serif-BoldItalic" : bold ? "Ser
236809
237256
  var isEmoji = (cp) => cp >= 126976 || cp >= 9728 && cp <= 10175;
236810
237257
  async function scriptToPdf(doc) {
236811
237258
  const { scriptFont: scriptFont2 } = await Promise.resolve().then(() => (init_script_fonts(), script_fonts_exports));
236812
- return new Promise((resolve5, reject2) => {
237259
+ return new Promise((resolve6, reject2) => {
236813
237260
  const pdf = new PDFDocument({ size: "A4", margins: { top: MARGIN, bottom: MARGIN, left: MARGIN, right: MARGIN }, info: { Title: doc.project, Author: "Patter" } });
236814
237261
  pdf.registerFont("Serif", scriptFont2("serif"));
236815
237262
  pdf.registerFont("Serif-Bold", scriptFont2("serifBold"));
@@ -236850,7 +237297,7 @@ async function scriptToPdf(doc) {
236850
237297
  const bodyPieces = (runs, color, base = {}) => runs.flatMap((r) => r.code ? split(r.text, "Mono", ACCENT) : split(r.text, SERIF2(base.bold || r.bold, base.italic || r.italic), color));
236851
237298
  const chunks = [];
236852
237299
  pdf.on("data", (c2) => chunks.push(c2));
236853
- pdf.on("end", () => resolve5(Buffer.concat(chunks)));
237300
+ pdf.on("end", () => resolve6(Buffer.concat(chunks)));
236854
237301
  pdf.on("error", reject2);
236855
237302
  const pageRight = pdf.page.width - MARGIN;
236856
237303
  const pageBottom = pdf.page.height - MARGIN;
@@ -237033,7 +237480,10 @@ function runInit(opts) {
237033
237480
  scene: sceneId,
237034
237481
  locale: "en",
237035
237482
  default: true,
237036
- strings: { [beatId]: `Welcome to ${name}. Edit scenes/start.patterflow, then run: patter play` }
237483
+ // The starter line is STORY content the writer replaces, so it must read the same however the
237484
+ // project was made: no file paths, no commands. (Front-ends give their own next step - `patter init`
237485
+ // prints "try: patter play <dir>" on the terminal, and Patterpad just opens the scene for editing.)
237486
+ strings: { [beatId]: `Welcome to ${name}. This is the first line of your story - replace it with your own.` }
237037
237487
  };
237038
237488
  const bundle = opts.bundle ?? "commit";
237039
237489
  const projectFile = join4(dir2, `${fileSlug}.patterproj`);
@@ -237402,7 +237852,7 @@ async function runPack(startPath) {
237402
237852
 
237403
237853
  // ../ops/src/unpack.ts
237404
237854
  var import_jszip2 = __toESM(require_lib3(), 1);
237405
- import { join as join5, normalize, isAbsolute as isAbsolute2, sep as sep3 } from "path";
237855
+ import { join as join5, normalize, isAbsolute as isAbsolute2, resolve as resolve4, sep as sep3 } from "path";
237406
237856
  import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
237407
237857
 
237408
237858
  // ../ops/src/merge.ts
@@ -237442,7 +237892,7 @@ function merge3(base, ours, theirs, id, path, conflicts) {
237442
237892
  conflicts.push({ id, path, base, ours, theirs, kind: deletedKind(base, ours, theirs) });
237443
237893
  return ours;
237444
237894
  }
237445
- function mergeMap(base, ours, theirs, prefix, conflicts, resolve5) {
237895
+ function mergeMap(base, ours, theirs, prefix, conflicts, resolve6) {
237446
237896
  const out = {};
237447
237897
  for (const k of /* @__PURE__ */ new Set([...Object.keys(base), ...Object.keys(ours), ...Object.keys(theirs)])) {
237448
237898
  const b = base[k], o = ours[k], t = theirs[k];
@@ -237451,7 +237901,7 @@ function mergeMap(base, ours, theirs, prefix, conflicts, resolve5) {
237451
237901
  else if (eq(b, o)) v = t;
237452
237902
  else if (eq(b, t)) v = o;
237453
237903
  else {
237454
- const r = resolve5?.(k, b, o, t);
237904
+ const r = resolve6?.(k, b, o, t);
237455
237905
  if (r && r.resolved) v = r.value;
237456
237906
  else {
237457
237907
  conflicts.push({ id: k, path: `${prefix}.${k}`, base: b, ours: o, theirs: t, kind: r ? r.kind : deletedKind(b, o, t) });
@@ -237726,29 +238176,60 @@ var arrEq = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
237726
238176
  var MANIFEST = "patter.manifest.json";
237727
238177
  var UnsafeEntryError = class extends Error {
237728
238178
  };
237729
- async function readDocShards(bytes) {
238179
+ async function readDoc(bytes) {
237730
238180
  const zip = await import_jszip2.default.loadAsync(bytes);
237731
- const out = /* @__PURE__ */ new Map();
238181
+ const shards = /* @__PURE__ */ new Map();
238182
+ let manifest;
237732
238183
  for (const [name, entry] of Object.entries(zip.files)) {
237733
- if (entry.dir || name === MANIFEST) continue;
238184
+ if (entry.dir) continue;
238185
+ if (name === MANIFEST) {
238186
+ try {
238187
+ manifest = JSON.parse(await entry.async("string"));
238188
+ } catch {
238189
+ }
238190
+ continue;
238191
+ }
237734
238192
  if (isUnsafeEntry(name)) throw new UnsafeEntryError(`document entry escapes the target directory: ${name}`);
237735
- out.set(name, await entry.async("string"));
238193
+ shards.set(name, await entry.async("string"));
237736
238194
  }
237737
- return out;
238195
+ return { shards, manifest };
238196
+ }
238197
+ async function readDocShards(bytes) {
238198
+ return (await readDoc(bytes)).shards;
237738
238199
  }
237739
238200
  async function runUnpack(bytes, targetDir) {
237740
238201
  const shards = await readDocShards(bytes);
237741
- return [...shards.entries()].map(([name, content]) => ({ path: join5(targetDir, name), content })).sort((a, b) => a.path.localeCompare(b.path));
238202
+ return [...shards.entries()].map(([name, content]) => ({ path: containedWrite(targetDir, name), content })).sort((a, b) => a.path.localeCompare(b.path));
238203
+ }
238204
+ function checkProvenance(returned, base, target) {
238205
+ const known = [returned, base, target].filter((id) => typeof id === "string" && id !== "");
238206
+ return {
238207
+ ...returned !== void 0 ? { returned } : {},
238208
+ ...base !== void 0 ? { base } : {},
238209
+ ...target !== void 0 ? { target } : {},
238210
+ ok: new Set(known).size <= 1
238211
+ };
238212
+ }
238213
+ function targetProjectId(projectDir) {
238214
+ try {
238215
+ const pf = parseSource(readFileSync5(findProjectFile(projectDir), "utf8"));
238216
+ return pf.project?.id;
238217
+ } catch {
238218
+ return void 0;
238219
+ }
237742
238220
  }
237743
238221
  async function runUnpackMerge(returnedBytes, baseBytes, projectDir) {
237744
- const theirs = await readDocShards(returnedBytes);
237745
- const base = await readDocShards(baseBytes);
238222
+ const returnedDoc = await readDoc(returnedBytes);
238223
+ const baseDoc = await readDoc(baseBytes);
238224
+ const theirs = returnedDoc.shards;
238225
+ const base = baseDoc.shards;
238226
+ const provenance = checkProvenance(returnedDoc.manifest?.project?.id, baseDoc.manifest?.project?.id, targetProjectId(projectDir));
237746
238227
  const shards = [];
237747
238228
  const writes = [];
237748
238229
  const sidecars = [];
237749
238230
  let conflicts = 0, warnings = 0;
237750
238231
  for (const [rel, theirText] of [...theirs.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
237751
- const outPath = join5(projectDir, rel);
238232
+ const outPath = containedWrite(projectDir, rel);
237752
238233
  if (!existsSync3(outPath)) {
237753
238234
  writes.push({ path: outPath, content: theirText });
237754
238235
  shards.push({ path: rel, added: true });
@@ -237767,16 +238248,24 @@ async function runUnpackMerge(returnedBytes, baseBytes, projectDir) {
237767
238248
  warnings += result.warnings.length;
237768
238249
  shards.push({ path: rel, result, added: false });
237769
238250
  }
237770
- return { shards, writes, sidecars, conflicts, warnings };
238251
+ return { shards, writes, sidecars, conflicts, warnings, provenance };
237771
238252
  }
237772
238253
  function isUnsafeEntry(name) {
237773
238254
  if (isAbsolute2(name) || /^[a-zA-Z]:/.test(name)) return true;
237774
238255
  const norm = normalize(name);
237775
238256
  return norm === ".." || norm.startsWith(".." + sep3) || norm.startsWith("../");
237776
238257
  }
238258
+ function containedWrite(dir2, name) {
238259
+ const root2 = resolve4(dir2);
238260
+ const full = resolve4(join5(dir2, name));
238261
+ if (full !== root2 && !full.startsWith(root2 + sep3)) {
238262
+ throw new UnsafeEntryError(`document entry escapes the target directory: ${name}`);
238263
+ }
238264
+ return full;
238265
+ }
237777
238266
 
237778
238267
  // ../../node_modules/@wildwinter/simple-vc-lib/dist/simpleVcLib.js
237779
- import { join as join6, dirname as dirname5, resolve as resolve4, basename as basename6 } from "path";
238268
+ import { join as join6, dirname as dirname5, resolve as resolve5, sep as sep4, basename as basename6 } from "path";
237780
238269
  import { existsSync as existsSync4, readFileSync as readFileSync6, statSync as statSync3, unlinkSync, rmSync, renameSync, accessSync, constants, chmodSync, mkdirSync as mkdirSync2, cpSync, readdirSync as readdirSync4, writeFileSync as writeFileSync2 } from "fs";
237781
238270
  import { spawnSync, spawn } from "child_process";
237782
238271
  var VALID_SYSTEMS = ["git", "perforce", "plastic", "svn", "filesystem"];
@@ -237831,7 +238320,7 @@ async function runCommandAsync(command, args, options = {}) {
237831
238320
  const overridden = await _overrideRunner(command, args, options);
237832
238321
  return { timedOut: false, ...overridden };
237833
238322
  }
237834
- return new Promise((resolve5) => {
238323
+ return new Promise((resolve6) => {
237835
238324
  const child = spawn(command, args, { cwd: options.cwd, windowsHide: true });
237836
238325
  let stdout = "";
237837
238326
  let stderr = "";
@@ -237853,7 +238342,7 @@ async function runCommandAsync(command, args, options = {}) {
237853
238342
  if (settled) return;
237854
238343
  settled = true;
237855
238344
  clearTimeout(timer);
237856
- resolve5(result);
238345
+ resolve6(result);
237857
238346
  };
237858
238347
  child.on("error", (err) => {
237859
238348
  finish({ exitCode: -1, output: "", error: stderr.trim() || err.message, timedOut });
@@ -237869,6 +238358,7 @@ async function runCommandAsync(command, args, options = {}) {
237869
238358
  });
237870
238359
  }
237871
238360
  var _rootCache = /* @__PURE__ */ new Map();
238361
+ var _probedCache = /* @__PURE__ */ new Map();
237872
238362
  function detectProvider(absPath) {
237873
238363
  let dir2;
237874
238364
  try {
@@ -237876,6 +238366,8 @@ function detectProvider(absPath) {
237876
238366
  } catch {
237877
238367
  dir2 = dirname5(absPath);
237878
238368
  }
238369
+ const known = _probedCache.get(dir2);
238370
+ if (known !== void 0) return known;
237879
238371
  let current = dir2;
237880
238372
  while (true) {
237881
238373
  if (_rootCache.has(current)) return _rootCache.get(current);
@@ -237902,8 +238394,9 @@ function detectProvider(absPath) {
237902
238394
  current = parent2;
237903
238395
  }
237904
238396
  const p42 = runCommand("p4", ["info"], { timeout: 3e3 });
237905
- if (p42.exitCode === 0 && p42.output.includes("Client name:")) return "perforce";
237906
- return "filesystem";
238397
+ const answer = p42.exitCode === 0 && p42.output.includes("Client name:") ? "perforce" : "filesystem";
238398
+ _probedCache.set(dir2, answer);
238399
+ return answer;
237907
238400
  }
237908
238401
  function okResult(message = "") {
237909
238402
  return { success: true, status: "ok", message };
@@ -237939,6 +238432,14 @@ var FilesystemProvider = class {
237939
238432
  get name() {
237940
238433
  return "filesystem";
237941
238434
  }
238435
+ /** No version control, so no user. Undefined is the honest answer, not ''. */
238436
+ currentUser() {
238437
+ return void 0;
238438
+ }
238439
+ /** Async twin of {@link currentUser}. */
238440
+ async currentUserAsync() {
238441
+ return void 0;
238442
+ }
237942
238443
  prepareToWrite(filePath) {
237943
238444
  if (!existsSync4(filePath)) return okResult();
237944
238445
  if (isWritable$1(filePath)) return okResult();
@@ -238014,7 +238515,7 @@ var FilesystemProvider = class {
238014
238515
  */
238015
238516
  status(filePaths) {
238016
238517
  return filePaths.map((filePath) => {
238017
- const abs = resolve4(filePath);
238518
+ const abs = resolve5(filePath);
238018
238519
  return { filePath: abs, system: "filesystem", writable: writableBit(abs) };
238019
238520
  });
238020
238521
  }
@@ -238047,20 +238548,48 @@ function git(args, cwd, options = {}) {
238047
238548
  function gitAsync(args, cwd, options = {}) {
238048
238549
  return runCommandAsync("git", gitArgv(args, cwd), { cwd, ...options });
238049
238550
  }
238551
+ function gitUserName(cwd) {
238552
+ const r = git(["config", "user.name"], cwd);
238553
+ const name = r.exitCode === 0 ? r.output.trim() : "";
238554
+ return name === "" ? void 0 : name;
238555
+ }
238556
+ async function gitUserNameAsync(cwd) {
238557
+ const r = await gitAsync(["config", "user.name"], cwd);
238558
+ const name = r.exitCode === 0 ? r.output.trim() : "";
238559
+ return name === "" ? void 0 : name;
238560
+ }
238050
238561
  function gitArgv(args, cwd) {
238051
238562
  const isWindows = process.platform === "win32";
238052
238563
  const safeCwd = isWindows ? cwd.replace(/\\/g, "/") : cwd;
238053
238564
  const safeArgs = isWindows ? args.map((arg) => typeof arg === "string" ? arg.replace(/\\/g, "/") : arg) : args;
238054
238565
  return ["-C", safeCwd, ...safeArgs];
238055
238566
  }
238567
+ var _trackedCache = /* @__PURE__ */ new Set();
238056
238568
  function isTracked$2(filePath) {
238569
+ const key2 = resolve5(filePath);
238570
+ if (_trackedCache.has(key2)) return true;
238057
238571
  const result = git(["ls-files", "--error-unmatch", filePath], dirname5(filePath));
238572
+ if (result.exitCode === 0) _trackedCache.add(key2);
238058
238573
  return result.exitCode === 0;
238059
238574
  }
238060
238575
  async function isTrackedAsync$2(filePath) {
238576
+ const key2 = resolve5(filePath);
238577
+ if (_trackedCache.has(key2)) return true;
238061
238578
  const result = await gitAsync(["ls-files", "--error-unmatch", filePath], dirname5(filePath));
238579
+ if (result.exitCode === 0) _trackedCache.add(key2);
238062
238580
  return result.exitCode === 0;
238063
238581
  }
238582
+ function markTracked(filePath) {
238583
+ _trackedCache.add(resolve5(filePath));
238584
+ }
238585
+ function unmarkTracked(filePath) {
238586
+ _trackedCache.delete(resolve5(filePath));
238587
+ }
238588
+ function unmarkTrackedUnder(folderPath) {
238589
+ const prefix = resolve5(folderPath) + sep4;
238590
+ for (const path of _trackedCache) if (path.startsWith(prefix)) _trackedCache.delete(path);
238591
+ _trackedCache.delete(resolve5(folderPath));
238592
+ }
238064
238593
  function isInRepo(dir2) {
238065
238594
  return git(["rev-parse", "--git-dir"], dir2).exitCode === 0;
238066
238595
  }
@@ -238071,6 +238600,14 @@ var GitProvider = class {
238071
238600
  get name() {
238072
238601
  return "git";
238073
238602
  }
238603
+ /** `git config user.name`, resolved from `cwd` so a repo-local override wins over the global one. */
238604
+ currentUser(cwd = process.cwd()) {
238605
+ return gitUserName(cwd);
238606
+ }
238607
+ /** Async twin of {@link currentUser}. */
238608
+ currentUserAsync(cwd = process.cwd()) {
238609
+ return gitUserNameAsync(cwd);
238610
+ }
238074
238611
  prepareToWrite(filePath) {
238075
238612
  if (!existsSync4(filePath)) return okResult();
238076
238613
  if (isWritable(filePath)) return okResult();
@@ -238085,7 +238622,10 @@ var GitProvider = class {
238085
238622
  if (!isInRepo(cwd))
238086
238623
  return fs$3.finishedWrite(filePath);
238087
238624
  const result = git(["add", filePath], cwd);
238088
- if (result.exitCode === 0) return okResult("File added to git");
238625
+ if (result.exitCode === 0) {
238626
+ markTracked(filePath);
238627
+ return okResult("File added to git");
238628
+ }
238089
238629
  const combined = (result.output + " " + result.error).toLowerCase();
238090
238630
  if (combined.includes("ignored")) return fs$3.finishedWrite(filePath);
238091
238631
  return errorResult("error", `Cannot add '${filePath}' to git: ${result.error || result.output}`);
@@ -238103,7 +238643,10 @@ var GitProvider = class {
238103
238643
  if (!await isInRepoAsync(cwd))
238104
238644
  return fs$3.finishedWriteAsync(filePath);
238105
238645
  const result = await gitAsync(["add", filePath], cwd);
238106
- if (result.exitCode === 0) return okResult("File added to git");
238646
+ if (result.exitCode === 0) {
238647
+ markTracked(filePath);
238648
+ return okResult("File added to git");
238649
+ }
238107
238650
  const combined = (result.output + " " + result.error).toLowerCase();
238108
238651
  if (combined.includes("ignored")) return fs$3.finishedWriteAsync(filePath);
238109
238652
  return errorResult("error", `Cannot add '${filePath}' to git: ${result.error || result.output}`);
@@ -238113,7 +238656,10 @@ var GitProvider = class {
238113
238656
  if (!existsSync4(filePath)) return okResult();
238114
238657
  if (await isTrackedAsync$2(filePath)) {
238115
238658
  const result = await gitAsync(["rm", "--force", filePath], dirname5(filePath));
238116
- if (result.exitCode === 0) return okResult();
238659
+ if (result.exitCode === 0) {
238660
+ unmarkTracked(filePath);
238661
+ return okResult();
238662
+ }
238117
238663
  return errorResult("error", `Cannot delete '${filePath}' from git: ${result.error || result.output}`);
238118
238664
  }
238119
238665
  try {
@@ -238129,6 +238675,7 @@ var GitProvider = class {
238129
238675
  const listResult = await gitAsync(["ls-files", folderPath], folderPath);
238130
238676
  if (listResult.exitCode === 0 && listResult.output.length > 0) {
238131
238677
  const rmResult = await gitAsync(["rm", "-r", "--force", folderPath], folderPath);
238678
+ if (rmResult.exitCode === 0) unmarkTrackedUnder(folderPath);
238132
238679
  if (rmResult.exitCode !== 0)
238133
238680
  return errorResult("error", `Cannot delete folder '${folderPath}' from git: ${rmResult.error || rmResult.output}`);
238134
238681
  }
@@ -238146,7 +238693,11 @@ var GitProvider = class {
238146
238693
  if (!existsSync4(oldPath)) return okResult();
238147
238694
  if (await isTrackedAsync$2(oldPath)) {
238148
238695
  const result = await gitAsync(["mv", oldPath, newPath], dirname5(oldPath));
238149
- if (result.exitCode === 0) return okResult();
238696
+ if (result.exitCode === 0) {
238697
+ unmarkTracked(oldPath);
238698
+ markTracked(newPath);
238699
+ return okResult();
238700
+ }
238150
238701
  return errorResult("error", `Cannot rename '${oldPath}' in git: ${result.error || result.output}`);
238151
238702
  }
238152
238703
  try {
@@ -238160,6 +238711,7 @@ var GitProvider = class {
238160
238711
  async renameFolderAsync(oldPath, newPath) {
238161
238712
  if (!existsSync4(oldPath)) return okResult();
238162
238713
  const result = await gitAsync(["mv", oldPath, newPath], dirname5(oldPath));
238714
+ unmarkTrackedUnder(oldPath);
238163
238715
  if (result.exitCode === 0) return okResult();
238164
238716
  try {
238165
238717
  renameSync(oldPath, newPath);
@@ -238172,7 +238724,10 @@ var GitProvider = class {
238172
238724
  if (!existsSync4(filePath)) return okResult();
238173
238725
  if (isTracked$2(filePath)) {
238174
238726
  const result = git(["rm", "--force", filePath], dirname5(filePath));
238175
- if (result.exitCode === 0) return okResult();
238727
+ if (result.exitCode === 0) {
238728
+ unmarkTracked(filePath);
238729
+ return okResult();
238730
+ }
238176
238731
  return errorResult("error", `Cannot delete '${filePath}' from git: ${result.error || result.output}`);
238177
238732
  }
238178
238733
  try {
@@ -238186,7 +238741,11 @@ var GitProvider = class {
238186
238741
  if (!existsSync4(oldPath)) return okResult();
238187
238742
  if (isTracked$2(oldPath)) {
238188
238743
  const result = git(["mv", oldPath, newPath], dirname5(oldPath));
238189
- if (result.exitCode === 0) return okResult();
238744
+ if (result.exitCode === 0) {
238745
+ unmarkTracked(oldPath);
238746
+ markTracked(newPath);
238747
+ return okResult();
238748
+ }
238190
238749
  return errorResult("error", `Cannot rename '${oldPath}' in git: ${result.error || result.output}`);
238191
238750
  }
238192
238751
  try {
@@ -238199,6 +238758,7 @@ var GitProvider = class {
238199
238758
  renameFolder(oldPath, newPath) {
238200
238759
  if (!existsSync4(oldPath)) return okResult();
238201
238760
  const result = git(["mv", oldPath, newPath], dirname5(oldPath));
238761
+ unmarkTrackedUnder(oldPath);
238202
238762
  if (result.exitCode === 0) return okResult();
238203
238763
  try {
238204
238764
  renameSync(oldPath, newPath);
@@ -238212,6 +238772,7 @@ var GitProvider = class {
238212
238772
  const listResult = git(["ls-files", folderPath], folderPath);
238213
238773
  if (listResult.exitCode === 0 && listResult.output.length > 0) {
238214
238774
  const rmResult = git(["rm", "-r", "--force", folderPath], folderPath);
238775
+ if (rmResult.exitCode === 0) unmarkTrackedUnder(folderPath);
238215
238776
  if (rmResult.exitCode !== 0) {
238216
238777
  return errorResult("error", `Cannot delete folder '${folderPath}' from git: ${rmResult.error || rmResult.output}`);
238217
238778
  }
@@ -238227,22 +238788,31 @@ var GitProvider = class {
238227
238788
  }
238228
238789
  /**
238229
238790
  * Status for a batch of files: per repository root, ONE
238230
- * `git status --porcelain -z` (tracked-ness) plus - when git-lfs is in play -
238231
- * ONE `git lfs locks --verify --json` (`--verify` splits ours vs theirs).
238232
- * git itself has no locks; lock-based git workflows are git-lfs locks.
238791
+ * `git status --porcelain -z` (tracked-ness) plus - only when this repo uses
238792
+ * git-lfs file locking AND `{ remote: true }` was asked - ONE
238793
+ * `git lfs locks --verify --json` (`--verify` splits ours vs theirs).
238794
+ *
238795
+ * `git lfs locks` ALWAYS contacts the lock server (there is no local lock list),
238796
+ * a network round-trip that can trigger a credential prompt (on Windows the
238797
+ * GitHub sign-in window, #26). So a plain git repo - no LFS locking - never hits
238798
+ * the network here, matching a lock-free git workflow's expectation, and even an
238799
+ * LFS-locking repo only pays the round-trip when the caller opts in with `remote`.
238800
+ * Lock use is detected locally by a `lockable` attribute in the repo's
238801
+ * `.gitattributes`; git itself has no locks.
238233
238802
  *
238234
238803
  * All matching is done on REPO-RELATIVE paths (via `rev-parse --show-prefix`),
238235
238804
  * never by joining absolute paths - so symlinked ancestors (macOS `/var` ->
238236
238805
  * `/private/var`, `/tmp` -> `/private/tmp`) cannot break the lookup.
238237
238806
  *
238238
238807
  * @param {string[]} filePaths
238808
+ * @param {import('../vcStatus.js').VCStatusOptions} [options]
238239
238809
  * @returns {import('../vcStatus.js').VCFileStatus[]}
238240
238810
  */
238241
- status(filePaths) {
238811
+ status(filePaths, options = {}) {
238242
238812
  const infoByDir = /* @__PURE__ */ new Map();
238243
238813
  const groups = /* @__PURE__ */ new Map();
238244
238814
  for (const filePath of filePaths) {
238245
- const abs = resolve4(filePath);
238815
+ const abs = resolve5(filePath);
238246
238816
  const dir2 = dirname5(abs);
238247
238817
  let info = infoByDir.get(dir2);
238248
238818
  if (info === void 0) {
@@ -238258,20 +238828,21 @@ var GitProvider = class {
238258
238828
  continue;
238259
238829
  }
238260
238830
  const st = git(["status", "--porcelain", "-z", "--", ...files.map((f) => f.relKey)], root2, { trim: false });
238261
- const locks = git(["lfs", "locks", "--verify", "--json"], root2);
238831
+ const locks = shouldQueryLfsLocks(root2, options) ? git(["lfs", "locks", "--verify", "--json"], root2) : NO_LOCKS;
238262
238832
  assembleGitStatuses(files, gitStates(st), gitLocks(locks), byInput);
238263
238833
  }
238264
238834
  return filePaths.map((filePath) => byInput.get(filePath));
238265
238835
  }
238266
238836
  /**
238267
238837
  * Async twin of {@link status}. Within each repo the porcelain status and the
238268
- * git-lfs lock list are independent, so they run concurrently.
238838
+ * git-lfs lock list are independent, so they run concurrently - and the lock
238839
+ * query is gated exactly as in {@link status} (LFS locking in use + `remote`).
238269
238840
  */
238270
- async statusAsync(filePaths) {
238841
+ async statusAsync(filePaths, options = {}) {
238271
238842
  const infoByDir = /* @__PURE__ */ new Map();
238272
238843
  const groups = /* @__PURE__ */ new Map();
238273
238844
  for (const filePath of filePaths) {
238274
- const abs = resolve4(filePath);
238845
+ const abs = resolve5(filePath);
238275
238846
  const dir2 = dirname5(abs);
238276
238847
  let info = infoByDir.get(dir2);
238277
238848
  if (info === void 0) {
@@ -238288,13 +238859,24 @@ var GitProvider = class {
238288
238859
  }
238289
238860
  const [st, locks] = await Promise.all([
238290
238861
  gitAsync(["status", "--porcelain", "-z", "--", ...files.map((f) => f.relKey)], root2, { trim: false }),
238291
- gitAsync(["lfs", "locks", "--verify", "--json"], root2)
238862
+ shouldQueryLfsLocks(root2, options) ? gitAsync(["lfs", "locks", "--verify", "--json"], root2) : Promise.resolve(NO_LOCKS)
238292
238863
  ]);
238293
238864
  assembleGitStatuses(files, gitStates(st), gitLocks(locks), byInput);
238294
238865
  }
238295
238866
  return filePaths.map((filePath) => byInput.get(filePath));
238296
238867
  }
238297
238868
  };
238869
+ var NO_LOCKS = { exitCode: 1, output: "", error: "" };
238870
+ function shouldQueryLfsLocks(root2, options) {
238871
+ return options.remote === true && repoUsesLfsLocks(root2);
238872
+ }
238873
+ function repoUsesLfsLocks(root2) {
238874
+ try {
238875
+ return /(^|\s)lockable(\s|$)/m.test(readFileSync6(join6(root2, ".gitattributes"), "utf8"));
238876
+ } catch {
238877
+ return false;
238878
+ }
238879
+ }
238298
238880
  function gitDirInfo(result) {
238299
238881
  if (result.exitCode === 0) {
238300
238882
  const lines = result.output.split("\n");
@@ -238367,6 +238949,18 @@ function p4(args) {
238367
238949
  function p4Async(args) {
238368
238950
  return runCommandAsync("p4", args);
238369
238951
  }
238952
+ function p4UserName() {
238953
+ return parseP4User(p4(["info"]));
238954
+ }
238955
+ async function p4UserNameAsync() {
238956
+ return parseP4User(await p4Async(["info"]));
238957
+ }
238958
+ function parseP4User(result) {
238959
+ if (result.exitCode !== 0) return void 0;
238960
+ const line2 = /^User name:\s*(.+)$/m.exec(result.output);
238961
+ const name = line2?.[1]?.trim() ?? "";
238962
+ return name === "" ? void 0 : name;
238963
+ }
238370
238964
  function fstat(filePath) {
238371
238965
  const result = p4(["fstat", filePath]);
238372
238966
  if (result.exitCode !== 0) return null;
@@ -238421,6 +239015,14 @@ var PerforceProvider = class {
238421
239015
  get name() {
238422
239016
  return "perforce";
238423
239017
  }
239018
+ /** The `User name` p4 reports, which is the name it puts in `lockedBy`. */
239019
+ currentUser() {
239020
+ return p4UserName();
239021
+ }
239022
+ /** Async twin of {@link currentUser}. */
239023
+ currentUserAsync() {
239024
+ return p4UserNameAsync();
239025
+ }
238424
239026
  prepareToWrite(filePath) {
238425
239027
  if (!existsSync4(filePath)) return okResult();
238426
239028
  const info = fstat(filePath);
@@ -238755,10 +239357,10 @@ function buildPerforceStatuses(output, filePaths) {
238755
239357
  const byClientFile = /* @__PURE__ */ new Map();
238756
239358
  for (const record of records) {
238757
239359
  const clientFile = record.fields.get("clientFile");
238758
- if (clientFile) byClientFile.set(resolve4(clientFile), record);
239360
+ if (clientFile) byClientFile.set(resolve5(clientFile), record);
238759
239361
  }
238760
239362
  return filePaths.map((filePath) => {
238761
- const abs = resolve4(filePath);
239363
+ const abs = resolve5(filePath);
238762
239364
  const status = { filePath: abs, system: "perforce", writable: writableBit(abs) };
238763
239365
  const record = byClientFile.get(abs);
238764
239366
  if (!record) {
@@ -238833,6 +239435,16 @@ var PlasticProvider = class {
238833
239435
  get name() {
238834
239436
  return "plastic";
238835
239437
  }
239438
+ /** `cm whoami`, the same call the lock check already makes to tell our lock from someone else's. */
239439
+ currentUser() {
239440
+ const u = plasticWhoami();
239441
+ return u === "" ? void 0 : u;
239442
+ }
239443
+ /** Async twin of {@link currentUser}. */
239444
+ async currentUserAsync() {
239445
+ const u = await plasticWhoamiAsync();
239446
+ return u === "" ? void 0 : u;
239447
+ }
238836
239448
  prepareToWrite(filePath) {
238837
239449
  if (!existsSync4(filePath)) return okResult();
238838
239450
  if (!isTracked$1(filePath)) {
@@ -239034,7 +239646,7 @@ var PlasticProvider = class {
239034
239646
  }
239035
239647
  };
239036
239648
  function plasticStatusArgs(filePaths) {
239037
- return ["status", "--machinereadable", "--all", "--ignored", ...filePaths.map((p) => resolve4(p))];
239649
+ return ["status", "--machinereadable", "--all", "--ignored", ...filePaths.map((p) => resolve5(p))];
239038
239650
  }
239039
239651
  function buildPlasticBase(result, filePaths) {
239040
239652
  const byPath = /* @__PURE__ */ new Map();
@@ -239044,7 +239656,7 @@ function buildPlasticBase(result, filePaths) {
239044
239656
  const parsed = parseCmStatusLine(line2);
239045
239657
  if (!parsed) continue;
239046
239658
  for (const p of parsed.paths) {
239047
- const abs = resolve4(p);
239659
+ const abs = resolve5(p);
239048
239660
  byPath.set(abs, parsed.info);
239049
239661
  const base = basename6(abs);
239050
239662
  if (!byBase.has(base)) byBase.set(base, []);
@@ -239053,7 +239665,7 @@ function buildPlasticBase(result, filePaths) {
239053
239665
  }
239054
239666
  }
239055
239667
  return filePaths.map((filePath) => {
239056
- const abs = resolve4(filePath);
239668
+ const abs = resolve5(filePath);
239057
239669
  const status = { filePath: abs, system: "plastic", writable: writableBit(abs) };
239058
239670
  let info = byPath.get(abs);
239059
239671
  if (!info) {
@@ -239160,6 +239772,22 @@ var SvnProvider = class {
239160
239772
  get name() {
239161
239773
  return "svn";
239162
239774
  }
239775
+ /**
239776
+ * Undefined, deliberately.
239777
+ *
239778
+ * Unlike the others this provider never learns a username: it tells our lock from someone else's by
239779
+ * comparing the working copy's lock TOKEN against the server's, which needs no identity at all. The
239780
+ * only sources are `svn auth` (1.9+, a human-readable dump whose shape is not a contract) and the
239781
+ * `~/.subversion/auth` cache (an implementation detail of the client). Guessing wrong here is worse
239782
+ * than saying nothing, because the answer seeds an identity box the author then has to correct.
239783
+ */
239784
+ currentUser() {
239785
+ return void 0;
239786
+ }
239787
+ /** Async twin of {@link currentUser}. */
239788
+ async currentUserAsync() {
239789
+ return void 0;
239790
+ }
239163
239791
  prepareToWrite(filePath) {
239164
239792
  if (!existsSync4(filePath)) return okResult();
239165
239793
  const fsResult = fs3.prepareToWrite(filePath);
@@ -239347,7 +239975,7 @@ var SvnProvider = class {
239347
239975
  }
239348
239976
  };
239349
239977
  function svnStatusArgs(filePaths, options) {
239350
- const targets = filePaths.map((p) => resolve4(p));
239978
+ const targets = filePaths.map((p) => resolve5(p));
239351
239979
  return ["status", "--xml", "-v", ...options.remote ? ["-u"] : [], ...targets];
239352
239980
  }
239353
239981
  function buildSvnStatuses(output, filePaths) {
@@ -239357,7 +239985,7 @@ function buildSvnStatuses(output, filePaths) {
239357
239985
  const entryRe = /<entry\b[^>]*\bpath="([^"]*)"[^>]*>([\s\S]*?)<\/entry>/g;
239358
239986
  let m;
239359
239987
  while ((m = entryRe.exec(output)) !== null) {
239360
- const entryPath = resolve4(decodeXmlAttr(m[1]));
239988
+ const entryPath = resolve5(decodeXmlAttr(m[1]));
239361
239989
  const info = parseSvnEntry(m[2]);
239362
239990
  if (!info) continue;
239363
239991
  byPath.set(entryPath, info);
@@ -239367,7 +239995,7 @@ function buildSvnStatuses(output, filePaths) {
239367
239995
  }
239368
239996
  }
239369
239997
  return filePaths.map((filePath) => {
239370
- const abs = resolve4(filePath);
239998
+ const abs = resolve5(filePath);
239371
239999
  const status = { filePath: abs, system: "svn", writable: writableBit(abs) };
239372
240000
  let info = byPath.get(abs);
239373
240001
  if (!info) {
@@ -239441,7 +240069,7 @@ var PROVIDER_MAP = {
239441
240069
  };
239442
240070
  var _overrideProvider = null;
239443
240071
  function dirOf(p) {
239444
- const abs = resolve4(p);
240072
+ const abs = resolve5(p);
239445
240073
  try {
239446
240074
  return statSync3(abs).isDirectory() ? abs : dirname5(abs);
239447
240075
  } catch {
@@ -239456,7 +240084,7 @@ function resolveProvider(filePath) {
239456
240084
  const factory = PROVIDER_MAP[config.system];
239457
240085
  if (factory) return factory();
239458
240086
  }
239459
- const detected = detectProvider(resolve4(filePath));
240087
+ const detected = detectProvider(resolve5(filePath));
239460
240088
  return (PROVIDER_MAP[detected] ?? PROVIDER_MAP.filesystem)();
239461
240089
  }
239462
240090
  function deleteFile(filePath) {
@@ -239470,14 +240098,15 @@ function writeTextFile(filePath, content, encoding = "utf8", forceWrite = false)
239470
240098
  } catch {
239471
240099
  }
239472
240100
  }
239473
- const prep = resolveProvider(filePath).prepareToWrite(filePath);
240101
+ const provider = resolveProvider(filePath);
240102
+ const prep = provider.prepareToWrite(filePath);
239474
240103
  if (!prep.success) return prep;
239475
240104
  try {
239476
240105
  writeFileSync2(filePath, content, { encoding });
239477
240106
  } catch (e) {
239478
240107
  return { success: false, status: "error", message: e.message };
239479
240108
  }
239480
- return resolveProvider(filePath).finishedWrite(filePath);
240109
+ return provider.finishedWrite(filePath);
239481
240110
  }
239482
240111
  function writeBinaryFile(filePath, data, forceWrite = false) {
239483
240112
  if (!forceWrite && existsSync4(filePath)) {
@@ -239488,19 +240117,20 @@ function writeBinaryFile(filePath, data, forceWrite = false) {
239488
240117
  } catch {
239489
240118
  }
239490
240119
  }
239491
- const prep = resolveProvider(filePath).prepareToWrite(filePath);
240120
+ const provider = resolveProvider(filePath);
240121
+ const prep = provider.prepareToWrite(filePath);
239492
240122
  if (!prep.success) return prep;
239493
240123
  try {
239494
240124
  writeFileSync2(filePath, data);
239495
240125
  } catch (e) {
239496
240126
  return { success: false, status: "error", message: e.message };
239497
240127
  }
239498
- return resolveProvider(filePath).finishedWrite(filePath);
240128
+ return provider.finishedWrite(filePath);
239499
240129
  }
239500
240130
  function writeTextFiles(files, encoding = "utf8") {
239501
240131
  const results = files.map(({ filePath, content }) => {
239502
240132
  try {
239503
- mkdirSync2(dirname5(resolve4(filePath)), { recursive: true });
240133
+ mkdirSync2(dirname5(resolve5(filePath)), { recursive: true });
239504
240134
  } catch (e) {
239505
240135
  return { filePath, success: false, status: "error", message: e.message };
239506
240136
  }
@@ -239962,6 +240592,13 @@ ${count} issue(s)`);
239962
240592
  return 2;
239963
240593
  }
239964
240594
  const res = await runUnpackMerge(readFileSync7(file), readFileSync7(flags.base), flags.o);
240595
+ if (!res.provenance.ok) {
240596
+ console.error("warning: these do not look like the same project");
240597
+ console.error(` returned pack: ${res.provenance.returned ?? "(no manifest)"}`);
240598
+ console.error(` base pack: ${res.provenance.base ?? "(no manifest)"}`);
240599
+ console.error(` project at -o: ${res.provenance.target ?? "(no project file)"}`);
240600
+ console.error(" merging anyway; expect spurious conflicts if the ancestor is wrong.");
240601
+ }
239965
240602
  if (!commitWrites([...res.writes, ...res.sidecars])) return 1;
239966
240603
  for (const s of res.shards) {
239967
240604
  const n = s.result ? s.result.conflicts.length : 0;