@patterkit/play-helpers 0.8.5 → 0.8.7

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ian Thomas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,5 +1,5 @@
1
- "use strict";var Patterplay=(()=>{var de=Object.defineProperty;var xt=Object.getOwnPropertyDescriptor;var kt=Object.getOwnPropertyNames;var Et=Object.prototype.hasOwnProperty;var Ct=(n,e)=>{for(var t in e)de(n,t,{get:e[t],enumerable:!0})},Dt=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of kt(e))!Et.call(n,s)&&s!==t&&de(n,s,{get:()=>e[s],enumerable:!(r=xt(e,s))||r.enumerable});return n};var It=n=>Dt(de({},"__esModule",{value:!0}),n);var tr={};Ct(tr,{Checkpoint:()=>Z,DEFAULT_PAD_AFTER:()=>F,Engine:()=>ae,Flow:()=>M,SAVE_SCHEMA:()=>$,applyLiveBundle:()=>ht,buildTagIndex:()=>ie,createAudioResolver:()=>vt,createBundleInspector:()=>bt,createDebugLink:()=>ft,createPropertyInspector:()=>yt,createStateLogger:()=>gt,describeBundle:()=>ce,deserializeState:()=>pe,diffState:()=>U,effectiveGameData:()=>at,gameDataFields:()=>it,gameDataValue:()=>Ee,getProperty:()=>ct,loadState:()=>De,saveState:()=>Ce,serializeState:()=>le,setProperties:()=>pt,setProperty:()=>lt,snapshotState:()=>Pe});function H(n,e){return n!==void 0&&Object.prototype.hasOwnProperty.call(n,e)?n[e]:void 0}function j(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:j(n[2])};case"bin":return{kind:"binary",op:n[1],left:j(n[2]),right:j(n[3])};case"call":{let e=n.slice(2).map(j);return{kind:"call",name:n[1],args:e}}case"fd":return{kind:"flagdelta",sign:n[1],name:n[2]}}}var S=class extends Error{constructor(e){super(e),this.name="EvalError"}};function te(n,e,t){let r=new Map(t.scopes.map(o=>[o.token,o.missing??"false"])),s=o=>{switch(o.kind){case"bool":return o.value;case"number":return o.value;case"string":return o.value;case"scopedvar":{let i=H(e.scopes,o.scope);if(i===void 0)return!1;let a=typeof i.get=="function"?i.get(o.name):H(i,o.name);if(a===void 0){if(r.get(o.scope)==="throw")throw new S(`@${o.scope}.${o.name} is not declared on the current ${o.scope}.`);return!1}return a}case"call":{if(o.name==="advance"&&!H(t.functions,o.name)){let a=o.args[0];if(o.args.length!==1||a===void 0)throw new S(`advance() takes exactly 1 argument, got ${o.args.length}`);let c=ue(a,e);if(c===void 0)throw new S("advance() needs a quality reference (@scope.name of a quality property)");let d=B(s(a),c,"advance");return c[Math.min(d+1,c.length-1)]}let i=H(t.functions,o.name);if(!i)throw new S(`unknown function '${o.name}'`);return i.eval(o.args,{evaluate:s,ctx:e})}case"flagdelta":throw new S("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(o.op==="not"){let a=s(o.operand);if(typeof a!="boolean")throw new S(`'not' requires a boolean operand, got ${typeof a}`);return!a}let i=s(o.operand);if(typeof i!="number")throw new S(`unary '-' requires a numeric operand, got ${typeof i}`);return-i}case"binary":{if(o.op==="and"){let l=s(o.left);if(typeof l!="boolean")throw new S(`'and' requires boolean operands, left is ${typeof l}`);if(!l)return!1;let f=s(o.right);if(typeof f!="boolean")throw new S(`'and' requires boolean operands, right is ${typeof f}`);return f}if(o.op==="or"){let l=s(o.left);if(typeof l!="boolean")throw new S(`'or' requires boolean operands, left is ${typeof l}`);if(l)return!0;let f=s(o.right);if(typeof f!="boolean")throw new S(`'or' requires boolean operands, right is ${typeof f}`);return f}let i=s(o.left),a=s(o.right),c=ue(o.left,e),d=ue(o.right,e),g=c??d;if(g!==void 0){if(c&&d&&!Pt(c,d)&&(o.op===">"||o.op===">="||o.op==="<"||o.op==="<="))throw new S(`'${o.op}' compares two different qualities, whose stage orders are unrelated`);switch(o.op){case">":return B(i,g,">")>B(a,g,">");case">=":return B(i,g,">=")>=B(a,g,">=");case"<":return B(i,g,"<")<B(a,g,"<");case"<=":return B(i,g,"<=")<=B(a,g,"<=");case"+":case"-":case"*":case"/":throw new S(`'${o.op}' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(o.op){case"==":return Re(i,a);case"!=":return!Re(i,a);case">":return T(i,a,">"),i>a;case">=":return T(i,a,">="),i>=a;case"<":return T(i,a,"<"),i<a;case"<=":return T(i,a,"<="),i<=a;case"+":if(typeof i=="number"&&typeof a=="number"||typeof i=="string"&&typeof a=="string")return i+a;throw new S(`'+' requires two numbers or two strings, got ${typeof i} and ${typeof a}`);case"-":return T(i,a,"-"),i-a;case"*":return T(i,a,"*"),i*a;case"/":if(T(i,a,"/"),a===0)throw new S("division by zero");return i/a}}}};return s(n)}function Re(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 T(n,e,t){if(typeof n!="number"||typeof e!="number")throw new S(`'${t}' requires numeric operands, got ${typeof n} and ${typeof e}`)}function ue(n,e){if(!(n.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(n.scope,n.name)}function B(n,e,t){if(typeof n!="string")throw new S(`'${t}' on a quality compares stages, got ${typeof n}`);let r=e.indexOf(n);if(r<0)throw new S(`"${n}" is not a stage of this quality (stages: ${e.join(", ")})`);return r}var Pt=(n,e)=>n.length===e.length&&n.every((t,r)=>t===e[r]);function _(n){if(Number.isNaN(n)||!Number.isFinite(n))return 0;let e=Math.trunc(n)%4294967296;return e<0?e+4294967296:e}function ge(n){let e=_(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 Ot={name:"check_flags",count:n=>Math.max(1,n.args.length-1)},Rt=[Ot];function Be(n,e,t){let r=t?.countingCalls??Rt;return re(n,t?.want??!0,e,r)}function re(n,e,t,r){if(n.kind==="binary"&&(n.op==="and"||n.op==="or")){let s=re(n.left,e,t,r),o=re(n.right,e,t,r);return n.op==="and"===e?s>0&&o>0?s+o:0:Math.max(s,o)}if(n.kind==="unary"&&n.op==="not")return re(n.operand,!e,t,r);if(n.kind==="call"){let s=r.find(o=>o.name===n.name);if(s){let o=s.count(n),i=t(n);return e?i?o:0:i?0:1}}return t(n)===e?1:0}function U(n,e){let t=[],r=new Set([...Object.keys(n),...Object.keys(e)]);for(let s of[...r].sort()){let o=n[s],i=e[s];JSON.stringify(o)!==JSON.stringify(i)&&t.push({path:s,from:o,to:i})}return t}var Ae=n=>n===void 0?"<unset>":JSON.stringify(n),Ne=n=>n.pathPrefix??n.bag.pathPrefix;function fe(n,e={}){let t=e.sink??(l=>console.log(l)),r=e.label??"",s=l=>{t(`${r}${l.path}: ${Ae(l.from)} -> ${Ae(l.to)}`)},o=()=>{let l={};for(let f of n.mounts()){let h=Ne(f);for(let[m,u]of Object.entries(f.bag.values))l[h+m]=u}return Object.assign(l,n.extra?.()??{}),structuredClone(l)},i=o(),a=[],c=[],d=(l,f)=>f.onAudit(h=>{let m=structuredClone({path:l+h.name,from:h.prev,to:h.next});s(m),a.push(m),i[m.path]=structuredClone(h.next)}),g=()=>{let l=n.mounts();if(!(c.length===l.length&&l.every((h,m)=>c[m].bag===h.bag))){for(let h of c)h.off();c=l.map(h=>({bag:h.bag,off:d(Ne(h),h.bag)}))}};return g(),{snapshot:o,capture(){let l=o(),f=U(i,l);for(let m of f)s(m);let h=[...a,...f];return a=[],i=l,g(),h},dispose(){for(let l of c)l.off();c=[],a=[]}}}var N=class n{values=Object.create(null);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??W(t))}}get(e){return this.values[this.norm(e)]}normalise(e){return this.norm(e)}writable(e){return this.decls.get(this.norm(e))?.writable!==!1}set(e,t,r){let s=this.norm(e);if(!r?.host&&!this.writable(s))throw new Error(`'${e}' is read-only`);let o={name:s,prev:this.values[s],next:t,silent:r?.silent??!1,reason:r?.reason};this.values[s]=t;for(let i of[...this.auditors])i(o);if(!o.silent)for(let i of[...this.subscribers])i(o);return o}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])=>Le(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 Le(n,e,t,r,s=""){let o=r??n.name.toLowerCase();return{name:o,path:s+o,type:n.type,value:e,default:n.default??W(n),...n.values!==void 0?{values:n.values}:{},...n.stages!==void 0?{stages:n.stages}:{},writable:t??n.writable??!0}}var Bt=n=>n.toLowerCase(),he=1,ne=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??{},o=new N(t,{pathPrefix:s.pathPrefix??`${e}.`,...s.normalise?{normalise:s.normalise}:{}});return this.mountOwned(e,o,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 o=typeof s=="boolean"?{writable:s}:s;this.assertFree(e,o.owner);let i=o.normalise??Bt,a=new Map;for(let c of r)a.set(i(c.name),c);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:a,scopeWritable:o.writable??!0,norm:i,...o.owner!==void 0?{owner:o.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 o=this.scopes.get(e);if(!o)throw new Error(`unknown scope '@${e}'`);if(o.kind==="owned"){if(!s?.host&&!o.bag.writable(t))throw new Error(`'@${e}.${t}' is read-only`);o.bag.set(t,r,s?.host?{host:!0}:void 0);return}let i=o.norm(t);if(!o.resolver.set)throw new Error(`'@${e}.${t}' is read-only`);if(!s?.host&&!this.foreignWritable(o,i))throw new Error(`'@${e}.${t}' is read-only`);o.resolver.set(i,r)}foreignWritable(e,t){return e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}listProperties(){let e=[];for(let[t,r]of this.scopes){let s=r.owner!==void 0?{owner:r.owner}:{};if(r.kind==="owned")for(let o of r.bag.rows())e.push({scope:t,...s,...o});else for(let[o,i]of r.decls)e.push({scope:t,...s,...Le(i,r.resolver.get(o),this.foreignWritable(r,o),o,`${t}.`)})}return e}toEvalContext(e,t){let r=this.view(t?.aliases),s={};for(let[i,a]of r)s[i]=a.kind==="owned"?a.bag.values:a.resolver;let o=this.qualityLadders(r);return o.size===0?{scopes:s,host:e}:{scopes:s,host:e,qualities:(i,a)=>{let c=r.get(i);return c?o.get(i)?.get(At(c)(a)):void 0}}}view(e){let t=new Map(this.scopes);for(let[r,s]of Object.entries(e??{})){let o=this.scopes.get(s);if(!o)throw new Error(`alias '@${r}' names '${s}', which is not registered`);t.set(r,o)}return t}qualityLadders(e){let t=new Map;for(let[r,s]of e)for(let[o,i]of Fe(s)){if(i.type!=="quality"||i.stages===void 0)continue;let a=t.get(r);a||(a=new Map,t.set(r,a)),a.set(o,i.stages)}return t}toSchema(e){let t=new Map;for(let[r,s]of this.view(e?.aliases)){let o=Fe(s);if(o.length===0)continue;let i=new Map;for(let[a,c]of o)i.set(a,{type:c.type,enumValues:c.values,...c.stages!==void 0?{stages:c.stages}:{}});t.set(r,i)}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 o=this.scopes.get(r);o?.kind==="owned"?o.bag.load(s):o||this.parked.set(r,structuredClone(s))}}saveFragment(){return{version:he,scopes:this.save()}}loadFragment(e){if(e.version!==he)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${he})`);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}`:"",o=t!==void 0?` (wanted by ${t})`:"";throw new Error(`scope '@${e}' is already registered${s}${o}`)}};function Fe(n){return n.kind==="foreign"?[...n.decls.entries()]:n.bag.declarations().map(e=>[n.bag.normalise(e.name),e])}function At(n){return n.kind==="foreign"?n.norm:e=>n.bag.normalise(e)}function W(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 je=[{token:"patter",engine:"Patterplay",means:"Patter's shared globals"},{token:"story",engine:"Storylet Engine",means:"the Storylet Engine's shared @story properties"}];function J(n){return n.ctx.host??{}}var me={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(n,e){if(n.length!==2)throw new S("random(a, b) requires exactly 2 arguments");let t=J(e).nextRandom;if(!t)throw new S("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 S("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(s))throw new S("random(a, b) arguments must be integers");let o=Math.min(r,s),i=Math.max(r,s);return Math.floor(t()*(i-o+1))+o}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:Ve("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 S("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:Ve("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 S("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let o=t.indexOf(s.name);o>=0&&t.splice(o,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:oe("visits"),eval:(n,e)=>J(e).visits?.(se(n,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:oe("seen"),eval:(n,e)=>(J(e).visits?.(se(n,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:oe("patter_visits"),eval:(n,e)=>J(e).patterVisits?.(se(n,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:oe("patter_seen"),eval:(n,e)=>(J(e).patterVisits?.(se(n,e,"patter_seen"))??0)>0}}},wr=je.map(n=>n.token).filter(n=>n!=="patter"&&n!=="scene");function Me(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 se(n,e,t){let r=e.evaluate(n[0]);if(typeof r!="string")throw new S(`${t}(id) requires a string node id`);return r}function oe(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 S(`${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 S(`${t}() first argument must be a flags property`)}function Ve(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 o=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}(): '@${o}' is not a flags property (got ${s.type})`});return}for(let o=1;o<e.length;o++){let i=e[o];i.kind!=="flagdelta"?t.report({path:[...t.path,"args",o],kind:"wrong-arg-type",severity:"error",message:`${n}(): argument ${o+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(i.name)&&t.report({path:[...t.path,"args",o],kind:"unknown-flag-name",severity:"error",message:`${n}(): unknown flag '${i.name}'`,reference:i.name})}}}var Nt=/^@[A-Za-z0-9_.]+$/;function*Ft(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 o=n.slice(t,s+1),i=n.slice(t+1,s).trim();if(i.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:o,inner:i,ref:Nt.test(i)?i:void 0},t=s+1;continue}e+=o,t=s+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function Lt(n){return Array.isArray(n)?n.join(", "):typeof n=="boolean"?n?"true":"false":String(n)}function jt(n){return n===" "||n===" "||n===`
2
- `||n==="\r"||n==="\f"||n==="\v"}function Tt(n){let e="",t=!1;for(let r of n){if(jt(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,o=!1;for(;s<n.length;){if(n.startsWith(e,s)){let i=n.indexOf(t,s+e.length);if(i>=0){s=i+t.length,o=!0;continue}r+=n.slice(s);break}r+=n[s],s+=1}return o?Tt(r):n}function $e(n,e){if(n.indexOf("{")<0)return n;let t="";for(let r of Ft(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?"":Lt(s)}return t}function G(n,e){for(let t of n){e(t);let r=t.children;r&&G(r,e)}}function Vt(n){return n.toLowerCase().replace(/['’]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function C(n){let e=n.gameId?.trim();return e||Vt(n.name)}var F=.6;function ye(n){return`cast:${n}`}function Se(n){return`qualifier:${n}`}var be={open:"[",close:"]"},qe="SFX",$="patter/save@0",z=3;function K(n){let e=new Set,t=[];for(let r of n)e.has(r)||(e.add(r),t.push(r));return t}function ie(n){let e=new Map,t=(r,s)=>{let o=K([...s,...r.tags??[]]);if(e.set(r.id,o),r.type==="group"&&r.prompt&&e.set(r.prompt.id,K([...o,...r.prompt.tags??[]])),r.type==="group")for(let i of r.children)t(i,o);else for(let i of r.beats??[])e.set(i.id,K([...o,...i.tags??[]]))};for(let r of Object.values(n.scenes)){let s=K(r.tags??[]);e.set(r.id,s);for(let o of r.blocks){let i=K([...s,...o.tags??[]]);e.set(o.id,i);for(let a of o.children)t(a,i)}}return e}var He=n=>n.kind==="line"||n.kind==="text",Q=n=>typeof n=="number"&&Number.isFinite(n)?n:void 0;function _e(n){let e=new Map,t=(o,i,a)=>{let c=o.kind==="gameEvent"?void 0:Q(o.padAfter),d=c??i;a&&d<0&&(d=0),e.set(o.id,c!==void 0?{own:c,resolved:d}:{resolved:d})},r=(o,i)=>{let a=Q(o.padAfterDefault)??i;if(o.type==="group"){o.prompt&&t(o.prompt,a,!1);for(let g of o.children)r(g,a);return}let c=o.beats??[],d=-1;c.forEach((g,l)=>{He(g)&&(d=l)}),c.forEach((g,l)=>{He(g)&&t(g,a,l===d)})},s=Q(n.padAfterDefault)??F;for(let o of Object.values(n.scenes)){let i=Q(o.padAfterDefault)??s;for(let a of o.blocks){let c=Q(a.padAfterDefault)??i;for(let d of a.children)r(d,c)}}return e}var Ue=new WeakMap,We=new WeakMap;function Mt(n){let e=We.get(n);return e||(e=ie(n),We.set(n,e)),e}var Je=new WeakMap;function Gt(n){let e=Je.get(n);return e||(e=_e(n),Je.set(n,e)),e}function V(n,e){return n.tagIndex.get(e)?.slice()}var X="Patter",Y=n=>n.replace(/%/g,"%25").replace(/\//g,"%2F"),$t=n=>n.replace(/%2F/g,"/").replace(/%25/g,"%"),ze=Symbol("ownsRegistry"),E={stage:n=>`patter/scene/${Y(n)}`,flow:n=>`patter/flow/${Y(n)}/`,flowGlobals:n=>`patter/flow/${Y(n)}/patter`,flowScene:(n,e)=>`patter/flow/${Y(n)}/scene/${Y(e)}`},Z=class{constructor(e){this.journal=e}journal},ae=class n{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineSeq=0;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 o=s[r]??{},i=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 p of e.cast??[])p.displayName&&d.set(p.name,p.displayName);let g=new Map;for(let p of e.qualifiers??[])p?.gameId&&g.set(p.gameId,p.name);this.defaultSeed=(t.seed??2654435769)>>>0;let l=new Map,f=new Map,h=new Map;for(let[p,y]of Object.entries(e.scenes)){this.sceneGameIdToId.set(C(y),p);let k=new Map;for(let x of y.blocks)f.set(x.id,{sceneId:p}),h.set(x.id,x),k.set(C(x),x.id),G(x.children,ee=>l.set(ee.id,ee));this.blockGameIdToId.set(p,k)}let m=e.properties??[],u=m.filter(p=>p.shared??!0).map(Xe),v=m.filter(p=>!(p.shared??!0)).map(Xe),D=new Set(u.map(p=>p.name.toLowerCase())),w=t.registry??new ne,O=!t.registry||t[ze]===!0,I=new N(u,{pathPrefix:"@patter."}),A=[],R=[];try{w.mountOwned("patter",I,{owner:X}),R.push("patter");let p=new Set;for(let[y,k]of Object.entries(Ze(t))){let x=e.scopeRegistry?.scopes.find(wt=>wt.token===y),ee=(x?.declarations??[]).map(nt);w.defineForeign(y,k,ee,{writable:x?.writable??!0,owner:X}),R.push(y),p.add(y)}for(let y of O?e.scopeRegistry?.scopes??[]:[]){if(p.has(y.token)||w.has(y.token))continue;let k=(y.declarations??[]).map(x=>Ht(x,y.writable));w.defineOwned(y.token,k,{owner:X}),R.push(y.token),A.push(y.token)}}catch(p){for(let y of R)w.remove(y,{keep:!0});throw p}let L=new Map;for(let[p,y]of Object.entries(e.scenes)){let k=new Set((y.sceneProps??[]).filter(x=>x.shared??!1).map(x=>x.name.toLowerCase()));L.set(p,k)}this.host={logEnabled:t.log??!1,tracing:t.log??!1,emitEngine:(p,y,k)=>this.emitEngine(p,y,k),bundle:e,emitIds:c,strings:o,defaultStrings:i,castDisplay:d,qualifierDisplay:g,nodeIndex:l,blockIndex:f,blockById:h,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:Mt(e),padIndex:Gt(e),registry:w,ownsRegistry:O,patterBag:I,hostScopes:A,patterSharedDecls:u,patterLocalDecls:v,patterSharedNames:D,sceneSharedNames:L,sharedVisits:new Map,qualityLadders:new Map,sharedSelectors:new Map,stageBags:new Map,journal:null,customRng:t.rng,onDryChoice:t.onDryChoice,onError:t.onError??(p=>console.warn(`Patterplay: ${p.kind} on ${p.node} in flow '${p.flow}' failed, played through: ${p.message}`)),replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??be).open,captionClose:(e.closedCaptions??be).close,captionCharacter:e.closedCaptions?.character||qe,refSplitCache:new Map,refSplitRevision:w.revision}}get locale(){return this.currentLocale}get isSourceDebug(){return this.sourceDebug}get buildId(){return this.host.bundle.content?.hash??""}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){this.refuseInCheckpoint("hotSwap");let t=this.saveGame(),r=i=>(i.setLocale(this.currentLocale),i.setClosedCaptions(this.host.captionsOn),i),s=()=>new n(e,{...this.creationOptions,registry:this.host.registry,[ze]:this.host.ownsRegistry});this.release(!0);let o=s();try{return o.loadGame(t),r(o)}catch{o.release(!0);let i=s();for(let[a,c]of Object.entries(t.flows)){let d=c.cursor.currentSceneId;try{i.openFlow(a,d!==null?{scene:d}:{})}catch{}}return r(i)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){this.assertExternalScopes();let{sceneId:r,blockId:s}=this.resolveOpenAddress(t.scene,t.block),o=this.flowsById.get(e),i=this.host.journal;if(i&&o&&!o.isClosed)throw new Error(`openFlow would replace the open flow '${e}', which can't be undone while a checkpoint is open`);o?.close();let a=new M(e,this.host,t.seed??this.defaultSeed);return i&&(i.flows.add(a),i.opened.add(a),i.undo.push(()=>{a.close(),o?this.flowsById.set(e,o):this.flowsById.delete(e)})),this.flowsById.set(e,a),a.begin(r,s),a}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`)}resolveOpenAddress(e,t){if(e!==void 0){let r=we(this.host,e);if(r===void 0)throw new Error(`unknown scene: ${e}`);if(t===void 0)return{sceneId:r};let s=xe(this.host,r,t);if(s===void 0)throw new Error(`unknown block: ${t}`);return{sceneId:r,blockId:s}}if(t!==void 0){if(!this.host.blockIndex.has(t))throw new Error(`unknown block: ${t}`);return{blockId:t}}if(Object.keys(this.host.bundle.scenes).length===0)throw new Error("no scenes in bundle");return{}}resolveSceneRef(e){if(e!=null)return we(this.host,e)??e}resolveBlockRef(e,t){if(t!=null)return e==null?t:xe(this.host,e,t)}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?C(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?C(t):void 0}tagsForBeat(e){return V(this.host,e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?V(this.host,t):void 0)??[]}tagsForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t);return(s!=null?V(this.host,s):void 0)??[]}gameDataForScene(e){let t=this.resolveSceneRef(e);return{...(t!=null?this.host.bundle.scenes[t]:void 0)?.gameData}}gameDataForBlock(e,t){let r=this.resolveBlockRef(this.resolveSceneRef(e),t);return{...(r!=null?this.host.blockById.get(r):void 0)?.gameData}}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 o of r.blocks)Ke(o.children,s);return[...s]}castForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t),o=s!=null?this.host.blockById.get(s):void 0;if(!o)return[];let i=new Set;return Ke(o.children,i),[...i]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...C(e)?{gameId:C(e)}:{},name:e.name,...Qe(e.gameData),...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...C(t)?{gameId:C(t)}:{},name:t.name,...Qe(t.gameData),...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)G(r.children,s=>{if(s.type==="snippet")for(let o of s.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:s.id,beat:this.beatInfo(o)})});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=V(this.host,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[ye(e.character)]??this.host.castDisplay.get(e.character);s!==void 0&&(r.characterName=s)}if(e.direction!==void 0&&(r.direction=e.direction),e.qualifier!==void 0){r.qualifier=e.qualifier;let s=this.host.defaultStrings[Se(e.qualifier)]??this.host.qualifierDisplay.get(e.qualifier);s!==void 0&&(r.qualifierName=s)}}if(e.kind==="line"||e.kind==="text"){let s=this.host.padIndex.get(e.id);r.padAfter=s?.resolved??F,s?.own!==void 0&&(r.ownPadAfter=s.own);let o=this.host.defaultStrings[e.id];o!==void 0&&(r.text=o)}return e.gameData&&Object.keys(e.gameData).length&&(r.gameData=e.gameData),t&&t.length&&(r.tags=t),r}tagsField(e){let t=V(this.host,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}checkpoint(){if(this.host.journal)throw new Error("a checkpoint is already open: roll it back or commit it first");let e={undo:[],flows:new Set,opened:new Set,selectors:new Set,flowSelectors:new Map};return this.host.journal=e,new Z(e)}rollback(e){this.endCheckpoint(e);let t=e.journal.undo;for(let r=t.length-1;r>=0;r--)t[r]();n.forget(e.journal)}commit(e){this.endCheckpoint(e),n.forget(e.journal)}get inCheckpoint(){return this.host.journal!==null}endCheckpoint(e){if(this.host.journal!==e.journal)throw new Error("that checkpoint is not the open one");this.host.journal=null}static forget(e){e.undo=[],e.flows.clear(),e.opened.clear(),e.selectors.clear(),e.flowSelectors.clear()}refuseInCheckpoint(e){if(this.host.journal)throw new Error(`${e} can't be undone, so it isn't allowed while a checkpoint is open`)}captureFlow(e){let t=this.flowsById.get(e);if(!t)throw new Error(`no open flow '${e}' to capture`);return{version:z,...t.snapshot(),...Ut(e,this.host.registry.save())}}restoreFlow(e,t){this.refuseInCheckpoint("restoreFlow");let r=t.version;if(r!==2&&r!==z)throw new Error(`unsupported flow state version: ${String(r)}`);let s=t.cursor;if(typeof s!="object"||s===null)throw new Error("malformed flow state: no cursor");if(this.flowsById.has(e))throw new Error(`a flow '${e}' is already open; close it before restoring another under that id`);this.assertExternalScopes();let o=E.flow(e);this.host.registry.discardParked(o),this.host.registry.load(ot(e,t),{keepParked:!0});let i=new M(e,this.host,this.defaultSeed);try{i.restore(t)}catch(a){throw i.close(),this.host.registry.discardParked(o),a}return this.flowsById.set(e,i),i}closeFlow(e){this.refuseInCheckpoint("closeFlow"),this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){this.refuseInCheckpoint("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(E.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(E.stage(r),{keep:e});this.host.stageBags.clear();for(let r of["patter",...this.host.hostScopes])t.has(r)&&t.remove(r,{keep:e});for(let r of Object.keys(Ze(this.creationOptions)))t.has(r)&&t.remove(r)}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),o=this.host.journal?this.host.registry.get(r,s):void 0;this.host.registry.set(r,s,t,{host:!0}),this.host.journal&&o!==void 0&&this.host.journal.undo.push(()=>this.host.registry.set(r,s,o,{host:!0}))}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),this.host.tracing=!0,()=>{this.engineTraceHandlers.delete(e),this.host.tracing=this.host.logEnabled||this.engineTraceHandlers.size>0}}emitEngine(e,t,r){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineSeq++,...r?{scene:r}:{}})}getVisitCounts(){return Object.fromEntries(this.host.sharedVisits)}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:W(e),writable:e.writable??!0}))}splitShared(e){let t=st(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:tt(this.host.sharedSelectors),flows:e}}loadGame(e){this.refuseInCheckpoint("loadGame");let t=e.version;if(t!==2&&t!==z)throw new Error(`unsupported save version: ${String(t)}`);let r=e.flows;if(typeof r!="object"||r===null||Array.isArray(r))throw new Error("malformed save: no flows");this.assertExternalScopes();let s=this.host.registry;for(let[i,a]of this.flowsById)a.releaseBags(i in e.flows),a.close();this.flowsById.clear();for(let i of this.host.stageBags.keys())s.remove(E.stage(i),{keep:!0});this.host.stageBags.clear();let o=e.version===2?_t(e):e.registry;o&&(this.host.ownsRegistry?s.load(o):s.load(o,{keepParked:!0})),this.host.sharedVisits.clear();for(let[i,a]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(i,a);this.host.sharedSelectors.clear();for(let[i,a]of rt(e.sharedSelectors))this.host.sharedSelectors.set(i,a);for(let[i,a]of Object.entries(e.flows)){let c=new M(i,this.host,this.defaultSeed);c.restore(a),this.flowsById.set(i,c)}}},M=class{id;host;local;registered=new Set;rngState;started=!1;flowEnded=!1;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPrompt=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),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,o)=>this.stagesFor(s,o)}}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();if(e==="patter")return ve(this.host,"patter",()=>[...this.host.patterSharedDecls,...this.host.patterLocalDecls]).get(r);if(e==="scene"){let s=this.currentSceneId;return s==null?void 0:ve(this.host,`scene/${s}`,()=>this.host.bundle.scenes[s]?.sceneProps).get(r)}return this.registryQualities?.(e,t)??ve(this.host,`host/${e}`,()=>this.host.bundle.scopeRegistry?.scopes.find(s=>s.token===e)?.declarations).get(r)}begin(e,t){if(this.host.journal&&!this.host.journal.opened.has(this))throw new Error("a flow can't be started or reset while a checkpoint is open");if(this.releaseBags(!1),this.host.registry.discardParked(E.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.clearPending(),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 o=s.blocks[0];o&&(this.stack=[{sceneId:r,containerId:o.id,index:0}],this.enter(o.id))}this.settle()}reset(e,t){this.begin(e,t)}start(e,t){this.reset(e,t)}goto(e,t){if(this.closed)return!1;if(this.touch(),e==="END")return this.started=!0,this.clearPending(),this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],!0;let r=we(this.host,e);if(r===void 0)return!1;let s;return t!==void 0&&(s=xe(this.host,r,t),s===void 0)?!1:this.started?(this.clearPending(),this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.enterTarget(s??r,"jump"),this.settle(),!0):(this.begin(r,s),!0)}close(){this.releaseBags(!1),this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.clearPending()}clearPending(){this.pendingChoice=null,this.pendingPrompt=null,this.pendingPromptOwnerId=null}touch(){let e=this.host.journal;if(!e||e.flows.has(this))return;e.flows.add(this);let{rngState:t,started:r,flowEnded:s,currentSceneId:o,activeSnippet:i,beatIndex:a,pendingChoice:c,pendingPrompt:d,pendingPromptOwnerId:g}=this,l=this.stack.map(f=>({...f}));e.undo.push(()=>{Object.assign(this,{rngState:t,started:r,flowEnded:s,currentSceneId:o,activeSnippet:i,beatIndex:a,pendingChoice:c,pendingPrompt:d,pendingPromptOwnerId:g,stack:l})})}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.touch(),this.pendingPrompt){let e=this.pendingPrompt;return this.pendingPrompt=null,this.pendingPromptOwnerId=null,e.shown?this.promptResult(e.beat,e.shown):this.beatResult(e.beat)}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,this.activeSnippet.id);let o=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(o);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.tracing&&t.index!==s&&this.emit({type:"select",group:t.containerId,selector:"run",children:r.slice(s,t.index+1).map((o,i)=>({id:o.id,eligible:s+i===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}:{}})}getVisitCounts(){return Object.fromEntries(this.visitCounts)}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}`);this.touch();let s=t.byId.get(e);this.host.tracing&&this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null;let o=this.host.replayPromptOnChoose?this.authoredPromptOf(s):void 0;this.pendingPrompt=o&&r.prompt?{beat:o,shown:{...r.prompt}}:null,this.pendingPromptOwnerId=this.pendingPrompt?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:o}=this.splitRef(e),i=this.host.journal;if(s==="patter"){if(i){let a=this.host.patterSharedNames.has(o),c=a?this.host.patterBag.get(o):this.local.get(o),d=this.local;c!==void 0&&i.undo.push(a?()=>this.host.registry.set("patter",o,c):()=>d.set(o,c))}this.patterResolver.set(o,t)}else if(s==="scene"){if(this.currentSceneId===null)throw new Error(`'${e}': the flow has not entered a scene yet`);if(i){let a=this.sceneBagFor(this.currentSceneId,o),c=a?.get(o);a&&c!==void 0&&i.undo.push(()=>a.set(o,c))}this.sceneResolver.set(o,t)}else{let a=i?this.host.registry.get(s,o):void 0;this.host.registry.set(s,o,t,r?{host:!0}:void 0),i&&a!==void 0&&i.undo.push(()=>this.host.registry.set(s,o,a,{host:!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,...this.pendingPrompt?.shown?{pendingPrompt:qt(this.pendingPrompt.shown)}:{},selectors:tt(this.selectors)}}}restore(e){if(this.host.journal)throw new Error("a flow can't be restored while a checkpoint is open");this.restoreCursor(e),this.releaseBags(!0),this.mountLocal();for(let t of new Set([this.currentSceneId,...this.stack.map(r=>r.sceneId)]))t!==null&&this.host.bundle.scenes[t]&&this.ensureSceneBags(t)}restoreCursor(e){this.rngState=_(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,...o}=r;if(s!==void 0){let i=this.childrenOf(o.containerId)?.findIndex(a=>a.id===s)??-1;if(i>=0)return{...o,index:i}}return{...o}}),this.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=rt(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,s=[];for(let o of t.pendingChoice.options){let i=this.host.nodeIndex.get(o.id);if(!i)continue;r.set(o.id,i);let{prompt:a,...c}=o;s.push({...c,...a?{prompt:{...a,padAfter:a.padAfter??this.promptPadOf(i)}}:{}})}s.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:s,byId:r})}if(this.pendingPrompt=null,this.pendingPromptOwnerId=t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let r=this.host.nodeIndex.get(this.pendingPromptOwnerId),s=r?this.authoredPromptOf(r):void 0;s?this.pendingPrompt={beat:s,...t.pendingPrompt?{shown:{...t.pendingPrompt,padAfter:t.pendingPrompt.padAfter??this.padOf(s.id)}}:{}}: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,t.id)}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,e.id),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],r=new Map,s=[];for(let i of e.children){if(i.fallback===!0){s.push(i);continue}if(i.sticky!==!0&&(this.visitCounts.get(i.id)??0)>=1)continue;let a=this.eligible(i),c=i.secretUntilEligible===!0;!a&&c||(t.push({id:i.id,prompt:this.promptFor(i),eligible:a,gameData:i.gameData}),r.set(i.id,i))}if(t.some(i=>i.eligible)){this.host.tracing&&this.emit({type:"choice",group:e.id,options:t.map(i=>({id:i.id,eligible:i.eligible}))}),this.pendingChoice={groupId:e.id,options:t,byId:r};return}let o=s.find(i=>this.eligible(i));if(o){this.enterChild(o);return}this.host.tracing&&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.host.tracing&&this.emit({type:"jump",to:e,mode:t}),e==="END"){this.flowEnded=!0,this.stack=[];return}let r,s,o=this.host.bundle.scenes[e];if(o){this.enterSceneSetup(e);let a=o.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 i={sceneId:r,containerId:s,index:0};t==="call"?this.stack.push(i):this.stack=[i]}selectChild(e){let t=e.children.map(c=>({id:c.id,eligible:this.eligible(c)})),r=e.children.filter((c,d)=>t[d].eligible),s=e.options?.order??"sequential",o=e.options?.exhaust??"once",i=c=>(this.host.tracing&&this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:o}:{},children:t,picked:c?.id??null}),c);if(r.length===0)return i(null);let a=this.selectorState(e);switch(e.selector){case"branch":return i(r[0]);case"sequence":return i(s==="shuffle"?this.pickShuffle(r,o,a):s==="specificity"?this.pickSpecificity(r,o,a):this.pickSequential(r,o,a));default:return null}}pickSequential(e,t,r){let s=e.length,o=r.seq??0;return r.seq=o+1,t==="repeat"?e[o%s]:o<s?e[o]:t==="stick"?e[s-1]:null}pickShuffle(e,t,r){let s=e.length,o=t==="stick",i=()=>(o?e.slice(0,s-1):e).map(f=>f.id),a=new Set(e.map(f=>f.id));if(r.bag===void 0&&(r.bag=i()),!r.bag.some(f=>a.has(f))){if(t==="once")return null;if(o){let f=e[s-1];return r.last=f.id,f}if(r.bag=i(),r.bag.length===0)return null}let c=r.bag.filter(f=>a.has(f)),d=r.last!==void 0&&c.length>1?c.indexOf(r.last):-1,g=Math.floor(this.rng()*(d>=0?c.length-1:c.length));d>=0&&g>=d&&g++;let l=c[g];return r.bag.splice(r.bag.indexOf(l),1),r.last=l,e.find(f=>f.id===l)}pickSpecificity(e,t,r){let s=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(g=>g.id));let d=new Set(r.bag);if(s=e.filter(g=>d.has(g.id)),s.length===0)return t==="stick"&&r.last!==void 0?e.find(g=>g.id===r.last)??null:null}let o=-1,a=s.map(d=>{let g=this.specScore(d);return g>o&&(o=g),{c:d,s:g}}).filter(d=>d.s===o).map(d=>d.c),c;if(a.length===1)c=a[0];else{let d=r.last!==void 0?a.findIndex(l=>l.id===r.last):-1,g=Math.floor(this.rng()*(d>=0?a.length-1:a.length));d>=0&&g>=d&&g++,c=a[g]}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,e):0}matchedSpec(e,t,r){return Be(e,o=>{try{return et(te(o,this.context(),me))}catch(i){return this.reportError("best-match",r.id,r.condition,i),!1}},{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,r=this.host.journal,s;if(r&&(s=e.shared?r.selectors:r.flowSelectors.get(this),s||(s=new Set,r.flowSelectors.set(this,s))),r&&s&&!s.has(e.id)){s.add(e.id);let i=t.get(e.id),a=i?{...i,...i.bag?{bag:[...i.bag]}:{}}:void 0;r.undo.push(()=>{a?t.set(e.id,a):t.delete(e.id)})}let o=t.get(e.id);return o||(o={},t.set(e.id,o)),o}runEffects(e,t){for(let r of e??[]){let s;try{s=this.evalExpr(r.value);let o=this.host.tracing?this.getProperty(r.target):void 0;this.writeProperty(r.target,s,!1),this.host.tracing&&this.emit({type:"write",target:r.target,value:s,...o!==void 0?{prev:o}:{}})}catch(o){this.reportError("effect",t,r.value,o)}}}eligible(e){if(!e.condition)return!0;try{return et(this.evalExpr(e.condition))}catch(t){return this.reportError("condition",e.id,e.condition,t),!1}}reportError(e,t,r,s){let o=s instanceof Error?s.message:String(s),i=r?.src;this.host.onError({flow:this.id,kind:e,node:t,...i?{source:i}:{},message:o}),this.host.tracing&&this.emit({type:"diagnostic",kind:e,node:t,...i?{source:i}:{},message:o})}evalExpr(e){return te(this.conditionAst(e),this.context(),me)}conditionAst(e){let t=Ue.get(e);return t||(t=j(e.ast),Ue.set(e,t)),t}enter(e){let t=this.visitCounts,r=t.get(e);t.set(e,(r??0)+1);let s=this.host.sharedVisits,o=s.get(e);s.set(e,(o??0)+1),this.host.journal&&this.host.journal.undo.push(()=>{r===void 0?t.delete(e):t.set(e,r),o===void 0?s.delete(e):s.set(e,o)})}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=ge(this.rngState),t=e.next();return this.rngState=e.state(),t};beatResult(e){let t=V(this.host,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)),padAfter:this.padOf(e.id),gameData:e.gameData,...r};case"line":{let s=this.resolveString(e.id),o=!this.host.captionsOn,a=o&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=o&&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,qualifier:c?void 0:e.qualifier,qualifierName:c?void 0:this.resolveQualifierName(e.qualifier),padAfter:this.padOf(e.id),gameData:e.gameData,...r}}}}interpolate(e){return $e(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)),s=this.padOf(t.id);return t.kind==="line"?{kind:"line",text:this.captionLine(r),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction,qualifier:t.qualifier,qualifierName:this.resolveQualifierName(t.qualifier),padAfter:s}:{kind:"text",text:r,padAfter:s}}authoredPromptOf(e){return e.type==="group"?e.prompt:void 0}promptResult(e,t){let r=V(this.host,e.id),s=r&&r.length?{tags:r}:{};return t.kind==="text"?{type:"text",id:e.id,text:t.text,padAfter:this.padOf(e.id),gameData:e.gameData,...s}:{type:"line",id:e.id,text:t.text,character:t.character,characterName:t.characterName,direction:t.direction,qualifier:t.qualifier,qualifierName:t.qualifierName,padAfter:this.padOf(e.id),gameData:e.gameData,...s}}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 G(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=ye(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}promptPadOf(e){let t=this.promptBeatOf(e);return t?this.padOf(t.id):F}padOf(e){return this.host.padIndex.get(e)?.resolved??F}resolveQualifierName(e){if(e===void 0||this.host.emitIds)return;let t=Se(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.qualifierDisplay.get(e)}splitRef(e){return st(this.host,e)}newLocal(){return new N(this.host.patterLocalDecls,{pathPrefix:"@patter."})}mountLocal(){this.local=this.newLocal();let e=E.flowGlobals(this.id);this.host.registry.mountOwned(e,this.local,{owner:X}),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??[],s=this.host.journal;if(!this.sceneBags.has(e)){let o=new N(r.filter(c=>!t.has(c.name.toLowerCase())),{pathPrefix:"@scene."}),i=E.flowScene(this.id,e),a=Ye(this.host.registry,i,o,s!==null);this.registered.add(i),this.sceneBags.set(e,o),s&&s.undo.push(()=>{this.sceneBags.get(e)===o&&(this.host.registry.remove(i,a?{keep:!0}:void 0),this.registered.delete(i),this.sceneBags.delete(e))})}if(!this.host.stageBags.has(e)){let o=new N(r.filter(a=>t.has(a.name.toLowerCase())),{pathPrefix:"@scene."}),i=Ye(this.host.registry,E.stage(e),o,s!==null);this.host.stageBags.set(e,o),s&&s.undo.push(()=>{this.host.stageBags.get(e)===o&&(this.host.registry.remove(E.stage(e),i?{keep:!0}:void 0),this.host.stageBags.delete(e))})}}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(),o=t.has(s)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);if(!o)continue;let i=this.host.journal?o.get(s):void 0;i!==void 0&&this.host.journal.undo.push(()=>o.set(s,i)),o.set(s,W(r))}}};function Ke(n,e){G(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 Qe(n){return n&&Object.keys(n).length?{gameData:n}:{}}function qt(n){let e={kind:n.kind,text:n.text};return n.character!==void 0&&(e.character=n.character),n.characterName!==void 0&&(e.characterName=n.characterName),n.direction!==void 0&&(e.direction=n.direction),n.qualifier!==void 0&&(e.qualifier=n.qualifier),n.qualifierName!==void 0&&(e.qualifierName=n.qualifierName),typeof n.padAfter=="number"&&(e.padAfter=n.padAfter),e}function tt(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 rt(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,e,t,r){let s=r?JSON.stringify(t.save()):"";return n.mountOwned(e,t,{owner:X}),r&&JSON.stringify(t.save())!==s}function Xe(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default}}function Ze(n){return{...n.world?{world:n.world}:{},...n.hostScopes}}function ve(n,e,t){let r=n.qualityLadders.get(e);if(!r){r=new Map;for(let s of t()??[]){let o=s.name.toLowerCase();s.type==="quality"&&s.stages&&!r.has(o)&&r.set(o,s.stages)}n.qualityLadders.set(e,r)}return r}function nt(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default,writable:n.writable}}function Ht(n,e){let t=nt(n),r=n.writable??e;return r===void 0?t:{...t,writable:r}}function we(n,e){return n.sceneGameIdToId.get(e)??(n.bundle.scenes[e]?e:void 0)}function xe(n,e,t){return n.blockGameIdToId.get(e)?.get(t)??(n.blockIndex.get(t)?.sceneId===e?t:void 0)}function st(n,e){n.refSplitRevision!==n.registry.revision&&(n.refSplitCache.clear(),n.refSplitRevision=n.registry.revision);let t=n.refSplitCache.get(e);return t||(t=Me(e,r=>r==="scene"||n.registry.has(r)||(n.bundle.externalScopes?.includes(r)??!1)),n.refSplitCache.set(e,t)),t}function _t(n){let e={};n.shared?.patter&&(e.patter=n.shared.patter);for(let[t,r]of Object.entries(n.stageBags??{}))e[E.stage(t)]=r;for(let[t,r]of Object.entries(n.flows??{}))Object.assign(e,ot(t,r));return e}function ot(n,e){let t={};e.scopes?.patter&&(t[E.flowGlobals(n)]=e.scopes.patter);for(let[r,s]of Object.entries(e.sceneBags??{}))t[E.flowScene(n,r)]=s;return t}function Ut(n,e){let t={scopes:{},sceneBags:{}},r=E.flow(n);for(let[s,o]of Object.entries(e)){if(!s.startsWith(r))continue;let i=s.slice(r.length);i==="patter"?t.scopes.patter=o:i.startsWith("scene/")&&(t.sceneBags[$t(i.slice(6))]=o)}return t}function et(n){return typeof n=="boolean"?n:typeof n=="number"?n!==0:typeof n=="string"?n!=="":n.length>0}var Wt=(n,e)=>n.shared??e;function ke(n,e){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.default!==void 0?{default:n.default}:{},shared:Wt(n,e)}}function Jt(n){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.values?{values:[...n.values]}:{},...n.purpose?{purpose:n.purpose}:{}}}function zt(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 ce(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 i of Object.values(n.scenes)){e.scenes++;let a=C(i);t.push({gameId:a,name:i.name,blocks:i.blocks.map(c=>({gameId:C(c),name:c.name}))});for(let c of i.blocks)zt(c,e);i.sceneProps?.length&&r.push({gameId:a,properties:i.sceneProps.map(c=>ke(c,!1))})}let s=(n.scopeRegistry?.scopes??[]).map(i=>({token:i.token,writable:i.writable??!0,opaque:i.declarations===void 0,properties:(i.declarations??[]).map(a=>ke(a,!0))})),o=Object.entries(n.gameDataFields??{}).filter(([,i])=>(i?.length??0)>0).map(([i,a])=>({kind:i,fields:(a??[]).map(Jt)}));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(i=>ke(i,!0)),scene:r},gameData:o,counts:e}}function it(n,e){return n.gameDataFields?.[e]??[]}function Ee(n,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:n.find(r=>r.name===t)?.default}function at(n,e){let t={};for(let r of n){let s=Ee(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}function Ce(n){return{schema:$,save:n.saveGame()}}function De(n,e){if(!e||e.schema!==$||!e.save)throw new Error(`loadState: not a ${$} envelope`);n.loadGame(e.save)}function le(n){return JSON.stringify(Ce(n))}function pe(n,e){De(n,JSON.parse(e))}function ct(n,e){return n.getProperty(e)}function lt(n,e,t){n.setProperty(e,t)}function pt(n,e){for(let[t,r]of Object.entries(e))n.setProperty(t,r)}function Pe(n){let e={};for(let t of dt(n)){let r=t.pathPrefix??t.bag.pathPrefix;for(let[s,o]of Object.entries(t.bag.save()))e[`${r}${s}`]=o}return Object.assign(e,ut(n)),e}function dt(n){return[...n.listBags(),...n.flows().flatMap(e=>e.listBags())]}function Kt(n){switch(n.type){case"line":return`line ${n.character??"?"}: ${JSON.stringify(n.text)}${Ie(n.gameData)}`;case"text":return`text: ${JSON.stringify(n.text)}${Ie(n.gameData)}`;case"gameEvent":return`game event ${n.id}${Ie(n.gameData)}`;case"choice":return`choice (${n.options.length} option${n.options.length===1?"":"s"})`;case"end":return"end"}}var Ie=n=>n?` gameData=${JSON.stringify(n)}`:"";function ut(n){let e={};for(let[t,r]of Object.entries(n.getVisitCounts()))e[`visit:${t}`]=r;for(let t of n.flows())for(let[r,s]of Object.entries(t.getVisitCounts()))e[`${t.id}/visit:${r}`]=s;return e}function gt(n,e={}){let t=e.label?`[${e.label}] `:"",r=fe({mounts:()=>dt(n),extra:()=>ut(n)},{sink:e.sink,label:t});return{snapshot:()=>Pe(n),capture:()=>r.capture(),dispose:()=>r.dispose(),logStep(s){(e.sink??(o=>console.log(o)))(`${t}${Kt(s)}`)}}}function ft(n){let e=n.url??"ws://127.0.0.1:4471",t=n.WebSocket??globalThis.WebSocket,r=new Set,s=[],o=null,i=!1,a=n.build,c=()=>{if(!(!o||o.readyState!==1)){for(let l of s)try{o.send(l)}catch{}s=[]}},d=l=>{i||!o||o.readyState>1||(s.push(JSON.stringify(l)),c())};if(!t)return{flowOpened(){},observe(){},flowClosed(){},setBuild(){},close(){i=!0},state:"closed",build:a,url:e};let g=()=>{let l=JSON.stringify({t:"hello",v:1,build:a,project:n.project,flows:[...r]});try{o?.send(l)}catch{}};try{o=new t(e),o.addEventListener("open",()=>{g(),c()}),o.addEventListener("message",l=>{if(!(!n.onBundle||typeof l.data!="string"))try{let f=JSON.parse(l.data);f.t==="bundle"&&typeof f.build=="string"&&typeof f.data=="string"&&n.onBundle({build:f.build,data:f.data})}catch{}}),o.addEventListener("error",()=>{}),o.addEventListener("close",()=>{o=null,s=[]})}catch{o=null}return{flowOpened(l){r.add(l),d({t:"flowOpen",flow:l})},flowClosed(l){r.delete(l),d({t:"flowClose",flow:l})},observe(l,f,h,m,u){r.has(l)||(r.add(l),d({t:"flowOpen",flow:l})),d({t:"frame",flow:l,sceneId:f,beatId:h,type:m,choiceId:u})},setBuild(l){i||l===a||(a=l,o&&o.readyState===1&&g())},close(){i=!0,s=[];try{o?.close()}catch{}o=null},get state(){return i||!o?"closed":o.readyState===1?"connected":"connecting"},get build(){return a},url:e}}function ht(n,e,t){let r=JSON.parse(t);return e.content.structureHash!==void 0&&e.content.structureHash===r.content.structureHash?(n.replaceStrings(r),{engine:n,bundle:r,kind:"text"}):{engine:n.hotSwap(r),bundle:r,kind:"structure"}}var mt="pp-inspector-style",Qt=`
1
+ "use strict";var Patterplay=(()=>{var me=Object.defineProperty;var Ot=Object.getOwnPropertyDescriptor;var Rt=Object.getOwnPropertyNames;var Bt=Object.prototype.hasOwnProperty;var At=(n,e)=>{for(var t in e)me(n,t,{get:e[t],enumerable:!0})},Nt=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Rt(e))!Bt.call(n,s)&&s!==t&&me(n,s,{get:()=>e[s],enumerable:!(r=Ot(e,s))||r.enumerable});return n};var Lt=n=>Nt(me({},"__esModule",{value:!0}),n);var lr={};At(lr,{Checkpoint:()=>re,DEFAULT_PAD_AFTER:()=>T,Engine:()=>ue,Flow:()=>G,SAVE_SCHEMA:()=>H,applyLiveBundle:()=>xt,buildTagIndex:()=>de,createAudioResolver:()=>Pt,createBundleInspector:()=>Dt,createDebugLink:()=>wt,createPropertyInspector:()=>Et,createStateLogger:()=>vt,describeBundle:()=>ge,deserializeState:()=>he,diffState:()=>J,effectiveGameData:()=>ft,gameDataFields:()=>gt,gameDataValue:()=>Pe,getProperty:()=>ht,loadState:()=>Oe,saveState:()=>Ie,serializeState:()=>fe,setProperties:()=>yt,setProperty:()=>mt,snapshotState:()=>Be});function U(n,e){return n!==void 0&&Object.prototype.hasOwnProperty.call(n,e)?n[e]:void 0}function V(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:V(n[2])};case"bin":return{kind:"binary",op:n[1],left:V(n[2]),right:V(n[3])};case"call":{let e=n.slice(2).map(V);return{kind:"call",name:n[1],args:e}}case"fd":return{kind:"flagdelta",sign:n[1],name:n[2]}}}var S=class extends Error{constructor(e){super(e),this.name="EvalError"}};function se(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=U(e.scopes,i.scope);if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):U(o,i.name);if(a===void 0){if(r.get(i.scope)==="throw")throw new S(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{if(i.name==="advance"&&!U(t.functions,i.name)){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new S(`advance() takes exactly 1 argument, got ${i.args.length}`);let l=ye(a,e);if(l===void 0)throw new S("advance() needs a quality reference (@scope.name of a quality property)");let p=A(s(a),l,"advance");return l[Math.min(p+1,l.length-1)]}let o=U(t.functions,i.name);if(!o)throw new S(`unknown function '${i.name}'`);return o.eval(i.args,{evaluate:s,ctx:e})}case"flagdelta":throw new S("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 S(`'not' requires a boolean operand, got ${typeof a}`);return!a}let o=s(i.operand);if(typeof o!="number")throw new S(`unary '-' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let c=s(i.left);if(typeof c!="boolean")throw new S(`'and' requires boolean operands, left is ${typeof c}`);if(!c)return!1;let f=s(i.right);if(typeof f!="boolean")throw new S(`'and' requires boolean operands, right is ${typeof f}`);return f}if(i.op==="or"){let c=s(i.left);if(typeof c!="boolean")throw new S(`'or' requires boolean operands, left is ${typeof c}`);if(c)return!0;let f=s(i.right);if(typeof f!="boolean")throw new S(`'or' requires boolean operands, right is ${typeof f}`);return f}let o=s(i.left),a=s(i.right),l=ye(i.left,e),p=ye(i.right,e),u=l??p;if(u!==void 0){if(l&&p&&!Ft(l,p)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new S(`'${i.op}' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return A(o,u,">")>A(a,u,">");case">=":return A(o,u,">=")>=A(a,u,">=");case"<":return A(o,u,"<")<A(a,u,"<");case"<=":return A(o,u,"<=")<=A(a,u,"<=");case"+":case"-":case"*":case"/":throw new S(`'${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 Ne(o,a);case"!=":return!Ne(o,a);case">":return M(o,a,">"),o>a;case">=":return M(o,a,">="),o>=a;case"<":return M(o,a,"<"),o<a;case"<=":return M(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new S(`'+' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return M(o,a,"-"),o-a;case"*":return M(o,a,"*"),o*a;case"/":if(M(o,a,"/"),a===0)throw new S("division by zero");return o/a}}}};return s(n)}function Ne(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 M(n,e,t){if(typeof n!="number"||typeof e!="number")throw new S(`'${t}' requires numeric operands, got ${typeof n} and ${typeof e}`)}function ye(n,e){if(!(n.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(n.scope,n.name)}function A(n,e,t){if(typeof n!="string")throw new S(`'${t}' on a quality compares stages, got ${typeof n}`);let r=e.indexOf(n);if(r<0)throw new S(`"${n}" is not a stage of this quality (stages: ${e.join(", ")})`);return r}var Ft=(n,e)=>n.length===e.length&&n.every((t,r)=>t===e[r]);function W(n){if(Number.isNaN(n)||!Number.isFinite(n))return 0;let e=Math.trunc(n)%4294967296;return e<0?e+4294967296:e}function Se(n){let e=W(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 Tt={name:"check_flags",count:n=>Math.max(1,n.args.length-1)},jt=[Tt];function Le(n,e,t){let r=t?.countingCalls??jt;return ie(n,t?.want??!0,e,r)}function ie(n,e,t,r){if(n.kind==="binary"&&(n.op==="and"||n.op==="or")){let s=ie(n.left,e,t,r),i=ie(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 ie(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}function J(n,e){let t=[],r=new Set([...Object.keys(n),...Object.keys(e)]);for(let s of[...r].sort()){let i=n[s],o=e[s];JSON.stringify(i)!==JSON.stringify(o)&&t.push({path:s,from:i,to:o})}return t}var Fe=n=>n===void 0?"<unset>":JSON.stringify(n),Te=n=>n.pathPrefix??n.bag.pathPrefix;function be(n,e={}){let t=e.sink??(c=>console.log(c)),r=e.label??"",s=c=>{t(`${r}${c.path}: ${Fe(c.from)} -> ${Fe(c.to)}`)},i=()=>{let c={};for(let f of n.mounts()){let g=Te(f);for(let[m,d]of Object.entries(f.bag.values))c[g+m]=d}return Object.assign(c,n.extra?.()??{}),structuredClone(c)},o=i(),a=[],l=[],p=(c,f)=>f.onAudit(g=>{let m=structuredClone({path:c+g.name,from:g.prev,to:g.next});s(m),a.push(m),o[m.path]=structuredClone(g.next)}),u=()=>{let c=n.mounts();if(!(l.length===c.length&&c.every((g,m)=>l[m].bag===g.bag))){for(let g of l)g.off();l=c.map(g=>({bag:g.bag,off:p(Te(g),g.bag)}))}};return u(),{snapshot:i,capture(){let c=i(),f=J(o,c);for(let m of f)s(m);let g=[...a,...f];return a=[],o=c,u(),g},dispose(){for(let c of l)c.off();l=[],a=[]}}}var F=class n{values=Object.create(null);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??K(t))}}get(e){return this.values[this.norm(e)]}normalise(e){return this.norm(e)}writable(e){return this.decls.get(this.norm(e))?.writable!==!1}set(e,t,r){let s=this.norm(e);if(!r?.host&&!this.writable(s))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])=>Ve(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 Ve(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??K(n),...n.values!==void 0?{values:n.values}:{},...n.stages!==void 0?{stages:n.stages}:{},writable:t??n.writable??!0}}var Vt=n=>n.toLowerCase(),ve=1,oe=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 F(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??Vt,a=new Map;for(let l of r)a.set(o(l.name),l);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"){if(!s?.host&&!i.bag.writable(t))throw new Error(`'@${e}.${t}' is read-only`);i.bag.set(t,r,s?.host?{host:!0}:void 0);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,...Ve(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 l=r.get(o);return l?i.get(o)?.get(Mt(l)(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 je(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=je(s);if(i.length===0)continue;let o=new Map;for(let[a,l]of i)o.set(a,{type:l.type,enumValues:l.values,...l.stages!==void 0?{stages:l.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:ve,scopes:this.save()}}loadFragment(e){if(e.version!==ve)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${ve})`);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 je(n){return n.kind==="foreign"?[...n.decls.entries()]:n.bag.declarations().map(e=>[n.bag.normalise(e.name),e])}function Mt(n){return n.kind==="foreign"?n.norm:e=>n.bag.normalise(e)}function K(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 Me=[{token:"patter",engine:"Patterplay",means:"Patter's shared globals"},{token:"story",engine:"Storylet Engine",means:"the Storylet Engine's shared @story properties"}];function z(n){return n.ctx.host??{}}var we={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(n,e){if(n.length!==2)throw new S("random(a, b) requires exactly 2 arguments");let t=z(e).nextRandom;if(!t)throw new S("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 S("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(s))throw new S("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:Ge("check_flags"),eval(n,e){let t=$e(n[0],e,"check_flags");for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new S("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:Ge("set_flags"),eval(n,e){let t=[...$e(n[0],e,"set_flags")];for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new S("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:le("visits"),eval:(n,e)=>z(e).visits?.(ae(n,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:le("seen"),eval:(n,e)=>(z(e).visits?.(ae(n,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:le("patter_visits"),eval:(n,e)=>z(e).patterVisits?.(ae(n,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:le("patter_seen"),eval:(n,e)=>(z(e).patterVisits?.(ae(n,e,"patter_seen"))??0)>0}}},Ir=Me.map(n=>n.token).filter(n=>n!=="patter"&&n!=="scene");function qe(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 ae(n,e,t){let r=e.evaluate(n[0]);if(typeof r!="string")throw new S(`${t}(id) requires a string node id`);return r}function le(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 $e(n,e,t){if(!n)throw new S(`${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 S(`${t}() first argument must be a flags property`)}function Ge(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 $t=/^@[A-Za-z0-9_.]+$/;function*Gt(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:$t.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 qt(n){return Array.isArray(n)?n.join(", "):typeof n=="boolean"?n?"true":"false":String(n)}function Ht(n){return n===" "||n===" "||n===`
2
+ `||n==="\r"||n==="\f"||n==="\v"}function _t(n){let e="",t=!1;for(let r of n){if(Ht(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function He(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?_t(r):n}function _e(n,e){if(n.indexOf("{")<0)return n;let t="";for(let r of Gt(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?"":qt(s)}return t}function q(n,e){for(let t of n){e(t);let r=t.children;r&&q(r,e)}}function Ut(n){return n.toLowerCase().replace(/['’]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function O(n){let e=n.gameId?.trim();return e||Ut(n.name)}var T=.6;function ce(n){return`cast:${n}`}function pe(n){return`qualifier:${n}`}function Ue(n,e){return`speaker:${n}:${e}`}var We="speaker:pattern",Je="{name} ({qualifier})";function Ke(n,e,t){return n.split("{name}").map(r=>r.split("{qualifier}").join(t)).join(e)}var xe={open:"[",close:"]"},ze="SFX",H="patter/save@0",Q=3;function Y(n){let e=new Set,t=[];for(let r of n)e.has(r)||(e.add(r),t.push(r));return t}function de(n){let e=new Map,t=(r,s)=>{let i=Y([...s,...r.tags??[]]);if(e.set(r.id,i),r.type==="group"&&r.prompt&&e.set(r.prompt.id,Y([...i,...r.prompt.tags??[]])),r.type==="group")for(let o of r.children)t(o,i);else for(let o of r.beats??[])e.set(o.id,Y([...i,...o.tags??[]]))};for(let r of Object.values(n.scenes)){let s=Y(r.tags??[]);e.set(r.id,s);for(let i of r.blocks){let o=Y([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var Qe=n=>n.kind==="line"||n.kind==="text",X=n=>typeof n=="number"&&Number.isFinite(n)?n:void 0;function Ye(n){let e=new Map,t=(i,o,a)=>{let l=i.kind==="gameEvent"?void 0:X(i.padAfter),p=l??o;a&&p<0&&(p=0),e.set(i.id,l!==void 0?{own:l,resolved:p}:{resolved:p})},r=(i,o)=>{let a=X(i.padAfterDefault)??o;if(i.type==="group"){i.prompt&&t(i.prompt,a,!1);for(let u of i.children)r(u,a);return}let l=i.beats??[],p=-1;l.forEach((u,c)=>{Qe(u)&&(p=c)}),l.forEach((u,c)=>{Qe(u)&&t(u,a,c===p)})},s=X(n.padAfterDefault)??T;for(let i of Object.values(n.scenes)){let o=X(i.padAfterDefault)??s;for(let a of i.blocks){let l=X(a.padAfterDefault)??o;for(let p of a.children)r(p,l)}}return e}var Xe=new WeakMap,Ze=new WeakMap;function Wt(n){let e=Ze.get(n);return e||(e=de(n),Ze.set(n,e)),e}var et=new WeakMap;function Jt(n){let e=et.get(n);return e||(e=Ye(n),et.set(n,e)),e}function $(n,e){return n.tagIndex.get(e)?.slice()}var te="Patter",Z=n=>n.replace(/%/g,"%25").replace(/\//g,"%2F"),Kt=n=>n.replace(/%2F/g,"/").replace(/%25/g,"%"),tt=Symbol("ownsRegistry"),P={stage:n=>`patter/scene/${Z(n)}`,flow:n=>`patter/flow/${Z(n)}/`,flowGlobals:n=>`patter/flow/${Z(n)}/patter`,flowScene:(n,e)=>`patter/flow/${Z(n)}/scene/${Z(e)}`},re=class{constructor(e){this.journal=e}journal},ue=class n{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineSeq=0;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,l=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let p=new Map;for(let y of e.cast??[])y.displayName&&p.set(y.name,y.displayName);let u=new Map;for(let y of e.qualifiers??[])y?.gameId&&u.set(y.gameId,y.name);let c=new Map;for(let y of e.cast??[])for(let[v,D]of Object.entries(y.qualifierLabels??{}))typeof D=="string"&&c.set(`${y.name}\0${v}`,D);let f=e.speakerPattern??Je;this.defaultSeed=(t.seed??2654435769)>>>0;let g=new Map,m=new Map,d=new Map;for(let[y,v]of Object.entries(e.scenes)){this.sceneGameIdToId.set(O(v),y);let D=new Map;for(let k of v.blocks)m.set(k.id,{sceneId:y}),d.set(k.id,k),D.set(O(k),k.id),q(k.children,ne=>g.set(ne.id,ne));this.blockGameIdToId.set(y,D)}let w=e.properties??[],E=w.filter(y=>y.shared??!0).map(it),C=w.filter(y=>!(y.shared??!0)).map(it),B=new Set(E.map(y=>y.name.toLowerCase())),x=t.registry??new oe,N=!t.registry||t[tt]===!0,L=new F(E,{pathPrefix:"@patter."}),j=[],h=[];try{x.mountOwned("patter",L,{owner:te}),h.push("patter");let y=new Set;for(let[v,D]of Object.entries(ot(t))){let k=e.scopeRegistry?.scopes.find(It=>It.token===v),ne=(k?.declarations??[]).map(pt);x.defineForeign(v,D,ne,{writable:k?.writable??!0,owner:te}),h.push(v),y.add(v)}for(let v of N?e.scopeRegistry?.scopes??[]:[]){if(y.has(v.token)||x.has(v.token))continue;let D=(v.declarations??[]).map(k=>Qt(k,v.writable));x.defineOwned(v.token,D,{owner:te}),h.push(v.token),j.push(v.token)}}catch(y){for(let v of h)x.remove(v,{keep:!0});throw y}let I=new Map;for(let[y,v]of Object.entries(e.scenes)){let D=new Set((v.sceneProps??[]).filter(k=>k.shared??!1).map(k=>k.name.toLowerCase()));I.set(y,D)}this.host={logEnabled:t.log??!1,tracing:t.log??!1,emitEngine:(y,v,D)=>this.emitEngine(y,v,D),bundle:e,emitIds:l,strings:i,defaultStrings:o,castDisplay:p,qualifierDisplay:u,speakerLabels:c,speakerPattern:f,nodeIndex:g,blockIndex:m,blockById:d,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:Wt(e),padIndex:Jt(e),registry:x,ownsRegistry:N,patterBag:L,hostScopes:j,patterSharedDecls:E,patterLocalDecls:C,patterSharedNames:B,sceneSharedNames:I,sharedVisits:new Map,qualityLadders:new Map,sharedSelectors:new Map,stageBags:new Map,journal:null,customRng:t.rng,onDryChoice:t.onDryChoice,onError:t.onError??(y=>console.warn(`Patterplay: ${y.kind} on ${y.node} in flow '${y.flow}' failed, played through: ${y.message}`)),replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??xe).open,captionClose:(e.closedCaptions??xe).close,captionCharacter:e.closedCaptions?.character||ze,refSplitCache:new Map,refSplitRevision:x.revision}}get locale(){return this.currentLocale}get isSourceDebug(){return this.sourceDebug}get buildId(){return this.host.bundle.content?.hash??""}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){this.refuseInCheckpoint("hotSwap");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,[tt]: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,l]of Object.entries(t.flows)){let p=l.cursor.currentSceneId;try{o.openFlow(a,p!==null?{scene:p}:{})}catch{}}return r(o)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){this.assertExternalScopes();let{sceneId:r,blockId:s}=this.resolveOpenAddress(t.scene,t.block),i=this.flowsById.get(e),o=this.host.journal;if(o&&i&&!i.isClosed)throw new Error(`openFlow would replace the open flow '${e}', which can't be undone while a checkpoint is open`);i?.close();let a=new G(e,this.host,t.seed??this.defaultSeed);return o&&(o.flows.add(a),o.opened.add(a),o.undo.push(()=>{a.close(),i?this.flowsById.set(e,i):this.flowsById.delete(e)})),this.flowsById.set(e,a),a.begin(r,s),a}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`)}resolveOpenAddress(e,t){if(e!==void 0){let r=Ee(this.host,e);if(r===void 0)throw new Error(`unknown scene: ${e}`);if(t===void 0)return{sceneId:r};let s=Ce(this.host,r,t);if(s===void 0)throw new Error(`unknown block: ${t}`);return{sceneId:r,blockId:s}}if(t!==void 0){if(!this.host.blockIndex.has(t))throw new Error(`unknown block: ${t}`);return{blockId:t}}if(Object.keys(this.host.bundle.scenes).length===0)throw new Error("no scenes in bundle");return{}}resolveSceneRef(e){if(e!=null)return Ee(this.host,e)??e}resolveBlockRef(e,t){if(t!=null)return e==null?t:Ce(this.host,e,t)}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?O(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?O(t):void 0}tagsForBeat(e){return $(this.host,e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?$(this.host,t):void 0)??[]}tagsForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t);return(s!=null?$(this.host,s):void 0)??[]}gameDataForScene(e){let t=this.resolveSceneRef(e);return{...(t!=null?this.host.bundle.scenes[t]:void 0)?.gameData}}gameDataForBlock(e,t){let r=this.resolveBlockRef(this.resolveSceneRef(e),t);return{...(r!=null?this.host.blockById.get(r):void 0)?.gameData}}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)rt(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 rt(i.children,o),[...o]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...O(e)?{gameId:O(e)}:{},name:e.name,...nt(e.gameData),...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...O(t)?{gameId:O(t)}:{},name:t.name,...nt(t.gameData),...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)q(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,e.id),r={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){r.character=e.character;let i=this.host.defaultStrings[ce(e.character)]??this.host.castDisplay.get(e.character);i!==void 0&&(r.characterName=i)}if(e.direction!==void 0&&(r.direction=e.direction),e.qualifier!==void 0){r.qualifier=e.qualifier;let i=this.host.defaultStrings[pe(e.qualifier)]??this.host.qualifierDisplay.get(e.qualifier);i!==void 0&&(r.qualifierName=i)}let s=ee(this.host,e.character,e.qualifier,!0);s!==void 0&&(r.speakerLabel=s)}if(e.kind==="line"||e.kind==="text"){let s=this.host.padIndex.get(e.id);r.padAfter=s?.resolved??T,s?.own!==void 0&&(r.ownPadAfter=s.own);let i=this.host.defaultStrings[e.id];i!==void 0&&(r.text=i)}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,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}checkpoint(){if(this.host.journal)throw new Error("a checkpoint is already open: roll it back or commit it first");let e={undo:[],flows:new Set,opened:new Set,selectors:new Set,flowSelectors:new Map};return this.host.journal=e,new re(e)}rollback(e){this.endCheckpoint(e);let t=e.journal.undo;for(let r=t.length-1;r>=0;r--)t[r]();n.forget(e.journal)}commit(e){this.endCheckpoint(e),n.forget(e.journal)}get inCheckpoint(){return this.host.journal!==null}endCheckpoint(e){if(this.host.journal!==e.journal)throw new Error("that checkpoint is not the open one");this.host.journal=null}static forget(e){e.undo=[],e.flows.clear(),e.opened.clear(),e.selectors.clear(),e.flowSelectors.clear()}refuseInCheckpoint(e){if(this.host.journal)throw new Error(`${e} can't be undone, so it isn't allowed while a checkpoint is open`)}captureFlow(e){let t=this.flowsById.get(e);if(!t)throw new Error(`no open flow '${e}' to capture`);return{version:Q,...t.snapshot(),...Xt(e,this.host.registry.save())}}restoreFlow(e,t){this.refuseInCheckpoint("restoreFlow");let r=t.version;if(r!==2&&r!==Q)throw new Error(`unsupported flow state version: ${String(r)}`);let s=t.cursor;if(typeof s!="object"||s===null)throw new Error("malformed flow state: no cursor");if(this.flowsById.has(e))throw new Error(`a flow '${e}' is already open; close it before restoring another under that id`);this.assertExternalScopes();let i=P.flow(e);this.host.registry.discardParked(i),this.host.registry.load(ut(e,t),{keepParked:!0});let o=new G(e,this.host,this.defaultSeed);try{o.restore(t)}catch(a){throw o.close(),this.host.registry.discardParked(i),a}return this.flowsById.set(e,o),o}closeFlow(e){this.refuseInCheckpoint("closeFlow"),this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){this.refuseInCheckpoint("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(P.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(P.stage(r),{keep:e});this.host.stageBags.clear();for(let r of["patter",...this.host.hostScopes])t.has(r)&&t.remove(r,{keep:e});for(let r of Object.keys(ot(this.creationOptions)))t.has(r)&&t.remove(r)}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),i=this.host.journal?this.host.registry.get(r,s):void 0;this.host.registry.set(r,s,t,{host:!0}),this.host.journal&&i!==void 0&&this.host.journal.undo.push(()=>this.host.registry.set(r,s,i,{host:!0}))}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),this.host.tracing=!0,()=>{this.engineTraceHandlers.delete(e),this.host.tracing=this.host.logEnabled||this.engineTraceHandlers.size>0}}emitEngine(e,t,r){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineSeq++,...r?{scene:r}:{}})}getVisitCounts(){return Object.fromEntries(this.host.sharedVisits)}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:K(e),writable:e.writable??!0}))}splitShared(e){let t=dt(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:Q,...this.host.ownsRegistry?{registry:this.host.registry.save()}:{},sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:lt(this.host.sharedSelectors),flows:e}}loadGame(e){this.refuseInCheckpoint("loadGame");let t=e.version;if(t!==2&&t!==Q)throw new Error(`unsupported save version: ${String(t)}`);let r=e.flows;if(typeof r!="object"||r===null||Array.isArray(r))throw new Error("malformed save: no flows");this.assertExternalScopes();let s=this.host.registry;for(let[o,a]of this.flowsById)a.releaseBags(o in e.flows),a.close();this.flowsById.clear();for(let o of this.host.stageBags.keys())s.remove(P.stage(o),{keep:!0});this.host.stageBags.clear();let i=e.version===2?Yt(e):e.registry;i&&(this.host.ownsRegistry?s.load(i):s.load(i,{keepParked:!0})),this.host.sharedVisits.clear();for(let[o,a]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(o,a);this.host.sharedSelectors.clear();for(let[o,a]of ct(e.sharedSelectors))this.host.sharedSelectors.set(o,a);for(let[o,a]of Object.entries(e.flows)){let l=new G(o,this.host,this.defaultSeed);l.restore(a),this.flowsById.set(o,l)}}},G=class{id;host;local;registered=new Set;rngState;started=!1;flowEnded=!1;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPrompt=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=W(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();if(e==="patter")return ke(this.host,"patter",()=>[...this.host.patterSharedDecls,...this.host.patterLocalDecls]).get(r);if(e==="scene"){let s=this.currentSceneId;return s==null?void 0:ke(this.host,`scene/${s}`,()=>this.host.bundle.scenes[s]?.sceneProps).get(r)}return this.registryQualities?.(e,t)??ke(this.host,`host/${e}`,()=>this.host.bundle.scopeRegistry?.scopes.find(s=>s.token===e)?.declarations).get(r)}begin(e,t){if(this.host.journal&&!this.host.journal.opened.has(this))throw new Error("a flow can't be started or reset while a checkpoint is open");if(this.releaseBags(!1),this.host.registry.discardParked(P.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.clearPending(),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.begin(e,t)}start(e,t){this.reset(e,t)}goto(e,t){if(this.closed)return!1;if(this.touch(),e==="END")return this.started=!0,this.clearPending(),this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],!0;let r=Ee(this.host,e);if(r===void 0)return!1;let s;return t!==void 0&&(s=Ce(this.host,r,t),s===void 0)?!1:this.started?(this.clearPending(),this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.enterTarget(s??r,"jump"),this.settle(),!0):(this.begin(r,s),!0)}close(){this.releaseBags(!1),this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.clearPending()}clearPending(){this.pendingChoice=null,this.pendingPrompt=null,this.pendingPromptOwnerId=null}touch(){let e=this.host.journal;if(!e||e.flows.has(this))return;e.flows.add(this);let{rngState:t,started:r,flowEnded:s,currentSceneId:i,activeSnippet:o,beatIndex:a,pendingChoice:l,pendingPrompt:p,pendingPromptOwnerId:u}=this,c=this.stack.map(f=>({...f}));e.undo.push(()=>{Object.assign(this,{rngState:t,started:r,flowEnded:s,currentSceneId:i,activeSnippet:o,beatIndex:a,pendingChoice:l,pendingPrompt:p,pendingPromptOwnerId:u,stack:c})})}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.touch(),this.pendingPrompt){let e=this.pendingPrompt;return this.pendingPrompt=null,this.pendingPromptOwnerId=null,e.shown?this.promptResult(e.beat,e.shown):this.beatResult(e.beat)}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,this.activeSnippet.id);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.tracing&&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}:{}})}getVisitCounts(){return Object.fromEntries(this.visitCounts)}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(o=>o.id===e);if(!r)throw new Error(`unknown choice option: ${e}`);if(!r.eligible)throw new Error(`choice option is not eligible: ${e}`);this.touch();let s=t.byId.get(e);this.host.tracing&&this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null;let i=this.host.replayPromptOnChoose?this.authoredPromptOf(s):void 0;this.pendingPrompt=i&&r.prompt?{beat:i,shown:{...r.prompt}}:null,this.pendingPromptOwnerId=this.pendingPrompt?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),o=this.host.journal;if(s==="patter"){if(o){let a=this.host.patterSharedNames.has(i),l=a?this.host.patterBag.get(i):this.local.get(i),p=this.local;l!==void 0&&o.undo.push(a?()=>this.host.registry.set("patter",i,l):()=>p.set(i,l))}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`);if(o){let a=this.sceneBagFor(this.currentSceneId,i),l=a?.get(i);a&&l!==void 0&&o.undo.push(()=>a.set(i,l))}this.sceneResolver.set(i,t)}else{let a=o?this.host.registry.get(s,i):void 0;this.host.registry.set(s,i,t,r?{host:!0}:void 0),o&&a!==void 0&&o.undo.push(()=>this.host.registry.set(s,i,a,{host:!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,...this.pendingPrompt?.shown?{pendingPrompt:zt(this.pendingPrompt.shown)}:{},selectors:lt(this.selectors)}}}restore(e){if(this.host.journal)throw new Error("a flow can't be restored while a checkpoint is open");this.restoreCursor(e),this.releaseBags(!0),this.mountLocal();for(let t of new Set([this.currentSceneId,...this.stack.map(r=>r.sceneId)]))t!==null&&this.host.bundle.scenes[t]&&this.ensureSceneBags(t)}restoreCursor(e){this.rngState=W(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.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=ct(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);if(!o)continue;r.set(i.id,o);let{prompt:a,...l}=i,p=a?.kind==="line"&&a.speakerLabel===void 0?ee(this.host,a.character,a.qualifier):void 0;s.push({...l,...a?{prompt:{...a,padAfter:a.padAfter??this.promptPadOf(o),...p!==void 0?{speakerLabel:p}:{}}}:{}})}s.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:s,byId:r})}if(this.pendingPrompt=null,this.pendingPromptOwnerId=t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let r=this.host.nodeIndex.get(this.pendingPromptOwnerId),s=r?this.authoredPromptOf(r):void 0,i=t.pendingPrompt,o=i?.kind==="line"&&i.speakerLabel===void 0?ee(this.host,i.character,i.qualifier):void 0;s?this.pendingPrompt={beat:s,...i?{shown:{...i,padAfter:i.padAfter??this.padOf(s.id),...o!==void 0?{speakerLabel:o}:{}}}:{}}: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,t.id)}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,e.id),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),l=o.secretUntilEligible===!0;!a&&l||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.some(o=>o.eligible)){this.host.tracing&&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.host.tracing&&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.host.tracing&&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(l=>({id:l.id,eligible:this.eligible(l)})),r=e.children.filter((l,p)=>t[p].eligible),s=e.options?.order??"sequential",i=e.options?.exhaust??"once",o=l=>(this.host.tracing&&this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:i}:{},children:t,picked:l?.id??null}),l);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(f=>f.id),a=new Set(e.map(f=>f.id));if(r.bag===void 0&&(r.bag=o()),!r.bag.some(f=>a.has(f))){if(t==="once")return null;if(i){let f=e[s-1];return r.last=f.id,f}if(r.bag=o(),r.bag.length===0)return null}let l=r.bag.filter(f=>a.has(f)),p=r.last!==void 0&&l.length>1?l.indexOf(r.last):-1,u=Math.floor(this.rng()*(p>=0?l.length-1:l.length));p>=0&&u>=p&&u++;let c=l[u];return r.bag.splice(r.bag.indexOf(c),1),r.last=c,e.find(f=>f.id===c)}pickSpecificity(e,t,r){let s=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(u=>u.id));let p=new Set(r.bag);if(s=e.filter(u=>p.has(u.id)),s.length===0)return t==="stick"&&r.last!==void 0?e.find(u=>u.id===r.last)??null:null}let i=-1,a=s.map(p=>{let u=this.specScore(p);return u>i&&(i=u),{c:p,s:u}}).filter(p=>p.s===i).map(p=>p.c),l;if(a.length===1)l=a[0];else{let p=r.last!==void 0?a.findIndex(c=>c.id===r.last):-1,u=Math.floor(this.rng()*(p>=0?a.length-1:a.length));p>=0&&u>=p&&u++,l=a[u]}return t!=="repeat"&&(r.bag=r.bag.filter(p=>p!==l.id)),r.last=l.id,l}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0,e):0}matchedSpec(e,t,r){return Le(e,i=>{try{return at(se(i,this.context(),we))}catch(o){return this.reportError("best-match",r.id,r.condition,o),!1}},{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,r=this.host.journal,s;if(r&&(s=e.shared?r.selectors:r.flowSelectors.get(this),s||(s=new Set,r.flowSelectors.set(this,s))),r&&s&&!s.has(e.id)){s.add(e.id);let o=t.get(e.id),a=o?{...o,...o.bag?{bag:[...o.bag]}:{}}:void 0;r.undo.push(()=>{a?t.set(e.id,a):t.delete(e.id)})}let i=t.get(e.id);return i||(i={},t.set(e.id,i)),i}runEffects(e,t){for(let r of e??[]){let s;try{s=this.evalExpr(r.value);let i=this.host.tracing?this.getProperty(r.target):void 0;this.writeProperty(r.target,s,!1),this.host.tracing&&this.emit({type:"write",target:r.target,value:s,...i!==void 0?{prev:i}:{}})}catch(i){this.reportError("effect",t,r.value,i)}}}eligible(e){if(!e.condition)return!0;try{return at(this.evalExpr(e.condition))}catch(t){return this.reportError("condition",e.id,e.condition,t),!1}}reportError(e,t,r,s){let i=s instanceof Error?s.message:String(s),o=r?.src;this.host.onError({flow:this.id,kind:e,node:t,...o?{source:o}:{},message:i}),this.host.tracing&&this.emit({type:"diagnostic",kind:e,node:t,...o?{source:o}:{},message:i})}evalExpr(e){return se(this.conditionAst(e),this.context(),we)}conditionAst(e){let t=Xe.get(e);return t||(t=V(e.ast),Xe.set(e,t)),t}enter(e){let t=this.visitCounts,r=t.get(e);t.set(e,(r??0)+1);let s=this.host.sharedVisits,i=s.get(e);s.set(e,(i??0)+1),this.host.journal&&this.host.journal.undo.push(()=>{r===void 0?t.delete(e):t.set(e,r),i===void 0?s.delete(e):s.set(e,i)})}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=Se(this.rngState),t=e.next();return this.rngState=e.state(),t};beatResult(e){let t=$(this.host,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)),padAfter:this.padOf(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)),l=i&&a.length===0;return{type:"line",id:e.id,text:a,character:l?void 0:e.character,characterName:l?void 0:this.resolveCharacterName(e.character),direction:l?void 0:e.direction,qualifier:l?void 0:e.qualifier,qualifierName:l?void 0:this.resolveQualifierName(e.qualifier),speakerLabel:l?void 0:ee(this.host,e.character,e.qualifier),padAfter:this.padOf(e.id),gameData:e.gameData,...r}}}}interpolate(e){return _e(e,t=>this.getProperty(t))}stripCaptions(e){return He(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)),s=this.padOf(t.id);return t.kind==="line"?{kind:"line",text:this.captionLine(r),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction,qualifier:t.qualifier,qualifierName:this.resolveQualifierName(t.qualifier),speakerLabel:ee(this.host,t.character,t.qualifier),padAfter:s}:{kind:"text",text:r,padAfter:s}}authoredPromptOf(e){return e.type==="group"?e.prompt:void 0}promptResult(e,t){let r=$(this.host,e.id),s=r&&r.length?{tags:r}:{};return t.kind==="text"?{type:"text",id:e.id,text:t.text,padAfter:this.padOf(e.id),gameData:e.gameData,...s}:{type:"line",id:e.id,text:t.text,character:t.character,characterName:t.characterName,direction:t.direction,qualifier:t.qualifier,qualifierName:t.qualifierName,speakerLabel:t.speakerLabel,padAfter:this.padOf(e.id),gameData:e.gameData,...s}}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 q(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=ce(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}promptPadOf(e){let t=this.promptBeatOf(e);return t?this.padOf(t.id):T}padOf(e){return this.host.padIndex.get(e)?.resolved??T}resolveQualifierName(e){if(e===void 0||this.host.emitIds)return;let t=pe(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.qualifierDisplay.get(e)}splitRef(e){return dt(this.host,e)}newLocal(){return new F(this.host.patterLocalDecls,{pathPrefix:"@patter."})}mountLocal(){this.local=this.newLocal();let e=P.flowGlobals(this.id);this.host.registry.mountOwned(e,this.local,{owner:te}),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??[],s=this.host.journal;if(!this.sceneBags.has(e)){let i=new F(r.filter(l=>!t.has(l.name.toLowerCase())),{pathPrefix:"@scene."}),o=P.flowScene(this.id,e),a=st(this.host.registry,o,i,s!==null);this.registered.add(o),this.sceneBags.set(e,i),s&&s.undo.push(()=>{this.sceneBags.get(e)===i&&(this.host.registry.remove(o,a?{keep:!0}:void 0),this.registered.delete(o),this.sceneBags.delete(e))})}if(!this.host.stageBags.has(e)){let i=new F(r.filter(a=>t.has(a.name.toLowerCase())),{pathPrefix:"@scene."}),o=st(this.host.registry,P.stage(e),i,s!==null);this.host.stageBags.set(e,i),s&&s.undo.push(()=>{this.host.stageBags.get(e)===i&&(this.host.registry.remove(P.stage(e),o?{keep:!0}:void 0),this.host.stageBags.delete(e))})}}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);if(!i)continue;let o=this.host.journal?i.get(s):void 0;o!==void 0&&this.host.journal.undo.push(()=>i.set(s,o)),i.set(s,K(r))}}};function rt(n,e){q(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 ee(n,e,t,r=!1){if(!e||n.emitIds)return;let s=l=>(r?void 0:n.strings[l])??n.defaultStrings[l],i=s(ce(e))??n.castDisplay.get(e)??e;if(t===void 0)return i;let o=n.speakerLabels.get(`${e}\0${t}`);if(o!==void 0)return s(Ue(e,t))??o;let a=s(pe(t))??n.qualifierDisplay.get(t)??t;return Ke(s(We)??n.speakerPattern,i,a)}function nt(n){return n&&Object.keys(n).length?{gameData:n}:{}}function zt(n){let e={kind:n.kind,text:n.text};return n.character!==void 0&&(e.character=n.character),n.characterName!==void 0&&(e.characterName=n.characterName),n.direction!==void 0&&(e.direction=n.direction),n.qualifier!==void 0&&(e.qualifier=n.qualifier),n.qualifierName!==void 0&&(e.qualifierName=n.qualifierName),n.speakerLabel!==void 0&&(e.speakerLabel=n.speakerLabel),typeof n.padAfter=="number"&&(e.padAfter=n.padAfter),e}function lt(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 ct(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 st(n,e,t,r){let s=r?JSON.stringify(t.save()):"";return n.mountOwned(e,t,{owner:te}),r&&JSON.stringify(t.save())!==s}function it(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default}}function ot(n){return{...n.world?{world:n.world}:{},...n.hostScopes}}function ke(n,e,t){let r=n.qualityLadders.get(e);if(!r){r=new Map;for(let s of t()??[]){let i=s.name.toLowerCase();s.type==="quality"&&s.stages&&!r.has(i)&&r.set(i,s.stages)}n.qualityLadders.set(e,r)}return r}function pt(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default,writable:n.writable}}function Qt(n,e){let t=pt(n),r=n.writable??e;return r===void 0?t:{...t,writable:r}}function Ee(n,e){return n.sceneGameIdToId.get(e)??(n.bundle.scenes[e]?e:void 0)}function Ce(n,e,t){return n.blockGameIdToId.get(e)?.get(t)??(n.blockIndex.get(t)?.sceneId===e?t:void 0)}function dt(n,e){n.refSplitRevision!==n.registry.revision&&(n.refSplitCache.clear(),n.refSplitRevision=n.registry.revision);let t=n.refSplitCache.get(e);return t||(t=qe(e,r=>r==="scene"||n.registry.has(r)||(n.bundle.externalScopes?.includes(r)??!1)),n.refSplitCache.set(e,t)),t}function Yt(n){let e={};n.shared?.patter&&(e.patter=n.shared.patter);for(let[t,r]of Object.entries(n.stageBags??{}))e[P.stage(t)]=r;for(let[t,r]of Object.entries(n.flows??{}))Object.assign(e,ut(t,r));return e}function ut(n,e){let t={};e.scopes?.patter&&(t[P.flowGlobals(n)]=e.scopes.patter);for(let[r,s]of Object.entries(e.sceneBags??{}))t[P.flowScene(n,r)]=s;return t}function Xt(n,e){let t={scopes:{},sceneBags:{}},r=P.flow(n);for(let[s,i]of Object.entries(e)){if(!s.startsWith(r))continue;let o=s.slice(r.length);o==="patter"?t.scopes.patter=i:o.startsWith("scene/")&&(t.sceneBags[Kt(o.slice(6))]=i)}return t}function at(n){return typeof n=="boolean"?n:typeof n=="number"?n!==0:typeof n=="string"?n!=="":n.length>0}var Zt=(n,e)=>n.shared??e;function De(n,e){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.default!==void 0?{default:n.default}:{},shared:Zt(n,e)}}function er(n){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.values?{values:[...n.values]}:{},...n.purpose?{purpose:n.purpose}:{}}}function tr(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 ge(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=O(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(l=>({gameId:O(l),name:l.name}))});for(let l of o.blocks)tr(l,e);o.sceneProps?.length&&r.push({gameId:a,properties:o.sceneProps.map(l=>De(l,!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=>De(a,!0))})),i=Object.entries(n.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(er)}));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=>De(o,!0)),scene:r},gameData:i,counts:e}}function gt(n,e){return n.gameDataFields?.[e]??[]}function Pe(n,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:n.find(r=>r.name===t)?.default}function ft(n,e){let t={};for(let r of n){let s=Pe(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}function Ie(n){return{schema:H,save:n.saveGame()}}function Oe(n,e){if(!e||e.schema!==H||!e.save)throw new Error(`loadState: not a ${H} envelope`);n.loadGame(e.save)}function fe(n){return JSON.stringify(Ie(n))}function he(n,e){Oe(n,JSON.parse(e))}function ht(n,e){return n.getProperty(e)}function mt(n,e,t){n.setProperty(e,t)}function yt(n,e){for(let[t,r]of Object.entries(e))n.setProperty(t,r)}function Be(n){let e={};for(let t of St(n)){let r=t.pathPrefix??t.bag.pathPrefix;for(let[s,i]of Object.entries(t.bag.save()))e[`${r}${s}`]=i}return Object.assign(e,bt(n)),e}function St(n){return[...n.listBags(),...n.flows().flatMap(e=>e.listBags())]}function rr(n){switch(n.type){case"line":return`line ${n.character??"?"}: ${JSON.stringify(n.text)}${Re(n.gameData)}`;case"text":return`text: ${JSON.stringify(n.text)}${Re(n.gameData)}`;case"gameEvent":return`game event ${n.id}${Re(n.gameData)}`;case"choice":return`choice (${n.options.length} option${n.options.length===1?"":"s"})`;case"end":return"end"}}var Re=n=>n?` gameData=${JSON.stringify(n)}`:"";function bt(n){let e={};for(let[t,r]of Object.entries(n.getVisitCounts()))e[`visit:${t}`]=r;for(let t of n.flows())for(let[r,s]of Object.entries(t.getVisitCounts()))e[`${t.id}/visit:${r}`]=s;return e}function vt(n,e={}){let t=e.label?`[${e.label}] `:"",r=be({mounts:()=>St(n),extra:()=>bt(n)},{sink:e.sink,label:t});return{snapshot:()=>Be(n),capture:()=>r.capture(),dispose:()=>r.dispose(),logStep(s){(e.sink??(i=>console.log(i)))(`${t}${rr(s)}`)}}}function wt(n){let e=n.url??"ws://127.0.0.1:4471",t=n.WebSocket??globalThis.WebSocket,r=new Set,s=[],i=null,o=!1,a=n.build,l=()=>{if(!(!i||i.readyState!==1)){for(let c of s)try{i.send(c)}catch{}s=[]}},p=c=>{o||!i||i.readyState>1||(s.push(JSON.stringify(c)),l())};if(!t)return{flowOpened(){},observe(){},flowClosed(){},setBuild(){},close(){o=!0},state:"closed",build:a,url:e};let u=()=>{let c=JSON.stringify({t:"hello",v:1,build:a,project:n.project,flows:[...r]});try{i?.send(c)}catch{}};try{i=new t(e),i.addEventListener("open",()=>{u(),l()}),i.addEventListener("message",c=>{if(!(!n.onBundle||typeof c.data!="string"))try{let f=JSON.parse(c.data);f.t==="bundle"&&typeof f.build=="string"&&typeof f.data=="string"&&n.onBundle({build:f.build,data:f.data})}catch{}}),i.addEventListener("error",()=>{}),i.addEventListener("close",()=>{i=null,s=[]})}catch{i=null}return{flowOpened(c){r.add(c),p({t:"flowOpen",flow:c})},flowClosed(c){r.delete(c),p({t:"flowClose",flow:c})},observe(c,f,g,m,d){r.has(c)||(r.add(c),p({t:"flowOpen",flow:c})),p({t:"frame",flow:c,sceneId:f,beatId:g,type:m,choiceId:d})},setBuild(c){o||c===a||(a=c,i&&i.readyState===1&&u())},close(){o=!0,s=[];try{i?.close()}catch{}i=null},get state(){return o||!i?"closed":i.readyState===1?"connected":"connecting"},get build(){return a},url:e}}function xt(n,e,t){let r=JSON.parse(t);return e.content.structureHash!==void 0&&e.content.structureHash===r.content.structureHash?(n.replaceStrings(r),{engine:n,bundle:r,kind:"text"}):{engine:n.hotSwap(r),bundle:r,kind:"structure"}}var kt="pp-inspector-style",nr=`
3
3
  .pp-insp{font:13px/1.4 ui-sans-serif,system-ui,sans-serif;color:#15201e;background:#f4efe6;border:1px solid #cfc7b8;border-radius:10px;padding:.6rem .7rem;max-width:22rem;box-shadow:0 6px 20px rgba(21,32,30,.12)}
4
4
  .pp-insp h4{margin:0 0 .4rem;font:600 .72rem/1 ui-sans-serif,system-ui,sans-serif;letter-spacing:.08em;text-transform:uppercase;color:#5c6b62}
5
5
  .pp-insp-empty{color:#8a9691;font-style:italic}
@@ -11,7 +11,7 @@
11
11
  .pp-insp-ctl input[type=text],.pp-insp-ctl input[type=number],.pp-insp-ctl select{width:100%;box-sizing:border-box;font:inherit;padding:.15rem .3rem;border:1px solid #cfc7b8;border-radius:6px;background:#fff;color:inherit}
12
12
  .pp-insp-reset{flex:0 0 auto;border:1px solid #cfc7b8;background:#fff;border-radius:6px;cursor:pointer;color:#5c6b62;width:1.6rem;height:1.6rem;line-height:1;padding:0}
13
13
  .pp-insp-reset:disabled{opacity:.35;cursor:default}
14
- `;function Yt(n){if(n.getElementById(mt))return;let e=n.createElement("style");e.id=mt,e.textContent=Qt,(n.head??n.documentElement).appendChild(e)}function Xt(n,e){return Array.isArray(n)&&Array.isArray(e)?n.length===e.length&&n.every((t,r)=>t===e[r]):n===e}function yt(n,e={}){let t=e.container?.ownerDocument??document;Yt(t);let r=t.createElement("div");r.className="pp-insp";let s=t.createElement("h4");s.textContent=e.title??"Runtime state";let o=t.createElement("div"),i=t.createElement("div");i.className="pp-insp-io";let a=t.createElement("button");a.type="button",a.textContent="Save state\u2026",a.addEventListener("click",()=>{let u=new Blob([le(n)],{type:"application/json"}),v=t.createElement("a");v.href=URL.createObjectURL(u),v.download="save.patterstate",v.click(),URL.revokeObjectURL(v.href)});let c=t.createElement("button");c.type="button",c.textContent="Load state\u2026",c.addEventListener("click",()=>{let u=t.createElement("input");u.type="file",u.accept=".patterstate,application/json",u.addEventListener("change",()=>{let v=u.files?.[0];v&&v.text().then(D=>{try{pe(n,D),f()}catch(w){console.error("Load state failed:",w instanceof Error?w.message:w)}})}),u.click()}),i.append(a,c),r.append(s,i,o);let d=[],g=u=>{let v=t.createElement("div");v.className="pp-insp-row";let D=t.createElement("span");D.className="pp-insp-ref",D.textContent=u.path,D.title=u.path;let w=t.createElement("div");w.className="pp-insp-ctl";let O=t.createElement("button");O.className="pp-insp-reset",O.type="button",O.textContent="\u21BA",O.title="Reset to default",v.append(D,w,O),o.appendChild(v);let I,A=p=>{n.setProperty(u.path,p),L()},R=p=>t.activeElement===p;function L(){O.disabled=Xt(n.getProperty(u.path),u.default)}if(O.addEventListener("click",()=>{n.setProperty(u.path,u.default),I(),L()}),u.type==="boolean"){let p=t.createElement("input");p.type="checkbox",p.addEventListener("change",()=>A(p.checked)),w.appendChild(p),I=()=>{R(p)||(p.checked=n.getProperty(u.path)===!0)}}else if(u.type==="number"){let p=t.createElement("input");p.type="number",p.addEventListener("change",()=>A(Number(p.value))),w.appendChild(p),I=()=>{R(p)||(p.value=String(n.getProperty(u.path)??""))}}else if(u.type==="enum"||u.type==="quality"){let p=t.createElement("select");for(let y of(u.type==="quality"?u.stages:u.values)??[]){let k=t.createElement("option");k.value=y,k.textContent=y,p.appendChild(k)}p.addEventListener("change",()=>A(p.value)),w.appendChild(p),I=()=>{R(p)||(p.value=String(n.getProperty(u.path)??""))}}else if(u.type==="flags"){let p=t.createElement("input");p.type="text",p.placeholder="comma, separated, flags",p.addEventListener("change",()=>A(p.value.split(",").map(y=>y.trim()).filter(y=>y.length>0))),w.appendChild(p),I=()=>{if(!R(p)){let y=n.getProperty(u.path);p.value=Array.isArray(y)?y.join(", "):""}}}else{let p=t.createElement("input");p.type="text",p.addEventListener("change",()=>A(p.value)),w.appendChild(p),I=()=>{R(p)||(p.value=String(n.getProperty(u.path)??""))}}I(),L(),d.push(()=>{I(),L()})},l=n.listProperties();if(l.length===0){let u=t.createElement("div");u.className="pp-insp-empty",u.textContent="No @patter properties.",o.appendChild(u)}else for(let u of l)g(u);let f=()=>{for(let u of d)u()};e.container?.appendChild(r);let h=e.pollMs??250,m;return h>0&&(m=setInterval(f,h)),{el:r,refresh:f,destroy(){m!==void 0&&clearInterval(m),r.remove()}}}var St="pp-bundle-style",Zt=`
14
+ `;function sr(n){if(n.getElementById(kt))return;let e=n.createElement("style");e.id=kt,e.textContent=nr,(n.head??n.documentElement).appendChild(e)}function ir(n,e){return Array.isArray(n)&&Array.isArray(e)?n.length===e.length&&n.every((t,r)=>t===e[r]):n===e}function Et(n,e={}){let t=e.container?.ownerDocument??document;sr(t);let r=t.createElement("div");r.className="pp-insp";let s=t.createElement("h4");s.textContent=e.title??"Runtime state";let i=t.createElement("div"),o=t.createElement("div");o.className="pp-insp-io";let a=t.createElement("button");a.type="button",a.textContent="Save state\u2026",a.addEventListener("click",()=>{let d=new Blob([fe(n)],{type:"application/json"}),w=t.createElement("a");w.href=URL.createObjectURL(d),w.download="save.patterstate",w.click(),URL.revokeObjectURL(w.href)});let l=t.createElement("button");l.type="button",l.textContent="Load state\u2026",l.addEventListener("click",()=>{let d=t.createElement("input");d.type="file",d.accept=".patterstate,application/json",d.addEventListener("change",()=>{let w=d.files?.[0];w&&w.text().then(E=>{try{he(n,E),f()}catch(C){console.error("Load state failed:",C instanceof Error?C.message:C)}})}),d.click()}),o.append(a,l),r.append(s,o,i);let p=[],u=d=>{let w=t.createElement("div");w.className="pp-insp-row";let E=t.createElement("span");E.className="pp-insp-ref",E.textContent=d.path,E.title=d.path;let C=t.createElement("div");C.className="pp-insp-ctl";let B=t.createElement("button");B.className="pp-insp-reset",B.type="button",B.textContent="\u21BA",B.title="Reset to default",w.append(E,C,B),i.appendChild(w);let x,N=h=>{n.setProperty(d.path,h),j()},L=h=>t.activeElement===h;function j(){B.disabled=ir(n.getProperty(d.path),d.default)}if(B.addEventListener("click",()=>{n.setProperty(d.path,d.default),x(),j()}),d.type==="boolean"){let h=t.createElement("input");h.type="checkbox",h.addEventListener("change",()=>N(h.checked)),C.appendChild(h),x=()=>{L(h)||(h.checked=n.getProperty(d.path)===!0)}}else if(d.type==="number"){let h=t.createElement("input");h.type="number",h.addEventListener("change",()=>N(Number(h.value))),C.appendChild(h),x=()=>{L(h)||(h.value=String(n.getProperty(d.path)??""))}}else if(d.type==="enum"||d.type==="quality"){let h=t.createElement("select");for(let I of(d.type==="quality"?d.stages:d.values)??[]){let y=t.createElement("option");y.value=I,y.textContent=I,h.appendChild(y)}h.addEventListener("change",()=>N(h.value)),C.appendChild(h),x=()=>{L(h)||(h.value=String(n.getProperty(d.path)??""))}}else if(d.type==="flags"){let h=t.createElement("input");h.type="text",h.placeholder="comma, separated, flags",h.addEventListener("change",()=>N(h.value.split(",").map(I=>I.trim()).filter(I=>I.length>0))),C.appendChild(h),x=()=>{if(!L(h)){let I=n.getProperty(d.path);h.value=Array.isArray(I)?I.join(", "):""}}}else{let h=t.createElement("input");h.type="text",h.addEventListener("change",()=>N(h.value)),C.appendChild(h),x=()=>{L(h)||(h.value=String(n.getProperty(d.path)??""))}}x(),j(),p.push(()=>{x(),j()})},c=n.listProperties();if(c.length===0){let d=t.createElement("div");d.className="pp-insp-empty",d.textContent="No @patter properties.",i.appendChild(d)}else for(let d of c)u(d);let f=()=>{for(let d of p)d()};e.container?.appendChild(r);let g=e.pollMs??250,m;return g>0&&(m=setInterval(f,g)),{el:r,refresh:f,destroy(){m!==void 0&&clearInterval(m),r.remove()}}}var Ct="pp-bundle-style",or=`
15
15
  .pp-bundle{font:13px/1.4 ui-sans-serif,system-ui,sans-serif;color:#15201e;background:#f4efe6;border:1px solid #cfc7b8;border-radius:10px;padding:.6rem .7rem;max-width:26rem;box-shadow:0 6px 20px rgba(21,32,30,.12)}
16
16
  .pp-bundle h4{margin:0 0 .4rem;font:600 .72rem/1 ui-sans-serif,system-ui,sans-serif;letter-spacing:.08em;text-transform:uppercase;color:#5c6b62}
17
17
  .pp-bundle details{border-top:1px solid #e3dccf;padding:.3rem 0}
@@ -28,5 +28,5 @@
28
28
  .pp-bundle-empty{color:#8a9691;font-style:italic;margin-left:1rem}
29
29
  .pp-bundle-warn{color:#8a3a2f;font-weight:600}
30
30
  .pp-bundle-tag{font-size:.7rem;color:#5c6b62;border:1px solid #cfc7b8;border-radius:5px;padding:0 .25rem;margin-left:.3rem}
31
- `;function er(n){if(n.getElementById(St))return;let e=n.createElement("style");e.id=St,e.textContent=Zt,(n.head??n.documentElement).appendChild(e)}var b=(n,e,t,r)=>{let s=n.createElement(e);return t&&(s.className=t),r!==void 0&&(s.textContent=r),s};function P(n,e,t,r="pp-bundle-val"){let s=b(n,"div","pp-bundle-row");return s.append(b(n,"span","pp-bundle-key",e),b(n,"span",r,t)),s}function Oe(n,e){let t=b(n,"div","pp-bundle-row");t.append(b(n,"span","pp-bundle-key pp-bundle-addr",e.name));let r=b(n,"span","pp-bundle-val",e.type);return e.hasDefault||r.append(b(n,"span","pp-bundle-tag","no default")),t.append(r),t}function q(n,e,t,r,s){let o=n.createElement("details");o.dataset.section=e,o.open=s;let i=n.createElement("summary");return i.textContent=t,r!==null&&i.append(b(n,"span","pp-bundle-count",` ${r}`)),o.append(i),o}function bt(n,e={}){let t=e.container?.ownerDocument??document;er(t);let r=ce(n),s=new Set(e.open??["identity","addresses"]),o=b(t,"div","pp-bundle");o.append(b(t,"h4",void 0,e.title??"Bundle"));let i=q(t,"identity",r.identity.project||"(unnamed project)",null,s.has("identity"));r.identity.version&&i.append(P(t,"version",r.identity.version)),i.append(P(t,"schema",r.identity.schema)),i.append(P(t,"locales",`${r.identity.defaultLocale}${r.identity.locales.length>1?` (+${r.identity.locales.length-1})`:""}`)),i.append(P(t,"strings",r.identity.localisation)),r.identity.voiced&&i.append(P(t,"voiced","yes")),r.identity.hash&&i.append(P(t,"hash",r.identity.hash)),r.identity.structureHash&&i.append(P(t,"structure",r.identity.structureHash)),r.identity.sourceDebug&&i.append(P(t,"build","SOURCE DEBUG - not shippable","pp-bundle-val pp-bundle-warn")),o.append(i);let a=q(t,"addresses","Addresses",r.addresses.length,s.has("addresses"));r.addresses.length||a.append(b(t,"div","pp-bundle-empty","no scenes"));for(let h of r.addresses){let m=b(t,"div","pp-bundle-row");m.append(b(t,"span","pp-bundle-key pp-bundle-addr",h.gameId),b(t,"span","pp-bundle-val",h.name)),a.append(m);for(let u of h.blocks){let v=b(t,"div","pp-bundle-row pp-bundle-sub");v.append(b(t,"span","pp-bundle-key pp-bundle-addr",u.gameId),b(t,"span","pp-bundle-val",u.name)),a.append(v)}}o.append(a);let c=r.hostScopes.reduce((h,m)=>h+m.properties.length,0),d=q(t,"hostScopes","Host properties",c,s.has("hostScopes"));r.hostScopes.length||d.append(b(t,"div","pp-bundle-empty","the game supplies nothing"));for(let h of r.hostScopes){let m=b(t,"div","pp-bundle-row");m.append(b(t,"span","pp-bundle-key pp-bundle-addr",`@${h.token}`));let u=b(t,"span","pp-bundle-val",h.opaque?"any name, unchecked":`${h.properties.length} declared`);h.writable||u.append(b(t,"span","pp-bundle-tag","read-only")),m.append(u),d.append(m);for(let v of h.properties){let D=Oe(t,v);D.classList.add("pp-bundle-sub"),d.append(D)}}o.append(d);let g=r.properties.patter.length+r.properties.scene.reduce((h,m)=>h+m.properties.length,0),l=q(t,"properties","Story properties",g,s.has("properties"));g||l.append(b(t,"div","pp-bundle-empty","none declared"));for(let h of r.properties.patter)l.append(Oe(t,h));for(let h of r.properties.scene){l.append(P(t,"@scene",h.gameId,"pp-bundle-val pp-bundle-addr"));for(let m of h.properties){let u=Oe(t,m);u.classList.add("pp-bundle-sub"),l.append(u)}}if(o.append(l),r.gameData.length){let h=q(t,"gameData","Game data",r.gameData.reduce((m,u)=>m+u.fields.length,0),s.has("gameData"));for(let m of r.gameData){h.append(P(t,"on",m.kind));for(let u of m.fields){let v=b(t,"div","pp-bundle-row pp-bundle-sub");v.append(b(t,"span","pp-bundle-key pp-bundle-addr",u.name),b(t,"span","pp-bundle-val",u.type)),h.append(v)}}o.append(h)}let f=q(t,"counts","Counts",null,s.has("counts"));for(let[h,m]of Object.entries(r.counts))f.append(P(t,h,String(m)));return o.append(f),e.container?.append(o),{el:o,description:r,destroy(){o.remove()}}}function vt(n,e){let r=JSON.parse(n).clips??{},s=e===""||/[/\\]$/.test(e)?"":"/";return{resolve(o){let i=r[o];return!i||!i.file?null:`${e}${s}${i.file}`}}}return It(tr);})();
31
+ `;function ar(n){if(n.getElementById(Ct))return;let e=n.createElement("style");e.id=Ct,e.textContent=or,(n.head??n.documentElement).appendChild(e)}var b=(n,e,t,r)=>{let s=n.createElement(e);return t&&(s.className=t),r!==void 0&&(s.textContent=r),s};function R(n,e,t,r="pp-bundle-val"){let s=b(n,"div","pp-bundle-row");return s.append(b(n,"span","pp-bundle-key",e),b(n,"span",r,t)),s}function Ae(n,e){let t=b(n,"div","pp-bundle-row");t.append(b(n,"span","pp-bundle-key pp-bundle-addr",e.name));let r=b(n,"span","pp-bundle-val",e.type);return e.hasDefault||r.append(b(n,"span","pp-bundle-tag","no default")),t.append(r),t}function _(n,e,t,r,s){let i=n.createElement("details");i.dataset.section=e,i.open=s;let o=n.createElement("summary");return o.textContent=t,r!==null&&o.append(b(n,"span","pp-bundle-count",` ${r}`)),i.append(o),i}function Dt(n,e={}){let t=e.container?.ownerDocument??document;ar(t);let r=ge(n),s=new Set(e.open??["identity","addresses"]),i=b(t,"div","pp-bundle");i.append(b(t,"h4",void 0,e.title??"Bundle"));let o=_(t,"identity",r.identity.project||"(unnamed project)",null,s.has("identity"));r.identity.version&&o.append(R(t,"version",r.identity.version)),o.append(R(t,"schema",r.identity.schema)),o.append(R(t,"locales",`${r.identity.defaultLocale}${r.identity.locales.length>1?` (+${r.identity.locales.length-1})`:""}`)),o.append(R(t,"strings",r.identity.localisation)),r.identity.voiced&&o.append(R(t,"voiced","yes")),r.identity.hash&&o.append(R(t,"hash",r.identity.hash)),r.identity.structureHash&&o.append(R(t,"structure",r.identity.structureHash)),r.identity.sourceDebug&&o.append(R(t,"build","SOURCE DEBUG - not shippable","pp-bundle-val pp-bundle-warn")),i.append(o);let a=_(t,"addresses","Addresses",r.addresses.length,s.has("addresses"));r.addresses.length||a.append(b(t,"div","pp-bundle-empty","no scenes"));for(let g of r.addresses){let m=b(t,"div","pp-bundle-row");m.append(b(t,"span","pp-bundle-key pp-bundle-addr",g.gameId),b(t,"span","pp-bundle-val",g.name)),a.append(m);for(let d of g.blocks){let w=b(t,"div","pp-bundle-row pp-bundle-sub");w.append(b(t,"span","pp-bundle-key pp-bundle-addr",d.gameId),b(t,"span","pp-bundle-val",d.name)),a.append(w)}}i.append(a);let l=r.hostScopes.reduce((g,m)=>g+m.properties.length,0),p=_(t,"hostScopes","Host properties",l,s.has("hostScopes"));r.hostScopes.length||p.append(b(t,"div","pp-bundle-empty","the game supplies nothing"));for(let g of r.hostScopes){let m=b(t,"div","pp-bundle-row");m.append(b(t,"span","pp-bundle-key pp-bundle-addr",`@${g.token}`));let d=b(t,"span","pp-bundle-val",g.opaque?"any name, unchecked":`${g.properties.length} declared`);g.writable||d.append(b(t,"span","pp-bundle-tag","read-only")),m.append(d),p.append(m);for(let w of g.properties){let E=Ae(t,w);E.classList.add("pp-bundle-sub"),p.append(E)}}i.append(p);let u=r.properties.patter.length+r.properties.scene.reduce((g,m)=>g+m.properties.length,0),c=_(t,"properties","Story properties",u,s.has("properties"));u||c.append(b(t,"div","pp-bundle-empty","none declared"));for(let g of r.properties.patter)c.append(Ae(t,g));for(let g of r.properties.scene){c.append(R(t,"@scene",g.gameId,"pp-bundle-val pp-bundle-addr"));for(let m of g.properties){let d=Ae(t,m);d.classList.add("pp-bundle-sub"),c.append(d)}}if(i.append(c),r.gameData.length){let g=_(t,"gameData","Game data",r.gameData.reduce((m,d)=>m+d.fields.length,0),s.has("gameData"));for(let m of r.gameData){g.append(R(t,"on",m.kind));for(let d of m.fields){let w=b(t,"div","pp-bundle-row pp-bundle-sub");w.append(b(t,"span","pp-bundle-key pp-bundle-addr",d.name),b(t,"span","pp-bundle-val",d.type)),g.append(w)}}i.append(g)}let f=_(t,"counts","Counts",null,s.has("counts"));for(let[g,m]of Object.entries(r.counts))f.append(R(t,g,String(m)));return i.append(f),e.container?.append(i),{el:i,description:r,destroy(){i.remove()}}}function Pt(n,e){let r=JSON.parse(n).clips??{},s=e===""||/[/\\]$/.test(e)?"":"/";return{resolve(i){let o=r[i];return!o||!o.file?null:`${e}${s}${o.file}`}}}return Lt(lr);})();
32
32
  //# sourceMappingURL=patterplay.min.js.map