@patterkit/cli 0.3.8 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +633 -331
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -105,7 +105,7 @@ var require_under_dash = __commonJS({
|
|
|
105
105
|
const bType = typeof b;
|
|
106
106
|
const aArray = Array.isArray(a);
|
|
107
107
|
const bArray = Array.isArray(b);
|
|
108
|
-
let
|
|
108
|
+
let keys2;
|
|
109
109
|
if (aType !== bType) {
|
|
110
110
|
return false;
|
|
111
111
|
}
|
|
@@ -123,11 +123,11 @@ var require_under_dash = __commonJS({
|
|
|
123
123
|
if (a === null || b === null) {
|
|
124
124
|
return a === b;
|
|
125
125
|
}
|
|
126
|
-
|
|
127
|
-
if (Object.keys(b).length !==
|
|
126
|
+
keys2 = Object.keys(a);
|
|
127
|
+
if (Object.keys(b).length !== keys2.length) {
|
|
128
128
|
return false;
|
|
129
129
|
}
|
|
130
|
-
for (const key2 of
|
|
130
|
+
for (const key2 of keys2) {
|
|
131
131
|
if (!b.hasOwnProperty(key2)) {
|
|
132
132
|
return false;
|
|
133
133
|
}
|
|
@@ -4908,11 +4908,11 @@ var require_stream_duplex = __commonJS({
|
|
|
4908
4908
|
"use strict";
|
|
4909
4909
|
var pna = require_process_nextick_args();
|
|
4910
4910
|
var objectKeys = Object.keys || function(obj2) {
|
|
4911
|
-
var
|
|
4911
|
+
var keys3 = [];
|
|
4912
4912
|
for (var key2 in obj2) {
|
|
4913
|
-
|
|
4913
|
+
keys3.push(key2);
|
|
4914
4914
|
}
|
|
4915
|
-
return
|
|
4915
|
+
return keys3;
|
|
4916
4916
|
};
|
|
4917
4917
|
module2.exports = Duplex;
|
|
4918
4918
|
var util2 = Object.create(require_util());
|
|
@@ -4921,13 +4921,13 @@ var require_stream_duplex = __commonJS({
|
|
|
4921
4921
|
var Writable = require_stream_writable();
|
|
4922
4922
|
util2.inherits(Duplex, Readable);
|
|
4923
4923
|
{
|
|
4924
|
-
|
|
4925
|
-
for (v = 0; v <
|
|
4926
|
-
method =
|
|
4924
|
+
keys2 = objectKeys(Writable.prototype);
|
|
4925
|
+
for (v = 0; v < keys2.length; v++) {
|
|
4926
|
+
method = keys2[v];
|
|
4927
4927
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
4928
4928
|
}
|
|
4929
4929
|
}
|
|
4930
|
-
var
|
|
4930
|
+
var keys2;
|
|
4931
4931
|
var method;
|
|
4932
4932
|
var v;
|
|
4933
4933
|
function Duplex(options) {
|
|
@@ -13820,14 +13820,14 @@ var require_buffer_list = __commonJS({
|
|
|
13820
13820
|
"../../node_modules/readable-stream/lib/internal/streams/buffer_list.js"(exports2, module2) {
|
|
13821
13821
|
"use strict";
|
|
13822
13822
|
function ownKeys2(object, enumerableOnly) {
|
|
13823
|
-
var
|
|
13823
|
+
var keys2 = Object.keys(object);
|
|
13824
13824
|
if (Object.getOwnPropertySymbols) {
|
|
13825
13825
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
13826
13826
|
enumerableOnly && (symbols = symbols.filter(function(sym) {
|
|
13827
13827
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
13828
|
-
})),
|
|
13828
|
+
})), keys2.push.apply(keys2, symbols);
|
|
13829
13829
|
}
|
|
13830
|
-
return
|
|
13830
|
+
return keys2;
|
|
13831
13831
|
}
|
|
13832
13832
|
function _objectSpread(target) {
|
|
13833
13833
|
for (var i = 1; i < arguments.length; i++) {
|
|
@@ -14747,22 +14747,22 @@ var require_stream_duplex2 = __commonJS({
|
|
|
14747
14747
|
"../../node_modules/readable-stream/lib/_stream_duplex.js"(exports2, module2) {
|
|
14748
14748
|
"use strict";
|
|
14749
14749
|
var objectKeys = Object.keys || function(obj2) {
|
|
14750
|
-
var
|
|
14751
|
-
for (var key2 in obj2)
|
|
14752
|
-
return
|
|
14750
|
+
var keys3 = [];
|
|
14751
|
+
for (var key2 in obj2) keys3.push(key2);
|
|
14752
|
+
return keys3;
|
|
14753
14753
|
};
|
|
14754
14754
|
module2.exports = Duplex;
|
|
14755
14755
|
var Readable = require_stream_readable2();
|
|
14756
14756
|
var Writable = require_stream_writable2();
|
|
14757
14757
|
require_inherits()(Duplex, Readable);
|
|
14758
14758
|
{
|
|
14759
|
-
|
|
14760
|
-
for (v = 0; v <
|
|
14761
|
-
method =
|
|
14759
|
+
keys2 = objectKeys(Writable.prototype);
|
|
14760
|
+
for (v = 0; v < keys2.length; v++) {
|
|
14761
|
+
method = keys2[v];
|
|
14762
14762
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
14763
14763
|
}
|
|
14764
14764
|
}
|
|
14765
|
-
var
|
|
14765
|
+
var keys2;
|
|
14766
14766
|
var method;
|
|
14767
14767
|
var v;
|
|
14768
14768
|
function Duplex(options) {
|
|
@@ -15141,14 +15141,14 @@ var require_from = __commonJS({
|
|
|
15141
15141
|
};
|
|
15142
15142
|
}
|
|
15143
15143
|
function ownKeys2(object, enumerableOnly) {
|
|
15144
|
-
var
|
|
15144
|
+
var keys2 = Object.keys(object);
|
|
15145
15145
|
if (Object.getOwnPropertySymbols) {
|
|
15146
15146
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
15147
15147
|
enumerableOnly && (symbols = symbols.filter(function(sym) {
|
|
15148
15148
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
15149
|
-
})),
|
|
15149
|
+
})), keys2.push.apply(keys2, symbols);
|
|
15150
15150
|
}
|
|
15151
|
-
return
|
|
15151
|
+
return keys2;
|
|
15152
15152
|
}
|
|
15153
15153
|
function _objectSpread(target) {
|
|
15154
15154
|
for (var i = 1; i < arguments.length; i++) {
|
|
@@ -29807,7 +29807,7 @@ var require_lodash2 = __commonJS({
|
|
|
29807
29807
|
return result;
|
|
29808
29808
|
}
|
|
29809
29809
|
function getAllKeys(object) {
|
|
29810
|
-
return baseGetAllKeys(object,
|
|
29810
|
+
return baseGetAllKeys(object, keys2, getSymbols);
|
|
29811
29811
|
}
|
|
29812
29812
|
function getMapData(map2, key2) {
|
|
29813
29813
|
var data = map2.__data__;
|
|
@@ -29929,7 +29929,7 @@ var require_lodash2 = __commonJS({
|
|
|
29929
29929
|
return value != null && typeof value == "object";
|
|
29930
29930
|
}
|
|
29931
29931
|
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
|
|
29932
|
-
function
|
|
29932
|
+
function keys2(object) {
|
|
29933
29933
|
return isArrayLike2(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|
29934
29934
|
}
|
|
29935
29935
|
function stubArray() {
|
|
@@ -31263,7 +31263,7 @@ var require_lodash8 = __commonJS({
|
|
|
31263
31263
|
var baseEach = createBaseEach(baseForOwn);
|
|
31264
31264
|
var baseFor = createBaseFor();
|
|
31265
31265
|
function baseForOwn(object, iteratee) {
|
|
31266
|
-
return object && baseFor(object, iteratee,
|
|
31266
|
+
return object && baseFor(object, iteratee, keys2);
|
|
31267
31267
|
}
|
|
31268
31268
|
function baseGet(object, path) {
|
|
31269
31269
|
path = isKey(path, object) ? [path] : castPath(path);
|
|
@@ -31542,7 +31542,7 @@ var require_lodash8 = __commonJS({
|
|
|
31542
31542
|
return false;
|
|
31543
31543
|
}
|
|
31544
31544
|
function equalObjects(object, other, equalFunc, customizer, bitmask, stack2) {
|
|
31545
|
-
var isPartial = bitmask & PARTIAL_COMPARE_FLAG, objProps =
|
|
31545
|
+
var isPartial = bitmask & PARTIAL_COMPARE_FLAG, objProps = keys2(object), objLength = objProps.length, othProps = keys2(other), othLength = othProps.length;
|
|
31546
31546
|
if (objLength != othLength && !isPartial) {
|
|
31547
31547
|
return false;
|
|
31548
31548
|
}
|
|
@@ -31588,7 +31588,7 @@ var require_lodash8 = __commonJS({
|
|
|
31588
31588
|
return isKeyable(key2) ? data[typeof key2 == "string" ? "string" : "hash"] : data.map;
|
|
31589
31589
|
}
|
|
31590
31590
|
function getMatchData(object) {
|
|
31591
|
-
var result =
|
|
31591
|
+
var result = keys2(object), length = result.length;
|
|
31592
31592
|
while (length--) {
|
|
31593
31593
|
var key2 = result[length], value = object[key2];
|
|
31594
31594
|
result[length] = [key2, value, isStrictComparable(value)];
|
|
@@ -31768,7 +31768,7 @@ var require_lodash8 = __commonJS({
|
|
|
31768
31768
|
function hasIn(object, path) {
|
|
31769
31769
|
return object != null && hasPath(object, path, baseHasIn);
|
|
31770
31770
|
}
|
|
31771
|
-
function
|
|
31771
|
+
function keys2(object) {
|
|
31772
31772
|
return isArrayLike2(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|
31773
31773
|
}
|
|
31774
31774
|
function identity(value) {
|
|
@@ -36918,9 +36918,9 @@ var require_legacy_streams = __commonJS({
|
|
|
36918
36918
|
this.mode = 438;
|
|
36919
36919
|
this.bufferSize = 64 * 1024;
|
|
36920
36920
|
options = options || {};
|
|
36921
|
-
var
|
|
36922
|
-
for (var index2 = 0, length =
|
|
36923
|
-
var key2 =
|
|
36921
|
+
var keys2 = Object.keys(options);
|
|
36922
|
+
for (var index2 = 0, length = keys2.length; index2 < length; index2++) {
|
|
36923
|
+
var key2 = keys2[index2];
|
|
36924
36924
|
this[key2] = options[key2];
|
|
36925
36925
|
}
|
|
36926
36926
|
if (this.encoding) this.setEncoding(this.encoding);
|
|
@@ -36966,9 +36966,9 @@ var require_legacy_streams = __commonJS({
|
|
|
36966
36966
|
this.mode = 438;
|
|
36967
36967
|
this.bytesWritten = 0;
|
|
36968
36968
|
options = options || {};
|
|
36969
|
-
var
|
|
36970
|
-
for (var index2 = 0, length =
|
|
36971
|
-
var key2 =
|
|
36969
|
+
var keys2 = Object.keys(options);
|
|
36970
|
+
for (var index2 = 0, length = keys2.length; index2 < length; index2++) {
|
|
36971
|
+
var key2 = keys2[index2];
|
|
36972
36972
|
this[key2] = options[key2];
|
|
36973
36973
|
}
|
|
36974
36974
|
if (this.start !== void 0) {
|
|
@@ -37987,11 +37987,11 @@ var require_stream_duplex3 = __commonJS({
|
|
|
37987
37987
|
"use strict";
|
|
37988
37988
|
var pna = require_process_nextick_args();
|
|
37989
37989
|
var objectKeys = Object.keys || function(obj2) {
|
|
37990
|
-
var
|
|
37990
|
+
var keys3 = [];
|
|
37991
37991
|
for (var key2 in obj2) {
|
|
37992
|
-
|
|
37992
|
+
keys3.push(key2);
|
|
37993
37993
|
}
|
|
37994
|
-
return
|
|
37994
|
+
return keys3;
|
|
37995
37995
|
};
|
|
37996
37996
|
module2.exports = Duplex;
|
|
37997
37997
|
var util2 = Object.create(require_util());
|
|
@@ -38000,13 +38000,13 @@ var require_stream_duplex3 = __commonJS({
|
|
|
38000
38000
|
var Writable = require_stream_writable3();
|
|
38001
38001
|
util2.inherits(Duplex, Readable);
|
|
38002
38002
|
{
|
|
38003
|
-
|
|
38004
|
-
for (v = 0; v <
|
|
38005
|
-
method =
|
|
38003
|
+
keys2 = objectKeys(Writable.prototype);
|
|
38004
|
+
for (v = 0; v < keys2.length; v++) {
|
|
38005
|
+
method = keys2[v];
|
|
38006
38006
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
38007
38007
|
}
|
|
38008
38008
|
}
|
|
38009
|
-
var
|
|
38009
|
+
var keys2;
|
|
38010
38010
|
var method;
|
|
38011
38011
|
var v;
|
|
38012
38012
|
function Duplex(options) {
|
|
@@ -39752,11 +39752,11 @@ var require_stream_duplex4 = __commonJS({
|
|
|
39752
39752
|
"use strict";
|
|
39753
39753
|
var pna = require_process_nextick_args();
|
|
39754
39754
|
var objectKeys = Object.keys || function(obj2) {
|
|
39755
|
-
var
|
|
39755
|
+
var keys3 = [];
|
|
39756
39756
|
for (var key2 in obj2) {
|
|
39757
|
-
|
|
39757
|
+
keys3.push(key2);
|
|
39758
39758
|
}
|
|
39759
|
-
return
|
|
39759
|
+
return keys3;
|
|
39760
39760
|
};
|
|
39761
39761
|
module2.exports = Duplex;
|
|
39762
39762
|
var util2 = Object.create(require_util());
|
|
@@ -39765,13 +39765,13 @@ var require_stream_duplex4 = __commonJS({
|
|
|
39765
39765
|
var Writable = require_stream_writable4();
|
|
39766
39766
|
util2.inherits(Duplex, Readable);
|
|
39767
39767
|
{
|
|
39768
|
-
|
|
39769
|
-
for (v = 0; v <
|
|
39770
|
-
method =
|
|
39768
|
+
keys2 = objectKeys(Writable.prototype);
|
|
39769
|
+
for (v = 0; v < keys2.length; v++) {
|
|
39770
|
+
method = keys2[v];
|
|
39771
39771
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
39772
39772
|
}
|
|
39773
39773
|
}
|
|
39774
|
-
var
|
|
39774
|
+
var keys2;
|
|
39775
39775
|
var method;
|
|
39776
39776
|
var v;
|
|
39777
39777
|
function Duplex(options) {
|
|
@@ -43509,10 +43509,10 @@ var require_glob = __commonJS({
|
|
|
43509
43509
|
if (add === null || typeof add !== "object") {
|
|
43510
43510
|
return origin;
|
|
43511
43511
|
}
|
|
43512
|
-
var
|
|
43513
|
-
var i =
|
|
43512
|
+
var keys2 = Object.keys(add);
|
|
43513
|
+
var i = keys2.length;
|
|
43514
43514
|
while (i--) {
|
|
43515
|
-
origin[
|
|
43515
|
+
origin[keys2[i]] = add[keys2[i]];
|
|
43516
43516
|
}
|
|
43517
43517
|
return origin;
|
|
43518
43518
|
}
|
|
@@ -49354,15 +49354,15 @@ var require_traverse = __commonJS({
|
|
|
49354
49354
|
if (modifiers.before) modifiers.before.call(state, state.node);
|
|
49355
49355
|
if (typeof state.node == "object" && state.node !== null && !state.circular) {
|
|
49356
49356
|
parents.push(state);
|
|
49357
|
-
var
|
|
49358
|
-
|
|
49357
|
+
var keys2 = Object.keys(state.node);
|
|
49358
|
+
keys2.forEach(function(key2, i2) {
|
|
49359
49359
|
path.push(key2);
|
|
49360
49360
|
if (modifiers.pre) modifiers.pre.call(state, state.node[key2], key2);
|
|
49361
49361
|
var child = walker(state.node[key2]);
|
|
49362
49362
|
if (immutable && Object.hasOwnProperty.call(state.node, key2)) {
|
|
49363
49363
|
state.node[key2] = child.node;
|
|
49364
49364
|
}
|
|
49365
|
-
child.isLast = i2 ==
|
|
49365
|
+
child.isLast = i2 == keys2.length - 1;
|
|
49366
49366
|
child.isFirst = i2 == 0;
|
|
49367
49367
|
if (modifiers.post) modifiers.post.call(state, child);
|
|
49368
49368
|
path.pop();
|
|
@@ -49742,12 +49742,12 @@ var require_vars = __commonJS({
|
|
|
49742
49742
|
module2.exports = function(store) {
|
|
49743
49743
|
function getset(name, value) {
|
|
49744
49744
|
var node = vars.store;
|
|
49745
|
-
var
|
|
49746
|
-
|
|
49745
|
+
var keys2 = name.split(".");
|
|
49746
|
+
keys2.slice(0, -1).forEach(function(k) {
|
|
49747
49747
|
if (node[k] === void 0) node[k] = {};
|
|
49748
49748
|
node = node[k];
|
|
49749
49749
|
});
|
|
49750
|
-
var key2 =
|
|
49750
|
+
var key2 = keys2[keys2.length - 1];
|
|
49751
49751
|
if (arguments.length == 1) {
|
|
49752
49752
|
return node[key2];
|
|
49753
49753
|
} else {
|
|
@@ -50282,14 +50282,14 @@ var require_util4 = __commonJS({
|
|
|
50282
50282
|
var ret2 = [];
|
|
50283
50283
|
var visitedKeys = /* @__PURE__ */ Object.create(null);
|
|
50284
50284
|
while (obj2 != null && !isExcludedProto(obj2)) {
|
|
50285
|
-
var
|
|
50285
|
+
var keys2;
|
|
50286
50286
|
try {
|
|
50287
|
-
|
|
50287
|
+
keys2 = getKeys(obj2);
|
|
50288
50288
|
} catch (e) {
|
|
50289
50289
|
return ret2;
|
|
50290
50290
|
}
|
|
50291
|
-
for (var i = 0; i <
|
|
50292
|
-
var key2 =
|
|
50291
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
50292
|
+
var key2 = keys2[i];
|
|
50293
50293
|
if (visitedKeys[key2]) continue;
|
|
50294
50294
|
visitedKeys[key2] = true;
|
|
50295
50295
|
var desc = Object.getOwnPropertyDescriptor(obj2, key2);
|
|
@@ -50326,9 +50326,9 @@ var require_util4 = __commonJS({
|
|
|
50326
50326
|
function isClass(fn) {
|
|
50327
50327
|
try {
|
|
50328
50328
|
if (typeof fn === "function") {
|
|
50329
|
-
var
|
|
50330
|
-
var hasMethods = es5.isES5 &&
|
|
50331
|
-
var hasMethodsOtherThanConstructor =
|
|
50329
|
+
var keys2 = es5.names(fn.prototype);
|
|
50330
|
+
var hasMethods = es5.isES5 && keys2.length > 1;
|
|
50331
|
+
var hasMethodsOtherThanConstructor = keys2.length > 0 && !(keys2.length === 1 && keys2[0] === "constructor");
|
|
50332
50332
|
var hasThisAssignmentAndStaticMethods = thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0;
|
|
50333
50333
|
if (hasMethods || hasMethodsOtherThanConstructor || hasThisAssignmentAndStaticMethods) {
|
|
50334
50334
|
return true;
|
|
@@ -50403,9 +50403,9 @@ var require_util4 = __commonJS({
|
|
|
50403
50403
|
return {}.toString.call(obj2);
|
|
50404
50404
|
}
|
|
50405
50405
|
function copyDescriptors(from, to, filter2) {
|
|
50406
|
-
var
|
|
50407
|
-
for (var i = 0; i <
|
|
50408
|
-
var key2 =
|
|
50406
|
+
var keys2 = es5.names(from);
|
|
50407
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
50408
|
+
var key2 = keys2[i];
|
|
50409
50409
|
if (filter2(key2)) {
|
|
50410
50410
|
try {
|
|
50411
50411
|
es5.defineProperty(to, key2, es5.getDescriptor(from, key2));
|
|
@@ -52207,9 +52207,9 @@ var require_catch_filter = __commonJS({
|
|
|
52207
52207
|
return tryCatch2(cb).call(boundTo, e);
|
|
52208
52208
|
}
|
|
52209
52209
|
} else if (util2.isObject(e)) {
|
|
52210
|
-
var
|
|
52211
|
-
for (var j = 0; j <
|
|
52212
|
-
var key2 =
|
|
52210
|
+
var keys2 = getKeys(item);
|
|
52211
|
+
for (var j = 0; j < keys2.length; ++j) {
|
|
52212
|
+
var key2 = keys2[j];
|
|
52213
52213
|
if (item[key2] != e[key2]) {
|
|
52214
52214
|
continue predicateLoop;
|
|
52215
52215
|
}
|
|
@@ -52245,9 +52245,9 @@ var require_nodeback = __commonJS({
|
|
|
52245
52245
|
ret2.name = obj2.name;
|
|
52246
52246
|
ret2.message = obj2.message;
|
|
52247
52247
|
ret2.stack = obj2.stack;
|
|
52248
|
-
var
|
|
52249
|
-
for (var i = 0; i <
|
|
52250
|
-
var key2 =
|
|
52248
|
+
var keys2 = es52.keys(obj2);
|
|
52249
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
52250
|
+
var key2 = keys2[i];
|
|
52251
52251
|
if (!rErrorKey.test(key2)) {
|
|
52252
52252
|
ret2[key2] = obj2[key2];
|
|
52253
52253
|
}
|
|
@@ -52993,9 +52993,9 @@ var require_call_get = __commonJS({
|
|
|
52993
52993
|
cache2[name] = ret2;
|
|
52994
52994
|
cache2[" size"]++;
|
|
52995
52995
|
if (cache2[" size"] > 512) {
|
|
52996
|
-
var
|
|
52997
|
-
for (var i = 0; i < 256; ++i) delete cache2[
|
|
52998
|
-
cache2[" size"] =
|
|
52996
|
+
var keys2 = Object.keys(cache2);
|
|
52997
|
+
for (var i = 0; i < 256; ++i) delete cache2[keys2[i]];
|
|
52998
|
+
cache2[" size"] = keys2.length - 256;
|
|
52999
52999
|
}
|
|
53000
53000
|
}
|
|
53001
53001
|
return ret2;
|
|
@@ -53714,10 +53714,10 @@ var require_promisify = __commonJS({
|
|
|
53714
53714
|
}
|
|
53715
53715
|
}
|
|
53716
53716
|
function promisifiableMethods(obj2, suffix, suffixRegexp, filter2) {
|
|
53717
|
-
var
|
|
53717
|
+
var keys2 = util2.inheritedDataKeys(obj2);
|
|
53718
53718
|
var ret2 = [];
|
|
53719
|
-
for (var i = 0; i <
|
|
53720
|
-
var key2 =
|
|
53719
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
53720
|
+
var key2 = keys2[i];
|
|
53721
53721
|
var value = obj2[key2];
|
|
53722
53722
|
var passesDefaultFilter = filter2 === defaultFilter ? true : defaultFilter(key2, value, obj2);
|
|
53723
53723
|
if (typeof value === "function" && !isPromisified(value) && !hasPromisified(obj2, key2, suffix) && filter2(key2, value, obj2, passesDefaultFilter)) {
|
|
@@ -53904,10 +53904,10 @@ var require_promisify = __commonJS({
|
|
|
53904
53904
|
if (!util2.isIdentifier(suffix)) {
|
|
53905
53905
|
throw new RangeError("suffix must be a valid identifier\n\n See http://goo.gl/MqrFmX\n");
|
|
53906
53906
|
}
|
|
53907
|
-
var
|
|
53908
|
-
for (var i = 0; i <
|
|
53909
|
-
var value = target[
|
|
53910
|
-
if (
|
|
53907
|
+
var keys2 = util2.inheritedDataKeys(target);
|
|
53908
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
53909
|
+
var value = target[keys2[i]];
|
|
53910
|
+
if (keys2[i] !== "constructor" && util2.isClass(value)) {
|
|
53911
53911
|
promisifyAll(
|
|
53912
53912
|
value.prototype,
|
|
53913
53913
|
suffix,
|
|
@@ -53967,11 +53967,11 @@ var require_props = __commonJS({
|
|
|
53967
53967
|
entries = mapToEntries(obj2);
|
|
53968
53968
|
isMap = true;
|
|
53969
53969
|
} else {
|
|
53970
|
-
var
|
|
53971
|
-
var len =
|
|
53970
|
+
var keys2 = es52.keys(obj2);
|
|
53971
|
+
var len = keys2.length;
|
|
53972
53972
|
entries = new Array(len * 2);
|
|
53973
53973
|
for (var i = 0; i < len; ++i) {
|
|
53974
|
-
var key2 =
|
|
53974
|
+
var key2 = keys2[i];
|
|
53975
53975
|
entries[i] = obj2[key2];
|
|
53976
53976
|
entries[i + len] = key2;
|
|
53977
53977
|
}
|
|
@@ -55796,11 +55796,11 @@ var require_stream_duplex5 = __commonJS({
|
|
|
55796
55796
|
"use strict";
|
|
55797
55797
|
var pna = require_process_nextick_args();
|
|
55798
55798
|
var objectKeys = Object.keys || function(obj2) {
|
|
55799
|
-
var
|
|
55799
|
+
var keys3 = [];
|
|
55800
55800
|
for (var key2 in obj2) {
|
|
55801
|
-
|
|
55801
|
+
keys3.push(key2);
|
|
55802
55802
|
}
|
|
55803
|
-
return
|
|
55803
|
+
return keys3;
|
|
55804
55804
|
};
|
|
55805
55805
|
module2.exports = Duplex;
|
|
55806
55806
|
var util2 = Object.create(require_util());
|
|
@@ -55809,13 +55809,13 @@ var require_stream_duplex5 = __commonJS({
|
|
|
55809
55809
|
var Writable = require_stream_writable5();
|
|
55810
55810
|
util2.inherits(Duplex, Readable);
|
|
55811
55811
|
{
|
|
55812
|
-
|
|
55813
|
-
for (v = 0; v <
|
|
55814
|
-
method =
|
|
55812
|
+
keys2 = objectKeys(Writable.prototype);
|
|
55813
|
+
for (v = 0; v < keys2.length; v++) {
|
|
55814
|
+
method = keys2[v];
|
|
55815
55815
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
55816
55816
|
}
|
|
55817
55817
|
}
|
|
55818
|
-
var
|
|
55818
|
+
var keys2;
|
|
55819
55819
|
var method;
|
|
55820
55820
|
var v;
|
|
55821
55821
|
function Duplex(options) {
|
|
@@ -57708,11 +57708,11 @@ var require_stream_duplex6 = __commonJS({
|
|
|
57708
57708
|
"use strict";
|
|
57709
57709
|
var pna = require_process_nextick_args();
|
|
57710
57710
|
var objectKeys = Object.keys || function(obj2) {
|
|
57711
|
-
var
|
|
57711
|
+
var keys3 = [];
|
|
57712
57712
|
for (var key2 in obj2) {
|
|
57713
|
-
|
|
57713
|
+
keys3.push(key2);
|
|
57714
57714
|
}
|
|
57715
|
-
return
|
|
57715
|
+
return keys3;
|
|
57716
57716
|
};
|
|
57717
57717
|
module2.exports = Duplex;
|
|
57718
57718
|
var util2 = Object.create(require_util());
|
|
@@ -57721,13 +57721,13 @@ var require_stream_duplex6 = __commonJS({
|
|
|
57721
57721
|
var Writable = require_stream_writable6();
|
|
57722
57722
|
util2.inherits(Duplex, Readable);
|
|
57723
57723
|
{
|
|
57724
|
-
|
|
57725
|
-
for (v = 0; v <
|
|
57726
|
-
method =
|
|
57724
|
+
keys2 = objectKeys(Writable.prototype);
|
|
57725
|
+
for (v = 0; v < keys2.length; v++) {
|
|
57726
|
+
method = keys2[v];
|
|
57727
57727
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
57728
57728
|
}
|
|
57729
57729
|
}
|
|
57730
|
-
var
|
|
57730
|
+
var keys2;
|
|
57731
57731
|
var method;
|
|
57732
57732
|
var v;
|
|
57733
57733
|
function Duplex(options) {
|
|
@@ -64001,7 +64001,7 @@ var require_fast_deep_equal = __commonJS({
|
|
|
64001
64001
|
if (a === b) return true;
|
|
64002
64002
|
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
64003
64003
|
if (a.constructor !== b.constructor) return false;
|
|
64004
|
-
var length, i,
|
|
64004
|
+
var length, i, keys2;
|
|
64005
64005
|
if (Array.isArray(a)) {
|
|
64006
64006
|
length = a.length;
|
|
64007
64007
|
if (length != b.length) return false;
|
|
@@ -64012,13 +64012,13 @@ var require_fast_deep_equal = __commonJS({
|
|
|
64012
64012
|
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
|
|
64013
64013
|
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
|
|
64014
64014
|
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
|
|
64015
|
-
|
|
64016
|
-
length =
|
|
64015
|
+
keys2 = Object.keys(a);
|
|
64016
|
+
length = keys2.length;
|
|
64017
64017
|
if (length !== Object.keys(b).length) return false;
|
|
64018
64018
|
for (i = length; i-- !== 0; )
|
|
64019
|
-
if (!Object.prototype.hasOwnProperty.call(b,
|
|
64019
|
+
if (!Object.prototype.hasOwnProperty.call(b, keys2[i])) return false;
|
|
64020
64020
|
for (i = length; i-- !== 0; ) {
|
|
64021
|
-
var key2 =
|
|
64021
|
+
var key2 = keys2[i];
|
|
64022
64022
|
if (!equal(a[key2], b[key2])) return false;
|
|
64023
64023
|
}
|
|
64024
64024
|
return true;
|
|
@@ -191986,9 +191986,9 @@ var stringify = function stringify2(value, replacer2, space) {
|
|
|
191986
191986
|
stack2.push(value2);
|
|
191987
191987
|
let stepback = indent;
|
|
191988
191988
|
indent = indent + gap;
|
|
191989
|
-
let
|
|
191989
|
+
let keys2 = propertyList || Object.keys(value2);
|
|
191990
191990
|
let partial = [];
|
|
191991
|
-
for (const key2 of
|
|
191991
|
+
for (const key2 of keys2) {
|
|
191992
191992
|
const propertyString = serializeProperty(key2, value2);
|
|
191993
191993
|
if (propertyString !== void 0) {
|
|
191994
191994
|
let member = serializeKey(key2) + ":";
|
|
@@ -192151,8 +192151,8 @@ function tokenise(src) {
|
|
|
192151
192151
|
while (i < src.length && src[i] !== quote) {
|
|
192152
192152
|
if (src[i] === "\\" && i + 1 < src.length) {
|
|
192153
192153
|
i++;
|
|
192154
|
-
const
|
|
192155
|
-
s +=
|
|
192154
|
+
const esc3 = { n: "\n", t: " ", r: "\r", "\\": "\\", "'": "'", '"': '"' };
|
|
192155
|
+
s += esc3[src[i]] ?? src[i];
|
|
192156
192156
|
} else {
|
|
192157
192157
|
s += src[i];
|
|
192158
192158
|
}
|
|
@@ -193141,6 +193141,7 @@ function castStringKey(name) {
|
|
|
193141
193141
|
}
|
|
193142
193142
|
var DEFAULT_CAPTION_DELIMITERS = { open: "[", close: "]" };
|
|
193143
193143
|
var DEFAULT_CAPTION_CHARACTER = "SFX";
|
|
193144
|
+
var SAVE_VERSION = 3;
|
|
193144
193145
|
|
|
193145
193146
|
// ../core/src/noderefs.ts
|
|
193146
193147
|
var VISIT_FN_RE = /\b(patter_visits|patter_seen|visits|seen)\s*\(\s*(?:(['"])(.*?)\2|([A-Za-z_]\w*))\s*\)/g;
|
|
@@ -193166,10 +193167,10 @@ ${indent}]`;
|
|
|
193166
193167
|
}
|
|
193167
193168
|
if (typeof v === "object") {
|
|
193168
193169
|
const obj2 = v;
|
|
193169
|
-
const
|
|
193170
|
-
if (
|
|
193170
|
+
const keys2 = Object.keys(obj2).filter((k) => obj2[k] !== void 0).sort();
|
|
193171
|
+
if (keys2.length === 0) return "{}";
|
|
193171
193172
|
const next = indent + " ";
|
|
193172
|
-
const entries =
|
|
193173
|
+
const entries = keys2.map((k) => `${next}${JSON.stringify(k)}: ${write(obj2[k], next, tc)}`);
|
|
193173
193174
|
return `{
|
|
193174
193175
|
${entries.join(",\n")}${tail}
|
|
193175
193176
|
${indent}}`;
|
|
@@ -194046,6 +194047,12 @@ function checkDuplicateIds(root2, conflicts) {
|
|
|
194046
194047
|
var idMap = (nodes) => new Map(nodes.filter((n) => n.id).map((n) => [n.id, n]));
|
|
194047
194048
|
var arrEq = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
|
|
194048
194049
|
|
|
194050
|
+
// ../dialect/src/engine-scopes.ts
|
|
194051
|
+
var ENGINE_SCOPES = [
|
|
194052
|
+
{ token: "patter", engine: "Patterplay", means: "Patter's shared globals" },
|
|
194053
|
+
{ token: "story", engine: "Storylet Engine", means: "the Storylet Engine's shared @story properties" }
|
|
194054
|
+
];
|
|
194055
|
+
|
|
194049
194056
|
// ../dialect/src/index.ts
|
|
194050
194057
|
function host(h) {
|
|
194051
194058
|
return h.ctx.host ?? {};
|
|
@@ -194143,8 +194150,15 @@ var patterDialect = {
|
|
|
194143
194150
|
}
|
|
194144
194151
|
}
|
|
194145
194152
|
};
|
|
194146
|
-
|
|
194147
|
-
|
|
194153
|
+
var EXTERNAL_SCOPES = ENGINE_SCOPES.map((s) => s.token).filter((t) => t !== "patter" && t !== "scene");
|
|
194154
|
+
function withEngineScopes(spec) {
|
|
194155
|
+
const present = new Set((spec?.scopes ?? []).map((s) => s.token));
|
|
194156
|
+
const extra = EXTERNAL_SCOPES.filter((t) => !present.has(t)).map((token2) => ({ token: token2 }));
|
|
194157
|
+
return { version: spec?.version ?? 1, scopes: [...spec?.scopes ?? [], ...extra] };
|
|
194158
|
+
}
|
|
194159
|
+
function dialectWithForeignScopes(given) {
|
|
194160
|
+
const spec = withEngineScopes(given);
|
|
194161
|
+
if (spec.scopes.length === 0) return patterDialect;
|
|
194148
194162
|
const known = new Set(patterDialect.scopes.map((s) => s.token));
|
|
194149
194163
|
const extra = spec.scopes.filter((s) => !known.has(s.token)).map((s) => ({ token: s.token }));
|
|
194150
194164
|
if (extra.length === 0) return patterDialect;
|
|
@@ -194383,7 +194397,7 @@ function compileExpression(src, foreign) {
|
|
|
194383
194397
|
}
|
|
194384
194398
|
function validateConditions(input, options = {}) {
|
|
194385
194399
|
const issues = [];
|
|
194386
|
-
const foreign = options.foreignScopes;
|
|
194400
|
+
const foreign = withEngineScopes(options.foreignScopes);
|
|
194387
194401
|
const dialect = dialectWithForeignScopes(foreign);
|
|
194388
194402
|
const readOnly = readOnlyForeignTargets(foreign);
|
|
194389
194403
|
const opaqueForeign = opaqueForeignTokens(foreign);
|
|
@@ -194478,10 +194492,11 @@ function validateInterpolation(input, options = {}) {
|
|
|
194478
194492
|
const voiced = input.project.voiced ?? false;
|
|
194479
194493
|
const tables = (input.locales ?? []).map((l2) => ({ locale: l2.locale, strings: l2.strings }));
|
|
194480
194494
|
const defaultLocale = input.project.locales.default;
|
|
194481
|
-
const
|
|
194482
|
-
const
|
|
194495
|
+
const foreign = withEngineScopes(options.foreignScopes);
|
|
194496
|
+
const opaqueForeign = opaqueForeignTokens(foreign);
|
|
194497
|
+
const isScopeToken = scopeTokenTest(foreign);
|
|
194483
194498
|
for (const scene of input.scenes) {
|
|
194484
|
-
const schema = buildSchema(input.project, scene.sceneProps,
|
|
194499
|
+
const schema = buildSchema(input.project, scene.sceneProps, foreign);
|
|
194485
194500
|
const known = (ref) => {
|
|
194486
194501
|
const { scope, name } = splitRef(ref, isScopeToken);
|
|
194487
194502
|
if (opaqueForeign.has(scope)) return true;
|
|
@@ -194644,11 +194659,33 @@ function compileScene(scene, foreign) {
|
|
|
194644
194659
|
blocks: scene.blocks.map((b) => compileBlock(b, foreign))
|
|
194645
194660
|
};
|
|
194646
194661
|
}
|
|
194662
|
+
function externalScopesIn(scenes) {
|
|
194663
|
+
const found = /* @__PURE__ */ new Set();
|
|
194664
|
+
const external = new Set(EXTERNAL_SCOPES);
|
|
194665
|
+
const walk2 = (node) => {
|
|
194666
|
+
if (!Array.isArray(node) && (node === null || typeof node !== "object")) return;
|
|
194667
|
+
if (Array.isArray(node)) {
|
|
194668
|
+
if (node[0] === "sv" && typeof node[1] === "string" && external.has(node[1])) found.add(node[1]);
|
|
194669
|
+
for (const n of node) walk2(n);
|
|
194670
|
+
return;
|
|
194671
|
+
}
|
|
194672
|
+
const o = node;
|
|
194673
|
+
if (o["kind"] === "set" && typeof o["target"] === "string") {
|
|
194674
|
+
const head = o["target"].replace(/^@/, "").split(".")[0];
|
|
194675
|
+
if (o["target"].includes(".") && external.has(head)) found.add(head);
|
|
194676
|
+
}
|
|
194677
|
+
for (const v of Object.values(o)) walk2(v);
|
|
194678
|
+
};
|
|
194679
|
+
walk2(scenes);
|
|
194680
|
+
return [...found].sort();
|
|
194681
|
+
}
|
|
194647
194682
|
function exportBundle(input) {
|
|
194648
194683
|
const { project, scenes, locales = [], includeLocales } = input;
|
|
194649
194684
|
const foreignScopes = input.foreignScopes ?? hostScopesToSpec(project.scopeRegistry);
|
|
194685
|
+
const compileScopes = withEngineScopes(foreignScopes);
|
|
194650
194686
|
const scenesOut = {};
|
|
194651
|
-
for (const scene of scenes) scenesOut[scene.id] = compileScene(scene,
|
|
194687
|
+
for (const scene of scenes) scenesOut[scene.id] = compileScene(scene, compileScopes);
|
|
194688
|
+
const externalScopes = externalScopesIn(scenesOut);
|
|
194652
194689
|
const strings = {};
|
|
194653
194690
|
for (const loc of locales) {
|
|
194654
194691
|
if (includeLocales && !includeLocales.includes(loc.locale)) continue;
|
|
@@ -194704,7 +194741,9 @@ function exportBundle(input) {
|
|
|
194704
194741
|
// runtime falls back to `[` / `]` when absent, so default projects keep their exact prior bundle.
|
|
194705
194742
|
...project.closedCaptions ? { closedCaptions: project.closedCaptions } : {},
|
|
194706
194743
|
scenes: scenesOut,
|
|
194707
|
-
strings
|
|
194744
|
+
strings,
|
|
194745
|
+
// Other engines' scopes the content names, so the engine can say when the game has not registered one.
|
|
194746
|
+
...externalScopes.length > 0 ? { externalScopes } : {}
|
|
194708
194747
|
};
|
|
194709
194748
|
}
|
|
194710
194749
|
|
|
@@ -195017,7 +195056,7 @@ function bundleOutputPath(loaded) {
|
|
|
195017
195056
|
}
|
|
195018
195057
|
|
|
195019
195058
|
// ../ops/src/playable-runtime.ts
|
|
195020
|
-
var PLAYABLE_RUNTIME_JS = 'var Patterplay=(()=>{var V=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var ve=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var we=(n,e)=>{for(var t in e)V(n,t,{get:e[t],enumerable:!0})},xe=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ve(e))!be.call(n,s)&&s!==t&&V(n,s,{get:()=>e[s],enumerable:!(r=ye(e,s))||r.enumerable});return n};var Ee=n=>xe(V({},"__esModule",{value:!0}),n);var Le={};we(Le,{Engine:()=>F,Flow:()=>C,buildTagIndex:()=>A,describeBundle:()=>ue,effectiveGameData:()=>fe,gameDataFields:()=>he,gameDataValue:()=>K});function w(n){switch(n[0]){case"b":return{kind:"bool",value:n[1]};case"n":return{kind:"number",value:n[1]};case"s":return{kind:"string",value:n[1]};case"sv":return{kind:"scopedvar",scope:n[1],name:n[2]};case"u":return{kind:"unary",op:n[1],operand:w(n[2])};case"bin":return{kind:"binary",op:n[1],left:w(n[2]),right:w(n[3])};case"call":{let e=n.slice(2).map(w);return{kind:"call",name:n[1],args:e}}case"fd":return{kind:"flagdelta",sign:n[1],name:n[2]}}}var l=class extends Error{constructor(e){super(e),this.name="EvalError"}};function B(n,e,t){let r=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),s=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 l(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{if(i.name==="advance"&&!t.functions[i.name]){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new l(`advance() takes exactly 1 argument, got ${i.args.length}`);let c=M(a,e);if(c===void 0)throw new l("advance() needs a quality reference (@scope.name of a quality property)");let d=y(s(a),c,"advance");return c[Math.min(d+1,c.length-1)]}let o=t.functions[i.name];if(!o)throw new l(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:s,ctx:e})}case"flagdelta":throw new l("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=s(i.operand);if(typeof a!="boolean")throw new l(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=s(i.operand);if(typeof o!="number")throw new l(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let u=s(i.left);if(typeof u!="boolean")throw new l(`\'and\' requires boolean operands, left is ${typeof u}`);if(!u)return!1;let f=s(i.right);if(typeof f!="boolean")throw new l(`\'and\' requires boolean operands, right is ${typeof f}`);return f}if(i.op==="or"){let u=s(i.left);if(typeof u!="boolean")throw new l(`\'or\' requires boolean operands, left is ${typeof u}`);if(u)return!0;let f=s(i.right);if(typeof f!="boolean")throw new l(`\'or\' requires boolean operands, right is ${typeof f}`);return f}let o=s(i.left),a=s(i.right),c=M(i.left,e),d=M(i.right,e),p=c??d;if(p!==void 0){if(c&&d&&!ke(c,d)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new l(`\'${i.op}\' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return y(o,p,">")>y(a,p,">");case">=":return y(o,p,">=")>=y(a,p,">=");case"<":return y(o,p,"<")<y(a,p,"<");case"<=":return y(o,p,"<=")<=y(a,p,"<=");case"+":case"-":case"*":case"/":throw new l(`\'${i.op}\' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(i.op){case"==":return Z(o,a);case"!=":return!Z(o,a);case">":return x(o,a,">"),o>a;case">=":return x(o,a,">="),o>=a;case"<":return x(o,a,"<"),o<a;case"<=":return x(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new l(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return x(o,a,"-"),o-a;case"*":return x(o,a,"*"),o*a;case"/":if(x(o,a,"/"),a===0)throw new l("division by zero");return o/a}}}};return s(n)}function Z(n,e){if(Array.isArray(n)||Array.isArray(e)){if(!Array.isArray(n)||!Array.isArray(e)||n.length!==e.length)return!1;let t=[...n].sort(),r=[...e].sort();for(let s=0;s<t.length;s++)if(t[s]!==r[s])return!1;return!0}return n===e}function x(n,e,t){if(typeof n!="number"||typeof e!="number")throw new l(`\'${t}\' requires numeric operands, got ${typeof n} and ${typeof e}`)}function M(n,e){if(!(n.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(n.scope,n.name)}function y(n,e,t){if(typeof n!="string")throw new l(`\'${t}\' on a quality compares stages, got ${typeof n}`);let r=e.indexOf(n);if(r<0)throw new l(`"${n}" is not a stage of this quality (stages: ${e.join(", ")})`);return r}var ke=(n,e)=>n.length===e.length&&n.every((t,r)=>t===e[r]);function I(n){if(Number.isNaN(n)||!Number.isFinite(n))return 0;let e=Math.trunc(n)%4294967296;return e<0?e+4294967296:e}function j(n){let e=I(n);return{next(){e=e+1831565813>>>0;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},state(){return e}}}var Ce={name:"check_flags",count:n=>Math.max(1,n.args.length-1)},Ie=[Ce];function Q(n,e,t){let r=t?.countingCalls??Ie;return P(n,t?.want??!0,e,r)}function P(n,e,t,r){if(n.kind==="binary"&&(n.op==="and"||n.op==="or")){let s=P(n.left,e,t,r),i=P(n.right,e,t,r);return n.op==="and"===e?s>0&&i>0?s+i:0:Math.max(s,i)}if(n.kind==="unary"&&n.op==="not")return P(n.operand,!e,t,r);if(n.kind==="call"){let s=r.find(i=>i.name===n.name);if(s){let i=s.count(n),o=t(n);return e?o?i:0:o?0:1}}return t(n)===e?1:0}var b=class n{values={};decls=new Map;subscribers=new Set;auditors=new Set;norm;pathPrefix;constructor(e=[],t){this.norm=t?.normalise??(r=>r.toLowerCase()),this.pathPrefix=t?.pathPrefix??"",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??E(t))}}get(e){return this.values[this.norm(e)]}set(e,t,r){let s=this.norm(e);if(!r?.host&&this.decls.get(s)?.writable===!1)throw new Error(`\'${e}\' is read-only`);let i={name:s,prev:this.values[s],next:t,silent:r?.silent??!1,reason:r?.reason};this.values[s]=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])=>ee(t,this.get(e),void 0,e,this.pathPrefix))}declarations(){return[...this.decls.values()]}clone(){let e=new n([],{normalise:this.norm,pathPrefix:this.pathPrefix});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 ee(n,e,t,r,s=""){let i=r??n.name.toLowerCase();return{name:i,path:s+i,type:n.type,value:e,default:n.default??E(n),...n.values!==void 0?{values:n.values}:{},...n.stages!==void 0?{stages:n.stages}:{},writable:t??n.writable??!0}}var $=1,D=class{scopes=new Map;defineOwned(e,t,r){return this.mountOwned(e,new b(t,{pathPrefix:r??`${e}.`}))}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=[],s=!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:s}),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,s){let i=this.scopes.get(e);if(!i)throw new Error(`unknown scope \'@${e}\'`);if(i.kind==="owned"){try{i.bag.set(t,r,s?.host?{host:!0}:void 0)}catch{throw new Error(`\'@${e}.${t}\' is read-only`)}return}let o=t.toLowerCase();if(!i.resolver.set)throw new Error(`\'@${e}.${t}\' is read-only`);if(!s?.host&&!this.foreignWritable(i,o))throw new Error(`\'@${e}.${t}\' is read-only`);i.resolver.set(o,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 s of r.bag.rows())e.push({scope:t,...s});else for(let s of r.decls.values())e.push({scope:t,...ee(s,r.resolver.get(s.name.toLowerCase()),this.foreignWritable(r,s.name.toLowerCase()),void 0,`${t}.`)});return e}toEvalContext(e){let t={};for(let[s,i]of this.scopes)t[s]=i.kind==="owned"?i.bag.values:i.resolver;let r=this.qualityLadders();return r.size===0?{scopes:t,host:e}:{scopes:t,host:e,qualities:(s,i)=>r.get(s)?.get(i.toLowerCase())}}qualityLadders(){let e=new Map;for(let[t,r]of this.scopes){let s=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];for(let i of s){if(i.type!=="quality"||i.stages===void 0)continue;let o=e.get(t);o||(o=new Map,e.set(t,o)),o.set(i.name.toLowerCase(),i.stages)}}return e}toSchema(){let e=new Map;for(let[t,r]of this.scopes){let s=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];if(s.length===0)continue;let i=new Map;for(let o of s)i.set(o.name.toLowerCase(),{type:o.type,enumValues:o.values,...o.stages!==void 0?{stages:o.stages}:{}});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 s=this.scopes.get(t);s?.kind==="owned"&&s.bag.load(r)}}saveFragment(){return{version:$,scopes:this.save()}}loadFragment(e){if(e.version!==$)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${$})`);this.load(e.scopes)}assertFree(e){if(this.scopes.has(e))throw new Error(`scope \'@${e}\' is already registered`)}};function E(n){if(n.default!==void 0)return n.default;switch(n.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"enum":return n.values?.[0]??"";case"flags":return[];case"quality":return n.stages?.[0]??"";default:return!1}}function R(n){return n.ctx.host??{}}var q={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(n,e){if(n.length!==2)throw new l("random(a, b) requires exactly 2 arguments");let t=R(e).nextRandom;if(!t)throw new l("random() called without a PRNG in context");let r=e.evaluate(n[0]),s=e.evaluate(n[1]);if(typeof r!="number"||typeof s!="number")throw new l("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(s))throw new l("random(a, b) arguments must be integers");let i=Math.min(r,s),o=Math.max(r,s);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:re("check_flags"),eval(n,e){let t=te(n[0],e,"check_flags");for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new l("check_flags() flag args must be +flagName or -flagName");if(s.sign==="+"?!t.includes(s.name):t.includes(s.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:re("set_flags"),eval(n,e){let t=[...te(n[0],e,"set_flags")];for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new l("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let i=t.indexOf(s.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:N("visits"),eval:(n,e)=>R(e).visits?.(O(n,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:N("seen"),eval:(n,e)=>(R(e).visits?.(O(n,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:N("patter_visits"),eval:(n,e)=>R(e).patterVisits?.(O(n,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:N("patter_seen"),eval:(n,e)=>(R(e).patterVisits?.(O(n,e,"patter_seen"))??0)>0}}};function H(n,e){let t=n.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function O(n,e,t){let r=e.evaluate(n[0]);if(typeof r!="string")throw new l(`${t}(id) requires a string node id`);return r}function N(n){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:`${n}(id): the argument must be a string id literal (a scene / block / node id)`})}}function te(n,e,t){if(!n)throw new l(`${t}() requires at least one argument (the flags variable)`);let r=e.evaluate(n);if(Array.isArray(r))return r;if(r===!1||r===null||r===void 0)return[];throw new l(`${t}() first argument must be a flags property`)}function re(n){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:`${n}(): first argument must be a flags property reference (@name or @scope.name)`});return}let s=t.schema.properties.get(r.scope)?.get(r.name);if(s&&s.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:`${n}(): \'@${i}\' is not a flags property (got ${s.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:`${n}(): argument ${i+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${n}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var De=/^@[A-Za-z0-9_.]+$/;function*Re(n){let e="",t=0;for(;t<n.length;){let r=n[t];if(r==="{"&&n[t+1]==="{"){e+="{",t+=2;continue}if(r==="}"&&n[t+1]==="}"){e+="}",t+=2;continue}if(r==="{"){let s=n.indexOf("}",t+1);if(s!==-1){let i=n.slice(t,s+1),o=n.slice(t+1,s).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:De.test(o)?o:void 0},t=s+1;continue}e+=i,t=s+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function Be(n){return Array.isArray(n)?n.join(", "):typeof n=="boolean"?n?"true":"false":String(n)}function Pe(n){return n===" "||n===" "||n===`\n`||n==="\\r"||n==="\\f"||n==="\\v"}function Oe(n){let e="",t=!1;for(let r of n){if(Pe(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function ne(n,e,t){if(e.length===0||n.indexOf(e)<0)return n;let r="",s=0,i=!1;for(;s<n.length;){if(n.startsWith(e,s)){let o=n.indexOf(t,s+e.length);if(o>=0){s=o+t.length,i=!0;continue}r+=n.slice(s);break}r+=n[s],s+=1}return i?Oe(r):n}function se(n,e){if(n.indexOf("{")<0)return n;let t="";for(let r of Re(n)){if(r.kind==="text"){t+=r.value;continue}if(!r.ref){t+=r.raw;continue}let s=e(r.ref);t+=s===void 0?"":Be(s)}return t}function k(n,e){for(let t of n){e(t);let r=t.children;r&&k(r,e)}}function Ne(n){return n.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function h(n){let e=n.gameId?.trim();return e||Ne(n.name)}function _(n){return`cast:${n}`}var U={open:"[",close:"]"},ie="SFX";function T(n){let e=new Set,t=[];for(let r of n)e.has(r)||(e.add(r),t.push(r));return t}function A(n){let e=new Map,t=(r,s)=>{let i=T([...s,...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,T([...i,...o.tags??[]]))};for(let r of Object.values(n.scenes)){let s=T(r.tags??[]);e.set(r.id,s);for(let i of r.blocks){let o=T([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var oe=new WeakMap,F=class n{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineTraceHandlers=new Set;constructor(e,t={}){this.creationOptions=t;let r=t.locale??e.locales.default,s=e.strings;this.allStrings=s,this.currentLocale=r;let i=s[r]??{},o=s[e.locales.default]??{},a=e.localisation,c=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 d=new Map;for(let g of e.cast??[])g.displayName&&d.set(g.name,g.displayName);this.defaultSeed=(t.seed??2654435769)>>>0;let p=new Map,u=new Map,f=new Map;for(let[g,m]of Object.entries(e.scenes)){this.sceneGameIdToId.set(h(m),g);let v=new Map;for(let S of m.blocks)u.set(S.id,{sceneId:g}),f.set(S.id,S),v.set(h(S),S.id),k(S.children,X=>p.set(X.id,X));this.blockGameIdToId.set(g,v)}let J=e.properties??[],G=J.filter(g=>g.shared??!0).map(ce),me=J.filter(g=>!(g.shared??!0)).map(ce),Se=new Set(G.map(g=>g.name.toLowerCase())),L=new D().defineOwned("patter",G,"@patter."),z=new Set;if(t.world){let g=e.scopeRegistry?.scopes.find(v=>v.token==="world"),m=(g?.declarations??[]).map(le);L.defineForeign("world",t.world,m,g?.writable??!0),z.add("world")}for(let g of e.scopeRegistry?.scopes??[]){if(z.has(g.token))continue;let m=(g.declarations??[]).map(le);L.defineForeign(g.token,Te(g.declarations??[]),m,g.writable??!0)}let Y=new Map;for(let[g,m]of Object.entries(e.scenes)){let v=new Set((m.sceneProps??[]).filter(S=>S.shared??!1).map(S=>S.name.toLowerCase()));Y.set(g,v)}this.host={logEnabled:t.log??!1,emitEngine:(g,m,v)=>this.emitEngine(g,m,v),bundle:e,emitIds:c,strings:i,defaultStrings:o,castDisplay:d,nodeIndex:p,blockIndex:u,blockById:f,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:A(e),shared:L,patterSharedDecls:G,patterLocalDecls:me,patterSharedNames:Se,sceneSharedNames:Y,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??U).open,captionClose:(e.closedCaptions??U).close,captionCharacter:e.closedCaptions?.character||ie,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),s=new n(e,this.creationOptions);try{return s.loadGame(t),r(s)}catch{let i=new n(e,this.creationOptions);for(let[o,a]of Object.entries(t.flows)){let c=a.cursor.currentSceneId;try{i.openFlow(o,c!==null?{scene:c}:{})}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),s=this.resolveBlockRef(r,t.block);this.flowsById.get(e)?.close();let i=new C(e,this.host,t.seed??this.defaultSeed);return this.flowsById.set(e,i),i.start(r,s),i}runFlow(e,t,r){let s=this.flowsById.get(e);if(!s)return this.openFlow(e,{scene:t,block:r}).advanceToStop().played;if(!s.goto(t,r))throw new Error(`runFlow: address not found: ${t}${r===void 0?"":` / ${r}`}`);return s.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?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),s=this.resolveBlockRef(r,t);return(s!=null?this.host.tagIndex.get(s):void 0)??[]}getCast(){let e=[];for(let t of this.host.bundle.cast??[])t?.name&&e.push(t.name);return e}castForScene(e){let t=this.resolveSceneRef(e),r=t!=null?this.host.bundle.scenes[t]:void 0;if(!r)return[];let s=new Set;for(let i of r.blocks)ae(i.children,s);return[...s]}castForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t),i=s!=null?this.host.blockById.get(s):void 0;if(!i)return[];let o=new Set;return ae(i.children,o),[...o]}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,s=>{if(s.type==="snippet")for(let i of s.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:s.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 s=this.host.defaultStrings[_(e.character)]??this.host.castDisplay.get(e.character);s!==void 0&&(r.characterName=s)}e.direction!==void 0&&(r.direction=e.direction)}if(e.kind==="line"||e.kind==="text"){let s=this.host.defaultStrings[e.id];s!==void 0&&(r.text=s)}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()]}listBags(){let e=[{bag:this.host.shared.ownedBag("patter")}];for(let[t,r]of this.host.stageBags)e.push({bag:r,pathPrefix:`@scene:${t}.`});return e}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:s}=this.splitShared(e);this.host.shared.set(r,s,t,{host:!0})}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),()=>this.engineTraceHandlers.delete(e)}emitEngine(e,t,r){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineLog.length,...r?{scene:r}:{}})}listProperties(){return this.host.patterSharedDecls.map(e=>({name:e.name,path:`@patter.${e.name}`,type:e.type,values:e.values,stages:e.stages,value:this.getProperty(`@${e.name}`),default:E(e),writable:e.writable??!0}))}splitShared(e){let t=this.host.refSplitCache.get(e);if(t||(t=H(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:de(this.host.sharedSelectors),stageBags:Object.fromEntries([...this.host.stageBags].map(([t,r])=>[t,r.save()])),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 ge(e.sharedSelectors))this.host.sharedSelectors.set(t,r);this.host.stageBags.clear();for(let[t,r]of Object.entries(e.stageBags??{})){let s=this.host.sceneSharedNames.get(t)??new Set,i=(this.host.bundle.scenes[t]?.sceneProps??[]).filter(a=>s.has(a.name.toLowerCase())),o=new b(i);o.load(r),this.host.stageBags.set(t,o)}this.flowsById.clear();for(let[t,r]of Object.entries(e.flows)){let s=new C(t,this.host,this.defaultSeed);s.restore(r),this.flowsById.set(t,s)}}},C=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))?.get(e)},set:(e,t)=>{let r=this.currentSceneId;if(r===null)return;let s=this.host.sceneSharedNames.get(r)?.has(e)?this.host.stageBags.get(r):this.sceneBags.get(r);s&&s.set(e,t)}};evalCtx;flowLog=[];flowSeq=0;constructor(e,t,r){this.id=e,this.host=t,this.rngState=I(r),this.local=this.freshLocal();let s={...t.shared.toEvalContext().scopes};s.patter=this.patterResolver,s.scene=this.sceneResolver,this.evalCtx={scopes:s,host:{nextRandom:this.rng,visits:i=>this.visitCounts.get(i)??0,patterVisits:i=>this.host.sharedVisits.get(i)??0},qualities:(i,o)=>this.stagesFor(i,o)}}stagesFor(e,t){let r=t.toLowerCase(),s=i=>i?.find(o=>o.name.toLowerCase()===r&&o.type==="quality")?.stages;if(e==="patter")return s(this.host.patterSharedDecls)??s(this.host.patterLocalDecls);if(e==="scene"){let i=this.currentSceneId!=null?this.host.bundle.scenes[this.currentSceneId]:void 0;return s(i?.sceneProps)}return s(this.host.bundle.scopeRegistry?.scopes.find(i=>i.token===e)?.declarations)}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],s=r?this.host.bundle.scenes[r]:void 0;if(!s)throw new Error(r?`unknown scene: ${r}`:"no scenes in bundle");this.enterSceneSetup(r);let i=s.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 s;return t!==void 0&&(s=this.host.blockGameIdToId.get(r)?.get(t)??(this.host.blockIndex.get(t)?.sceneId===r?t:void 0),s===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(s??r,"jump"),this.settle(),!0):(this.start(r,s),!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 i=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(i);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}let s=t.index;for(;t.index<r.length&&!this.eligible(r[t.index]);)t.index++;if(this.host.logEnabled&&t.index!==s&&this.emit({type:"select",group:t.containerId,selector:"run",children:r.slice(s,t.index+1).map((i,o)=>({id:i.id,eligible:s+o===t.index})),picked:r[t.index]?.id??null}),t.index>=r.length){this.stack.pop();continue}this.enterChild(r[t.index++])}}listBags(){let e=[{bag:this.local.ownedBag("patter"),pathPrefix:`${this.id}/@patter.`}];for(let[t,r]of this.sceneBags)e.push({bag:r,pathPrefix:`${this.id}/@scene:${t}.`});return e}log(){return this.flowLog}clearLog(){this.flowLog.length=0}emit(e){let t=this.currentSceneId??void 0;this.host.emitEngine(this.id,e,t),this.host.logEnabled&&this.flowLog.push({...e,seq:this.flowSeq++,...t?{scene:t}:{}})}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 s=t.byId.get(e);this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null,this.pendingPromptBeat=this.host.replayPromptOnChoose?this.promptBeatOf(s)??null:null,this.pendingPromptOwnerId=this.pendingPromptBeat?s.id:null,this.enterChild(s)}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){this.writeProperty(e,t,!0)}writeProperty(e,t,r){let{scope:s,name:i}=this.splitRef(e);if(s==="patter")this.patterResolver.set(i,t);else if(s==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);this.sceneResolver.set(i,t)}else this.host.shared.set(s,i,t,r?{host:!0}:void 0)}snapshot(){return{scopes:this.local.save(),sceneBags:Object.fromEntries([...this.sceneBags].map(([e,t])=>[e,t.save()])),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:de(this.selectors)}}}restore(e){this.rngState=I(e.rngState),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:s,...i}=r;if(s!==void 0){let o=this.childrenOf(i.containerId)?.findIndex(a=>a.id===s)??-1;if(o>=0)return{...i,index:o}}return{...i}}),this.sceneBags=new Map(Object.entries(e.sceneBags??{}).map(([r,s])=>{let i=this.host.sceneSharedNames.get(r)??new Set,o=(this.host.bundle.scenes[r]?.sceneProps??[]).filter(c=>!i.has(c.name.toLowerCase())),a=new b(o);return a.load(s),[r,a]})),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=ge(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,s=[];for(let i of t.pendingChoice.options){let o=this.host.nodeIndex.get(i.id);o&&(r.set(i.id,o),s.push({...i}))}s.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:s,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,s=[];for(let o of e.children){if(o.fallback===!0){s.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),c=o.secretUntilEligible===!0;!a&&c||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.length>0){this.emit({type:"choice",group:e.id,options:t.map(o=>({id:o.id,eligible:o.eligible}))}),this.pendingChoice={groupId:e.id,options:t,byId:r};return}let i=s.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.emit({type:"dry",group:e.id}),this.host.onDryChoice?.(e.id)}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(this.emit({type:"jump",to:e,mode:t}),e==="END"){this.flowEnded=!0,this.stack=[];return}let r,s,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,s=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,s=e}this.enter(s);let o={sceneId:r,containerId:s,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.map(c=>({id:c.id,eligible:this.eligible(c)})),r=e.children.filter(c=>this.eligible(c)),s=e.options?.order??"sequential",i=e.options?.exhaust??"once",o=c=>(this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:i}:{},children:t,picked:c?.id??null}),c);if(r.length===0)return o(null);let a=this.selectorState(e);switch(e.selector){case"branch":return o(r[0]);case"sequence":return o(s==="shuffle"?this.pickShuffle(r,i,a):s==="specificity"?this.pickSpecificity(r,i,a):this.pickSequential(r,i,a));default:return null}}pickSequential(e,t,r){let s=e.length,i=r.seq??0;return r.seq=i+1,t==="repeat"?e[i%s]:i<s?e[i]:t==="stick"?e[s-1]:null}pickShuffle(e,t,r){let s=e.length,i=t==="stick",o=()=>(i?e.slice(0,s-1):e).map(u=>u.id);if(r.bag===void 0&&(r.bag=o()),r.bag.length===0){if(t==="once")return null;if(i){let u=e[s-1];return r.last=u.id,u}r.bag=o()}let a=r.bag,c=r.last!==void 0&&a.length>1?a.indexOf(r.last):-1,d=Math.floor(this.rng()*(c>=0?a.length-1:a.length));c>=0&&d>=c&&d++;let p=a[d];return a.splice(d,1),r.last=p,e.find(u=>u.id===p)}pickSpecificity(e,t,r){let s=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(p=>p.id));let d=new Set(r.bag);if(s=e.filter(p=>d.has(p.id)),s.length===0)return t==="stick"&&r.last!==void 0?e.find(p=>p.id===r.last)??null:null}let i=-1,a=s.map(d=>{let p=this.specScore(d);return p>i&&(i=p),{c:d,s:p}}).filter(d=>d.s===i).map(d=>d.c),c;if(a.length===1)c=a[0];else{let d=r.last!==void 0?a.findIndex(u=>u.id===r.last):-1,p=Math.floor(this.rng()*(d>=0?a.length-1:a.length));d>=0&&p>=d&&p++,c=a[p]}return t!=="repeat"&&(r.bag=r.bag.filter(d=>d!==c.id)),r.last=c.id,c}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0):0}matchedSpec(e,t){return Q(e,s=>pe(B(s,this.evalCtx,q)),{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??[]){let r=this.evalExpr(t.value),s=this.host.logEnabled?this.getProperty(t.target):void 0;this.writeProperty(t.target,r,!1),this.emit({type:"write",target:t.target,value:r,...s!==void 0?{prev:s}:{}})}}eligible(e){return e.condition?pe(this.evalExpr(e.condition)):!0}evalExpr(e){return B(this.conditionAst(e),this.evalCtx,q)}conditionAst(e){let t=oe.get(e);return t||(t=w(e.ast),oe.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=j(this.rngState),t=e.next();return this.rngState=e.state(),t};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 s=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=i&&a.length===0;return{type:"line",id:e.id,text:a,character:c?void 0:e.character,characterName:c?void 0:this.resolveCharacterName(e.character),direction:c?void 0:e.direction,gameData:e.gameData,...r}}}}interpolate(e){return se(e,t=>this.getProperty(t))}stripCaptions(e){return ne(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(s=>s.kind==="line"||s.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=_(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=H(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t}freshLocal(){return new D().defineOwned("patter",this.host.patterLocalDecls,"@patter.")}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set,r=e.sceneProps??[];this.sceneBags.has(e.id)||this.sceneBags.set(e.id,new b(r.filter(s=>!t.has(s.name.toLowerCase())))),this.host.stageBags.has(e.id)||this.host.stageBags.set(e.id,new b(r.filter(s=>t.has(s.name.toLowerCase()))));for(let s of e.sceneProps??[]){if(!s.temporary)continue;let i=s.name.toLowerCase(),o=t.has(i)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);o&&o.set(i,E(s))}}};function ae(n,e){k(n,t=>{if(t.type==="group"){t.prompt?.kind==="line"&&t.prompt.character&&e.add(t.prompt.character);return}for(let r of t.beats??[])r.kind==="line"&&r.character&&e.add(r.character)})}function de(n){let e={};for(let[t,r]of n){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e[t]=s}return e}function ge(n){let e=new Map;for(let[t,r]of Object.entries(n??{})){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e.set(t,s)}return e}function ce(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default}}function le(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default,writable:n.writable}}function Te(n){let e=r=>r.toLowerCase(),t=new Map;for(let r of n)t.set(e(r.name),E(r));return{get:r=>t.get(e(r)),set:(r,s)=>{t.set(e(r),s)}}}function pe(n){return typeof n=="boolean"?n:typeof n=="number"?n!==0:typeof n=="string"?n!=="":n.length>0}var Ae=(n,e)=>n.shared??e;function W(n,e){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.default!==void 0?{default:n.default}:{},shared:Ae(n,e)}}function Fe(n){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.values?{values:[...n.values]}:{},...n.purpose?{purpose:n.purpose}:{}}}function Ge(n,e){e.blocks++;let t=[...n.children];for(;t.length;){let r=t.pop();if(r.type==="group"){e.groups++,r.prompt&&e.prompts++,t.push(...r.children);continue}e.snippets++;for(let s of r.beats??[])e.beats++,s.kind==="gameEvent"&&e.gameEvents++}}function ue(n){let e={scenes:0,blocks:0,groups:0,snippets:0,beats:0,prompts:0,gameEvents:0,cast:n.cast?.length??0},t=[],r=[];for(let o of Object.values(n.scenes)){e.scenes++;let a=h(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(c=>({gameId:h(c),name:c.name}))});for(let c of o.blocks)Ge(c,e);o.sceneProps?.length&&r.push({gameId:a,properties:o.sceneProps.map(c=>W(c,!1))})}let s=(n.scopeRegistry?.scopes??[]).map(o=>({token:o.token,writable:o.writable??!0,opaque:o.declarations===void 0,properties:(o.declarations??[]).map(a=>W(a,!0))})),i=Object.entries(n.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(Fe)}));return{identity:{schema:n.schema,project:n.content.project,...n.content.version!==void 0?{version:n.content.version}:{},...n.content.hash!==void 0?{hash:n.content.hash}:{},...n.content.structureHash!==void 0?{structureHash:n.content.structureHash}:{},voiced:n.voiced,defaultLocale:n.locales.default,locales:[...n.locales.included],localisation:n.localisation?.mode??"embedded",sourceDebug:n.localisation?.sourceDebug??!1},addresses:t,hostScopes:s,properties:{patter:(n.properties??[]).map(o=>W(o,!0)),scene:r},gameData:i,counts:e}}function he(n,e){return n.gameDataFields?.[e]??[]}function K(n,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:n.find(r=>r.name===t)?.default}function fe(n,e){let t={};for(let r of n){let s=K(n,e,r.name);s!==void 0&&(t[r.name]=s)}for(let[r,s]of Object.entries(e??{}))r in t||(t[r]=s);return t}return Ee(Le);})();\n';
|
|
195059
|
+
var PLAYABLE_RUNTIME_JS = 'var Patterplay=(()=>{var q=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var Pe=Object.prototype.hasOwnProperty;var Ne=(n,e)=>{for(var t in e)q(n,t,{get:e[t],enumerable:!0})},Fe=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Be(e))!Pe.call(n,s)&&s!==t&&q(n,s,{get:()=>e[s],enumerable:!(r=Oe(e,s))||r.enumerable});return n};var Te=n=>Fe(q({},"__esModule",{value:!0}),n);var Qe={};Ne(Qe,{Engine:()=>$,Flow:()=>D,buildTagIndex:()=>M,describeBundle:()=>ke,effectiveGameData:()=>Ie,gameDataFields:()=>Ce,gameDataValue:()=>Q});function E(n){switch(n[0]){case"b":return{kind:"bool",value:n[1]};case"n":return{kind:"number",value:n[1]};case"s":return{kind:"string",value:n[1]};case"sv":return{kind:"scopedvar",scope:n[1],name:n[2]};case"u":return{kind:"unary",op:n[1],operand:E(n[2])};case"bin":return{kind:"binary",op:n[1],left:E(n[2]),right:E(n[3])};case"call":{let e=n.slice(2).map(E);return{kind:"call",name:n[1],args:e}}case"fd":return{kind:"flagdelta",sign:n[1],name:n[2]}}}var p=class extends Error{constructor(e){super(e),this.name="EvalError"}};function F(n,e,t){let r=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),s=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":{if(i.name==="advance"&&!t.functions[i.name]){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new p(`advance() takes exactly 1 argument, got ${i.args.length}`);let c=_(a,e);if(c===void 0)throw new p("advance() needs a quality reference (@scope.name of a quality property)");let l=w(s(a),c,"advance");return c[Math.min(l+1,c.length-1)]}let o=t.functions[i.name];if(!o)throw new p(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:s,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=s(i.operand);if(typeof a!="boolean")throw new p(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=s(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 u=s(i.left);if(typeof u!="boolean")throw new p(`\'and\' requires boolean operands, left is ${typeof u}`);if(!u)return!1;let S=s(i.right);if(typeof S!="boolean")throw new p(`\'and\' requires boolean operands, right is ${typeof S}`);return S}if(i.op==="or"){let u=s(i.left);if(typeof u!="boolean")throw new p(`\'or\' requires boolean operands, left is ${typeof u}`);if(u)return!0;let S=s(i.right);if(typeof S!="boolean")throw new p(`\'or\' requires boolean operands, right is ${typeof S}`);return S}let o=s(i.left),a=s(i.right),c=_(i.left,e),l=_(i.right,e),d=c??l;if(d!==void 0){if(c&&l&&!Ae(c,l)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new p(`\'${i.op}\' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return w(o,d,">")>w(a,d,">");case">=":return w(o,d,">=")>=w(a,d,">=");case"<":return w(o,d,"<")<w(a,d,"<");case"<=":return w(o,d,"<=")<=w(a,d,"<=");case"+":case"-":case"*":case"/":throw new p(`\'${i.op}\' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(i.op){case"==":return se(o,a);case"!=":return!se(o,a);case">":return k(o,a,">"),o>a;case">=":return k(o,a,">="),o>=a;case"<":return k(o,a,"<"),o<a;case"<=":return k(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 k(o,a,"-"),o-a;case"*":return k(o,a,"*"),o*a;case"/":if(k(o,a,"/"),a===0)throw new p("division by zero");return o/a}}}};return s(n)}function se(n,e){if(Array.isArray(n)||Array.isArray(e)){if(!Array.isArray(n)||!Array.isArray(e)||n.length!==e.length)return!1;let t=[...n].sort(),r=[...e].sort();for(let s=0;s<t.length;s++)if(t[s]!==r[s])return!1;return!0}return n===e}function k(n,e,t){if(typeof n!="number"||typeof e!="number")throw new p(`\'${t}\' requires numeric operands, got ${typeof n} and ${typeof e}`)}function _(n,e){if(!(n.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(n.scope,n.name)}function w(n,e,t){if(typeof n!="string")throw new p(`\'${t}\' on a quality compares stages, got ${typeof n}`);let r=e.indexOf(n);if(r<0)throw new p(`"${n}" is not a stage of this quality (stages: ${e.join(", ")})`);return r}var Ae=(n,e)=>n.length===e.length&&n.every((t,r)=>t===e[r]);function R(n){if(Number.isNaN(n)||!Number.isFinite(n))return 0;let e=Math.trunc(n)%4294967296;return e<0?e+4294967296:e}function H(n){let e=R(n);return{next(){e=e+1831565813>>>0;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},state(){return e}}}var Ge={name:"check_flags",count:n=>Math.max(1,n.args.length-1)},Ve=[Ge];function ie(n,e,t){let r=t?.countingCalls??Ve;return T(n,t?.want??!0,e,r)}function T(n,e,t,r){if(n.kind==="binary"&&(n.op==="and"||n.op==="or")){let s=T(n.left,e,t,r),i=T(n.right,e,t,r);return n.op==="and"===e?s>0&&i>0?s+i:0:Math.max(s,i)}if(n.kind==="unary"&&n.op==="not")return T(n.operand,!e,t,r);if(n.kind==="call"){let s=r.find(i=>i.name===n.name);if(s){let i=s.count(n),o=t(n);return e?o?i:0:o?0:1}}return t(n)===e?1:0}var b=class n{values={};decls=new Map;subscribers=new Set;auditors=new Set;norm;pathPrefix;constructor(e=[],t){this.norm=t?.normalise??(r=>r.toLowerCase()),this.pathPrefix=t?.pathPrefix??"",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??O(t))}}get(e){return this.values[this.norm(e)]}normalise(e){return this.norm(e)}set(e,t,r){let s=this.norm(e);if(!r?.host&&this.decls.get(s)?.writable===!1)throw new Error(`\'${e}\' is read-only`);let i={name:s,prev:this.values[s],next:t,silent:r?.silent??!1,reason:r?.reason};this.values[s]=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])=>ae(t,this.get(e),void 0,e,this.pathPrefix))}declarations(){return[...this.decls.values()]}clone(){let e=new n([],{normalise:this.norm,pathPrefix:this.pathPrefix});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 ae(n,e,t,r,s=""){let i=r??n.name.toLowerCase();return{name:i,path:s+i,type:n.type,value:e,default:n.default??O(n),...n.values!==void 0?{values:n.values}:{},...n.stages!==void 0?{stages:n.stages}:{},writable:t??n.writable??!0}}var Le=n=>n.toLowerCase(),U=1,A=class{scopes=new Map;parked=new Map;rev=0;get revision(){return this.rev}defineOwned(e,t,r){let s=typeof r=="string"?{pathPrefix:r}:r??{},i=new b(t,{pathPrefix:s.pathPrefix??`${e}.`,...s.normalise?{normalise:s.normalise}:{}});return this.mountOwned(e,i,s.owner!==void 0?{owner:s.owner}:void 0)}mountOwned(e,t,r){this.assertFree(e,r?.owner),this.scopes.set(e,{kind:"owned",bag:t,...r?.owner!==void 0?{owner:r.owner}:{}}),this.rev++;let s=this.parked.get(e);return s&&(t.load(s),this.parked.delete(e)),this}remove(e,t){let r=this.scopes.get(e);if(!r)throw new Error(`unknown scope \'@${e}\'`);return t?.keep&&r.kind==="owned"&&this.parked.set(e,r.bag.save()),this.scopes.delete(e),this.rev++,this}discardParked(e){if(e===void 0)this.parked.clear();else for(let t of[...this.parked.keys()])t.startsWith(e)&&this.parked.delete(t);return 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=[],s=!0){let i=typeof s=="boolean"?{writable:s}:s;this.assertFree(e,i.owner);let o=i.normalise??Le,a=new Map;for(let c of r)a.set(o(c.name),c);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:a,scopeWritable:i.writable??!0,norm:o,...i.owner!==void 0?{owner:i.owner}:{}}),this.rev++,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(r.norm(t))}set(e,t,r,s){let i=this.scopes.get(e);if(!i)throw new Error(`unknown scope \'@${e}\'`);if(i.kind==="owned"){try{i.bag.set(t,r,s?.host?{host:!0}:void 0)}catch{throw new Error(`\'@${e}.${t}\' is read-only`)}return}let o=i.norm(t);if(!i.resolver.set)throw new Error(`\'@${e}.${t}\' is read-only`);if(!s?.host&&!this.foreignWritable(i,o))throw new Error(`\'@${e}.${t}\' is read-only`);i.resolver.set(o,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){let s=r.owner!==void 0?{owner:r.owner}:{};if(r.kind==="owned")for(let i of r.bag.rows())e.push({scope:t,...s,...i});else for(let[i,o]of r.decls)e.push({scope:t,...s,...ae(o,r.resolver.get(i),this.foreignWritable(r,i),i,`${t}.`)})}return e}toEvalContext(e,t){let r=this.view(t?.aliases),s={};for(let[o,a]of r)s[o]=a.kind==="owned"?a.bag.values:a.resolver;let i=this.qualityLadders(r);return i.size===0?{scopes:s,host:e}:{scopes:s,host:e,qualities:(o,a)=>{let c=r.get(o);return c?i.get(o)?.get(Me(c)(a)):void 0}}}view(e){let t=new Map(this.scopes);for(let[r,s]of Object.entries(e??{})){let i=this.scopes.get(s);if(!i)throw new Error(`alias \'@${r}\' names \'${s}\', which is not registered`);t.set(r,i)}return t}qualityLadders(e){let t=new Map;for(let[r,s]of e)for(let[i,o]of oe(s)){if(o.type!=="quality"||o.stages===void 0)continue;let a=t.get(r);a||(a=new Map,t.set(r,a)),a.set(i,o.stages)}return t}toSchema(e){let t=new Map;for(let[r,s]of this.view(e?.aliases)){let i=oe(s);if(i.length===0)continue;let o=new Map;for(let[a,c]of i)o.set(a,{type:c.type,enumValues:c.values,...c.stages!==void 0?{stages:c.stages}:{}});t.set(r,o)}return{properties:t}}save(){let e={};for(let[t,r]of this.scopes)r.kind==="owned"&&(e[t]=r.bag.save());for(let[t,r]of this.parked)e[t]=structuredClone(r);return e}load(e,t){t?.keepParked||this.parked.clear();for(let[r,s]of Object.entries(e)){let i=this.scopes.get(r);i?.kind==="owned"?i.bag.load(s):i||this.parked.set(r,structuredClone(s))}}saveFragment(){return{version:U,scopes:this.save()}}loadFragment(e){if(e.version!==U)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${U})`);this.load(e.scopes)}assertFree(e,t){let r=this.scopes.get(e);if(!r)return;let s=r.owner!==void 0?` by ${r.owner}`:"",i=t!==void 0?` (wanted by ${t})`:"";throw new Error(`scope \'@${e}\' is already registered${s}${i}`)}};function oe(n){return n.kind==="foreign"?[...n.decls.entries()]:n.bag.declarations().map(e=>[n.bag.normalise(e.name),e])}function Me(n){return n.kind==="foreign"?n.norm:e=>n.bag.normalise(e)}function O(n){if(n.default!==void 0)return n.default;switch(n.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"enum":return n.values?.[0]??"";case"flags":return[];case"quality":return n.stages?.[0]??"";default:return!1}}var ce=[{token:"patter",engine:"Patterplay",means:"Patter\'s shared globals"},{token:"story",engine:"Storylet Engine",means:"the Storylet Engine\'s shared @story properties"}];function B(n){return n.ctx.host??{}}var W={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(n,e){if(n.length!==2)throw new p("random(a, b) requires exactly 2 arguments");let t=B(e).nextRandom;if(!t)throw new p("random() called without a PRNG in context");let r=e.evaluate(n[0]),s=e.evaluate(n[1]);if(typeof r!="number"||typeof s!="number")throw new p("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(s))throw new p("random(a, b) arguments must be integers");let i=Math.min(r,s),o=Math.max(r,s);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:pe("check_flags"),eval(n,e){let t=le(n[0],e,"check_flags");for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new p("check_flags() flag args must be +flagName or -flagName");if(s.sign==="+"?!t.includes(s.name):t.includes(s.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:pe("set_flags"),eval(n,e){let t=[...le(n[0],e,"set_flags")];for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new p("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let i=t.indexOf(s.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:V("visits"),eval:(n,e)=>B(e).visits?.(G(n,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:V("seen"),eval:(n,e)=>(B(e).visits?.(G(n,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:V("patter_visits"),eval:(n,e)=>B(e).patterVisits?.(G(n,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:V("patter_seen"),eval:(n,e)=>(B(e).patterVisits?.(G(n,e,"patter_seen"))??0)>0}}},ut=ce.map(n=>n.token).filter(n=>n!=="patter"&&n!=="scene");function de(n,e){let t=n.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function G(n,e,t){let r=e.evaluate(n[0]);if(typeof r!="string")throw new p(`${t}(id) requires a string node id`);return r}function V(n){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:`${n}(id): the argument must be a string id literal (a scene / block / node id)`})}}function le(n,e,t){if(!n)throw new p(`${t}() requires at least one argument (the flags variable)`);let r=e.evaluate(n);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 pe(n){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:`${n}(): first argument must be a flags property reference (@name or @scope.name)`});return}let s=t.schema.properties.get(r.scope)?.get(r.name);if(s&&s.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:`${n}(): \'@${i}\' is not a flags property (got ${s.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:`${n}(): argument ${i+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${n}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var $e=/^@[A-Za-z0-9_.]+$/;function*je(n){let e="",t=0;for(;t<n.length;){let r=n[t];if(r==="{"&&n[t+1]==="{"){e+="{",t+=2;continue}if(r==="}"&&n[t+1]==="}"){e+="}",t+=2;continue}if(r==="{"){let s=n.indexOf("}",t+1);if(s!==-1){let i=n.slice(t,s+1),o=n.slice(t+1,s).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:$e.test(o)?o:void 0},t=s+1;continue}e+=i,t=s+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function qe(n){return Array.isArray(n)?n.join(", "):typeof n=="boolean"?n?"true":"false":String(n)}function _e(n){return n===" "||n===" "||n===`\n`||n==="\\r"||n==="\\f"||n==="\\v"}function He(n){let e="",t=!1;for(let r of n){if(_e(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function ge(n,e,t){if(e.length===0||n.indexOf(e)<0)return n;let r="",s=0,i=!1;for(;s<n.length;){if(n.startsWith(e,s)){let o=n.indexOf(t,s+e.length);if(o>=0){s=o+t.length,i=!0;continue}r+=n.slice(s);break}r+=n[s],s+=1}return i?He(r):n}function ue(n,e){if(n.indexOf("{")<0)return n;let t="";for(let r of je(n)){if(r.kind==="text"){t+=r.value;continue}if(!r.ref){t+=r.raw;continue}let s=e(r.ref);t+=s===void 0?"":qe(s)}return t}function C(n,e){for(let t of n){e(t);let r=t.children;r&&C(r,e)}}function Ue(n){return n.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function m(n){let e=n.gameId?.trim();return e||Ue(n.name)}function K(n){return`cast:${n}`}var J={open:"[",close:"]"},he="SFX";var z=3;function L(n){let e=new Set,t=[];for(let r of n)e.has(r)||(e.add(r),t.push(r));return t}function M(n){let e=new Map,t=(r,s)=>{let i=L([...s,...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,L([...i,...o.tags??[]]))};for(let r of Object.values(n.scenes)){let s=L(r.tags??[]);e.set(r.id,s);for(let i of r.blocks){let o=L([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var fe=new WeakMap,I="Patter",P=n=>n.replace(/%/g,"%25").replace(/\\//g,"%2F"),me=Symbol("ownsRegistry"),v={stage:n=>`patter/scene/${P(n)}`,flow:n=>`patter/flow/${P(n)}/`,flowGlobals:n=>`patter/flow/${P(n)}/patter`,flowScene:(n,e)=>`patter/flow/${P(n)}/scene/${P(e)}`},$=class n{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineTraceHandlers=new Set;constructor(e,t={}){this.creationOptions=t;let r=t.locale??e.locales.default,s=e.strings;this.allStrings=s,this.currentLocale=r;let i=s[r]??{},o=s[e.locales.default]??{},a=e.localisation,c=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 l=new Map;for(let g of e.cast??[])g.displayName&&l.set(g.name,g.displayName);this.defaultSeed=(t.seed??2654435769)>>>0;let d=new Map,u=new Map,S=new Map;for(let[g,h]of Object.entries(e.scenes)){this.sceneGameIdToId.set(m(h),g);let y=new Map;for(let f of h.blocks)u.set(f.id,{sceneId:g}),S.set(f.id,f),y.set(m(f),f.id),C(f.children,ne=>d.set(ne.id,ne));this.blockGameIdToId.set(g,y)}let X=e.properties??[],j=X.filter(g=>g.shared??!0).map(ye),De=X.filter(g=>!(g.shared??!0)).map(ye),Re=new Set(j.map(g=>g.name.toLowerCase())),x=t.registry??new A,Z=!t.registry||t[me]===!0,ee=new b(j,{pathPrefix:"@patter."}),te=[],N=[];try{x.mountOwned("patter",ee,{owner:I}),N.push("patter");let g=new Set;if(t.world){let h=e.scopeRegistry?.scopes.find(f=>f.token==="world"),y=(h?.declarations??[]).map(xe);x.defineForeign("world",t.world,y,{writable:h?.writable??!0,owner:I}),N.push("world"),g.add("world")}for(let h of Z?e.scopeRegistry?.scopes??[]:[]){if(g.has(h.token)||x.has(h.token))continue;let y=(h.declarations??[]).map(f=>We(f,h.writable));x.defineOwned(h.token,y,{owner:I}),N.push(h.token),te.push(h.token)}}catch(g){for(let h of N)x.remove(h,{keep:!0});throw g}let re=new Map;for(let[g,h]of Object.entries(e.scenes)){let y=new Set((h.sceneProps??[]).filter(f=>f.shared??!1).map(f=>f.name.toLowerCase()));re.set(g,y)}this.host={logEnabled:t.log??!1,emitEngine:(g,h,y)=>this.emitEngine(g,h,y),bundle:e,emitIds:c,strings:i,defaultStrings:o,castDisplay:l,nodeIndex:d,blockIndex:u,blockById:S,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:M(e),registry:x,ownsRegistry:Z,patterBag:ee,hostScopes:te,patterSharedDecls:j,patterLocalDecls:De,patterSharedNames:Re,sceneSharedNames:re,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||he,refSplitCache:new Map,refSplitRevision:x.revision}}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=o=>(o.setLocale(this.currentLocale),o.setClosedCaptions(this.host.captionsOn),o),s=()=>new n(e,{...this.creationOptions,registry:this.host.registry,[me]:this.host.ownsRegistry});this.release(!0);let i=s();try{return i.loadGame(t),r(i)}catch{i.release(!0);let o=s();for(let[a,c]of Object.entries(t.flows)){let l=c.cursor.currentSceneId;try{o.openFlow(a,l!==null?{scene:l}:{})}catch{}}return r(o)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){this.assertExternalScopes();let r=this.resolveSceneRef(t.scene),s=this.resolveBlockRef(r,t.block);this.flowsById.get(e)?.close();let i=new D(e,this.host,t.seed??this.defaultSeed);return this.flowsById.set(e,i),i.start(r,s),i}runFlow(e,t,r){let s=this.flowsById.get(e);if(!s)return this.openFlow(e,{scene:t,block:r}).advanceToStop().played;if(!s.goto(t,r))throw new Error(`runFlow: address not found: ${t}${r===void 0?"":` / ${r}`}`);return s.advanceToStop().played}assertExternalScopes(){for(let e of this.host.bundle.externalScopes??[])if(!this.host.registry.has(e))throw new Error(`this content names @${e}, which no engine on this registry registered: give every engine the game\'s one registry`)}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?m(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?m(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),s=this.resolveBlockRef(r,t);return(s!=null?this.host.tagIndex.get(s):void 0)??[]}getCast(){let e=[];for(let t of this.host.bundle.cast??[])t?.name&&e.push(t.name);return e}castForScene(e){let t=this.resolveSceneRef(e),r=t!=null?this.host.bundle.scenes[t]:void 0;if(!r)return[];let s=new Set;for(let i of r.blocks)Se(i.children,s);return[...s]}castForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t),i=s!=null?this.host.blockById.get(s):void 0;if(!i)return[];let o=new Set;return Se(i.children,o),[...o]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...m(e)?{gameId:m(e)}:{},name:e.name,...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...m(t)?{gameId:m(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)C(r.children,s=>{if(s.type==="snippet")for(let i of s.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:s.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 s=this.host.defaultStrings[K(e.character)]??this.host.castDisplay.get(e.character);s!==void 0&&(r.characterName=s)}e.direction!==void 0&&(r.direction=e.direction)}if(e.kind==="line"||e.kind==="text"){let s=this.host.defaultStrings[e.id];s!==void 0&&(r.text=s)}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()]}listBags(){let e=[{bag:this.host.patterBag}];for(let[t,r]of this.host.stageBags)e.push({bag:r,pathPrefix:`@scene:${t}.`});return e}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.patterBag.reseed(this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear();for(let e of this.host.stageBags.keys())this.host.registry.remove(v.stage(e));this.host.stageBags.clear(),this.host.registry.discardParked("patter/")}release(e){for(let r of this.flowsById.values())r.releaseBags(e),r.close();this.flowsById.clear();let t=this.host.registry;for(let r of this.host.stageBags.keys())t.remove(v.stage(r),{keep:e});this.host.stageBags.clear();for(let r of["patter",...this.host.hostScopes])t.has(r)&&t.remove(r,{keep:e});this.creationOptions.world&&t.has("world")&&t.remove("world")}getProperty(e){let{scope:t,name:r}=this.splitShared(e);return this.host.registry.get(t,r)}setProperty(e,t){let{scope:r,name:s}=this.splitShared(e);this.host.registry.set(r,s,t,{host:!0})}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),()=>this.engineTraceHandlers.delete(e)}emitEngine(e,t,r){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineLog.length,...r?{scene:r}:{}})}listProperties(){return this.host.patterSharedDecls.map(e=>({name:e.name,path:`@patter.${e.name}`,type:e.type,values:e.values,stages:e.stages,value:this.getProperty(`@${e.name}`),default:O(e),writable:e.writable??!0}))}splitShared(e){let t=Ee(this.host,e);if(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{patter:this.host.patterBag.save()}}load(e){e.patter&&this.host.patterBag.load(e.patter)}saveGame(){let e={};for(let[t,r]of this.flowsById)e[t]=r.snapshot();return{version:z,...this.host.ownsRegistry?{registry:this.host.registry.save()}:{},sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:we(this.host.sharedSelectors),flows:e}}loadGame(e){let t=e.version;if(t!==2&&t!==z)throw new Error(`unsupported save version: ${String(t)}`);this.assertExternalScopes();let r=this.host.registry;for(let[i,o]of this.flowsById)o.releaseBags(i in e.flows),o.close();this.flowsById.clear();for(let i of this.host.stageBags.keys())r.remove(v.stage(i),{keep:!0});this.host.stageBags.clear();let s=e.version===2?Ke(e):e.registry;s&&(this.host.ownsRegistry?r.load(s):r.load(s,{keepParked:!0})),this.host.sharedVisits.clear();for(let[i,o]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(i,o);this.host.sharedSelectors.clear();for(let[i,o]of be(e.sharedSelectors))this.host.sharedSelectors.set(i,o);for(let[i,o]of Object.entries(e.flows)){let a=new D(i,this.host,this.defaultSeed);a.restore(o),this.flowsById.set(i,a)}}},D=class{id;host;local;registered=new Set;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.patterBag.get(e):this.local.get(e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.registry.set("patter",e,t):this.local.set(e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;if(t!==null)return this.sceneBagFor(t,e)?.get(e)},set:(e,t)=>{let r=this.currentSceneId;if(r===null)return;let s=this.sceneBagFor(r,e);s&&s.set(e,t)}};evalCtx;ctxRevision=-1;registryQualities;flowLog=[];flowSeq=0;constructor(e,t,r){this.id=e,this.host=t,this.rngState=R(r),this.local=this.newLocal(),this.evalCtx={scopes:{},host:{nextRandom:this.rng,visits:s=>this.visitCounts.get(s)??0,patterVisits:s=>this.host.sharedVisits.get(s)??0},qualities:(s,i)=>this.stagesFor(s,i)}}context(){let e=this.host.registry;if(e.revision!==this.ctxRevision){let t=e.toEvalContext(),r=this.evalCtx.scopes;for(let s of Object.keys(r))delete r[s];Object.assign(r,t.scopes),r.patter=this.patterResolver,r.scene=this.sceneResolver,this.registryQualities=t.qualities,this.ctxRevision=e.revision}return this.evalCtx}stagesFor(e,t){let r=t.toLowerCase(),s=i=>i?.find(o=>o.name.toLowerCase()===r&&o.type==="quality")?.stages;if(e==="patter")return s(this.host.patterSharedDecls)??s(this.host.patterLocalDecls);if(e==="scene"){let i=this.currentSceneId!=null?this.host.bundle.scenes[this.currentSceneId]:void 0;return s(i?.sceneProps)}return this.registryQualities?.(e,t)??s(this.host.bundle.scopeRegistry?.scopes.find(i=>i.token===e)?.declarations)}start(e,t){if(this.releaseBags(!1),this.host.registry.discardParked(v.flow(this.id)),this.mountLocal(),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],s=r?this.host.bundle.scenes[r]:void 0;if(!s)throw new Error(r?`unknown scene: ${r}`:"no scenes in bundle");this.enterSceneSetup(r);let i=s.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 s;return t!==void 0&&(s=this.host.blockGameIdToId.get(r)?.get(t)??(this.host.blockIndex.get(t)?.sceneId===r?t:void 0),s===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(s??r,"jump"),this.settle(),!0):(this.start(r,s),!0)}close(){this.releaseBags(!1),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 i=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(i);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}let s=t.index;for(;t.index<r.length&&!this.eligible(r[t.index]);)t.index++;if(this.host.logEnabled&&t.index!==s&&this.emit({type:"select",group:t.containerId,selector:"run",children:r.slice(s,t.index+1).map((i,o)=>({id:i.id,eligible:s+o===t.index})),picked:r[t.index]?.id??null}),t.index>=r.length){this.stack.pop();continue}this.enterChild(r[t.index++])}}listBags(){let e=[{bag:this.local,pathPrefix:`${this.id}/@patter.`}];for(let[t,r]of this.sceneBags)e.push({bag:r,pathPrefix:`${this.id}/@scene:${t}.`});return e}log(){return this.flowLog}clearLog(){this.flowLog.length=0}emit(e){let t=this.currentSceneId??void 0;this.host.emitEngine(this.id,e,t),this.host.logEnabled&&this.flowLog.push({...e,seq:this.flowSeq++,...t?{scene:t}:{}})}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 s=t.byId.get(e);this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null,this.pendingPromptBeat=this.host.replayPromptOnChoose?this.promptBeatOf(s)??null:null,this.pendingPromptOwnerId=this.pendingPromptBeat?s.id:null,this.enterChild(s)}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.registry.get(t,r)}setProperty(e,t){this.writeProperty(e,t,!0)}writeProperty(e,t,r){let{scope:s,name:i}=this.splitRef(e);if(s==="patter")this.patterResolver.set(i,t);else if(s==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);this.sceneResolver.set(i,t)}else this.host.registry.set(s,i,t,r?{host:!0}:void 0)}snapshot(){return{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:we(this.selectors)}}}restore(e){this.rngState=R(e.rngState),this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;this.started=!0,this.flowEnded=t.flowEnded,this.beatIndex=t.beatIndex,this.currentSceneId=t.currentSceneId,this.stack=t.stack.map(r=>{let{nextId:s,...i}=r;if(s!==void 0){let o=this.childrenOf(i.containerId)?.findIndex(a=>a.id===s)??-1;if(o>=0)return{...i,index:o}}return{...i}}),this.releaseBags(!1),this.mountLocal();for(let r of new Set([t.currentSceneId,...this.stack.map(s=>s.sceneId)]))r!==null&&this.host.bundle.scenes[r]&&this.ensureSceneBags(r);if(this.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=be(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,s=[];for(let i of t.pendingChoice.options){let o=this.host.nodeIndex.get(i.id);o&&(r.set(i.id,o),s.push({...i}))}s.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:s,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,s=[];for(let o of e.children){if(o.fallback===!0){s.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),c=o.secretUntilEligible===!0;!a&&c||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.length>0){this.emit({type:"choice",group:e.id,options:t.map(o=>({id:o.id,eligible:o.eligible}))}),this.pendingChoice={groupId:e.id,options:t,byId:r};return}let i=s.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.emit({type:"dry",group:e.id}),this.host.onDryChoice?.(e.id)}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(this.emit({type:"jump",to:e,mode:t}),e==="END"){this.flowEnded=!0,this.stack=[];return}let r,s,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,s=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,s=e}this.enter(s);let o={sceneId:r,containerId:s,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.map(c=>({id:c.id,eligible:this.eligible(c)})),r=e.children.filter(c=>this.eligible(c)),s=e.options?.order??"sequential",i=e.options?.exhaust??"once",o=c=>(this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:i}:{},children:t,picked:c?.id??null}),c);if(r.length===0)return o(null);let a=this.selectorState(e);switch(e.selector){case"branch":return o(r[0]);case"sequence":return o(s==="shuffle"?this.pickShuffle(r,i,a):s==="specificity"?this.pickSpecificity(r,i,a):this.pickSequential(r,i,a));default:return null}}pickSequential(e,t,r){let s=e.length,i=r.seq??0;return r.seq=i+1,t==="repeat"?e[i%s]:i<s?e[i]:t==="stick"?e[s-1]:null}pickShuffle(e,t,r){let s=e.length,i=t==="stick",o=()=>(i?e.slice(0,s-1):e).map(u=>u.id);if(r.bag===void 0&&(r.bag=o()),r.bag.length===0){if(t==="once")return null;if(i){let u=e[s-1];return r.last=u.id,u}r.bag=o()}let a=r.bag,c=r.last!==void 0&&a.length>1?a.indexOf(r.last):-1,l=Math.floor(this.rng()*(c>=0?a.length-1:a.length));c>=0&&l>=c&&l++;let d=a[l];return a.splice(l,1),r.last=d,e.find(u=>u.id===d)}pickSpecificity(e,t,r){let s=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(d=>d.id));let l=new Set(r.bag);if(s=e.filter(d=>l.has(d.id)),s.length===0)return t==="stick"&&r.last!==void 0?e.find(d=>d.id===r.last)??null:null}let i=-1,a=s.map(l=>{let d=this.specScore(l);return d>i&&(i=d),{c:l,s:d}}).filter(l=>l.s===i).map(l=>l.c),c;if(a.length===1)c=a[0];else{let l=r.last!==void 0?a.findIndex(u=>u.id===r.last):-1,d=Math.floor(this.rng()*(l>=0?a.length-1:a.length));l>=0&&d>=l&&d++,c=a[d]}return t!=="repeat"&&(r.bag=r.bag.filter(l=>l!==c.id)),r.last=c.id,c}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0):0}matchedSpec(e,t){return ie(e,s=>ve(F(s,this.context(),W)),{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??[]){let r=this.evalExpr(t.value),s=this.host.logEnabled?this.getProperty(t.target):void 0;this.writeProperty(t.target,r,!1),this.emit({type:"write",target:t.target,value:r,...s!==void 0?{prev:s}:{}})}}eligible(e){return e.condition?ve(this.evalExpr(e.condition)):!0}evalExpr(e){return F(this.conditionAst(e),this.context(),W)}conditionAst(e){let t=fe.get(e);return t||(t=E(e.ast),fe.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=H(this.rngState),t=e.next();return this.rngState=e.state(),t};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 s=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=i&&a.length===0;return{type:"line",id:e.id,text:a,character:c?void 0:e.character,characterName:c?void 0:this.resolveCharacterName(e.character),direction:c?void 0:e.direction,gameData:e.gameData,...r}}}}interpolate(e){return ue(e,t=>this.getProperty(t))}stripCaptions(e){return ge(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 C(e,r=>{!t&&r.type==="snippet"&&(r.beats??[]).some(s=>s.kind==="line"||s.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=K(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}splitRef(e){return Ee(this.host,e)}newLocal(){return new b(this.host.patterLocalDecls,{pathPrefix:"@patter."})}mountLocal(){this.local=this.newLocal();let e=v.flowGlobals(this.id);this.host.registry.mountOwned(e,this.local,{owner:I}),this.registered.add(e)}releaseBags(e){for(let t of this.registered)this.host.registry.remove(t,{keep:e});this.registered.clear(),this.sceneBags.clear()}sceneBagFor(e,t){if(this.host.bundle.scenes[e])return this.ensureSceneBags(e),this.host.sceneSharedNames.get(e)?.has(t.toLowerCase())?this.host.stageBags.get(e):this.sceneBags.get(e)}ensureSceneBags(e){let t=this.host.sceneSharedNames.get(e)??new Set,r=this.host.bundle.scenes[e]?.sceneProps??[];if(!this.sceneBags.has(e)){let s=new b(r.filter(o=>!t.has(o.name.toLowerCase())),{pathPrefix:"@scene."}),i=v.flowScene(this.id,e);this.host.registry.mountOwned(i,s,{owner:I}),this.registered.add(i),this.sceneBags.set(e,s)}if(!this.host.stageBags.has(e)){let s=new b(r.filter(i=>t.has(i.name.toLowerCase())),{pathPrefix:"@scene."});this.host.registry.mountOwned(v.stage(e),s,{owner:I}),this.host.stageBags.set(e,s)}}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set;this.ensureSceneBags(e.id);for(let r of e.sceneProps??[]){if(!r.temporary)continue;let s=r.name.toLowerCase(),i=t.has(s)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);i&&i.set(s,O(r))}}};function Se(n,e){C(n,t=>{if(t.type==="group"){t.prompt?.kind==="line"&&t.prompt.character&&e.add(t.prompt.character);return}for(let r of t.beats??[])r.kind==="line"&&r.character&&e.add(r.character)})}function we(n){let e={};for(let[t,r]of n){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e[t]=s}return e}function be(n){let e=new Map;for(let[t,r]of Object.entries(n??{})){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e.set(t,s)}return e}function ye(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default}}function xe(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default,writable:n.writable}}function We(n,e){let t=xe(n),r=n.writable??e;return r===void 0?t:{...t,writable:r}}function Ee(n,e){n.refSplitRevision!==n.registry.revision&&(n.refSplitCache.clear(),n.refSplitRevision=n.registry.revision);let t=n.refSplitCache.get(e);return t||(t=de(e,r=>r==="scene"||n.registry.has(r)||(n.bundle.externalScopes?.includes(r)??!1)),n.refSplitCache.set(e,t)),t}function Ke(n){let e={};n.shared?.patter&&(e.patter=n.shared.patter);for(let[t,r]of Object.entries(n.stageBags??{}))e[v.stage(t)]=r;for(let[t,r]of Object.entries(n.flows??{})){r.scopes?.patter&&(e[v.flowGlobals(t)]=r.scopes.patter);for(let[s,i]of Object.entries(r.sceneBags??{}))e[v.flowScene(t,s)]=i}return e}function ve(n){return typeof n=="boolean"?n:typeof n=="number"?n!==0:typeof n=="string"?n!=="":n.length>0}var Je=(n,e)=>n.shared??e;function Y(n,e){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.default!==void 0?{default:n.default}:{},shared:Je(n,e)}}function ze(n){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.values?{values:[...n.values]}:{},...n.purpose?{purpose:n.purpose}:{}}}function Ye(n,e){e.blocks++;let t=[...n.children];for(;t.length;){let r=t.pop();if(r.type==="group"){e.groups++,r.prompt&&e.prompts++,t.push(...r.children);continue}e.snippets++;for(let s of r.beats??[])e.beats++,s.kind==="gameEvent"&&e.gameEvents++}}function ke(n){let e={scenes:0,blocks:0,groups:0,snippets:0,beats:0,prompts:0,gameEvents:0,cast:n.cast?.length??0},t=[],r=[];for(let o of Object.values(n.scenes)){e.scenes++;let a=m(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(c=>({gameId:m(c),name:c.name}))});for(let c of o.blocks)Ye(c,e);o.sceneProps?.length&&r.push({gameId:a,properties:o.sceneProps.map(c=>Y(c,!1))})}let s=(n.scopeRegistry?.scopes??[]).map(o=>({token:o.token,writable:o.writable??!0,opaque:o.declarations===void 0,properties:(o.declarations??[]).map(a=>Y(a,!0))})),i=Object.entries(n.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(ze)}));return{identity:{schema:n.schema,project:n.content.project,...n.content.version!==void 0?{version:n.content.version}:{},...n.content.hash!==void 0?{hash:n.content.hash}:{},...n.content.structureHash!==void 0?{structureHash:n.content.structureHash}:{},voiced:n.voiced,defaultLocale:n.locales.default,locales:[...n.locales.included],localisation:n.localisation?.mode??"embedded",sourceDebug:n.localisation?.sourceDebug??!1},addresses:t,hostScopes:s,properties:{patter:(n.properties??[]).map(o=>Y(o,!0)),scene:r},gameData:i,counts:e}}function Ce(n,e){return n.gameDataFields?.[e]??[]}function Q(n,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:n.find(r=>r.name===t)?.default}function Ie(n,e){let t={};for(let r of n){let s=Q(n,e,r.name);s!==void 0&&(t[r.name]=s)}for(let[r,s]of Object.entries(e??{}))r in t||(t[r]=s);return t}return Te(Qe);})();\n';
|
|
195021
195060
|
|
|
195022
195061
|
// ../ops/src/export-html.ts
|
|
195023
195062
|
var esc = (s) => s.replace(/[&<>]/g, (c2) => ({ "&": "&", "<": "<", ">": ">" })[c2]);
|
|
@@ -195284,6 +195323,13 @@ var PropertyBag = class _PropertyBag {
|
|
|
195284
195323
|
get(name) {
|
|
195285
195324
|
return this.values[this.norm(name)];
|
|
195286
195325
|
}
|
|
195326
|
+
/** A name as this bag keys it: its normalisation policy applied. The registry
|
|
195327
|
+
* uses it to key quality ladders and the validation schema the bag's own way,
|
|
195328
|
+
* so a case-significant (identity) bag is not quietly folded to lower case
|
|
195329
|
+
* one layer up. */
|
|
195330
|
+
normalise(name) {
|
|
195331
|
+
return this.norm(name);
|
|
195332
|
+
}
|
|
195287
195333
|
/** Write a property. Engine writes (the default) notify subscribers;
|
|
195288
195334
|
* pass `silent: true` for a host write, which reaches only the audit
|
|
195289
195335
|
* hook. Throws on a read-only property unless the caller says it is the
|
|
@@ -195367,25 +195413,82 @@ function rowFor(d, value, writable, name, pathPrefix = "") {
|
|
|
195367
195413
|
writable: writable ?? d.writable ?? true
|
|
195368
195414
|
};
|
|
195369
195415
|
}
|
|
195416
|
+
var lowerCase = (name) => name.toLowerCase();
|
|
195370
195417
|
var SAVE_FRAGMENT_VERSION = 1;
|
|
195371
195418
|
var ScopeRegistry = class {
|
|
195372
195419
|
scopes = /* @__PURE__ */ new Map();
|
|
195420
|
+
/** Values loaded for keys nobody has registered yet, waiting to be claimed. */
|
|
195421
|
+
parked = /* @__PURE__ */ new Map();
|
|
195422
|
+
rev = 0;
|
|
195423
|
+
/**
|
|
195424
|
+
* A counter that moves whenever a scope is registered or removed, and at no
|
|
195425
|
+
* other time: it starts at 0 and each registration or removal adds 1. Values
|
|
195426
|
+
* changing does not move it. A caller that caches a context built by
|
|
195427
|
+
* `toEvalContext()` rebuilds it when this moves, because the context's set of
|
|
195428
|
+
* scopes is fixed when it is built while the values it reads stay live.
|
|
195429
|
+
*/
|
|
195430
|
+
get revision() {
|
|
195431
|
+
return this.rev;
|
|
195432
|
+
}
|
|
195373
195433
|
/**
|
|
195374
195434
|
* Register a scope this registry **owns and stores**. Its bag is seeded from
|
|
195375
195435
|
* each declaration's `default` (or a type default). Owned scopes are
|
|
195376
195436
|
* type-checked (declarations) and serialized by `save`/`load`.
|
|
195437
|
+
*
|
|
195438
|
+
* The third argument may be the path prefix alone (the pre-0.7 form) or an
|
|
195439
|
+
* options object.
|
|
195440
|
+
*/
|
|
195441
|
+
defineOwned(token2, declarations, opts) {
|
|
195442
|
+
const o = typeof opts === "string" ? { pathPrefix: opts } : opts ?? {};
|
|
195443
|
+
const bag = new PropertyBag(declarations, {
|
|
195444
|
+
pathPrefix: o.pathPrefix ?? `${token2}.`,
|
|
195445
|
+
...o.normalise ? { normalise: o.normalise } : {}
|
|
195446
|
+
});
|
|
195447
|
+
return this.mountOwned(token2, bag, o.owner !== void 0 ? { owner: o.owner } : void 0);
|
|
195448
|
+
}
|
|
195449
|
+
/**
|
|
195450
|
+
* Attach an EXISTING bag as an owned scope: an engine (or a host) holds the
|
|
195451
|
+
* bag and this registry reads, writes, lists and saves it like its own.
|
|
195452
|
+
*
|
|
195453
|
+
* If values were loaded for this key before anyone registered it, the bag
|
|
195454
|
+
* claims them now: laid over its seeded defaults by the bag's own `load` rule.
|
|
195455
|
+
*/
|
|
195456
|
+
mountOwned(token2, bag, opts) {
|
|
195457
|
+
this.assertFree(token2, opts?.owner);
|
|
195458
|
+
this.scopes.set(token2, { kind: "owned", bag, ...opts?.owner !== void 0 ? { owner: opts.owner } : {} });
|
|
195459
|
+
this.rev++;
|
|
195460
|
+
const waiting = this.parked.get(token2);
|
|
195461
|
+
if (waiting) {
|
|
195462
|
+
bag.load(waiting);
|
|
195463
|
+
this.parked.delete(token2);
|
|
195464
|
+
}
|
|
195465
|
+
return this;
|
|
195466
|
+
}
|
|
195467
|
+
/**
|
|
195468
|
+
* Unregister a scope. With `{ keep: true }` an owned scope's values are parked
|
|
195469
|
+
* and handed back when the same key is next registered, which is how a live
|
|
195470
|
+
* reload hands an engine's state to its replacement. Throws on an unknown key.
|
|
195377
195471
|
*/
|
|
195378
|
-
|
|
195379
|
-
|
|
195472
|
+
remove(token2, opts) {
|
|
195473
|
+
const e = this.scopes.get(token2);
|
|
195474
|
+
if (!e) throw new Error(`unknown scope '@${token2}'`);
|
|
195475
|
+
if (opts?.keep && e.kind === "owned") this.parked.set(token2, e.bag.save());
|
|
195476
|
+
this.scopes.delete(token2);
|
|
195477
|
+
this.rev++;
|
|
195478
|
+
return this;
|
|
195380
195479
|
}
|
|
195381
195480
|
/**
|
|
195382
|
-
*
|
|
195383
|
-
*
|
|
195384
|
-
*
|
|
195481
|
+
* Drop parked values nobody claimed. Parked values are kept in the next save by
|
|
195482
|
+
* default, so nothing loaded is lost to a flow or deck that simply has not
|
|
195483
|
+
* reopened yet; a game that knows they are dead drops them here.
|
|
195484
|
+
*
|
|
195485
|
+
* With a `prefix`, only keys starting with it are dropped: an engine resetting
|
|
195486
|
+
* itself drops its own instance keys (`my-engine/`) and leaves every other
|
|
195487
|
+
* engine's alone.
|
|
195385
195488
|
*/
|
|
195386
|
-
|
|
195387
|
-
this.
|
|
195388
|
-
this.
|
|
195489
|
+
discardParked(prefix) {
|
|
195490
|
+
if (prefix === void 0) this.parked.clear();
|
|
195491
|
+
else for (const key2 of [...this.parked.keys()]) if (key2.startsWith(prefix)) this.parked.delete(key2);
|
|
195389
195492
|
return this;
|
|
195390
195493
|
}
|
|
195391
195494
|
/** An owned scope's bag (subscribe, audit, rows live there). */
|
|
@@ -195411,11 +195514,21 @@ var ScopeRegistry = class {
|
|
|
195411
195514
|
* `declarations` (optional, e.g. imported from a `scopeRegistrySpec`) are used
|
|
195412
195515
|
* only for validation; omit them for an opaque scope.
|
|
195413
195516
|
*/
|
|
195414
|
-
defineForeign(token2, resolver, declarations = [],
|
|
195415
|
-
|
|
195517
|
+
defineForeign(token2, resolver, declarations = [], opts = true) {
|
|
195518
|
+
const o = typeof opts === "boolean" ? { writable: opts } : opts;
|
|
195519
|
+
this.assertFree(token2, o.owner);
|
|
195520
|
+
const norm = o.normalise ?? lowerCase;
|
|
195416
195521
|
const decls = /* @__PURE__ */ new Map();
|
|
195417
|
-
for (const d of declarations) decls.set(d.name
|
|
195418
|
-
this.scopes.set(token2, {
|
|
195522
|
+
for (const d of declarations) decls.set(norm(d.name), d);
|
|
195523
|
+
this.scopes.set(token2, {
|
|
195524
|
+
kind: "foreign",
|
|
195525
|
+
resolver,
|
|
195526
|
+
decls,
|
|
195527
|
+
scopeWritable: o.writable ?? true,
|
|
195528
|
+
norm,
|
|
195529
|
+
...o.owner !== void 0 ? { owner: o.owner } : {}
|
|
195530
|
+
});
|
|
195531
|
+
this.rev++;
|
|
195419
195532
|
return this;
|
|
195420
195533
|
}
|
|
195421
195534
|
has(token2) {
|
|
@@ -195425,7 +195538,7 @@ var ScopeRegistry = class {
|
|
|
195425
195538
|
get(scope, name) {
|
|
195426
195539
|
const e = this.scopes.get(scope);
|
|
195427
195540
|
if (!e) return void 0;
|
|
195428
|
-
return e.kind === "owned" ? e.bag.get(name) : e.resolver.get(
|
|
195541
|
+
return e.kind === "owned" ? e.bag.get(name) : e.resolver.get(e.norm(name));
|
|
195429
195542
|
}
|
|
195430
195543
|
/** Write a property (an ENGINE write: the bag's subscribers fire; use
|
|
195431
195544
|
* the bag directly for silent host writes). Throws on an unknown scope.
|
|
@@ -195447,7 +195560,7 @@ var ScopeRegistry = class {
|
|
|
195447
195560
|
}
|
|
195448
195561
|
return;
|
|
195449
195562
|
}
|
|
195450
|
-
const n =
|
|
195563
|
+
const n = e.norm(name);
|
|
195451
195564
|
if (!e.resolver.set) throw new Error(`'@${scope}.${name}' is read-only`);
|
|
195452
195565
|
if (!opts?.host && !this.foreignWritable(e, n)) throw new Error(`'@${scope}.${name}' is read-only`);
|
|
195453
195566
|
e.resolver.set(n, value);
|
|
@@ -195462,19 +195575,15 @@ var ScopeRegistry = class {
|
|
|
195462
195575
|
listProperties() {
|
|
195463
195576
|
const out = [];
|
|
195464
195577
|
for (const [token2, e] of this.scopes) {
|
|
195578
|
+
const owner = e.owner !== void 0 ? { owner: e.owner } : {};
|
|
195465
195579
|
if (e.kind === "owned") {
|
|
195466
|
-
for (const row of e.bag.rows()) out.push({ scope: token2, ...row });
|
|
195580
|
+
for (const row of e.bag.rows()) out.push({ scope: token2, ...owner, ...row });
|
|
195467
195581
|
} else {
|
|
195468
|
-
for (const d of e.decls
|
|
195582
|
+
for (const [n, d] of e.decls) {
|
|
195469
195583
|
out.push({
|
|
195470
195584
|
scope: token2,
|
|
195471
|
-
...
|
|
195472
|
-
|
|
195473
|
-
e.resolver.get(d.name.toLowerCase()),
|
|
195474
|
-
this.foreignWritable(e, d.name.toLowerCase()),
|
|
195475
|
-
void 0,
|
|
195476
|
-
`${token2}.`
|
|
195477
|
-
)
|
|
195585
|
+
...owner,
|
|
195586
|
+
...rowFor(d, e.resolver.get(n), this.foreignWritable(e, n), n, `${token2}.`)
|
|
195478
195587
|
});
|
|
195479
195588
|
}
|
|
195480
195589
|
}
|
|
@@ -195486,31 +195595,48 @@ var ScopeRegistry = class {
|
|
|
195486
195595
|
* bags, foreign scopes as their resolvers. `host` carries dialect-function
|
|
195487
195596
|
* callbacks (PRNG, tag lookups) and is passed through untouched.
|
|
195488
195597
|
*/
|
|
195489
|
-
toEvalContext(host2) {
|
|
195598
|
+
toEvalContext(host2, opts) {
|
|
195599
|
+
const view = this.view(opts?.aliases);
|
|
195490
195600
|
const scopes = {};
|
|
195491
|
-
for (const [token2, e] of
|
|
195492
|
-
|
|
195493
|
-
}
|
|
195494
|
-
const qualities = this.qualityLadders();
|
|
195601
|
+
for (const [token2, e] of view) scopes[token2] = e.kind === "owned" ? e.bag.values : e.resolver;
|
|
195602
|
+
const qualities = this.qualityLadders(view);
|
|
195495
195603
|
return qualities.size === 0 ? { scopes, host: host2 } : {
|
|
195496
195604
|
scopes,
|
|
195497
195605
|
host: host2,
|
|
195498
|
-
qualities: (scope, name) =>
|
|
195606
|
+
qualities: (scope, name) => {
|
|
195607
|
+
const e = view.get(scope);
|
|
195608
|
+
return e ? qualities.get(scope)?.get(normOf(e)(name)) : void 0;
|
|
195609
|
+
}
|
|
195499
195610
|
};
|
|
195500
195611
|
}
|
|
195501
|
-
/**
|
|
195502
|
-
|
|
195612
|
+
/**
|
|
195613
|
+
* The scopes an expression sees: every registered key under its own token,
|
|
195614
|
+
* then each alias token pointing at its key's entry (an alias shadows a key of
|
|
195615
|
+
* the same name). Keys an engine uses for instance bags (`engine/flow-2/...`)
|
|
195616
|
+
* are not valid expression tokens, so they are present but unreachable.
|
|
195617
|
+
*/
|
|
195618
|
+
view(aliases) {
|
|
195619
|
+
const out = new Map(this.scopes);
|
|
195620
|
+
for (const [token2, key2] of Object.entries(aliases ?? {})) {
|
|
195621
|
+
const e = this.scopes.get(key2);
|
|
195622
|
+
if (!e) throw new Error(`alias '@${token2}' names '${key2}', which is not registered`);
|
|
195623
|
+
out.set(token2, e);
|
|
195624
|
+
}
|
|
195625
|
+
return out;
|
|
195626
|
+
}
|
|
195627
|
+
/** Every quality declaration's ladder, keyed scope token then name (the
|
|
195628
|
+
* scope's own normalisation). */
|
|
195629
|
+
qualityLadders(view) {
|
|
195503
195630
|
const out = /* @__PURE__ */ new Map();
|
|
195504
|
-
for (const [token2, e] of
|
|
195505
|
-
const
|
|
195506
|
-
for (const d of decls) {
|
|
195631
|
+
for (const [token2, e] of view) {
|
|
195632
|
+
for (const [n, d] of declsOf(e)) {
|
|
195507
195633
|
if (d.type !== "quality" || d.stages === void 0) continue;
|
|
195508
195634
|
let m = out.get(token2);
|
|
195509
195635
|
if (!m) {
|
|
195510
195636
|
m = /* @__PURE__ */ new Map();
|
|
195511
195637
|
out.set(token2, m);
|
|
195512
195638
|
}
|
|
195513
|
-
m.set(
|
|
195639
|
+
m.set(n, d.stages);
|
|
195514
195640
|
}
|
|
195515
195641
|
}
|
|
195516
195642
|
return out;
|
|
@@ -195518,15 +195644,17 @@ var ScopeRegistry = class {
|
|
|
195518
195644
|
/**
|
|
195519
195645
|
* Build the `ExpressionSchema` expr's validator consumes. Scopes with no
|
|
195520
195646
|
* declarations are **omitted** (opaque - references into them are not flagged);
|
|
195521
|
-
* declared scopes contribute their property types for validation.
|
|
195647
|
+
* declared scopes contribute their property types for validation. Aliases
|
|
195648
|
+
* apply as they do to `toEvalContext`, so a condition written against `@scene`
|
|
195649
|
+
* validates against the instance bag the engine names.
|
|
195522
195650
|
*/
|
|
195523
|
-
toSchema() {
|
|
195651
|
+
toSchema(opts) {
|
|
195524
195652
|
const properties = /* @__PURE__ */ new Map();
|
|
195525
|
-
for (const [token2, e] of this.
|
|
195526
|
-
const decls =
|
|
195653
|
+
for (const [token2, e] of this.view(opts?.aliases)) {
|
|
195654
|
+
const decls = declsOf(e);
|
|
195527
195655
|
if (decls.length === 0) continue;
|
|
195528
195656
|
const m = /* @__PURE__ */ new Map();
|
|
195529
|
-
for (const d of decls) m.set(
|
|
195657
|
+
for (const [n, d] of decls) m.set(n, {
|
|
195530
195658
|
type: d.type,
|
|
195531
195659
|
enumValues: d.values,
|
|
195532
195660
|
...d.stages !== void 0 ? { stages: d.stages } : {}
|
|
@@ -195535,40 +195663,78 @@ var ScopeRegistry = class {
|
|
|
195535
195663
|
}
|
|
195536
195664
|
return { properties };
|
|
195537
195665
|
}
|
|
195538
|
-
/** Serialize **owned** scopes
|
|
195539
|
-
*
|
|
195540
|
-
*
|
|
195541
|
-
*
|
|
195666
|
+
/** Serialize **owned** scopes (foreign scopes are the game's, and the game
|
|
195667
|
+
* saves them), as bare bags keyed by token, plus any values still parked, so
|
|
195668
|
+
* a save taken before every engine has re-registered loses nothing. The
|
|
195669
|
+
* registry knows nothing about game saves: a game embeds this in its own. */
|
|
195542
195670
|
save() {
|
|
195543
195671
|
const out = {};
|
|
195544
195672
|
for (const [token2, e] of this.scopes) if (e.kind === "owned") out[token2] = e.bag.save();
|
|
195673
|
+
for (const [token2, vals] of this.parked) out[token2] = structuredClone(vals);
|
|
195545
195674
|
return out;
|
|
195546
195675
|
}
|
|
195547
|
-
/**
|
|
195548
|
-
*
|
|
195549
|
-
|
|
195676
|
+
/**
|
|
195677
|
+
* Restore from a `save` blob. An owned scope lays its section over its current
|
|
195678
|
+
* values (the bag's `load` rule). A section for a key nobody has registered
|
|
195679
|
+
* yet is PARKED and handed over when that key registers, so a game can load
|
|
195680
|
+
* its registry before its engines have reopened their flows or decks. A
|
|
195681
|
+
* section for a foreign scope is ignored: those values are the game's.
|
|
195682
|
+
*
|
|
195683
|
+
* A load replaces whatever was parked before it: it is a whole restore, and
|
|
195684
|
+
* residue from an earlier load must not leak into this one.
|
|
195685
|
+
*
|
|
195686
|
+
* Changed in 0.7.0: sections for unregistered keys used to be dropped.
|
|
195687
|
+
*/
|
|
195688
|
+
load(blob, opts) {
|
|
195689
|
+
if (!opts?.keepParked) this.parked.clear();
|
|
195550
195690
|
for (const [token2, vals] of Object.entries(blob)) {
|
|
195551
195691
|
const e = this.scopes.get(token2);
|
|
195552
195692
|
if (e?.kind === "owned") e.bag.load(vals);
|
|
195693
|
+
else if (!e) this.parked.set(token2, structuredClone(vals));
|
|
195553
195694
|
}
|
|
195554
195695
|
}
|
|
195555
|
-
/**
|
|
195556
|
-
*
|
|
195557
|
-
*
|
|
195696
|
+
/**
|
|
195697
|
+
* `save()` wrapped with a version stamp.
|
|
195698
|
+
*
|
|
195699
|
+
* @deprecated Versioning belongs to the save that embeds the values; no
|
|
195700
|
+
* engine ever called this. Embed `save()` in your own versioned save.
|
|
195701
|
+
* Removed at the next breaking release.
|
|
195702
|
+
*/
|
|
195558
195703
|
saveFragment() {
|
|
195559
195704
|
return { version: SAVE_FRAGMENT_VERSION, scopes: this.save() };
|
|
195560
195705
|
}
|
|
195561
|
-
/**
|
|
195706
|
+
/**
|
|
195707
|
+
* Restore from a versioned fragment; an unsupported version throws.
|
|
195708
|
+
*
|
|
195709
|
+
* @deprecated See `saveFragment`. Removed at the next breaking release.
|
|
195710
|
+
*/
|
|
195562
195711
|
loadFragment(fragment) {
|
|
195563
195712
|
if (fragment.version !== SAVE_FRAGMENT_VERSION) {
|
|
195564
195713
|
throw new Error(`unsupported owned-state fragment version ${fragment.version} (supported: ${SAVE_FRAGMENT_VERSION})`);
|
|
195565
195714
|
}
|
|
195566
195715
|
this.load(fragment.scopes);
|
|
195567
195716
|
}
|
|
195568
|
-
|
|
195569
|
-
|
|
195717
|
+
/**
|
|
195718
|
+
* A token is taken once. There is no reserved-token list: a clash surfaces
|
|
195719
|
+
* here, the moment a game combines its engines, which is the only moment
|
|
195720
|
+
* anyone knows which engines are present. With owners recorded the error says
|
|
195721
|
+
* whose token it already is.
|
|
195722
|
+
*/
|
|
195723
|
+
assertFree(token2, owner) {
|
|
195724
|
+
const e = this.scopes.get(token2);
|
|
195725
|
+
if (!e) return;
|
|
195726
|
+
const by = e.owner !== void 0 ? ` by ${e.owner}` : "";
|
|
195727
|
+
const wants = owner !== void 0 ? ` (wanted by ${owner})` : "";
|
|
195728
|
+
throw new Error(`scope '@${token2}' is already registered${by}${wants}`);
|
|
195570
195729
|
}
|
|
195571
195730
|
};
|
|
195731
|
+
function declsOf(e) {
|
|
195732
|
+
if (e.kind === "foreign") return [...e.decls.entries()];
|
|
195733
|
+
return e.bag.declarations().map((d) => [e.bag.normalise(d.name), d]);
|
|
195734
|
+
}
|
|
195735
|
+
function normOf(e) {
|
|
195736
|
+
return e.kind === "foreign" ? e.norm : (n) => e.bag.normalise(n);
|
|
195737
|
+
}
|
|
195572
195738
|
function defaultFor(d) {
|
|
195573
195739
|
if (d.default !== void 0) return d.default;
|
|
195574
195740
|
switch (d.type) {
|
|
@@ -195630,6 +195796,19 @@ function buildTagIndex(bundle) {
|
|
|
195630
195796
|
|
|
195631
195797
|
// ../runtime/src/engine.ts
|
|
195632
195798
|
var astCache = /* @__PURE__ */ new WeakMap();
|
|
195799
|
+
var OWNER = "Patter";
|
|
195800
|
+
var esc2 = (id) => id.replace(/%/g, "%25").replace(/\//g, "%2F");
|
|
195801
|
+
var OWNS_REGISTRY = /* @__PURE__ */ Symbol("ownsRegistry");
|
|
195802
|
+
var keys = {
|
|
195803
|
+
/** A scene's SHARED `@scene` props (one bag per scene, every flow's). */
|
|
195804
|
+
stage: (sceneId) => `patter/scene/${esc2(sceneId)}`,
|
|
195805
|
+
/** Everything one flow registers starts with this. */
|
|
195806
|
+
flow: (flowId) => `patter/flow/${esc2(flowId)}/`,
|
|
195807
|
+
/** A flow's NOT-shared `@patter` globals. */
|
|
195808
|
+
flowGlobals: (flowId) => `patter/flow/${esc2(flowId)}/patter`,
|
|
195809
|
+
/** A flow's NOT-shared `@scene` props for one scene. */
|
|
195810
|
+
flowScene: (flowId, sceneId) => `patter/flow/${esc2(flowId)}/scene/${esc2(sceneId)}`
|
|
195811
|
+
};
|
|
195633
195812
|
var Engine = class _Engine {
|
|
195634
195813
|
host;
|
|
195635
195814
|
defaultSeed;
|
|
@@ -195689,18 +195868,32 @@ var Engine = class _Engine {
|
|
|
195689
195868
|
const patterSharedDecls = props.filter((p) => p.shared ?? true).map(toDecl);
|
|
195690
195869
|
const patterLocalDecls = props.filter((p) => !(p.shared ?? true)).map(toDecl);
|
|
195691
195870
|
const patterSharedNames = new Set(patterSharedDecls.map((d) => d.name.toLowerCase()));
|
|
195692
|
-
const
|
|
195693
|
-
const
|
|
195694
|
-
|
|
195695
|
-
|
|
195696
|
-
|
|
195697
|
-
|
|
195698
|
-
|
|
195699
|
-
|
|
195700
|
-
|
|
195701
|
-
if (
|
|
195702
|
-
|
|
195703
|
-
|
|
195871
|
+
const registry = options.registry ?? new ScopeRegistry();
|
|
195872
|
+
const ownsRegistry = !options.registry || options[OWNS_REGISTRY] === true;
|
|
195873
|
+
const patterBag = new PropertyBag(patterSharedDecls, { pathPrefix: "@patter." });
|
|
195874
|
+
const hostScopes = [];
|
|
195875
|
+
const registered = [];
|
|
195876
|
+
try {
|
|
195877
|
+
registry.mountOwned("patter", patterBag, { owner: OWNER });
|
|
195878
|
+
registered.push("patter");
|
|
195879
|
+
const hostBound = /* @__PURE__ */ new Set();
|
|
195880
|
+
if (options.world) {
|
|
195881
|
+
const worldSpec = bundle.scopeRegistry?.scopes.find((s) => s.token === "world");
|
|
195882
|
+
const decls = (worldSpec?.declarations ?? []).map(toForeignDecl);
|
|
195883
|
+
registry.defineForeign("world", options.world, decls, { writable: worldSpec?.writable ?? true, owner: OWNER });
|
|
195884
|
+
registered.push("world");
|
|
195885
|
+
hostBound.add("world");
|
|
195886
|
+
}
|
|
195887
|
+
for (const spec of ownsRegistry ? bundle.scopeRegistry?.scopes ?? [] : []) {
|
|
195888
|
+
if (hostBound.has(spec.token) || registry.has(spec.token)) continue;
|
|
195889
|
+
const decls = (spec.declarations ?? []).map((d) => selfBackedDecl(d, spec.writable));
|
|
195890
|
+
registry.defineOwned(spec.token, decls, { owner: OWNER });
|
|
195891
|
+
registered.push(spec.token);
|
|
195892
|
+
hostScopes.push(spec.token);
|
|
195893
|
+
}
|
|
195894
|
+
} catch (e) {
|
|
195895
|
+
for (const k of registered) registry.remove(k, { keep: true });
|
|
195896
|
+
throw e;
|
|
195704
195897
|
}
|
|
195705
195898
|
const sceneSharedNames = /* @__PURE__ */ new Map();
|
|
195706
195899
|
for (const [sceneId, scene] of Object.entries(bundle.scenes)) {
|
|
@@ -195722,7 +195915,10 @@ var Engine = class _Engine {
|
|
|
195722
195915
|
blockGameIdToId: this.blockGameIdToId,
|
|
195723
195916
|
// same instances the engine resolves with
|
|
195724
195917
|
tagIndex: buildTagIndex(bundle),
|
|
195725
|
-
|
|
195918
|
+
registry,
|
|
195919
|
+
ownsRegistry,
|
|
195920
|
+
patterBag,
|
|
195921
|
+
hostScopes,
|
|
195726
195922
|
patterSharedDecls,
|
|
195727
195923
|
patterLocalDecls,
|
|
195728
195924
|
patterSharedNames,
|
|
@@ -195739,7 +195935,8 @@ var Engine = class _Engine {
|
|
|
195739
195935
|
captionClose: (bundle.closedCaptions ?? DEFAULT_CAPTION_DELIMITERS).close,
|
|
195740
195936
|
captionCharacter: bundle.closedCaptions?.character || DEFAULT_CAPTION_CHARACTER,
|
|
195741
195937
|
// absent/empty -> SFX
|
|
195742
|
-
refSplitCache: /* @__PURE__ */ new Map()
|
|
195938
|
+
refSplitCache: /* @__PURE__ */ new Map(),
|
|
195939
|
+
refSplitRevision: registry.revision
|
|
195743
195940
|
};
|
|
195744
195941
|
}
|
|
195745
195942
|
/** The active locale (string + character-name lookups resolve in it). */
|
|
@@ -195784,10 +195981,12 @@ var Engine = class _Engine {
|
|
|
195784
195981
|
* content-drift policy (§9.8) resolves edits under the cursor: stack frames re-find their next
|
|
195785
195982
|
* child by id, drifted options drop, a vanished snippet is skipped.
|
|
195786
195983
|
*
|
|
195787
|
-
* Returns the REPLACEMENT engine
|
|
195788
|
-
*
|
|
195789
|
-
*
|
|
195790
|
-
*
|
|
195984
|
+
* Returns the REPLACEMENT engine, on the same registry. This one hands its bags over (each is
|
|
195985
|
+
* removed from the registry with its values kept, and the replacement claims them as it
|
|
195986
|
+
* registers), its flows are closed, and it should be discarded. Hosts re-bind their flow handles
|
|
195987
|
+
* via `next.getFlow(id)`. If the restore throws (defensive - §9.8 makes this unreachable for
|
|
195988
|
+
* ordinary edits), the swap falls back to a fresh engine with each saved flow restarted from the
|
|
195989
|
+
* top of the scene it was in; the shared properties carry over.
|
|
195791
195990
|
*/
|
|
195792
195991
|
hotSwap(bundle) {
|
|
195793
195992
|
const snapshot = this.saveGame();
|
|
@@ -195796,12 +195995,19 @@ var Engine = class _Engine {
|
|
|
195796
195995
|
next2.setClosedCaptions(this.host.captionsOn);
|
|
195797
195996
|
return next2;
|
|
195798
195997
|
};
|
|
195799
|
-
const
|
|
195998
|
+
const make = () => new _Engine(bundle, {
|
|
195999
|
+
...this.creationOptions,
|
|
196000
|
+
registry: this.host.registry,
|
|
196001
|
+
[OWNS_REGISTRY]: this.host.ownsRegistry
|
|
196002
|
+
});
|
|
196003
|
+
this.release(true);
|
|
196004
|
+
const next = make();
|
|
195800
196005
|
try {
|
|
195801
196006
|
next.loadGame(snapshot);
|
|
195802
196007
|
return carryOver(next);
|
|
195803
196008
|
} catch {
|
|
195804
|
-
|
|
196009
|
+
next.release(true);
|
|
196010
|
+
const fresh = make();
|
|
195805
196011
|
for (const [id, f] of Object.entries(snapshot.flows)) {
|
|
195806
196012
|
const sceneId = f.cursor.currentSceneId;
|
|
195807
196013
|
try {
|
|
@@ -195840,6 +196046,7 @@ var Engine = class _Engine {
|
|
|
195840
196046
|
* call to reach for when you want a speaker's variation state to carry on.
|
|
195841
196047
|
*/
|
|
195842
196048
|
openFlow(id, opts = {}) {
|
|
196049
|
+
this.assertExternalScopes();
|
|
195843
196050
|
const sceneId = this.resolveSceneRef(opts.scene);
|
|
195844
196051
|
const blockId = this.resolveBlockRef(sceneId, opts.block);
|
|
195845
196052
|
this.flowsById.get(id)?.close();
|
|
@@ -195879,6 +196086,17 @@ var Engine = class _Engine {
|
|
|
195879
196086
|
}
|
|
195880
196087
|
return existing.advanceToStop().played;
|
|
195881
196088
|
}
|
|
196089
|
+
/** Content that names another engine's scope (`@story.act`) runs only where that engine is on this
|
|
196090
|
+
* registry: without it every read would answer false and every write fail, so the flow is refused as
|
|
196091
|
+
* it opens (or the save as it loads), before anything changes. By then a game has built all of its
|
|
196092
|
+
* engines, whatever order it built them in. The same message on every runtime. */
|
|
196093
|
+
assertExternalScopes() {
|
|
196094
|
+
for (const token2 of this.host.bundle.externalScopes ?? []) {
|
|
196095
|
+
if (!this.host.registry.has(token2)) {
|
|
196096
|
+
throw new Error(`this content names @${token2}, which no engine on this registry registered: give every engine the game's one registry`);
|
|
196097
|
+
}
|
|
196098
|
+
}
|
|
196099
|
+
}
|
|
195882
196100
|
/** Resolve a scene reference (a gameId address OR an internal id) to its internal id. */
|
|
195883
196101
|
resolveSceneRef(ref) {
|
|
195884
196102
|
if (ref == null) return void 0;
|
|
@@ -196064,7 +196282,7 @@ var Engine = class _Engine {
|
|
|
196064
196282
|
* loadGame() replaces every bag, so re-enumerate after a load.
|
|
196065
196283
|
*/
|
|
196066
196284
|
listBags() {
|
|
196067
|
-
const mounts = [{ bag: this.host.
|
|
196285
|
+
const mounts = [{ bag: this.host.patterBag }];
|
|
196068
196286
|
for (const [sceneId, bag] of this.host.stageBags) mounts.push({ bag, pathPrefix: `@scene:${sceneId}.` });
|
|
196069
196287
|
return mounts;
|
|
196070
196288
|
}
|
|
@@ -196083,15 +196301,31 @@ var Engine = class _Engine {
|
|
|
196083
196301
|
reset() {
|
|
196084
196302
|
for (const flow of this.flowsById.values()) flow.close();
|
|
196085
196303
|
this.flowsById.clear();
|
|
196086
|
-
this.host.
|
|
196304
|
+
this.host.patterBag.reseed(this.host.patterSharedDecls);
|
|
196087
196305
|
this.host.sharedVisits.clear();
|
|
196088
196306
|
this.host.sharedSelectors.clear();
|
|
196307
|
+
for (const s of this.host.stageBags.keys()) this.host.registry.remove(keys.stage(s));
|
|
196089
196308
|
this.host.stageBags.clear();
|
|
196309
|
+
this.host.registry.discardParked("patter/");
|
|
196310
|
+
}
|
|
196311
|
+
/** Remove every bag this engine registered, keeping the values parked when `keep` (a live reload
|
|
196312
|
+
* handing its state to a replacement), and close its flows. The engine is inert afterwards. */
|
|
196313
|
+
release(keep) {
|
|
196314
|
+
for (const flow of this.flowsById.values()) {
|
|
196315
|
+
flow.releaseBags(keep);
|
|
196316
|
+
flow.close();
|
|
196317
|
+
}
|
|
196318
|
+
this.flowsById.clear();
|
|
196319
|
+
const reg = this.host.registry;
|
|
196320
|
+
for (const s of this.host.stageBags.keys()) reg.remove(keys.stage(s), { keep });
|
|
196321
|
+
this.host.stageBags.clear();
|
|
196322
|
+
for (const t of ["patter", ...this.host.hostScopes]) if (reg.has(t)) reg.remove(t, { keep });
|
|
196323
|
+
if (this.creationOptions.world && reg.has("world")) reg.remove("world");
|
|
196090
196324
|
}
|
|
196091
196325
|
/** Read a shared (`@patter` / foreign) property by ref. `@scene` refs are rejected (flow-level). */
|
|
196092
196326
|
getProperty(ref) {
|
|
196093
196327
|
const { scope, name } = this.splitShared(ref);
|
|
196094
|
-
return this.host.
|
|
196328
|
+
return this.host.registry.get(scope, name);
|
|
196095
196329
|
}
|
|
196096
196330
|
/** Write a shared (`@patter` / foreign) property by ref. `@scene` refs are rejected (flow-level).
|
|
196097
196331
|
*
|
|
@@ -196102,7 +196336,7 @@ var Engine = class _Engine {
|
|
|
196102
196336
|
* were each refused the one property they existed to move.) */
|
|
196103
196337
|
setProperty(ref, value) {
|
|
196104
196338
|
const { scope, name } = this.splitShared(ref);
|
|
196105
|
-
this.host.
|
|
196339
|
+
this.host.registry.set(scope, name, value, { host: true });
|
|
196106
196340
|
}
|
|
196107
196341
|
/** The shared `@patter` properties, for a live state inspector: each with its ref, type, current
|
|
196108
196342
|
* value, declared default (for reset), and enum options. Mirrors the Unity / Godot ports. */
|
|
@@ -196149,54 +196383,66 @@ var Engine = class _Engine {
|
|
|
196149
196383
|
// @scene is scene-namespaced and needs a flow's current scene - silently
|
|
196150
196384
|
// routing it into the shared bag (as a junk "scene.x" key) was a trap.
|
|
196151
196385
|
splitShared(ref) {
|
|
196152
|
-
|
|
196153
|
-
if (!split) {
|
|
196154
|
-
split = splitRef(ref, (t) => t === "scene" || this.host.shared.has(t));
|
|
196155
|
-
this.host.refSplitCache.set(ref, split);
|
|
196156
|
-
}
|
|
196386
|
+
const split = splitHostRef(this.host, ref);
|
|
196157
196387
|
if (split.scope === "scene") {
|
|
196158
196388
|
throw new Error(`'${ref}': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);
|
|
196159
196389
|
}
|
|
196160
196390
|
return split;
|
|
196161
196391
|
}
|
|
196162
|
-
/**
|
|
196392
|
+
/** The shared `@patter` values alone, as `{ patter: {...} }`.
|
|
196393
|
+
* @deprecated The registry holds every property now: a game saves `registry.save()` once, and a
|
|
196394
|
+
* standalone engine's `saveGame()` carries its registry's values. Removed at the next breaking release. */
|
|
196163
196395
|
save() {
|
|
196164
|
-
return this.host.
|
|
196396
|
+
return { patter: this.host.patterBag.save() };
|
|
196165
196397
|
}
|
|
196166
|
-
/**
|
|
196398
|
+
/** Lay a `{ patter: {...} }` section over the shared `@patter` values; anything else is ignored.
|
|
196399
|
+
* @deprecated See `save`. Removed at the next breaking release. */
|
|
196167
196400
|
load(blob) {
|
|
196168
|
-
this.host.
|
|
196401
|
+
if (blob.patter) this.host.patterBag.load(blob.patter);
|
|
196169
196402
|
}
|
|
196170
|
-
/** Snapshot the whole game
|
|
196403
|
+
/** Snapshot the whole game's NON-property state: visit counts, shared selector cursors, and every
|
|
196404
|
+
* live flow's cursor and PRNG. The property values are the registry's: a standalone engine (one that
|
|
196405
|
+
* made its own registry) carries them here under `registry`; a game that passed a registry saves it
|
|
196406
|
+
* once itself, beside each engine's `saveGame()`. */
|
|
196171
196407
|
saveGame() {
|
|
196172
196408
|
const flows = {};
|
|
196173
196409
|
for (const [id, flow] of this.flowsById) flows[id] = flow.snapshot();
|
|
196174
196410
|
return {
|
|
196175
|
-
version:
|
|
196176
|
-
|
|
196411
|
+
version: SAVE_VERSION,
|
|
196412
|
+
...this.host.ownsRegistry ? { registry: this.host.registry.save() } : {},
|
|
196177
196413
|
sharedVisits: Object.fromEntries(this.host.sharedVisits),
|
|
196178
196414
|
sharedSelectors: serialiseSelectors(this.host.sharedSelectors),
|
|
196179
|
-
stageBags: Object.fromEntries([...this.host.stageBags].map(([s, bag]) => [s, bag.save()])),
|
|
196180
196415
|
flows
|
|
196181
196416
|
};
|
|
196182
196417
|
}
|
|
196183
|
-
/**
|
|
196418
|
+
/**
|
|
196419
|
+
* Restore a `saveGame()`: visit counts, shared selector cursors, and every flow. Property values come
|
|
196420
|
+
* from the registry. A save that carries them (a standalone engine's, or a version 2 save from before
|
|
196421
|
+
* the registry held them) has them moved into the registry here; otherwise the game loads its
|
|
196422
|
+
* registry itself, before or after this call. Either order works: this engine's bags are handed back
|
|
196423
|
+
* to the registry (values kept) and the restored flows claim them as they register.
|
|
196424
|
+
*/
|
|
196184
196425
|
loadGame(save) {
|
|
196185
|
-
|
|
196186
|
-
|
|
196426
|
+
const version2 = save.version;
|
|
196427
|
+
if (version2 !== 2 && version2 !== SAVE_VERSION) throw new Error(`unsupported save version: ${String(version2)}`);
|
|
196428
|
+
this.assertExternalScopes();
|
|
196429
|
+
const reg = this.host.registry;
|
|
196430
|
+
for (const [id, flow] of this.flowsById) {
|
|
196431
|
+
flow.releaseBags(id in save.flows);
|
|
196432
|
+
flow.close();
|
|
196433
|
+
}
|
|
196434
|
+
this.flowsById.clear();
|
|
196435
|
+
for (const s of this.host.stageBags.keys()) reg.remove(keys.stage(s), { keep: true });
|
|
196436
|
+
this.host.stageBags.clear();
|
|
196437
|
+
const values = save.version === 2 ? sectionsFromV2(save) : save.registry;
|
|
196438
|
+
if (values) {
|
|
196439
|
+
if (this.host.ownsRegistry) reg.load(values);
|
|
196440
|
+
else reg.load(values, { keepParked: true });
|
|
196441
|
+
}
|
|
196187
196442
|
this.host.sharedVisits.clear();
|
|
196188
196443
|
for (const [id, n] of Object.entries(save.sharedVisits ?? {})) this.host.sharedVisits.set(id, n);
|
|
196189
196444
|
this.host.sharedSelectors.clear();
|
|
196190
196445
|
for (const [id, st] of deserialiseSelectors(save.sharedSelectors)) this.host.sharedSelectors.set(id, st);
|
|
196191
|
-
this.host.stageBags.clear();
|
|
196192
|
-
for (const [s, values] of Object.entries(save.stageBags ?? {})) {
|
|
196193
|
-
const shared = this.host.sceneSharedNames.get(s) ?? /* @__PURE__ */ new Set();
|
|
196194
|
-
const decls = (this.host.bundle.scenes[s]?.sceneProps ?? []).filter((d) => shared.has(d.name.toLowerCase()));
|
|
196195
|
-
const bag = new PropertyBag(decls);
|
|
196196
|
-
bag.load(values);
|
|
196197
|
-
this.host.stageBags.set(s, bag);
|
|
196198
|
-
}
|
|
196199
|
-
this.flowsById.clear();
|
|
196200
196446
|
for (const [id, snap] of Object.entries(save.flows)) {
|
|
196201
196447
|
const flow = new Flow(id, this.host, this.defaultSeed);
|
|
196202
196448
|
flow.restore(snap);
|
|
@@ -196208,7 +196454,9 @@ var Flow = class {
|
|
|
196208
196454
|
id;
|
|
196209
196455
|
host;
|
|
196210
196456
|
local;
|
|
196211
|
-
//
|
|
196457
|
+
// the NOT-shared `@patter` globals (this flow's copy), keys.flowGlobals
|
|
196458
|
+
/** The registry keys this flow has registered (its globals and each scene bag). */
|
|
196459
|
+
registered = /* @__PURE__ */ new Set();
|
|
196212
196460
|
rngState;
|
|
196213
196461
|
// Execution cursor. The `stack` is the continuation stack: each frame is a
|
|
196214
196462
|
// position within a block's children (the top frame is the active block run;
|
|
@@ -196233,40 +196481,44 @@ var Flow = class {
|
|
|
196233
196481
|
/** Per-node entry counts for this flow (node id -> times entered). */
|
|
196234
196482
|
visitCounts = /* @__PURE__ */ new Map();
|
|
196235
196483
|
// Per-flow halves of the two scopes. The NOT-shared `@patter` globals live in
|
|
196236
|
-
// `local
|
|
196237
|
-
//
|
|
196238
|
-
//
|
|
196239
|
-
// resolver presents one merged scope, routing each property
|
|
196240
|
-
// declared `shared` flag
|
|
196484
|
+
// `local`; the NOT-shared `@scene` props live in `sceneBags` (namespaced per
|
|
196485
|
+
// scene; they PERSIST across re-entries, spec §7). The SHARED halves live on the
|
|
196486
|
+
// host (`host.patterBag` / `host.stageBags`). All of them are registered in the
|
|
196487
|
+
// game's registry. Each resolver presents one merged scope, routing each property
|
|
196488
|
+
// to its half by the declared `shared` flag: that split is why `@patter` and
|
|
196489
|
+
// `@scene` are composed here rather than aliased to a single registry key.
|
|
196241
196490
|
/** This flow's per-scene LOCAL scene props; see FlowHost.stageBags. */
|
|
196242
196491
|
sceneBags = /* @__PURE__ */ new Map();
|
|
196243
196492
|
patterResolver = {
|
|
196244
|
-
get: (n) => this.host.patterSharedNames.has(n) ? this.host.
|
|
196493
|
+
get: (n) => this.host.patterSharedNames.has(n) ? this.host.patterBag.get(n) : this.local.get(n),
|
|
196245
196494
|
set: (n, v) => {
|
|
196246
|
-
if (this.host.patterSharedNames.has(n)) this.host.
|
|
196247
|
-
else this.local.set(
|
|
196495
|
+
if (this.host.patterSharedNames.has(n)) this.host.registry.set("patter", n, v);
|
|
196496
|
+
else this.local.set(n, v);
|
|
196248
196497
|
}
|
|
196249
196498
|
};
|
|
196250
196499
|
sceneResolver = {
|
|
196251
196500
|
get: (n) => {
|
|
196252
196501
|
const s = this.currentSceneId;
|
|
196253
196502
|
if (s === null) return void 0;
|
|
196254
|
-
|
|
196255
|
-
return bag?.get(n);
|
|
196503
|
+
return this.sceneBagFor(s, n)?.get(n);
|
|
196256
196504
|
},
|
|
196257
196505
|
set: (n, v) => {
|
|
196258
196506
|
const s = this.currentSceneId;
|
|
196259
196507
|
if (s === null) return;
|
|
196260
|
-
const bag = this.
|
|
196508
|
+
const bag = this.sceneBagFor(s, n);
|
|
196261
196509
|
if (bag) bag.set(n, v);
|
|
196262
196510
|
}
|
|
196263
196511
|
};
|
|
196264
|
-
// The eval context is built
|
|
196265
|
-
//
|
|
196266
|
-
//
|
|
196267
|
-
//
|
|
196268
|
-
//
|
|
196512
|
+
// The eval context is built once and REFRESHED only when the registry's set of
|
|
196513
|
+
// scopes moves (its `revision`): every constituent resolves live state at call
|
|
196514
|
+
// time (bags mutate in place per scoperegistry's contract; patter/scene route
|
|
196515
|
+
// through this flow's resolvers, which read the current `local`/`sceneBags`/
|
|
196516
|
+
// `currentSceneId`; the host callbacks read current flow fields), but another
|
|
196517
|
+
// engine registering `@story` after this flow opened must still be readable.
|
|
196518
|
+
// Rebuilding it per evaluation was the engine's hottest allocation.
|
|
196269
196519
|
evalCtx;
|
|
196520
|
+
ctxRevision = -1;
|
|
196521
|
+
registryQualities;
|
|
196270
196522
|
flowLog = [];
|
|
196271
196523
|
/** Monotonic across the flow's life; survives clearLog so two reads agree on order. */
|
|
196272
196524
|
flowSeq = 0;
|
|
@@ -196274,12 +196526,9 @@ var Flow = class {
|
|
|
196274
196526
|
this.id = id;
|
|
196275
196527
|
this.host = host2;
|
|
196276
196528
|
this.rngState = toUint32(seed);
|
|
196277
|
-
this.local = this.
|
|
196278
|
-
const scopes = { ...host2.shared.toEvalContext().scopes };
|
|
196279
|
-
scopes["patter"] = this.patterResolver;
|
|
196280
|
-
scopes["scene"] = this.sceneResolver;
|
|
196529
|
+
this.local = this.newLocal();
|
|
196281
196530
|
this.evalCtx = {
|
|
196282
|
-
scopes,
|
|
196531
|
+
scopes: {},
|
|
196283
196532
|
host: {
|
|
196284
196533
|
nextRandom: this.rng,
|
|
196285
196534
|
visits: (id2) => this.visitCounts.get(id2) ?? 0,
|
|
@@ -196292,6 +196541,21 @@ var Flow = class {
|
|
|
196292
196541
|
qualities: (scope, name) => this.stagesFor(scope, name)
|
|
196293
196542
|
};
|
|
196294
196543
|
}
|
|
196544
|
+
/** The eval context, its scopes refreshed if the registry's set of scopes has moved since. */
|
|
196545
|
+
context() {
|
|
196546
|
+
const reg = this.host.registry;
|
|
196547
|
+
if (reg.revision !== this.ctxRevision) {
|
|
196548
|
+
const base = reg.toEvalContext();
|
|
196549
|
+
const scopes = this.evalCtx.scopes;
|
|
196550
|
+
for (const k of Object.keys(scopes)) delete scopes[k];
|
|
196551
|
+
Object.assign(scopes, base.scopes);
|
|
196552
|
+
scopes["patter"] = this.patterResolver;
|
|
196553
|
+
scopes["scene"] = this.sceneResolver;
|
|
196554
|
+
this.registryQualities = base.qualities;
|
|
196555
|
+
this.ctxRevision = reg.revision;
|
|
196556
|
+
}
|
|
196557
|
+
return this.evalCtx;
|
|
196558
|
+
}
|
|
196295
196559
|
/** The stage ladder of `@scope.name` when it is a declared quality, else undefined. Names compare
|
|
196296
196560
|
* lowercase, as the compiler emits references (the selfBackedResolver lesson). */
|
|
196297
196561
|
stagesFor(scope, name) {
|
|
@@ -196304,13 +196568,14 @@ var Flow = class {
|
|
|
196304
196568
|
const scene = this.currentSceneId != null ? this.host.bundle.scenes[this.currentSceneId] : void 0;
|
|
196305
196569
|
return fromDecls(scene?.sceneProps);
|
|
196306
196570
|
}
|
|
196307
|
-
return fromDecls(this.host.bundle.scopeRegistry?.scopes.find((s) => s.token === scope)?.declarations);
|
|
196571
|
+
return this.registryQualities?.(scope, name) ?? fromDecls(this.host.bundle.scopeRegistry?.scopes.find((s) => s.token === scope)?.declarations);
|
|
196308
196572
|
}
|
|
196309
196573
|
// -- Host API -------------------------------------------------------------
|
|
196310
196574
|
/** Begin this flow at a scene (and optionally a specific block within it). */
|
|
196311
196575
|
start(sceneId, blockId) {
|
|
196312
|
-
this.
|
|
196313
|
-
this.
|
|
196576
|
+
this.releaseBags(false);
|
|
196577
|
+
this.host.registry.discardParked(keys.flow(this.id));
|
|
196578
|
+
this.mountLocal();
|
|
196314
196579
|
this.selectors.clear();
|
|
196315
196580
|
this.visitCounts.clear();
|
|
196316
196581
|
this.stack = [];
|
|
@@ -196410,6 +196675,7 @@ var Flow = class {
|
|
|
196410
196675
|
* cannot quietly mutate the world. Terminal: unlike ending, a close is never revived.
|
|
196411
196676
|
*/
|
|
196412
196677
|
close() {
|
|
196678
|
+
this.releaseBags(false);
|
|
196413
196679
|
this.closed = true;
|
|
196414
196680
|
this.flowEnded = true;
|
|
196415
196681
|
this.stack = [];
|
|
@@ -196519,7 +196785,7 @@ var Flow = class {
|
|
|
196519
196785
|
* halves are the Engine's listBags.
|
|
196520
196786
|
*/
|
|
196521
196787
|
listBags() {
|
|
196522
|
-
const mounts = [{ bag: this.local
|
|
196788
|
+
const mounts = [{ bag: this.local, pathPrefix: `${this.id}/@patter.` }];
|
|
196523
196789
|
for (const [sceneId, bag] of this.sceneBags) mounts.push({ bag, pathPrefix: `${this.id}/@scene:${sceneId}.` });
|
|
196524
196790
|
return mounts;
|
|
196525
196791
|
}
|
|
@@ -196567,7 +196833,7 @@ var Flow = class {
|
|
|
196567
196833
|
const { scope, name } = this.splitRef(ref);
|
|
196568
196834
|
if (scope === "patter") return this.patterResolver.get(name);
|
|
196569
196835
|
if (scope === "scene") return this.sceneResolver.get(name);
|
|
196570
|
-
return this.host.
|
|
196836
|
+
return this.host.registry.get(scope, name);
|
|
196571
196837
|
}
|
|
196572
196838
|
/** Write a property by ref (routed by scope, then by the property's `shared` flag). The GAME's
|
|
196573
196839
|
* surface: it writes with host authority, so a `writable: false` host declaration does not refuse
|
|
@@ -196585,16 +196851,13 @@ var Flow = class {
|
|
|
196585
196851
|
if (this.currentSceneId === null) throw new Error(`'${ref}': the flow has not entered a scene yet`);
|
|
196586
196852
|
this.sceneResolver.set(name, value);
|
|
196587
196853
|
} else {
|
|
196588
|
-
this.host.
|
|
196854
|
+
this.host.registry.set(scope, name, value, host2 ? { host: true } : void 0);
|
|
196589
196855
|
}
|
|
196590
196856
|
}
|
|
196591
196857
|
// -- Save / restore (engine-driven) --------------------------------------
|
|
196592
|
-
/** @internal Snapshot this flow's cursor +
|
|
196858
|
+
/** @internal Snapshot this flow's cursor + PRNG + visits. Its properties are the registry's. */
|
|
196593
196859
|
snapshot() {
|
|
196594
196860
|
return {
|
|
196595
|
-
scopes: this.local.save(),
|
|
196596
|
-
// owned scope "patter" = the NOT-shared globals (@scene saved separately)
|
|
196597
|
-
sceneBags: Object.fromEntries([...this.sceneBags].map(([s, bag]) => [s, bag.save()])),
|
|
196598
196861
|
rngState: this.rngState,
|
|
196599
196862
|
visits: Object.fromEntries(this.visitCounts),
|
|
196600
196863
|
cursor: {
|
|
@@ -196632,15 +196895,11 @@ var Flow = class {
|
|
|
196632
196895
|
}
|
|
196633
196896
|
return { ...frame };
|
|
196634
196897
|
});
|
|
196635
|
-
this.
|
|
196636
|
-
|
|
196637
|
-
|
|
196638
|
-
|
|
196639
|
-
|
|
196640
|
-
return [s, bag];
|
|
196641
|
-
}));
|
|
196642
|
-
this.local = this.freshLocal();
|
|
196643
|
-
this.local.load(snap.scopes);
|
|
196898
|
+
this.releaseBags(false);
|
|
196899
|
+
this.mountLocal();
|
|
196900
|
+
for (const s of /* @__PURE__ */ new Set([c2.currentSceneId, ...this.stack.map((f) => f.sceneId)])) {
|
|
196901
|
+
if (s !== null && this.host.bundle.scenes[s]) this.ensureSceneBags(s);
|
|
196902
|
+
}
|
|
196644
196903
|
this.activeSnippet = null;
|
|
196645
196904
|
if (c2.activeSnippetId !== null) {
|
|
196646
196905
|
const node = this.host.nodeIndex.get(c2.activeSnippetId);
|
|
@@ -196911,7 +197170,7 @@ var Flow = class {
|
|
|
196911
197170
|
* node (comparisons, scoped vars, literals, other calls) is an atom, evaluated whole.
|
|
196912
197171
|
*/
|
|
196913
197172
|
matchedSpec(node, want) {
|
|
196914
|
-
const evalTruthy = (n) => truthy(evaluate(n, this.
|
|
197173
|
+
const evalTruthy = (n) => truthy(evaluate(n, this.context(), patterDialect));
|
|
196915
197174
|
return matchedSpecificity(node, evalTruthy, { want });
|
|
196916
197175
|
}
|
|
196917
197176
|
/** A selector's cursor state - shared across flows (`group.shared`) or this flow's own. */
|
|
@@ -196938,7 +197197,7 @@ var Flow = class {
|
|
|
196938
197197
|
return truthy(this.evalExpr(node.condition));
|
|
196939
197198
|
}
|
|
196940
197199
|
evalExpr(expr) {
|
|
196941
|
-
return evaluate(this.conditionAst(expr), this.
|
|
197200
|
+
return evaluate(this.conditionAst(expr), this.context(), patterDialect);
|
|
196942
197201
|
}
|
|
196943
197202
|
/** The deserialised (in-memory) AST for an expression, cached per Expression. Shared by the
|
|
196944
197203
|
* evaluator and the Best-match specificity walker so both work off one parse. */
|
|
@@ -197063,18 +197322,51 @@ var Flow = class {
|
|
|
197063
197322
|
const key2 = castStringKey(character);
|
|
197064
197323
|
return this.host.strings[key2] ?? this.host.defaultStrings[key2] ?? this.host.castDisplay.get(character);
|
|
197065
197324
|
}
|
|
197066
|
-
/** Split a ref into scope + name. Tokens: `@scene`,
|
|
197325
|
+
/** Split a ref into scope + name. Tokens: `@scene`, registered tokens, else `@patter` (incl. bare `@name`). */
|
|
197067
197326
|
splitRef(ref) {
|
|
197068
|
-
|
|
197069
|
-
|
|
197070
|
-
|
|
197071
|
-
|
|
197072
|
-
}
|
|
197073
|
-
|
|
197327
|
+
return splitHostRef(this.host, ref);
|
|
197328
|
+
}
|
|
197329
|
+
/** A fresh, unregistered bag for the NOT-shared `@patter` globals (the shared ones live on the host). */
|
|
197330
|
+
newLocal() {
|
|
197331
|
+
return new PropertyBag(this.host.patterLocalDecls, { pathPrefix: "@patter." });
|
|
197332
|
+
}
|
|
197333
|
+
/** Register a fresh globals bag under this flow's key; it claims any values waiting there. */
|
|
197334
|
+
mountLocal() {
|
|
197335
|
+
this.local = this.newLocal();
|
|
197336
|
+
const key2 = keys.flowGlobals(this.id);
|
|
197337
|
+
this.host.registry.mountOwned(key2, this.local, { owner: OWNER });
|
|
197338
|
+
this.registered.add(key2);
|
|
197339
|
+
}
|
|
197340
|
+
/** @internal Remove every bag this flow registered; with `keep`, their values wait in the registry for
|
|
197341
|
+
* the flow that replaces this one. Engine-driven (close, loadGame, hotSwap). */
|
|
197342
|
+
releaseBags(keep) {
|
|
197343
|
+
for (const key2 of this.registered) this.host.registry.remove(key2, { keep });
|
|
197344
|
+
this.registered.clear();
|
|
197345
|
+
this.sceneBags.clear();
|
|
197074
197346
|
}
|
|
197075
|
-
/** The
|
|
197076
|
-
|
|
197077
|
-
|
|
197347
|
+
/** The bag a `@scene` property of scene `s` lives in (stage or this flow's), made if missing. */
|
|
197348
|
+
sceneBagFor(s, name) {
|
|
197349
|
+
if (!this.host.bundle.scenes[s]) return void 0;
|
|
197350
|
+
this.ensureSceneBags(s);
|
|
197351
|
+
return this.host.sceneSharedNames.get(s)?.has(name.toLowerCase()) ? this.host.stageBags.get(s) : this.sceneBags.get(s);
|
|
197352
|
+
}
|
|
197353
|
+
/** Make (and register) scene `s`'s stage bag and this flow's bag for it, if not made yet. A bag made
|
|
197354
|
+
* here claims whatever values the registry holds for its key: that is how a loaded save reaches it. */
|
|
197355
|
+
ensureSceneBags(s) {
|
|
197356
|
+
const shared = this.host.sceneSharedNames.get(s) ?? /* @__PURE__ */ new Set();
|
|
197357
|
+
const props = this.host.bundle.scenes[s]?.sceneProps ?? [];
|
|
197358
|
+
if (!this.sceneBags.has(s)) {
|
|
197359
|
+
const bag = new PropertyBag(props.filter((d) => !shared.has(d.name.toLowerCase())), { pathPrefix: "@scene." });
|
|
197360
|
+
const key2 = keys.flowScene(this.id, s);
|
|
197361
|
+
this.host.registry.mountOwned(key2, bag, { owner: OWNER });
|
|
197362
|
+
this.registered.add(key2);
|
|
197363
|
+
this.sceneBags.set(s, bag);
|
|
197364
|
+
}
|
|
197365
|
+
if (!this.host.stageBags.has(s)) {
|
|
197366
|
+
const bag = new PropertyBag(props.filter((d) => shared.has(d.name.toLowerCase())), { pathPrefix: "@scene." });
|
|
197367
|
+
this.host.registry.mountOwned(keys.stage(s), bag, { owner: OWNER });
|
|
197368
|
+
this.host.stageBags.set(s, bag);
|
|
197369
|
+
}
|
|
197078
197370
|
}
|
|
197079
197371
|
/**
|
|
197080
197372
|
* Seed a scene's `@scene` props (spec §7). The not-shared props seed THIS flow's
|
|
@@ -197085,13 +197377,7 @@ var Flow = class {
|
|
|
197085
197377
|
*/
|
|
197086
197378
|
seedScene(scene) {
|
|
197087
197379
|
const shared = this.host.sceneSharedNames.get(scene.id) ?? /* @__PURE__ */ new Set();
|
|
197088
|
-
|
|
197089
|
-
if (!this.sceneBags.has(scene.id)) {
|
|
197090
|
-
this.sceneBags.set(scene.id, new PropertyBag(props.filter((d) => !shared.has(d.name.toLowerCase()))));
|
|
197091
|
-
}
|
|
197092
|
-
if (!this.host.stageBags.has(scene.id)) {
|
|
197093
|
-
this.host.stageBags.set(scene.id, new PropertyBag(props.filter((d) => shared.has(d.name.toLowerCase()))));
|
|
197094
|
-
}
|
|
197380
|
+
this.ensureSceneBags(scene.id);
|
|
197095
197381
|
for (const decl of scene.sceneProps ?? []) {
|
|
197096
197382
|
if (!decl.temporary) continue;
|
|
197097
197383
|
const name = decl.name.toLowerCase();
|
|
@@ -197137,16 +197423,32 @@ function toDecl(decl) {
|
|
|
197137
197423
|
function toForeignDecl(decl) {
|
|
197138
197424
|
return { name: decl.name, type: decl.type, values: decl.values, stages: decl.stages, default: decl.default, writable: decl.writable };
|
|
197139
197425
|
}
|
|
197140
|
-
function
|
|
197141
|
-
const
|
|
197142
|
-
const
|
|
197143
|
-
|
|
197144
|
-
|
|
197145
|
-
|
|
197146
|
-
|
|
197147
|
-
|
|
197148
|
-
|
|
197149
|
-
}
|
|
197426
|
+
function selfBackedDecl(decl, scopeWritable) {
|
|
197427
|
+
const d = toForeignDecl(decl);
|
|
197428
|
+
const writable = decl.writable ?? scopeWritable;
|
|
197429
|
+
return writable === void 0 ? d : { ...d, writable };
|
|
197430
|
+
}
|
|
197431
|
+
function splitHostRef(host2, ref) {
|
|
197432
|
+
if (host2.refSplitRevision !== host2.registry.revision) {
|
|
197433
|
+
host2.refSplitCache.clear();
|
|
197434
|
+
host2.refSplitRevision = host2.registry.revision;
|
|
197435
|
+
}
|
|
197436
|
+
let hit = host2.refSplitCache.get(ref);
|
|
197437
|
+
if (!hit) {
|
|
197438
|
+
hit = splitRef(ref, (t) => t === "scene" || host2.registry.has(t) || (host2.bundle.externalScopes?.includes(t) ?? false));
|
|
197439
|
+
host2.refSplitCache.set(ref, hit);
|
|
197440
|
+
}
|
|
197441
|
+
return hit;
|
|
197442
|
+
}
|
|
197443
|
+
function sectionsFromV2(save) {
|
|
197444
|
+
const out = {};
|
|
197445
|
+
if (save.shared?.patter) out["patter"] = save.shared.patter;
|
|
197446
|
+
for (const [s, v] of Object.entries(save.stageBags ?? {})) out[keys.stage(s)] = v;
|
|
197447
|
+
for (const [id, f] of Object.entries(save.flows ?? {})) {
|
|
197448
|
+
if (f.scopes?.patter) out[keys.flowGlobals(id)] = f.scopes.patter;
|
|
197449
|
+
for (const [s, v] of Object.entries(f.sceneBags ?? {})) out[keys.flowScene(id, s)] = v;
|
|
197450
|
+
}
|
|
197451
|
+
return out;
|
|
197150
197452
|
}
|
|
197151
197453
|
function truthy(v) {
|
|
197152
197454
|
if (typeof v === "boolean") return v;
|
|
@@ -198712,8 +199014,8 @@ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
|
198712
199014
|
var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
198713
199015
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
198714
199016
|
var __copyProps2 = (to, from, except, desc) => {
|
|
198715
|
-
if (from && typeof from === "object" || typeof from === "function") for (var
|
|
198716
|
-
key2 =
|
|
199017
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys2 = __getOwnPropNames2(from), i = 0, n = keys2.length, key2; i < n; i++) {
|
|
199018
|
+
key2 = keys2[i];
|
|
198717
199019
|
if (!__hasOwnProp2.call(to, key2) && key2 !== except) __defProp2(to, key2, {
|
|
198718
199020
|
get: ((k) => from[k]).bind(null, key2),
|
|
198719
199021
|
enumerable: !(desc = __getOwnPropDesc2(from, key2)) || desc.enumerable
|
|
@@ -199169,10 +199471,10 @@ var require_events = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
|
|
|
199169
199471
|
return this;
|
|
199170
199472
|
}
|
|
199171
199473
|
if (arguments.length === 0) {
|
|
199172
|
-
var
|
|
199474
|
+
var keys2 = Object.keys(events);
|
|
199173
199475
|
var key2;
|
|
199174
|
-
for (i = 0; i <
|
|
199175
|
-
key2 =
|
|
199476
|
+
for (i = 0; i < keys2.length; ++i) {
|
|
199477
|
+
key2 = keys2[i];
|
|
199176
199478
|
if (key2 === "removeListener") continue;
|
|
199177
199479
|
this.removeAllListeners(key2);
|
|
199178
199480
|
}
|
|
@@ -201785,9 +202087,9 @@ var require_isBufferBrowser = /* @__PURE__ */ __commonJSMin(((exports2, module2)
|
|
|
201785
202087
|
var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
201786
202088
|
init_dist();
|
|
201787
202089
|
var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || function getOwnPropertyDescriptors2(obj2) {
|
|
201788
|
-
var
|
|
202090
|
+
var keys2 = Object.keys(obj2);
|
|
201789
202091
|
var descriptors = {};
|
|
201790
|
-
for (var i = 0; i <
|
|
202092
|
+
for (var i = 0; i < keys2.length; i++) descriptors[keys2[i]] = Object.getOwnPropertyDescriptor(obj2, keys2[i]);
|
|
201791
202093
|
return descriptors;
|
|
201792
202094
|
};
|
|
201793
202095
|
var formatRegExp = /%[sdj%]/g;
|
|
@@ -201923,11 +202225,11 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
201923
202225
|
}
|
|
201924
202226
|
var primitive = formatPrimitive(ctx, value);
|
|
201925
202227
|
if (primitive) return primitive;
|
|
201926
|
-
var
|
|
201927
|
-
var visibleKeys = arrayToHash(
|
|
201928
|
-
if (ctx.showHidden)
|
|
201929
|
-
if (isError2(value) && (
|
|
201930
|
-
if (
|
|
202228
|
+
var keys2 = Object.keys(value);
|
|
202229
|
+
var visibleKeys = arrayToHash(keys2);
|
|
202230
|
+
if (ctx.showHidden) keys2 = Object.getOwnPropertyNames(value);
|
|
202231
|
+
if (isError2(value) && (keys2.indexOf("message") >= 0 || keys2.indexOf("description") >= 0)) return formatError(value);
|
|
202232
|
+
if (keys2.length === 0) {
|
|
201931
202233
|
if (isFunction(value)) {
|
|
201932
202234
|
var name = value.name ? ": " + value.name : "";
|
|
201933
202235
|
return ctx.stylize("[Function" + name + "]", "special");
|
|
@@ -201945,13 +202247,13 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
201945
202247
|
if (isRegExp(value)) base = " " + RegExp.prototype.toString.call(value);
|
|
201946
202248
|
if (isDate(value)) base = " " + Date.prototype.toUTCString.call(value);
|
|
201947
202249
|
if (isError2(value)) base = " " + formatError(value);
|
|
201948
|
-
if (
|
|
202250
|
+
if (keys2.length === 0 && (!array || value.length == 0)) return braces[0] + base + braces[1];
|
|
201949
202251
|
if (recurseTimes < 0) if (isRegExp(value)) return ctx.stylize(RegExp.prototype.toString.call(value), "regexp");
|
|
201950
202252
|
else return ctx.stylize("[Object]", "special");
|
|
201951
202253
|
ctx.seen.push(value);
|
|
201952
202254
|
var output;
|
|
201953
|
-
if (array) output = formatArray(ctx, value, recurseTimes, visibleKeys,
|
|
201954
|
-
else output =
|
|
202255
|
+
if (array) output = formatArray(ctx, value, recurseTimes, visibleKeys, keys2);
|
|
202256
|
+
else output = keys2.map(function(key2) {
|
|
201955
202257
|
return formatProperty(ctx, value, recurseTimes, visibleKeys, key2, array);
|
|
201956
202258
|
});
|
|
201957
202259
|
ctx.seen.pop();
|
|
@@ -201970,11 +202272,11 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
201970
202272
|
function formatError(value) {
|
|
201971
202273
|
return "[" + Error.prototype.toString.call(value) + "]";
|
|
201972
202274
|
}
|
|
201973
|
-
function formatArray(ctx, value, recurseTimes, visibleKeys,
|
|
202275
|
+
function formatArray(ctx, value, recurseTimes, visibleKeys, keys2) {
|
|
201974
202276
|
var output = [];
|
|
201975
202277
|
for (var i = 0, l2 = value.length; i < l2; ++i) if (hasOwnProperty(value, String(i))) output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true));
|
|
201976
202278
|
else output.push("");
|
|
201977
|
-
|
|
202279
|
+
keys2.forEach(function(key2) {
|
|
201978
202280
|
if (!key2.match(/^\d+$/)) output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key2, true));
|
|
201979
202281
|
});
|
|
201980
202282
|
return output;
|
|
@@ -202117,9 +202419,9 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
202117
202419
|
exports2.inherits = require_inherits_browser2();
|
|
202118
202420
|
exports2._extend = function(origin, add) {
|
|
202119
202421
|
if (!add || !isObject3(add)) return origin;
|
|
202120
|
-
var
|
|
202121
|
-
var i =
|
|
202122
|
-
while (i--) origin[
|
|
202422
|
+
var keys2 = Object.keys(add);
|
|
202423
|
+
var i = keys2.length;
|
|
202424
|
+
while (i--) origin[keys2[i]] = add[keys2[i]];
|
|
202123
202425
|
return origin;
|
|
202124
202426
|
};
|
|
202125
202427
|
function hasOwnProperty(obj2, prop) {
|
|
@@ -202201,14 +202503,14 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
202201
202503
|
}));
|
|
202202
202504
|
var require_buffer_list2 = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
|
|
202203
202505
|
function ownKeys2(object, enumerableOnly) {
|
|
202204
|
-
var
|
|
202506
|
+
var keys2 = Object.keys(object);
|
|
202205
202507
|
if (Object.getOwnPropertySymbols) {
|
|
202206
202508
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
202207
202509
|
enumerableOnly && (symbols = symbols.filter(function(sym) {
|
|
202208
202510
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
202209
|
-
})),
|
|
202511
|
+
})), keys2.push.apply(keys2, symbols);
|
|
202210
202512
|
}
|
|
202211
|
-
return
|
|
202513
|
+
return keys2;
|
|
202212
202514
|
}
|
|
202213
202515
|
function _objectSpread(target) {
|
|
202214
202516
|
for (var i = 1; i < arguments.length; i++) {
|
|
@@ -203056,17 +203358,17 @@ var require__stream_writable = /* @__PURE__ */ __commonJSMin(((exports2, module2
|
|
|
203056
203358
|
var require__stream_duplex = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
|
|
203057
203359
|
init_dist();
|
|
203058
203360
|
var objectKeys = Object.keys || function(obj2) {
|
|
203059
|
-
var
|
|
203060
|
-
for (var key2 in obj2)
|
|
203061
|
-
return
|
|
203361
|
+
var keys3 = [];
|
|
203362
|
+
for (var key2 in obj2) keys3.push(key2);
|
|
203363
|
+
return keys3;
|
|
203062
203364
|
};
|
|
203063
203365
|
module2.exports = Duplex;
|
|
203064
203366
|
var Readable = require__stream_readable();
|
|
203065
203367
|
var Writable = require__stream_writable();
|
|
203066
203368
|
require_inherits_browser2()(Duplex, Readable);
|
|
203067
|
-
var
|
|
203068
|
-
for (var v = 0; v <
|
|
203069
|
-
var method =
|
|
203369
|
+
var keys2 = objectKeys(Writable.prototype);
|
|
203370
|
+
for (var v = 0; v < keys2.length; v++) {
|
|
203371
|
+
var method = keys2[v];
|
|
203070
203372
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
203071
203373
|
}
|
|
203072
203374
|
function Duplex(options) {
|
|
@@ -217473,12 +217775,12 @@ var Bitfield = class extends Base {
|
|
|
217473
217775
|
size() {
|
|
217474
217776
|
return this.type.size();
|
|
217475
217777
|
}
|
|
217476
|
-
encode(stream2,
|
|
217778
|
+
encode(stream2, keys2) {
|
|
217477
217779
|
let val = 0;
|
|
217478
217780
|
for (let i = 0; i < this.flags.length; i++) {
|
|
217479
217781
|
const flag = this.flags[i];
|
|
217480
217782
|
if (flag != null) {
|
|
217481
|
-
if (
|
|
217783
|
+
if (keys2[flag]) {
|
|
217482
217784
|
val |= 1 << i;
|
|
217483
217785
|
}
|
|
217484
217786
|
}
|
|
@@ -238875,8 +239177,8 @@ function parsePropertyQuery(query) {
|
|
|
238875
239177
|
if (!m) return null;
|
|
238876
239178
|
const prop = m[1];
|
|
238877
239179
|
const value = m[2].replace(/^[\s=<>!]+/, "").replace(/^["']|["']$/g, "").trim().toLowerCase() || void 0;
|
|
238878
|
-
const
|
|
238879
|
-
const regexes = prop.includes(".") ? [new RegExp(`@${
|
|
239180
|
+
const esc3 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
239181
|
+
const regexes = prop.includes(".") ? [new RegExp(`@${esc3(prop)}\\b`, "i")] : [new RegExp(`@${esc3(prop)}\\b`, "i"), new RegExp(`@patter\\.${esc3(prop)}\\b`, "i")];
|
|
238880
239182
|
return { regexes, value };
|
|
238881
239183
|
}
|
|
238882
239184
|
var indexCache = null;
|
|
@@ -240971,7 +241273,7 @@ function writeTextFiles(files, encoding = "utf8") {
|
|
|
240971
241273
|
// package.json
|
|
240972
241274
|
var package_default = {
|
|
240973
241275
|
name: "@patterkit/cli",
|
|
240974
|
-
version: "0.3.
|
|
241276
|
+
version: "0.3.9",
|
|
240975
241277
|
description: "The `patter` CLI: validate, format, export, and play a Patter project.",
|
|
240976
241278
|
type: "module",
|
|
240977
241279
|
license: "MIT",
|
|
@@ -241000,8 +241302,8 @@ var package_default = {
|
|
|
241000
241302
|
"build:standalone:others": "node scripts/build-standalone.mjs --targets=linux-x64,linux-arm64,windows-x64"
|
|
241001
241303
|
},
|
|
241002
241304
|
dependencies: {
|
|
241003
|
-
"@patterkit/core": "0.2.
|
|
241004
|
-
"@patterkit/ops": "0.7.
|
|
241305
|
+
"@patterkit/core": "0.2.5",
|
|
241306
|
+
"@patterkit/ops": "0.7.7",
|
|
241005
241307
|
"@wildwinter/simple-vc-lib": "^0.4.1"
|
|
241006
241308
|
}
|
|
241007
241309
|
};
|