{"version":3,"file":"ink-full.mjs","sources":["../src/compiler/CompilerOptions.ts","../src/compiler/DebugSourceRange.ts","../src/compiler/Parser/ErrorType.ts","../src/compiler/Parser/ParsedHierarchy/Argument.ts","../src/engine/TypeAssertion.ts","../src/compiler/Parser/ParsedHierarchy/Object.ts","../src/compiler/Parser/ParsedHierarchy/AuthorWarning.ts","../src/engine/Path.ts","../src/engine/Debug.ts","../src/engine/Value.ts","../src/engine/PushPop.ts","../src/engine/NullException.ts","../src/engine/Object.ts","../src/engine/StringBuilder.ts","../src/engine/InkList.ts","../src/engine/StoryException.ts","../src/engine/TryGetResult.ts","../src/engine/SearchResult.ts","../src/engine/Container.ts","../src/engine/ControlCommand.ts","../src/compiler/Parser/ParsedHierarchy/Expression/Expression.ts","../src/engine/Void.ts","../src/engine/NativeFunctionCall.ts","../src/compiler/Parser/ParsedHierarchy/Expression/NumberExpression.ts","../src/compiler/Parser/ParsedHierarchy/Expression/UnaryExpression.ts","../src/compiler/Parser/ParsedHierarchy/Expression/BinaryExpression.ts","../src/compiler/Parser/CharacterSet.ts","../src/compiler/Parser/CharacterRange.ts","../src/engine/ChoicePoint.ts","../src/engine/Pointer.ts","../src/engine/Divert.ts","../src/compiler/Parser/ParsedHierarchy/SymbolType.ts","../src/engine/VariableAssignment.ts","../src/compiler/Parser/ParsedHierarchy/Choice.ts","../src/compiler/Parser/StringParser/StringParserElement.ts","../src/compiler/Parser/StringParser/StringParserState.ts","../src/compiler/Parser/StringParser/StringParser.ts","../src/compiler/Parser/CommentEliminator.ts","../src/compiler/Parser/ParsedHierarchy/Conditional/Conditional.ts","../src/compiler/Parser/ParsedHierarchy/Text.ts","../src/compiler/Parser/ParsedHierarchy/Declaration/ConstantDeclaration.ts","../src/compiler/Parser/ParsedHierarchy/Flow/FlowLevel.ts","../src/compiler/Parser/ParsedHierarchy/Gather/Gather.ts","../src/compiler/Parser/ParsedHierarchy/Path.ts","../src/compiler/Parser/ParsedHierarchy/ReturnType.ts","../src/compiler/Parser/ParsedHierarchy/Flow/ClosestFlowBase.ts","../src/compiler/Parser/ParsedHierarchy/Identifier.ts","../src/compiler/Parser/ParsedHierarchy/Flow/FlowBase.ts","../src/compiler/Parser/ParsedHierarchy/ContentList.ts","../src/engine/VariableReference.ts","../src/compiler/Parser/ParsedHierarchy/Variable/VariableReference.ts","../src/compiler/Parser/ParsedHierarchy/FunctionCall.ts","../src/compiler/Parser/ParsedHierarchy/Expression/MultipleConditionExpression.ts","../src/compiler/Parser/ParsedHierarchy/Divert/DivertTarget.ts","../src/compiler/Parser/ParsedHierarchy/Divert/Divert.ts","../src/compiler/Parser/ParsedHierarchy/Gather/GatherPointToResolve.ts","../src/compiler/Parser/ParsedHierarchy/Sequence/SequenceDivertToResolve.ts","../src/compiler/Parser/ParsedHierarchy/Sequence/SequenceType.ts","../src/compiler/Parser/ParsedHierarchy/Sequence/Sequence.ts","../src/compiler/Parser/ParsedHierarchy/TunnelOnwards.ts","../src/engine/ListDefinition.ts","../src/compiler/Parser/ParsedHierarchy/List/ListDefinition.ts","../src/compiler/Parser/ParsedHierarchy/Variable/VariableAssignment.ts","../src/compiler/Parser/ParsedHierarchy/Weave.ts","../src/compiler/Parser/ParsedHierarchy/Conditional/ConditionalSingleBranch.ts","../src/compiler/Parser/CustomFlags.ts","../src/engine/DebugMetadata.ts","../src/compiler/Parser/ParsedHierarchy/Declaration/ExternalDeclaration.ts","../src/compiler/Parser/FlowDecl.ts","../src/compiler/Parser/ParsedHierarchy/Wrap.ts","../src/compiler/Parser/ParsedHierarchy/Glue.ts","../src/engine/Glue.ts","../src/compiler/Parser/ParsedHierarchy/Expression/IncDecExpression.ts","../src/compiler/Parser/ParsedHierarchy/IncludedFile.ts","../src/compiler/Parser/InfixOperator.ts","../src/compiler/Parser/ParsedHierarchy/Knot.ts","../src/compiler/Parser/ParsedHierarchy/List/List.ts","../src/compiler/Parser/ParsedHierarchy/List/ListElementDefinition.ts","../src/compiler/Parser/StatementLevel.ts","../src/compiler/Parser/ParsedHierarchy/Stitch.ts","../src/engine/Tag.ts","../src/engine/Choice.ts","../src/engine/ListDefinitionsOrigin.ts","../src/engine/JsonSerialisation.ts","../src/engine/CallStack.ts","../src/engine/VariablesState.ts","../src/engine/PRNG.ts","../src/engine/StatePatch.ts","../src/engine/SimpleJson.ts","../src/engine/Flow.ts","../src/engine/StoryState.ts","../src/engine/StopWatch.ts","../src/engine/Error.ts","../src/engine/Story.ts","../src/compiler/Parser/ParsedHierarchy/Story.ts","../src/compiler/Parser/ParsedHierarchy/Expression/StringExpression.ts","../src/compiler/Parser/ParsedHierarchy/Tag.ts","../src/compiler/FileHandler/DefaultFileHandler.ts","../src/compiler/Parser/InkParser.ts","../src/compiler/FileHandler/JsonFileHandler.ts","../src/compiler/Compiler.ts","../src/compiler/Stats.ts"],"sourcesContent":["import { ErrorHandler } from \"../engine/Error\";\nimport { IFileHandler } from \"./IFileHandler\";\n\nexport class CompilerOptions {\n  constructor(\n    public readonly sourceFilename: string | null = null,\n    public readonly pluginNames: string[] = [],\n    public readonly countAllVisits: boolean = false,\n    public readonly errorHandler: ErrorHandler | null = null,\n    public readonly fileHandler: IFileHandler | null = null\n  ) {}\n}\n","import { DebugMetadata } from \"../engine/DebugMetadata\";\n\nexport class DebugSourceRange {\n  constructor(\n    public readonly length: number,\n    public readonly debugMetadata: DebugMetadata | null,\n    public text: string\n  ) {}\n}\n","// TODO: Unifify with Engine.\n\nexport enum ErrorType {\n  Author,\n  Warning,\n  Error,\n}\n","import { Identifier } from \"./Identifier\";\n\nexport class Argument {\n  constructor(\n    public identifier: Identifier | null = null,\n    public isByReference: boolean | null = null,\n    public isDivertTarget: boolean | null = null\n  ) {}\n\n  get typeName(): string {\n    return \"Argument\";\n  }\n}\n","import { INamedContent } from \"./INamedContent\";\n\nexport function asOrNull<T>(\n  obj: any,\n  type: (new (...arg: any[]) => T) | (Function & { prototype: T })\n): T | null {\n  if (obj instanceof type) {\n    return unsafeTypeAssertion(obj, type);\n  } else {\n    return null;\n  }\n}\n\nexport function asOrThrows<T>(\n  obj: any,\n  type: (new (...arg: any[]) => T) | (Function & { prototype: T })\n): T | never {\n  if (obj instanceof type) {\n    return unsafeTypeAssertion(obj, type);\n  } else {\n    throw new Error(`${obj} is not of type ${type}`);\n  }\n}\n\nexport function asNumberOrThrows(obj: any) {\n  if (typeof obj === \"number\") {\n    return obj as number;\n  } else {\n    throw new Error(`${obj} is not a number`);\n  }\n}\n\nexport function asBooleanOrThrows(obj: any) {\n  if (typeof obj === \"boolean\") {\n    return obj as boolean;\n  } else {\n    throw new Error(`${obj} is not a boolean`);\n  }\n}\n\n// So here, in the reference implementation, contentObj is casted to an INamedContent\n// but here we use js-style duck typing: if it implements the same props as the interface,\n// we treat it as valid.\nexport function asINamedContentOrNull(obj: any): INamedContent | null {\n  if (obj.hasValidName && obj.name) {\n    return obj as INamedContent;\n  }\n\n  return null;\n}\n\nexport function nullIfUndefined<T>(obj: T | undefined): T | null {\n  if (typeof obj === \"undefined\") {\n    return null;\n  }\n\n  return obj;\n}\n\nexport function isEquatable(type: any) {\n  return typeof type === \"object\" && typeof type.Equals === \"function\";\n}\n\nfunction unsafeTypeAssertion<T>(\n  obj: any,\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  type: (new () => T) | (Function & { prototype: T })\n) {\n  return obj as T;\n}\n\nexport function filterUndef<T>(element: T | undefined): element is T {\n  return element != undefined;\n}\n","import { Container as RuntimeContainer } from \"../../../engine/Container\";\nimport { DebugMetadata } from \"../../../engine/DebugMetadata\";\nimport { FindQueryFunc } from \"./FindQueryFunc\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\nimport { Path as RuntimePath } from \"../../../engine/Path\";\nimport { Story } from \"./Story\";\nimport { asOrNull } from \"../../../engine/TypeAssertion\";\n\nexport abstract class ParsedObject {\n  public abstract readonly GenerateRuntimeObject: () => RuntimeObject | null;\n\n  private _alreadyHadError: boolean = false;\n  private _alreadyHadWarning: boolean = false;\n  private _debugMetadata: DebugMetadata | null = null;\n  private _runtimeObject: RuntimeObject | null = null;\n\n  public content: ParsedObject[] = [];\n  public parent: ParsedObject | null = null;\n\n  get debugMetadata() {\n    if (this._debugMetadata === null && this.parent) {\n      return this.parent.debugMetadata;\n    }\n\n    return this._debugMetadata;\n  }\n\n  set debugMetadata(value: DebugMetadata | null) {\n    this._debugMetadata = value;\n  }\n\n  get hasOwnDebugMetadata(): boolean {\n    return Boolean(this.debugMetadata);\n  }\n\n  get typeName(): string {\n    return \"ParsedObject\";\n  }\n\n  public readonly GetType = (): string => this.typeName;\n\n  get story(): Story {\n    let ancestor: ParsedObject = this;\n    while (ancestor.parent) {\n      ancestor = ancestor.parent;\n    }\n\n    return ancestor as Story;\n  }\n\n  get runtimeObject(): RuntimeObject {\n    if (!this._runtimeObject) {\n      this._runtimeObject = this.GenerateRuntimeObject();\n      if (this._runtimeObject) {\n        this._runtimeObject.debugMetadata = this.debugMetadata;\n      }\n    }\n\n    return this._runtimeObject as RuntimeObject;\n  }\n\n  set runtimeObject(value: RuntimeObject) {\n    this._runtimeObject = value;\n  }\n\n  get runtimePath(): RuntimePath {\n    if (!this.runtimeObject.path) {\n      throw new Error();\n    }\n\n    return this.runtimeObject.path;\n  }\n\n  // When counting visits and turns since, different object\n  // types may have different containers that needs to be counted.\n  // For most it'll just be the object's main runtime object,\n  // but for e.g. choices, it'll be the target container.\n  get containerForCounting(): RuntimeContainer | null {\n    return this.runtimeObject as RuntimeContainer;\n  }\n\n  get ancestry(): ParsedObject[] {\n    let result = [];\n\n    let ancestor = this.parent;\n    while (ancestor) {\n      result.push(ancestor);\n      ancestor = ancestor.parent;\n    }\n\n    result = result.reverse();\n\n    return result;\n  }\n\n  /*\n  get descriptionOfScope(): string {\n    const locationNames: string[] = [];\n\n    let ancestor: ParsedObject | null = this;\n    while (ancestor) {\n      var ancestorFlow = ancestor as FlowBase;\n      if (ancestorFlow && ancestorFlow.name != null) {\n        locationNames.push(`'${ancestorFlow.name}'`);\n      }\n      ancestor = ancestor.parent;\n    }\n\n    let scopeSB = '';\n    if (locationNames.length > 0) {\n      const locationsListStr = locationNames.join(', ');\n      scopeSB += `${locationsListStr} and`;\n    }\n\n    scopeSB += 'at top scope';\n\n    return scopeSB;\n  }\n*/\n\n  // Return the object so that method can be chained easily\n  public readonly AddContent = <T extends ParsedObject, V extends T | T[]>(\n    subContent: V\n  ) => {\n    if (this.content === null) {\n      this.content = [];\n    }\n\n    const sub = Array.isArray(subContent) ? subContent : [subContent];\n\n    // Make resilient to content not existing, which can happen\n    // in the case of parse errors where we've already reported\n    // an error but still want a valid structure so we can\n    // carry on parsing.\n    for (const ss of sub) {\n      if (ss.hasOwnProperty(\"parent\")) {\n        ss.parent = this;\n      }\n      this.content.push(ss);\n    }\n\n    if (Array.isArray(subContent)) {\n      return;\n    } else {\n      return subContent;\n    }\n  };\n\n  public readonly InsertContent = <T extends ParsedObject>(\n    index: number,\n    subContent: T\n  ): T => {\n    if (this.content === null) {\n      this.content = [];\n    }\n\n    subContent.parent = this;\n    this.content.splice(index, 0, subContent);\n\n    return subContent;\n  };\n\n  public readonly Find =\n    <T extends ParsedObject>(\n      type: (new (...arg: any[]) => T) | (Function & { prototype: T })\n    ) =>\n    (queryFunc: FindQueryFunc<T> | null = null): T | null => {\n      let tObj = asOrNull(this, type) as any as T;\n      if (tObj !== null && (queryFunc === null || queryFunc(tObj) === true)) {\n        return tObj;\n      }\n\n      if (this.content === null) {\n        return null;\n      }\n\n      for (const obj of this.content) {\n        let nestedResult = obj.Find && obj.Find(type)(queryFunc);\n        if (nestedResult) {\n          return nestedResult as T;\n        }\n      }\n\n      return null;\n    };\n\n  public readonly FindAll =\n    <T extends ParsedObject>(\n      type: (new (...arg: any[]) => T) | (Function & { prototype: T })\n    ) =>\n    (queryFunc?: FindQueryFunc<T>, foundSoFar?: T[]): T[] => {\n      const found = Array.isArray(foundSoFar) ? foundSoFar : [];\n\n      const tObj = asOrNull(this, type);\n      if (tObj !== null && (!queryFunc || queryFunc(tObj) === true)) {\n        found.push(tObj);\n      }\n\n      if (this.content === null) {\n        return [];\n      }\n\n      for (const obj of this.content) {\n        obj.FindAll && obj.FindAll(type)(queryFunc, found);\n      }\n\n      return found;\n    };\n\n  public ResolveReferences(context: Story) {\n    if (this.content !== null) {\n      for (const obj of this.content) {\n        obj.ResolveReferences(context);\n      }\n    }\n  }\n\n  public Error(\n    message: string,\n    source: ParsedObject | null = null,\n    isWarning: boolean = false\n  ): void {\n    if (source === null) {\n      source = this;\n    }\n\n    // Only allow a single parsed object to have a single error *directly* associated with it\n    if (\n      (source._alreadyHadError && !isWarning) ||\n      (source._alreadyHadWarning && isWarning)\n    ) {\n      return;\n    }\n\n    if (this.parent) {\n      this.parent.Error(message, source, isWarning);\n    } else {\n      throw new Error(`No parent object to send error to: ${message}`);\n    }\n\n    if (isWarning) {\n      source._alreadyHadWarning = true;\n    } else {\n      source._alreadyHadError = true;\n    }\n  }\n\n  public readonly Warning = (\n    message: string,\n    source: ParsedObject | null = null\n  ): void => {\n    this.Error(message, source, true);\n  };\n}\n","import { ParsedObject } from \"./Object\";\n\nexport class AuthorWarning extends ParsedObject {\n  constructor(public readonly warningMessage: string) {\n    super();\n  }\n\n  get typeName(): string {\n    return \"AuthorWarning\";\n  }\n\n  public readonly GenerateRuntimeObject = (): null => {\n    this.Warning(this.warningMessage);\n    return null;\n  };\n}\n","export class Path {\n  public static parentId = \"^\";\n\n  public _isRelative: boolean;\n  public _components: Path.Component[];\n  public _componentsString: string | null;\n\n  constructor();\n  constructor(componentsString: string);\n  constructor(head: Path.Component, tail: Path);\n  constructor(head: Path.Component[], relative?: boolean);\n  constructor() {\n    this._components = [];\n    this._componentsString = null;\n    this._isRelative = false;\n\n    if (typeof arguments[0] == \"string\") {\n      let componentsString = arguments[0] as string;\n      this.componentsString = componentsString;\n    } else if (\n      arguments[0] instanceof Path.Component &&\n      arguments[1] instanceof Path\n    ) {\n      let head = arguments[0] as Path.Component;\n      let tail = arguments[1] as Path;\n      this._components.push(head);\n      this._components = this._components.concat(tail._components);\n    } else if (arguments[0] instanceof Array) {\n      let head = arguments[0] as Path.Component[];\n      let relative = !!arguments[1] as boolean;\n      this._components = this._components.concat(head);\n      this._isRelative = relative;\n    }\n  }\n  get isRelative() {\n    return this._isRelative;\n  }\n  get componentCount(): number {\n    return this._components.length;\n  }\n  get head(): Path.Component | null {\n    if (this._components.length > 0) {\n      return this._components[0];\n    } else {\n      return null;\n    }\n  }\n  get tail(): Path {\n    if (this._components.length >= 2) {\n      // careful, the original code uses length-1 here. This is because the second argument of\n      // List.GetRange is a number of elements to extract, wherease Array.slice uses an index\n      let tailComps = this._components.slice(1, this._components.length);\n      return new Path(tailComps);\n    } else {\n      return Path.self;\n    }\n  }\n  get length(): number {\n    return this._components.length;\n  }\n  get lastComponent(): Path.Component | null {\n    let lastComponentIdx = this._components.length - 1;\n    if (lastComponentIdx >= 0) {\n      return this._components[lastComponentIdx];\n    } else {\n      return null;\n    }\n  }\n  get containsNamedComponent(): boolean {\n    for (let i = 0, l = this._components.length; i < l; i++) {\n      if (!this._components[i].isIndex) {\n        return true;\n      }\n    }\n    return false;\n  }\n  static get self(): Path {\n    let path = new Path();\n    path._isRelative = true;\n    return path;\n  }\n\n  public GetComponent(index: number): Path.Component {\n    return this._components[index];\n  }\n  public PathByAppendingPath(pathToAppend: Path): Path {\n    let p = new Path();\n\n    let upwardMoves = 0;\n    for (let i = 0; i < pathToAppend._components.length; ++i) {\n      if (pathToAppend._components[i].isParent) {\n        upwardMoves++;\n      } else {\n        break;\n      }\n    }\n\n    for (let i = 0; i < this._components.length - upwardMoves; ++i) {\n      p._components.push(this._components[i]);\n    }\n\n    for (let i = upwardMoves; i < pathToAppend._components.length; ++i) {\n      p._components.push(pathToAppend._components[i]);\n    }\n\n    return p;\n  }\n  get componentsString(): string {\n    if (this._componentsString == null) {\n      this._componentsString = this._components.join(\".\");\n      if (this.isRelative)\n        this._componentsString = \".\" + this._componentsString;\n    }\n\n    return this._componentsString;\n  }\n  set componentsString(value: string) {\n    this._components.length = 0;\n\n    this._componentsString = value;\n\n    if (this._componentsString == null || this._componentsString == \"\") return;\n\n    if (this._componentsString[0] == \".\") {\n      this._isRelative = true;\n      this._componentsString = this._componentsString.substring(1);\n    }\n\n    let componentStrings = this._componentsString.split(\".\");\n    for (let str of componentStrings) {\n      // we need to distinguish between named components that start with a number, eg \"42somewhere\", and indexed components\n      // the normal parseInt won't do for the detection because it's too relaxed.\n      // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt\n      if (/^(\\-|\\+)?([0-9]+|Infinity)$/.test(str)) {\n        this._components.push(new Path.Component(parseInt(str)));\n      } else {\n        this._components.push(new Path.Component(str));\n      }\n    }\n  }\n  public toString(): string {\n    return this.componentsString;\n  }\n  public Equals(otherPath: Path | null): boolean {\n    if (otherPath == null) return false;\n\n    if (otherPath._components.length != this._components.length) return false;\n\n    if (otherPath.isRelative != this.isRelative) return false;\n\n    // the original code uses SequenceEqual here, so we need to iterate over the components manually.\n    for (let i = 0, l = otherPath._components.length; i < l; i++) {\n      // it's not quite clear whether this test should use Equals or a simple == operator,\n      // see https://github.com/y-lohse/inkjs/issues/22\n      if (!otherPath._components[i].Equals(this._components[i])) return false;\n    }\n\n    return true;\n  }\n  public PathByAppendingComponent(c: Path.Component): Path {\n    let p = new Path();\n    p._components.push(...this._components);\n    p._components.push(c);\n    return p;\n  }\n}\n\nexport namespace Path {\n  export class Component {\n    public readonly index: number;\n    public readonly name: string | null;\n\n    constructor(indexOrName: string | number) {\n      this.index = -1;\n      this.name = null;\n      if (typeof indexOrName == \"string\") {\n        this.name = indexOrName;\n      } else {\n        this.index = indexOrName;\n      }\n    }\n    get isIndex(): boolean {\n      return this.index >= 0;\n    }\n    get isParent(): boolean {\n      return this.name == Path.parentId;\n    }\n\n    public static ToParent(): Component {\n      return new Component(Path.parentId);\n    }\n    public toString(): string | null {\n      if (this.isIndex) {\n        return this.index.toString();\n      } else {\n        return this.name;\n      }\n    }\n    public Equals(otherComp: Component): boolean {\n      if (otherComp != null && otherComp.isIndex == this.isIndex) {\n        if (this.isIndex) {\n          return this.index == otherComp.index;\n        } else {\n          return this.name == otherComp.name;\n        }\n      }\n\n      return false;\n    }\n  }\n}\n","export namespace Debug {\n  export function AssertType<T>(\n    variable: any,\n    type: new () => T,\n    message: string\n  ): void | never {\n    Assert(variable instanceof type, message);\n  }\n\n  export function Assert(condition: boolean, message?: string): void | never {\n    if (!condition) {\n      if (typeof message !== \"undefined\") {\n        console.warn(message);\n      }\n\n      if (console.trace) {\n        console.trace();\n      }\n\n      throw new Error(\"\");\n    }\n  }\n}\n","import { InkObject } from \"./Object\";\nimport { Path } from \"./Path\";\nimport { InkList, InkListItem } from \"./InkList\";\nimport { StoryException } from \"./StoryException\";\nimport { asOrNull, asOrThrows } from \"./TypeAssertion\";\nimport { tryParseInt, tryParseFloat } from \"./TryGetResult\";\nimport { throwNullException } from \"./NullException\";\n\nexport abstract class AbstractValue extends InkObject {\n  public abstract get valueType(): ValueType;\n  public abstract get isTruthy(): boolean;\n  public abstract get valueObject(): any;\n\n  public abstract Cast(newType: ValueType): Value<any>;\n\n  public static Create(\n    val: any,\n    preferredNumberType?: ValueType\n  ): Value<any> | null {\n    // This code doesn't exist in upstream and is simply here to enforce\n    // the creation of the proper number value.\n    // If `preferredNumberType` is not provided or if value doesn't match\n    // `preferredNumberType`, this conditional does nothing.\n    if (preferredNumberType) {\n      if (\n        preferredNumberType === (ValueType.Int as ValueType) &&\n        Number.isInteger(Number(val))\n      ) {\n        return new IntValue(Number(val));\n      } else if (\n        preferredNumberType === (ValueType.Float as ValueType) &&\n        !isNaN(val)\n      ) {\n        return new FloatValue(Number(val));\n      }\n    }\n\n    if (typeof val === \"boolean\") {\n      return new BoolValue(Boolean(val));\n    }\n\n    // https://github.com/y-lohse/inkjs/issues/425\n    // Changed condition sequence, because Number('') is\n    // parsed to 0, which made setting string to empty\n    // impossible\n    if (typeof val === \"string\") {\n      return new StringValue(String(val));\n    } else if (Number.isInteger(Number(val))) {\n      return new IntValue(Number(val));\n    } else if (!isNaN(val)) {\n      return new FloatValue(Number(val));\n    } else if (val instanceof Path) {\n      return new DivertTargetValue(asOrThrows(val, Path));\n    } else if (val instanceof InkList) {\n      return new ListValue(asOrThrows(val, InkList));\n    }\n\n    return null;\n  }\n  public Copy() {\n    return asOrThrows(AbstractValue.Create(this.valueObject), InkObject);\n  }\n  public BadCastException(targetType: ValueType) {\n    return new StoryException(\n      \"Can't cast \" +\n        this.valueObject +\n        \" from \" +\n        this.valueType +\n        \" to \" +\n        targetType\n    );\n  }\n}\n\nexport abstract class Value<\n  T extends { toString: () => string },\n> extends AbstractValue {\n  public value: T | null;\n\n  constructor(val: T | null) {\n    super();\n    this.value = val;\n  }\n  public get valueObject() {\n    return this.value;\n  }\n  public toString() {\n    if (this.value === null) return throwNullException(\"Value.value\");\n    return this.value.toString();\n  }\n}\n\nexport class BoolValue extends Value<boolean> {\n  constructor(val: boolean) {\n    super(val || false);\n  }\n  public get isTruthy() {\n    return Boolean(this.value);\n  }\n  public get valueType() {\n    return ValueType.Bool;\n  }\n\n  public Cast(newType: ValueType): Value<any> {\n    if (this.value === null) return throwNullException(\"Value.value\");\n\n    if (newType == this.valueType) {\n      return this;\n    }\n\n    if (newType == ValueType.Int) {\n      return new IntValue(this.value ? 1 : 0);\n    }\n\n    if (newType == ValueType.Float) {\n      return new FloatValue(this.value ? 1.0 : 0.0);\n    }\n\n    if (newType == ValueType.String) {\n      return new StringValue(this.value ? \"true\" : \"false\");\n    }\n\n    throw this.BadCastException(newType);\n  }\n\n  public toString() {\n    return this.value ? \"true\" : \"false\";\n  }\n}\n\nexport class IntValue extends Value<number> {\n  constructor(val: number) {\n    super(val || 0);\n  }\n  public get isTruthy() {\n    return this.value != 0;\n  }\n  public get valueType() {\n    return ValueType.Int;\n  }\n\n  public Cast(newType: ValueType): Value<any> {\n    if (this.value === null) return throwNullException(\"Value.value\");\n\n    if (newType == this.valueType) {\n      return this;\n    }\n\n    if (newType == ValueType.Bool) {\n      return new BoolValue(this.value === 0 ? false : true);\n    }\n\n    if (newType == ValueType.Float) {\n      return new FloatValue(this.value);\n    }\n\n    if (newType == ValueType.String) {\n      return new StringValue(\"\" + this.value);\n    }\n\n    throw this.BadCastException(newType);\n  }\n}\n\nexport class FloatValue extends Value<number> {\n  constructor(val: number) {\n    super(val || 0.0);\n  }\n  public get isTruthy() {\n    return this.value != 0.0;\n  }\n  public get valueType() {\n    return ValueType.Float;\n  }\n\n  public Cast(newType: ValueType): Value<any> {\n    if (this.value === null) return throwNullException(\"Value.value\");\n\n    if (newType == this.valueType) {\n      return this;\n    }\n\n    if (newType == ValueType.Bool) {\n      return new BoolValue(this.value === 0.0 ? false : true);\n    }\n\n    if (newType == ValueType.Int) {\n      return new IntValue(this.value);\n    }\n\n    if (newType == ValueType.String) {\n      return new StringValue(\"\" + this.value);\n    }\n\n    throw this.BadCastException(newType);\n  }\n}\n\nexport class StringValue extends Value<string> {\n  public _isNewline: boolean;\n  public _isInlineWhitespace: boolean;\n\n  constructor(val: string) {\n    super(val || \"\");\n\n    this._isNewline = this.value == \"\\n\";\n    this._isInlineWhitespace = true;\n\n    if (this.value === null) return throwNullException(\"Value.value\");\n\n    if (this.value.length > 0) {\n      this.value.split(\"\").every((c) => {\n        if (c != \" \" && c != \"\\t\") {\n          this._isInlineWhitespace = false;\n          return false;\n        }\n\n        return true;\n      });\n    }\n  }\n  public get valueType() {\n    return ValueType.String;\n  }\n  public get isTruthy() {\n    if (this.value === null) return throwNullException(\"Value.value\");\n    return this.value.length > 0;\n  }\n  public get isNewline() {\n    return this._isNewline;\n  }\n  public get isInlineWhitespace() {\n    return this._isInlineWhitespace;\n  }\n  public get isNonWhitespace() {\n    return !this.isNewline && !this.isInlineWhitespace;\n  }\n\n  public Cast(newType: ValueType): Value<any> {\n    if (newType == this.valueType) {\n      return this;\n    }\n\n    if (newType == ValueType.Int) {\n      let parsedInt = tryParseInt(this.value);\n      if (parsedInt.exists) {\n        return new IntValue(parsedInt.result);\n      } else {\n        throw this.BadCastException(newType);\n      }\n    }\n\n    if (newType == ValueType.Float) {\n      let parsedFloat = tryParseFloat(this.value);\n      if (parsedFloat.exists) {\n        return new FloatValue(parsedFloat.result);\n      } else {\n        throw this.BadCastException(newType);\n      }\n    }\n\n    throw this.BadCastException(newType);\n  }\n}\n\nexport class DivertTargetValue extends Value<Path> {\n  constructor(targetPath: Path | null = null) {\n    super(targetPath);\n  }\n  public get valueType() {\n    return ValueType.DivertTarget;\n  }\n  public get targetPath() {\n    if (this.value === null) return throwNullException(\"Value.value\");\n    return this.value;\n  }\n  public set targetPath(value: Path) {\n    this.value = value;\n  }\n  public get isTruthy(): never {\n    throw new Error(\"Shouldn't be checking the truthiness of a divert target\");\n  }\n\n  public Cast(newType: ValueType): Value<any> {\n    if (newType == this.valueType) return this;\n\n    throw this.BadCastException(newType);\n  }\n  public toString() {\n    return \"DivertTargetValue(\" + this.targetPath + \")\";\n  }\n}\n\nexport class VariablePointerValue extends Value<string> {\n  public _contextIndex: number;\n\n  constructor(variableName: string, contextIndex: number = -1) {\n    super(variableName);\n\n    this._contextIndex = contextIndex;\n  }\n\n  public get contextIndex() {\n    return this._contextIndex;\n  }\n  public set contextIndex(value: number) {\n    this._contextIndex = value;\n  }\n  public get variableName() {\n    if (this.value === null) return throwNullException(\"Value.value\");\n    return this.value;\n  }\n  public set variableName(value: string) {\n    this.value = value;\n  }\n  public get valueType() {\n    return ValueType.VariablePointer;\n  }\n\n  public get isTruthy(): never {\n    throw new Error(\n      \"Shouldn't be checking the truthiness of a variable pointer\"\n    );\n  }\n\n  public Cast(newType: ValueType): Value<any> {\n    if (newType == this.valueType) return this;\n\n    throw this.BadCastException(newType);\n  }\n  public toString() {\n    return \"VariablePointerValue(\" + this.variableName + \")\";\n  }\n  public Copy() {\n    return new VariablePointerValue(this.variableName, this.contextIndex);\n  }\n}\n\nexport class ListValue extends Value<InkList> {\n  public get isTruthy() {\n    if (this.value === null) {\n      return throwNullException(\"this.value\");\n    }\n    return this.value.Count > 0;\n  }\n  public get valueType() {\n    return ValueType.List;\n  }\n  public Cast(newType: ValueType): Value<any> {\n    if (this.value === null) return throwNullException(\"Value.value\");\n\n    if (newType == ValueType.Int) {\n      let max = this.value.maxItem;\n      if (max.Key.isNull) return new IntValue(0);\n      else return new IntValue(max.Value);\n    } else if (newType == ValueType.Float) {\n      let max = this.value.maxItem;\n      if (max.Key.isNull) return new FloatValue(0.0);\n      else return new FloatValue(max.Value);\n    } else if (newType == ValueType.String) {\n      let max = this.value.maxItem;\n      if (max.Key.isNull) return new StringValue(\"\");\n      else {\n        return new StringValue(max.Key.toString());\n      }\n    }\n\n    if (newType == this.valueType) return this;\n\n    throw this.BadCastException(newType);\n  }\n  constructor();\n  constructor(list: InkList);\n  constructor(listOrSingleItem: InkListItem, singleValue: number);\n  constructor(listOrSingleItem?: InkListItem | InkList, singleValue?: number) {\n    super(null);\n\n    if (!listOrSingleItem && !singleValue) {\n      this.value = new InkList();\n    } else if (listOrSingleItem instanceof InkList) {\n      this.value = new InkList(listOrSingleItem);\n    } else if (\n      listOrSingleItem instanceof InkListItem &&\n      typeof singleValue === \"number\"\n    ) {\n      this.value = new InkList({\n        Key: listOrSingleItem,\n        Value: singleValue,\n      });\n    }\n  }\n  public static RetainListOriginsForAssignment(\n    oldValue: InkObject | null,\n    newValue: InkObject\n  ) {\n    let oldList = asOrNull(oldValue, ListValue);\n    let newList = asOrNull(newValue, ListValue);\n\n    if (newList && newList.value === null)\n      return throwNullException(\"newList.value\");\n    if (oldList && oldList.value === null)\n      return throwNullException(\"oldList.value\");\n\n    // When assigning the empty list, try to retain any initial origin names\n    if (oldList && newList && newList.value!.Count == 0)\n      newList.value!.SetInitialOriginNames(oldList.value!.originNames);\n  }\n}\n\nexport enum ValueType {\n  Bool = -1,\n  Int = 0,\n  Float = 1,\n  List = 2,\n  String = 3,\n  DivertTarget = 4,\n  VariablePointer = 5,\n}\n","export enum PushPopType {\n  Tunnel = 0,\n  Function = 1,\n  FunctionEvaluationFromGame = 2,\n}\n","/**\n * In the original C# code, a SystemException would be thrown when passing\n * null to methods expected a valid instance. Javascript has no such\n * concept, but TypeScript will not allow `null` to be passed to methods\n * explicitely requiring a valid type.\n *\n * Whenever TypeScript complain about the possibility of a `null` value,\n * check the offending value and it it's null, throw this exception using\n * `throwNullException(name: string)`.\n */\nexport class NullException extends Error {}\n\n/**\n * Throw a NullException.\n *\n * @param name a short description of the offending value (often its name within the code).\n */\nexport function throwNullException(name: string): never {\n  throw new NullException(`${name} is null or undefined`);\n}\n","import { Path } from \"./Path\";\nimport { Container } from \"./Container\";\nimport { Debug } from \"./Debug\";\nimport { asOrNull, asINamedContentOrNull } from \"./TypeAssertion\";\nimport { throwNullException } from \"./NullException\";\nimport { SearchResult } from \"./SearchResult\";\nimport { DebugMetadata } from \"./DebugMetadata\";\n\nexport class InkObject {\n  public parent: InkObject | null = null;\n\n  get debugMetadata(): DebugMetadata | null {\n    if (this._debugMetadata === null) {\n      if (this.parent) {\n        return this.parent.debugMetadata;\n      }\n    }\n\n    return this._debugMetadata;\n  }\n\n  set debugMetadata(value) {\n    this._debugMetadata = value;\n  }\n\n  get ownDebugMetadata() {\n    return this._debugMetadata;\n  }\n\n  private _debugMetadata: DebugMetadata | null = null;\n\n  public DebugLineNumberOfPath(path: Path) {\n    if (path === null) return null;\n\n    // Try to get a line number from debug metadata\n    let root = this.rootContentContainer;\n    if (root) {\n      let targetContent = root.ContentAtPath(path).obj;\n      if (targetContent) {\n        let dm = targetContent.debugMetadata;\n        if (dm !== null) {\n          return dm.startLineNumber;\n        }\n      }\n    }\n\n    return null;\n  }\n\n  get path() {\n    if (this._path == null) {\n      if (this.parent == null) {\n        this._path = new Path();\n      } else {\n        let comps: Path.Component[] = [];\n\n        let child: InkObject = this;\n        let container = asOrNull(child.parent, Container);\n\n        while (container !== null) {\n          let namedChild = asINamedContentOrNull(child);\n          if (namedChild != null && namedChild.hasValidName) {\n            if (namedChild.name === null)\n              return throwNullException(\"namedChild.name\");\n            comps.unshift(new Path.Component(namedChild.name!));\n          } else {\n            comps.unshift(new Path.Component(container.content.indexOf(child)));\n          }\n\n          child = container;\n          container = asOrNull(container.parent, Container);\n        }\n\n        this._path = new Path(comps);\n      }\n    }\n\n    return this._path;\n  }\n  private _path: Path | null = null;\n\n  public ResolvePath(path: Path | null): SearchResult {\n    if (path === null) return throwNullException(\"path\");\n    if (path.isRelative) {\n      let nearestContainer = asOrNull(this, Container);\n\n      if (nearestContainer === null) {\n        Debug.Assert(\n          this.parent !== null,\n          \"Can't resolve relative path because we don't have a parent\"\n        );\n        nearestContainer = asOrNull(this.parent, Container);\n        Debug.Assert(\n          nearestContainer !== null,\n          \"Expected parent to be a container\"\n        );\n        Debug.Assert(path.GetComponent(0).isParent);\n        path = path.tail;\n      }\n\n      if (nearestContainer === null) {\n        return throwNullException(\"nearestContainer\");\n      }\n      return nearestContainer.ContentAtPath(path);\n    } else {\n      let contentContainer = this.rootContentContainer;\n      if (contentContainer === null) {\n        return throwNullException(\"contentContainer\");\n      }\n      return contentContainer.ContentAtPath(path);\n    }\n  }\n\n  public ConvertPathToRelative(globalPath: Path) {\n    let ownPath = this.path;\n\n    let minPathLength = Math.min(globalPath.length, ownPath.length);\n    let lastSharedPathCompIndex = -1;\n\n    for (let i = 0; i < minPathLength; ++i) {\n      let ownComp = ownPath.GetComponent(i);\n      let otherComp = globalPath.GetComponent(i);\n\n      if (ownComp.Equals(otherComp)) {\n        lastSharedPathCompIndex = i;\n      } else {\n        break;\n      }\n    }\n\n    // No shared path components, so just use global path\n    if (lastSharedPathCompIndex == -1) return globalPath;\n\n    let numUpwardsMoves = ownPath.componentCount - 1 - lastSharedPathCompIndex;\n\n    let newPathComps: Path.Component[] = [];\n\n    for (let up = 0; up < numUpwardsMoves; ++up)\n      newPathComps.push(Path.Component.ToParent());\n\n    for (\n      let down = lastSharedPathCompIndex + 1;\n      down < globalPath.componentCount;\n      ++down\n    )\n      newPathComps.push(globalPath.GetComponent(down));\n\n    let relativePath = new Path(newPathComps, true);\n    return relativePath;\n  }\n\n  public CompactPathString(otherPath: Path) {\n    let globalPathStr = null;\n    let relativePathStr = null;\n\n    if (otherPath.isRelative) {\n      relativePathStr = otherPath.componentsString;\n      globalPathStr = this.path.PathByAppendingPath(otherPath).componentsString;\n    } else {\n      let relativePath = this.ConvertPathToRelative(otherPath);\n      relativePathStr = relativePath.componentsString;\n      globalPathStr = otherPath.componentsString;\n    }\n\n    if (relativePathStr.length < globalPathStr.length) return relativePathStr;\n    else return globalPathStr;\n  }\n\n  get rootContentContainer() {\n    let ancestor: InkObject = this;\n    while (ancestor.parent) {\n      ancestor = ancestor.parent;\n    }\n    return asOrNull(ancestor, Container);\n  }\n\n  public Copy(): InkObject {\n    throw Error(\"Not Implemented: Doesn't support copying\");\n  }\n  // SetChild works slightly diferently in the js implementation.\n  // Since we can't pass an objets property by reference, we instead pass\n  // the object and the property string.\n  // TODO: This method can probably be rewritten with type-safety in mind.\n  public SetChild(obj: any, prop: any, value: any) {\n    if (obj[prop]) obj[prop] = null;\n\n    obj[prop] = value;\n\n    if (obj[prop]) obj[prop].parent = this;\n  }\n\n  public Equals(obj: any) {\n    return obj === this;\n  }\n}\n","export class StringBuilder {\n  private string: string;\n\n  constructor(str?: string) {\n    str = typeof str !== \"undefined\" ? str.toString() : \"\";\n    this.string = str;\n  }\n  get Length(): number {\n    return this.string.length;\n  }\n  public Append(str: string | null) {\n    if (str !== null) {\n      this.string += str;\n    }\n  }\n  public AppendLine(str?: string) {\n    if (typeof str !== \"undefined\") this.Append(str);\n    this.string += \"\\n\";\n  }\n  public AppendFormat(format: string, ...args: any[]) {\n    // taken from http://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format\n    this.string += format.replace(/{(\\d+)}/g, (match: string, num: number) =>\n      typeof args[num] != \"undefined\" ? args[num] : match\n    );\n  }\n  public toString(): string {\n    return this.string;\n  }\n\n  public Clear() {\n    this.string = \"\";\n  }\n}\n","import { throwNullException } from \"./NullException\";\nimport { StringBuilder } from \"./StringBuilder\";\nimport { ListDefinition } from \"./ListDefinition\";\nimport { Story } from \"./Story\";\n\nexport class InkListItem implements IInkListItem {\n  // InkListItem is a struct\n\n  public readonly originName: string | null = null;\n  public readonly itemName: string | null = null;\n\n  constructor(originName: string | null, itemName: string | null);\n  constructor(fullName: string | null);\n  constructor() {\n    if (typeof arguments[1] !== \"undefined\") {\n      let originName = arguments[0] as string | null;\n      let itemName = arguments[1] as string | null;\n\n      this.originName = originName;\n      this.itemName = itemName;\n    } else if (arguments[0]) {\n      let fullName = arguments[0] as string;\n\n      let nameParts = fullName.toString().split(\".\");\n      this.originName = nameParts[0];\n      this.itemName = nameParts[1];\n    }\n  }\n  public static get Null() {\n    return new InkListItem(null, null);\n  }\n  public get isNull() {\n    return this.originName == null && this.itemName == null;\n  }\n  get fullName() {\n    return (\n      (this.originName !== null ? this.originName : \"?\") + \".\" + this.itemName\n    );\n  }\n  public toString(): string {\n    return this.fullName;\n  }\n  public Equals(obj: InkListItem) {\n    if (obj instanceof InkListItem) {\n      let otherItem = obj;\n      return (\n        otherItem.itemName == this.itemName &&\n        otherItem.originName == this.originName\n      );\n    }\n\n    return false;\n  }\n\n  // These methods did not exist in the original C# code. Their purpose is to\n  // make `InkListItem` mimics the value-type semantics of the original\n  // struct. Please refer to the end of this file, for a more in-depth\n  // explanation.\n\n  /**\n   * Returns a shallow clone of the current instance.\n   */\n  public copy() {\n    return new InkListItem(this.originName, this.itemName);\n  }\n  /**\n   * Returns a `SerializedInkListItem` representing the current\n   * instance. The result is intended to be used as a key inside a Map.\n   */\n  public serialized(): SerializedInkListItem {\n    // We are simply using a JSON representation as a value-typed key.\n    return JSON.stringify({\n      originName: this.originName,\n      itemName: this.itemName,\n    });\n  }\n\n  /**\n   * Reconstructs a `InkListItem` from the given SerializedInkListItem.\n   */\n  public static fromSerializedKey(key: SerializedInkListItem): InkListItem {\n    let obj = JSON.parse(key);\n    if (!InkListItem.isLikeInkListItem(obj)) return InkListItem.Null;\n\n    let inkListItem = obj as IInkListItem;\n\n    return new InkListItem(inkListItem.originName, inkListItem.itemName);\n  }\n\n  /**\n   * Determines whether the given item is sufficiently `InkListItem`-like\n   * to be used as a template when reconstructing the InkListItem.\n   */\n  private static isLikeInkListItem(item: any) {\n    if (typeof item !== \"object\") return false;\n    if (!item.hasOwnProperty(\"originName\") || !item.hasOwnProperty(\"itemName\"))\n      return false;\n    if (typeof item.originName !== \"string\" && typeof item.originName !== null)\n      return false;\n    if (typeof item.itemName !== \"string\" && typeof item.itemName !== null)\n      return false;\n\n    return true;\n  }\n}\n\nexport class InkList extends Map<SerializedInkListItem, number> {\n  public origins: ListDefinition[] | null = null;\n  public _originNames: string[] | null = [];\n\n  constructor();\n  constructor(otherList: InkList);\n  constructor(singleOriginListName: string, originStory: Story);\n  constructor(singleElement: KeyValuePair<InkListItem, number>);\n  constructor() {\n    // Trying to be smart here, this emulates the constructor inheritance found\n    // in the original code, but only if otherList is an InkList. IIFE FTW.\n    super(\n      (() => {\n        if (arguments[0] instanceof InkList) {\n          return arguments[0];\n        } else {\n          return [];\n        }\n      })()\n    );\n\n    if (arguments[0] instanceof InkList) {\n      let otherList = arguments[0] as InkList;\n\n      let otherOriginNames = otherList.originNames as string[];\n      if (otherOriginNames !== null)\n        this._originNames = otherOriginNames.slice();\n      if (otherList.origins !== null) {\n        this.origins = otherList.origins.slice();\n      }\n    } else if (typeof arguments[0] === \"string\") {\n      let singleOriginListName = arguments[0] as string;\n      let originStory = arguments[1] as Story;\n      this.SetInitialOriginName(singleOriginListName);\n\n      if (originStory.listDefinitions === null) {\n        return throwNullException(\"originStory.listDefinitions\");\n      }\n      let def = originStory.listDefinitions.TryListGetDefinition(\n        singleOriginListName,\n        null\n      );\n      if (def.exists) {\n        // Throwing now, because if the value is `null` it will\n        // eventually throw down the line.\n        if (def.result === null) {\n          return throwNullException(\"def.result\");\n        }\n        this.origins = [def.result];\n      } else {\n        throw new Error(\n          \"InkList origin could not be found in story when constructing new list: \" +\n            singleOriginListName\n        );\n      }\n    } else if (\n      typeof arguments[0] === \"object\" &&\n      arguments[0].hasOwnProperty(\"Key\") &&\n      arguments[0].hasOwnProperty(\"Value\")\n    ) {\n      let singleElement = arguments[0] as KeyValuePair<InkListItem, number>;\n      this.Add(singleElement.Key, singleElement.Value);\n    }\n  }\n\n  public static FromString(myListItem: string, originStory: Story) {\n    if (myListItem == null || myListItem == \"\") return new InkList();\n    let listValue =\n      originStory.listDefinitions?.FindSingleItemListWithName(myListItem);\n    if (listValue) {\n      if (listValue.value === null) {\n        return throwNullException(\"listValue.value\");\n      }\n      return new InkList(listValue.value);\n    } else {\n      throw new Error(\n        \"Could not find the InkListItem from the string '\" +\n          myListItem +\n          \"' to create an InkList because it doesn't exist in the original list definition in ink.\"\n      );\n    }\n  }\n\n  public AddItem(\n    itemOrItemName: InkListItem | string | null,\n    storyObject: Story | null = null\n  ) {\n    if (itemOrItemName instanceof InkListItem) {\n      let item = itemOrItemName;\n\n      if (item.originName == null) {\n        this.AddItem(item.itemName);\n        return;\n      }\n\n      if (this.origins === null) return throwNullException(\"this.origins\");\n\n      for (let origin of this.origins) {\n        if (origin.name == item.originName) {\n          let intVal = origin.TryGetValueForItem(item, 0);\n          if (intVal.exists) {\n            this.Add(item, intVal.result);\n            return;\n          } else {\n            throw new Error(\n              \"Could not add the item \" +\n                item +\n                \" to this list because it doesn't exist in the original list definition in ink.\"\n            );\n          }\n        }\n      }\n\n      throw new Error(\n        \"Failed to add item to list because the item was from a new list definition that wasn't previously known to this list. Only items from previously known lists can be used, so that the int value can be found.\"\n      );\n    } else if (itemOrItemName !== null) {\n      //itemOrItemName is a string\n      let itemName = itemOrItemName as string;\n\n      let foundListDef: ListDefinition | null = null;\n\n      if (this.origins === null) return throwNullException(\"this.origins\");\n\n      for (let origin of this.origins) {\n        if (itemName === null) return throwNullException(\"itemName\");\n\n        if (origin.ContainsItemWithName(itemName)) {\n          if (foundListDef != null) {\n            throw new Error(\n              \"Could not add the item \" +\n                itemName +\n                \" to this list because it could come from either \" +\n                origin.name +\n                \" or \" +\n                foundListDef.name\n            );\n          } else {\n            foundListDef = origin;\n          }\n        }\n      }\n\n      if (foundListDef == null) {\n        if (storyObject == null) {\n          throw new Error(\n            \"Could not add the item \" +\n              itemName +\n              \" to this list because it isn't known to any list definitions previously associated with this list.\"\n          );\n        } else {\n          let newItem = InkList.FromString(itemName, storyObject)\n            .orderedItems[0];\n          this.Add(newItem.Key, newItem.Value);\n        }\n      } else {\n        let item = new InkListItem(foundListDef.name, itemName);\n        let itemVal = foundListDef.ValueForItem(item);\n        this.Add(item, itemVal);\n      }\n    }\n  }\n  public ContainsItemNamed(itemName: string | null) {\n    for (let [key] of this) {\n      let item = InkListItem.fromSerializedKey(key);\n      if (item.itemName == itemName) return true;\n    }\n\n    return false;\n  }\n  public ContainsKey(key: InkListItem) {\n    return this.has(key.serialized());\n  }\n  public Add(key: InkListItem, value: number) {\n    let serializedKey = key.serialized();\n    if (this.has(serializedKey)) {\n      // Throw an exception to match the C# behavior.\n      throw new Error(`The Map already contains an entry for ${key}`);\n    }\n    this.set(serializedKey, value);\n  }\n  public Remove(key: InkListItem) {\n    return this.delete(key.serialized());\n  }\n  get Count() {\n    return this.size;\n  }\n  get originOfMaxItem(): ListDefinition | null {\n    if (this.origins == null) return null;\n\n    let maxOriginName = this.maxItem.Key.originName;\n    let result = null;\n    this.origins.every((origin) => {\n      if (origin.name == maxOriginName) {\n        result = origin;\n        return false;\n      } else return true;\n    });\n\n    return result;\n  }\n  get originNames(): string[] {\n    if (this.Count > 0) {\n      if (this._originNames == null && this.Count > 0) this._originNames = [];\n      else {\n        if (!this._originNames) this._originNames = [];\n        this._originNames.length = 0;\n      }\n\n      for (let [key] of this) {\n        let item = InkListItem.fromSerializedKey(key);\n        if (item.originName === null)\n          return throwNullException(\"item.originName\");\n        this._originNames.push(item.originName);\n      }\n    }\n\n    return this._originNames as string[];\n  }\n  public SetInitialOriginName(initialOriginName: string) {\n    this._originNames = [initialOriginName];\n  }\n  public SetInitialOriginNames(initialOriginNames: string[]) {\n    if (initialOriginNames == null) this._originNames = null;\n    else this._originNames = initialOriginNames.slice(); // store a copy\n  }\n  get maxItem() {\n    let max: KeyValuePair<InkListItem, number> = {\n      Key: InkListItem.Null,\n      Value: 0,\n    };\n    for (let [key, value] of this) {\n      let item = InkListItem.fromSerializedKey(key);\n      if (max.Key.isNull || value > max.Value)\n        max = { Key: item, Value: value };\n    }\n\n    return max;\n  }\n  get minItem() {\n    let min: KeyValuePair<InkListItem, number> = {\n      Key: InkListItem.Null,\n      Value: 0,\n    };\n    for (let [key, value] of this) {\n      let item = InkListItem.fromSerializedKey(key);\n      if (min.Key.isNull || value < min.Value) {\n        min = { Key: item, Value: value };\n      }\n    }\n    return min;\n  }\n  get inverse() {\n    let list = new InkList();\n    if (this.origins != null) {\n      for (let origin of this.origins) {\n        for (let [key, value] of origin.items) {\n          let item = InkListItem.fromSerializedKey(key);\n          if (!this.ContainsKey(item)) list.Add(item, value);\n        }\n      }\n    }\n    return list;\n  }\n  get all() {\n    let list = new InkList();\n    if (this.origins != null) {\n      for (let origin of this.origins) {\n        for (let [key, value] of origin.items) {\n          let item = InkListItem.fromSerializedKey(key);\n          list.set(item.serialized(), value);\n        }\n      }\n    }\n    return list;\n  }\n  public Union(otherList: InkList) {\n    let union = new InkList(this);\n    for (let [key, value] of otherList) {\n      union.set(key, value);\n    }\n    return union;\n  }\n  public Intersect(otherList: InkList) {\n    let intersection = new InkList();\n    for (let [key, value] of this) {\n      if (otherList.has(key)) intersection.set(key, value);\n    }\n\n    return intersection;\n  }\n  public HasIntersection(otherList: InkList): boolean {\n    for (let [key] of this) {\n      if (otherList.has(key)) return true;\n    }\n    return false;\n  }\n  public Without(listToRemove: InkList) {\n    let result = new InkList(this);\n    for (let [key] of listToRemove) {\n      result.delete(key);\n    }\n\n    return result;\n  }\n\n  public Contains(key: string): boolean;\n  public Contains(otherList: InkList): boolean;\n  public Contains(what: string | InkList): boolean {\n    if (typeof what == \"string\") return this.ContainsItemNamed(what);\n    const otherList = what;\n    if (otherList.size == 0 || this.size == 0) return false;\n    for (let [key] of otherList) {\n      if (!this.has(key)) return false;\n    }\n\n    return true;\n  }\n  public GreaterThan(otherList: InkList) {\n    if (this.Count == 0) return false;\n    if (otherList.Count == 0) return true;\n\n    return this.minItem.Value > otherList.maxItem.Value;\n  }\n  public GreaterThanOrEquals(otherList: InkList) {\n    if (this.Count == 0) return false;\n    if (otherList.Count == 0) return true;\n\n    return (\n      this.minItem.Value >= otherList.minItem.Value &&\n      this.maxItem.Value >= otherList.maxItem.Value\n    );\n  }\n  public LessThan(otherList: InkList) {\n    if (otherList.Count == 0) return false;\n    if (this.Count == 0) return true;\n\n    return this.maxItem.Value < otherList.minItem.Value;\n  }\n  public LessThanOrEquals(otherList: InkList) {\n    if (otherList.Count == 0) return false;\n    if (this.Count == 0) return true;\n\n    return (\n      this.maxItem.Value <= otherList.maxItem.Value &&\n      this.minItem.Value <= otherList.minItem.Value\n    );\n  }\n  public MaxAsList() {\n    if (this.Count > 0) return new InkList(this.maxItem);\n    else return new InkList();\n  }\n  public MinAsList() {\n    if (this.Count > 0) return new InkList(this.minItem);\n    else return new InkList();\n  }\n  public ListWithSubRange(minBound: any, maxBound: any) {\n    if (this.Count == 0) return new InkList();\n\n    let ordered = this.orderedItems;\n\n    let minValue = 0;\n    let maxValue = Number.MAX_SAFE_INTEGER;\n\n    if (Number.isInteger(minBound)) {\n      minValue = minBound;\n    } else {\n      if (minBound instanceof InkList && minBound.Count > 0)\n        minValue = minBound.minItem.Value;\n    }\n\n    if (Number.isInteger(maxBound)) {\n      maxValue = maxBound;\n    } else {\n      if (maxBound instanceof InkList && maxBound.Count > 0)\n        maxValue = maxBound.maxItem.Value;\n    }\n\n    let subList = new InkList();\n    subList.SetInitialOriginNames(this.originNames);\n    for (let item of ordered) {\n      if (item.Value >= minValue && item.Value <= maxValue) {\n        subList.Add(item.Key, item.Value);\n      }\n    }\n\n    return subList;\n  }\n  public Equals(otherInkList: InkList) {\n    if (otherInkList instanceof InkList === false) return false;\n    if (otherInkList.Count != this.Count) return false;\n\n    for (let [key] of this) {\n      if (!otherInkList.has(key)) return false;\n    }\n\n    return true;\n  }\n  // GetHashCode not implemented\n  get orderedItems() {\n    // List<KeyValuePair<InkListItem, int>>\n    let ordered = new Array<KeyValuePair<InkListItem, number>>();\n\n    for (let [key, value] of this) {\n      let item = InkListItem.fromSerializedKey(key);\n      ordered.push({ Key: item, Value: value });\n    }\n\n    ordered.sort((x, y) => {\n      if (x.Key.originName === null) {\n        return throwNullException(\"x.Key.originName\");\n      }\n      if (y.Key.originName === null) {\n        return throwNullException(\"y.Key.originName\");\n      }\n\n      if (x.Value == y.Value) {\n        return x.Key.originName.localeCompare(y.Key.originName);\n      } else {\n        // TODO: refactor this bit into a numberCompareTo method?\n        if (x.Value < y.Value) return -1;\n        return x.Value > y.Value ? 1 : 0;\n      }\n    });\n\n    return ordered;\n  }\n\n  get singleItem(): InkListItem | null {\n    for (let item of this.orderedItems) {\n      return item.Key;\n    }\n    return null;\n  }\n\n  public toString() {\n    let ordered = this.orderedItems;\n\n    let sb = new StringBuilder();\n    for (let i = 0; i < ordered.length; i++) {\n      if (i > 0) sb.Append(\", \");\n\n      let item = ordered[i].Key;\n      if (item.itemName === null) return throwNullException(\"item.itemName\");\n      sb.Append(item.itemName);\n    }\n\n    return sb.toString();\n  }\n  // casting a InkList to a Number, for somereason, actually gives a number.\n  // This messes up the type detection when creating a Value from a InkList.\n  // Returning NaN here prevents that.\n  public valueOf() {\n    return NaN;\n  }\n}\n\n/**\n * In the original C# code, `InkListItem` was defined as value type, meaning\n * that two `InkListItem` would be considered equal as long as they held the\n * same values. This doesn't hold true in Javascript, as `InkListItem` is a\n * reference type (Javascript doesn't allow the creation of custom value types).\n *\n * The key equality of Map objects is based on the \"SameValueZero\" algorithm;\n * since `InkListItem` is a value type, two keys will only be considered\n * equal if they are, in fact, the same object. As we are trying to emulate\n * the original behavior as close as possible, this will lead to unforeseen\n * side effects.\n *\n * In order to have a key equality based on value semantics, we'll convert\n * `InkListItem` to a valid string representation and use this representation\n * as a key (strings are value types in Javascript). Rather than using the\n * type `string` directly, we'll alias it to `SerializedInkListItem` and use\n * this type as the key for our Map-based `InkList`.\n *\n * Reducing `InkListItem` to a JSON representation would not be bulletproof\n * in the general case, but for our needs it works well. The major downside of\n * this method is that we will have to to reconstruct the original `InkListItem`\n * every time we'll need to access its properties.\n */\nexport type SerializedInkListItem = string;\n\n/**\n * An interface inherited by `InkListItem`, defining exposed\n * properties. It's mainly used when deserializing a `InkListItem` from its\n * key (`SerializedInkListItem`)\n */\ninterface IInkListItem {\n  readonly originName: string | null;\n  readonly itemName: string | null;\n}\nexport interface KeyValuePair<K, V> {\n  Key: K;\n  Value: V;\n}\n","export class StoryException extends Error {\n  public useEndLineNumber: boolean;\n  public message: string;\n  public name: string;\n\n  constructor(message: string) {\n    super(message);\n    this.useEndLineNumber = false;\n    this.message = message;\n    this.name = \"StoryException\";\n  }\n}\n","/**\n * This interface normalize the `TryGet` behavior found in the original\n * C# project. Any `TryGet` method will return a object conforming to this\n * interface.\n *\n * The original function returns a boolean and has a second parameter called\n * item that is an `out`. Both are needed and we can't just return the item\n * because it'll always be truthy. Instead, we return an object containing\n * whether the result exists (`exists`) and the result itself (`result`).\n *\n * For instance a `TryGet` prototype would look like this:\n```\nTryGetItemWithValue(val: number, item: InkListItem): TryGetResult<InkListItem>{\n```\n *\n * On the other hand, dealing with the result can be done in the following way:\n```\nvar item = item.TryGetItemWithValue(intVal, InkListItem.Null);\nif (item.exists) {\n\tconsole.log(item.result)\n}\n```\n *\n */\nexport interface TryGetResult<T> {\n  result: T;\n  exists: boolean;\n}\n\nexport function tryGetValueFromMap<K, V>(\n  map: Map<K, V> | null,\n  key: K,\n  /* out */ value: V\n): TryGetResult<V> {\n  if (map === null) {\n    return { result: value, exists: false };\n  }\n\n  let val = map.get(key);\n\n  if (typeof val === \"undefined\") {\n    return { result: value, exists: false };\n  } else {\n    return { result: val, exists: true };\n  }\n}\n\nexport function tryParseInt(\n  value: any,\n  /* out */ defaultValue: number = 0\n): TryGetResult<number> {\n  let val = parseInt(value);\n\n  if (!Number.isNaN(val)) {\n    return { result: val, exists: true };\n  } else {\n    return { result: defaultValue, exists: false };\n  }\n}\n\nexport function tryParseFloat(\n  value: any,\n  /* out */ defaultValue: number = 0\n): TryGetResult<number> {\n  let val = parseFloat(value);\n\n  if (!Number.isNaN(val)) {\n    return { result: val, exists: true };\n  } else {\n    return { result: defaultValue, exists: false };\n  }\n}\n","import { InkObject } from \"./Object\";\nimport { Container } from \"./Container\";\n\nexport class SearchResult {\n  public obj: InkObject | null = null;\n  public approximate: boolean = false;\n\n  get correctObj() {\n    return this.approximate ? null : this.obj;\n  }\n\n  get container() {\n    return this.obj instanceof Container ? this.obj : null;\n  }\n\n  public copy() {\n    let searchResult = new SearchResult();\n    searchResult.obj = this.obj;\n    searchResult.approximate = this.approximate;\n\n    return searchResult;\n  }\n}\n","import { StringValue } from \"./Value\";\nimport { throwNullException } from \"./NullException\";\nimport { StringBuilder } from \"./StringBuilder\";\nimport { INamedContent } from \"./INamedContent\";\nimport { InkObject } from \"./Object\";\nimport { SearchResult } from \"./SearchResult\";\nimport { Path } from \"./Path\";\nimport { Debug } from \"./Debug\";\nimport { tryGetValueFromMap } from \"./TryGetResult\";\nimport { asINamedContentOrNull, asOrNull, asOrThrows } from \"./TypeAssertion\";\n\nexport class Container extends InkObject implements INamedContent {\n  public name: string | null = null;\n\n  public _content: InkObject[] = [];\n  public namedContent: Map<string, INamedContent> = new Map();\n\n  public visitsShouldBeCounted: boolean = false;\n  public turnIndexShouldBeCounted: boolean = false;\n  public countingAtStartOnly: boolean = false;\n\n  public _pathToFirstLeafContent: Path | null = null;\n\n  get hasValidName() {\n    return this.name != null && this.name.length > 0;\n  }\n  get content() {\n    return this._content;\n  }\n  set content(value: InkObject[]) {\n    this.AddContent(value);\n  }\n  get namedOnlyContent() {\n    let namedOnlyContentDict: Map<string, InkObject> | null = new Map();\n\n    for (let [key, value] of this.namedContent) {\n      let inkObject = asOrThrows(value, InkObject);\n      namedOnlyContentDict.set(key, inkObject);\n    }\n\n    for (let c of this.content) {\n      let named = asINamedContentOrNull(c);\n      if (named != null && named.hasValidName) {\n        namedOnlyContentDict.delete(named.name!);\n      }\n    }\n\n    if (namedOnlyContentDict.size == 0) namedOnlyContentDict = null;\n\n    return namedOnlyContentDict;\n  }\n  set namedOnlyContent(value: Map<string, InkObject> | null) {\n    let existingNamedOnly = this.namedOnlyContent;\n    if (existingNamedOnly != null) {\n      for (let [key] of existingNamedOnly) {\n        this.namedContent.delete(key);\n      }\n    }\n\n    if (value == null) return;\n\n    for (let [, val] of value) {\n      let named = asINamedContentOrNull(val);\n      if (named != null) this.AddToNamedContentOnly(named);\n    }\n  }\n  get countFlags(): number {\n    let flags: Container.CountFlags = 0;\n    if (this.visitsShouldBeCounted) flags |= Container.CountFlags.Visits;\n    if (this.turnIndexShouldBeCounted) flags |= Container.CountFlags.Turns;\n    if (this.countingAtStartOnly) flags |= Container.CountFlags.CountStartOnly;\n\n    if (flags == Container.CountFlags.CountStartOnly) {\n      flags = 0;\n    }\n\n    return flags;\n  }\n  set countFlags(value: number) {\n    let flag: Container.CountFlags = value;\n    if ((flag & Container.CountFlags.Visits) > 0)\n      this.visitsShouldBeCounted = true;\n    if ((flag & Container.CountFlags.Turns) > 0)\n      this.turnIndexShouldBeCounted = true;\n    if ((flag & Container.CountFlags.CountStartOnly) > 0)\n      this.countingAtStartOnly = true;\n  }\n  get pathToFirstLeafContent() {\n    if (this._pathToFirstLeafContent == null)\n      this._pathToFirstLeafContent = this.path.PathByAppendingPath(\n        this.internalPathToFirstLeafContent\n      );\n\n    return this._pathToFirstLeafContent;\n  }\n  get internalPathToFirstLeafContent() {\n    let components: Path.Component[] = [];\n    let container: Container = this;\n    while (container instanceof Container) {\n      if (container.content.length > 0) {\n        components.push(new Path.Component(0));\n        container = container.content[0] as Container;\n      }\n    }\n    return new Path(components);\n  }\n\n  public AddContent(contentObjOrList: InkObject | InkObject[]) {\n    if (contentObjOrList instanceof Array) {\n      let contentList = contentObjOrList as InkObject[];\n\n      for (let c of contentList) {\n        this.AddContent(c);\n      }\n    } else {\n      let contentObj = contentObjOrList as InkObject;\n\n      this._content.push(contentObj);\n\n      if (contentObj.parent) {\n        throw new Error(\"content is already in \" + contentObj.parent);\n      }\n\n      contentObj.parent = this;\n\n      this.TryAddNamedContent(contentObj);\n    }\n  }\n  public TryAddNamedContent(contentObj: InkObject) {\n    let namedContentObj = asINamedContentOrNull(contentObj);\n    if (namedContentObj != null && namedContentObj.hasValidName) {\n      this.AddToNamedContentOnly(namedContentObj);\n    }\n  }\n  public AddToNamedContentOnly(namedContentObj: INamedContent) {\n    Debug.AssertType(\n      namedContentObj,\n      InkObject,\n      \"Can only add Runtime.Objects to a Runtime.Container\"\n    );\n    let runtimeObj = asOrThrows(namedContentObj, InkObject);\n    runtimeObj.parent = this;\n\n    if (namedContentObj.name === null)\n      return throwNullException(\"namedContentObj.name\");\n    this.namedContent.set(namedContentObj.name!, namedContentObj);\n  }\n  public ContentAtPath(\n    path: Path,\n    partialPathStart: number = 0,\n    partialPathLength: number = -1\n  ) {\n    if (partialPathLength == -1) partialPathLength = path.length;\n\n    let result = new SearchResult();\n    result.approximate = false;\n\n    let currentContainer: Container | null = this;\n    let currentObj: InkObject = this;\n\n    for (let i = partialPathStart; i < partialPathLength; ++i) {\n      let comp = path.GetComponent(i);\n      if (currentContainer == null) {\n        result.approximate = true;\n        break;\n      }\n\n      let foundObj: InkObject | null =\n        currentContainer.ContentWithPathComponent(comp);\n\n      // Couldn't resolve entire path?\n      if (foundObj == null) {\n        result.approximate = true;\n        break;\n      }\n\n      // Are we about to loop into another container?\n      // Is the object a container as expected? It might\n      // no longer be if the content has shuffled around, so what\n      // was originally a container no longer is.\n      const nextContainer: Container | null = asOrNull(foundObj, Container);\n      if (i < partialPathLength - 1 && nextContainer == null) {\n        result.approximate = true;\n        break;\n      }\n\n      currentObj = foundObj;\n      currentContainer = nextContainer;\n    }\n\n    result.obj = currentObj;\n\n    return result;\n  }\n  public InsertContent(contentObj: InkObject, index: number) {\n    this.content.splice(index, 0, contentObj);\n\n    if (contentObj.parent) {\n      throw new Error(\"content is already in \" + contentObj.parent);\n    }\n\n    contentObj.parent = this;\n\n    this.TryAddNamedContent(contentObj);\n  }\n  public AddContentsOfContainer(otherContainer: Container) {\n    this.content.push(...otherContainer.content);\n\n    for (let obj of otherContainer.content) {\n      obj.parent = this;\n      this.TryAddNamedContent(obj);\n    }\n  }\n  public ContentWithPathComponent(component: Path.Component): InkObject | null {\n    if (component.isIndex) {\n      if (component.index >= 0 && component.index < this.content.length) {\n        return this.content[component.index];\n      } else {\n        return null;\n      }\n    } else if (component.isParent) {\n      return this.parent;\n    } else {\n      if (component.name === null) {\n        return throwNullException(\"component.name\");\n      }\n      let foundContent = tryGetValueFromMap(\n        this.namedContent,\n        component.name,\n        null\n      );\n      if (foundContent.exists) {\n        return asOrThrows(foundContent.result, InkObject);\n      } else {\n        return null;\n      }\n    }\n  }\n  public BuildStringOfHierarchy(): string;\n  public BuildStringOfHierarchy(\n    sb: StringBuilder,\n    indentation: number,\n    pointedObj: InkObject | null\n  ): string;\n  public BuildStringOfHierarchy() {\n    let sb: StringBuilder;\n    if (arguments.length == 0) {\n      sb = new StringBuilder();\n      this.BuildStringOfHierarchy(sb, 0, null);\n      return sb.toString();\n    }\n\n    sb = arguments[0] as StringBuilder;\n    let indentation = arguments[1] as number;\n    let pointedObj = arguments[2] as InkObject | null;\n\n    function appendIndentation() {\n      const spacesPerIndent = 4; // Truly const in the original code\n      for (let i = 0; i < spacesPerIndent * indentation; ++i) {\n        sb.Append(\" \");\n      }\n    }\n\n    appendIndentation();\n    sb.Append(\"[\");\n\n    if (this.hasValidName) {\n      sb.AppendFormat(\" ({0})\", this.name);\n    }\n\n    if (this == pointedObj) {\n      sb.Append(\"  <---\");\n    }\n\n    sb.AppendLine();\n\n    indentation++;\n\n    for (let i = 0; i < this.content.length; ++i) {\n      let obj = this.content[i];\n\n      if (obj instanceof Container) {\n        let container = obj as Container;\n\n        container.BuildStringOfHierarchy(sb, indentation, pointedObj);\n      } else {\n        appendIndentation();\n        if (obj instanceof StringValue) {\n          sb.Append('\"');\n          sb.Append(obj.toString().replace(\"\\n\", \"\\\\n\"));\n          sb.Append('\"');\n        } else {\n          sb.Append(obj.toString());\n        }\n      }\n\n      if (i != this.content.length - 1) {\n        sb.Append(\",\");\n      }\n\n      if (!(obj instanceof Container) && obj == pointedObj) {\n        sb.Append(\"  <---\");\n      }\n\n      sb.AppendLine();\n    }\n\n    let onlyNamed: Map<string, INamedContent> = new Map();\n\n    for (let [key, value] of this.namedContent) {\n      if (this.content.indexOf(asOrThrows(value, InkObject)) >= 0) {\n        continue;\n      } else {\n        onlyNamed.set(key, value);\n      }\n    }\n\n    if (onlyNamed.size > 0) {\n      appendIndentation();\n      sb.AppendLine(\"-- named: --\");\n\n      for (let [, value] of onlyNamed) {\n        Debug.AssertType(\n          value,\n          Container,\n          \"Can only print out named Containers\"\n        );\n        let container = value as Container;\n        container.BuildStringOfHierarchy(sb, indentation, pointedObj);\n        sb.AppendLine();\n      }\n    }\n\n    indentation--;\n\n    appendIndentation();\n    sb.Append(\"]\");\n  }\n}\n\nexport namespace Container {\n  export enum CountFlags {\n    Start = 0,\n    Visits = 1,\n    Turns = 2,\n    CountStartOnly = 4,\n  }\n}\n","import { InkObject } from \"./Object\";\n\nexport class ControlCommand extends InkObject {\n  private _commandType: ControlCommand.CommandType;\n\n  get commandType(): ControlCommand.CommandType {\n    return this._commandType;\n  }\n\n  constructor(\n    commandType: ControlCommand.CommandType = ControlCommand.CommandType.NotSet\n  ) {\n    super();\n    this._commandType = commandType;\n  }\n\n  public Copy() {\n    return new ControlCommand(this.commandType);\n  }\n  public static EvalStart() {\n    return new ControlCommand(ControlCommand.CommandType.EvalStart);\n  }\n  public static EvalOutput() {\n    return new ControlCommand(ControlCommand.CommandType.EvalOutput);\n  }\n  public static EvalEnd() {\n    return new ControlCommand(ControlCommand.CommandType.EvalEnd);\n  }\n  public static Duplicate() {\n    return new ControlCommand(ControlCommand.CommandType.Duplicate);\n  }\n  public static PopEvaluatedValue() {\n    return new ControlCommand(ControlCommand.CommandType.PopEvaluatedValue);\n  }\n  public static PopFunction() {\n    return new ControlCommand(ControlCommand.CommandType.PopFunction);\n  }\n  public static PopTunnel() {\n    return new ControlCommand(ControlCommand.CommandType.PopTunnel);\n  }\n  public static BeginString() {\n    return new ControlCommand(ControlCommand.CommandType.BeginString);\n  }\n  public static EndString() {\n    return new ControlCommand(ControlCommand.CommandType.EndString);\n  }\n  public static NoOp() {\n    return new ControlCommand(ControlCommand.CommandType.NoOp);\n  }\n  public static ChoiceCount() {\n    return new ControlCommand(ControlCommand.CommandType.ChoiceCount);\n  }\n  public static Turns() {\n    return new ControlCommand(ControlCommand.CommandType.Turns);\n  }\n  public static TurnsSince() {\n    return new ControlCommand(ControlCommand.CommandType.TurnsSince);\n  }\n  public static ReadCount() {\n    return new ControlCommand(ControlCommand.CommandType.ReadCount);\n  }\n  public static Random() {\n    return new ControlCommand(ControlCommand.CommandType.Random);\n  }\n  public static SeedRandom() {\n    return new ControlCommand(ControlCommand.CommandType.SeedRandom);\n  }\n  public static VisitIndex() {\n    return new ControlCommand(ControlCommand.CommandType.VisitIndex);\n  }\n  public static SequenceShuffleIndex() {\n    return new ControlCommand(ControlCommand.CommandType.SequenceShuffleIndex);\n  }\n  public static StartThread() {\n    return new ControlCommand(ControlCommand.CommandType.StartThread);\n  }\n  public static Done() {\n    return new ControlCommand(ControlCommand.CommandType.Done);\n  }\n  public static End() {\n    return new ControlCommand(ControlCommand.CommandType.End);\n  }\n  public static ListFromInt() {\n    return new ControlCommand(ControlCommand.CommandType.ListFromInt);\n  }\n  public static ListRange() {\n    return new ControlCommand(ControlCommand.CommandType.ListRange);\n  }\n  public static ListRandom() {\n    return new ControlCommand(ControlCommand.CommandType.ListRandom);\n  }\n  public static BeginTag() {\n    return new ControlCommand(ControlCommand.CommandType.BeginTag);\n  }\n  public static EndTag() {\n    return new ControlCommand(ControlCommand.CommandType.EndTag);\n  }\n  public toString() {\n    return \"ControlCommand \" + this.commandType.toString();\n  }\n}\n\nexport namespace ControlCommand {\n  export enum CommandType {\n    NotSet = -1,\n    EvalStart, // 0\n    EvalOutput, // 1\n    EvalEnd, // 2\n    Duplicate, // 3\n    PopEvaluatedValue, // 4\n    PopFunction, // 5\n    PopTunnel, // 6\n    BeginString, // 7\n    EndString, // 8\n    NoOp, // 9\n    ChoiceCount, // 10\n    Turns, // 11\n    TurnsSince, // 12\n    ReadCount, // 13\n    Random, // 14\n    SeedRandom, // 15\n    VisitIndex, // 16\n    SequenceShuffleIndex, // 17\n    StartThread, // 18\n    Done, // 19\n    End, // 20\n    ListFromInt, // 21\n    ListRange, // 22\n    ListRandom, // 23\n    BeginTag, // 24\n    EndTag, // 25\n\n    TOTAL_VALUES,\n  }\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../../engine/ControlCommand\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\n\nexport abstract class Expression extends ParsedObject {\n  public abstract GenerateIntoContainer: (container: RuntimeContainer) => void;\n\n  private _prototypeRuntimeConstantExpression: RuntimeContainer | null = null;\n  public outputWhenComplete: boolean = false;\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    const container = new RuntimeContainer();\n\n    // Tell Runtime to start evaluating the following content as an expression\n    container.AddContent(RuntimeControlCommand.EvalStart());\n\n    this.GenerateIntoContainer(container);\n\n    // Tell Runtime to output the result of the expression evaluation to the output stream\n    if (this.outputWhenComplete) {\n      container.AddContent(RuntimeControlCommand.EvalOutput());\n    }\n\n    // Tell Runtime to stop evaluating the content as an expression\n    container.AddContent(RuntimeControlCommand.EvalEnd());\n\n    return container;\n  };\n\n  // When generating the value of a constant expression,\n  // we can't just keep generating the same constant expression into\n  // different places where the constant value is referenced, since then\n  // the same runtime objects would be used in multiple places, which\n  // is impossible since each runtime object should have one parent.\n  // Instead, we generate a prototype of the runtime object(s), then\n  // copy them each time they're used.\n  public readonly GenerateConstantIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    if (this._prototypeRuntimeConstantExpression === null) {\n      this._prototypeRuntimeConstantExpression = new RuntimeContainer();\n      this.GenerateIntoContainer(this._prototypeRuntimeConstantExpression);\n    }\n\n    for (const runtimeObj of this._prototypeRuntimeConstantExpression.content) {\n      const copy = runtimeObj.Copy();\n      if (copy) {\n        container.AddContent(copy);\n      }\n    }\n  };\n\n  get typeName(): string {\n    return \"Expression\";\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public Equals(obj: ParsedObject): boolean {\n    return false;\n  }\n\n  public readonly toString = () => \"No string value in JavaScript.\";\n}\n","import { InkObject } from \"./Object\";\n\nexport class Void extends InkObject {\n  public toString() {\n    return \"Void\";\n  }\n}\n","import { Value, ValueType, IntValue, ListValue, BoolValue } from \"./Value\";\nimport { StoryException } from \"./StoryException\";\nimport { Void } from \"./Void\";\nimport { Path } from \"./Path\";\nimport { InkList, InkListItem } from \"./InkList\";\nimport { InkObject } from \"./Object\";\nimport { asOrNull, asOrThrows, asBooleanOrThrows } from \"./TypeAssertion\";\nimport { throwNullException } from \"./NullException\";\n\ntype BinaryOp<T> = (left: T, right: T) => any;\ntype UnaryOp<T> = (val: T) => any;\n\nexport class NativeFunctionCall extends InkObject {\n  public static readonly Add: string = \"+\";\n  public static readonly Subtract: string = \"-\";\n  public static readonly Divide: string = \"/\";\n  public static readonly Multiply: string = \"*\";\n  public static readonly Mod: string = \"%\";\n  public static readonly Negate: string = \"_\";\n  public static readonly Equal: string = \"==\";\n  public static readonly Greater: string = \">\";\n  public static readonly Less: string = \"<\";\n  public static readonly GreaterThanOrEquals: string = \">=\";\n  public static readonly LessThanOrEquals: string = \"<=\";\n  public static readonly NotEquals: string = \"!=\";\n  public static readonly Not: string = \"!\";\n  public static readonly And: string = \"&&\";\n  public static readonly Or: string = \"||\";\n  public static readonly Min: string = \"MIN\";\n  public static readonly Max: string = \"MAX\";\n  public static readonly Pow: string = \"POW\";\n  public static readonly Floor: string = \"FLOOR\";\n  public static readonly Ceiling: string = \"CEILING\";\n  public static readonly Int: string = \"INT\";\n  public static readonly Float: string = \"FLOAT\";\n  public static readonly Has: string = \"?\";\n  public static readonly Hasnt: string = \"!?\";\n  public static readonly Intersect: string = \"^\";\n  public static readonly ListMin: string = \"LIST_MIN\";\n  public static readonly ListMax: string = \"LIST_MAX\";\n  public static readonly All: string = \"LIST_ALL\";\n  public static readonly Count: string = \"LIST_COUNT\";\n  public static readonly ValueOfList: string = \"LIST_VALUE\";\n  public static readonly Invert: string = \"LIST_INVERT\";\n\n  public static CallWithName(functionName: string) {\n    return new NativeFunctionCall(functionName);\n  }\n\n  public static CallExistsWithName(functionName: string) {\n    this.GenerateNativeFunctionsIfNecessary();\n    return this._nativeFunctions!.get(functionName);\n  }\n\n  get name() {\n    if (this._name === null)\n      return throwNullException(\"NativeFunctionCall._name\");\n    return this._name;\n  }\n  set name(value: string) {\n    this._name = value;\n    if (!this._isPrototype) {\n      if (NativeFunctionCall._nativeFunctions === null)\n        throwNullException(\"NativeFunctionCall._nativeFunctions\");\n      else\n        this._prototype =\n          NativeFunctionCall._nativeFunctions.get(this._name) || null;\n    }\n  }\n  public _name: string | null = null;\n\n  get numberOfParameters() {\n    if (this._prototype) {\n      return this._prototype.numberOfParameters;\n    } else {\n      return this._numberOfParameters;\n    }\n  }\n  set numberOfParameters(value: number) {\n    this._numberOfParameters = value;\n  }\n  public _numberOfParameters: number = 0;\n\n  public Call(parameters: InkObject[]): InkObject | null {\n    if (this._prototype) {\n      return this._prototype.Call(parameters);\n    }\n\n    if (this.numberOfParameters != parameters.length) {\n      throw new Error(\"Unexpected number of parameters\");\n    }\n\n    let hasList = false;\n    for (let p of parameters) {\n      if (p instanceof Void)\n        throw new StoryException(\n          \"Attempting to perform \" +\n            this.name +\n            ' on a void value. Did you forget to \"return\" a value from a function you called here?'\n        );\n      if (p instanceof ListValue) hasList = true;\n    }\n\n    if (parameters.length == 2 && hasList) {\n      return this.CallBinaryListOperation(parameters);\n    }\n\n    let coercedParams = this.CoerceValuesToSingleType(parameters);\n    let coercedType = coercedParams[0].valueType;\n\n    if (coercedType == ValueType.Int) {\n      return this.CallType<number>(coercedParams);\n    } else if (coercedType == ValueType.Float) {\n      return this.CallType<number>(coercedParams);\n    } else if (coercedType == ValueType.String) {\n      return this.CallType<string>(coercedParams);\n    } else if (coercedType == ValueType.DivertTarget) {\n      return this.CallType<Path>(coercedParams);\n    } else if (coercedType == ValueType.List) {\n      return this.CallType<InkList>(coercedParams);\n    }\n\n    return null;\n  }\n\n  public CallType<T extends { toString: () => string }>(\n    parametersOfSingleType: Array<Value<T>>\n  ) {\n    let param1 = asOrThrows(parametersOfSingleType[0], Value);\n    let valType = param1.valueType;\n\n    let val1 = param1 as Value<T>;\n\n    let paramCount = parametersOfSingleType.length;\n\n    if (paramCount == 2 || paramCount == 1) {\n      if (this._operationFuncs === null)\n        return throwNullException(\"NativeFunctionCall._operationFuncs\");\n      let opForTypeObj = this._operationFuncs.get(valType);\n      if (!opForTypeObj) {\n        const key = ValueType[valType];\n        throw new StoryException(\n          \"Cannot perform operation \" + this.name + \" on \" + key\n        );\n      }\n\n      if (paramCount == 2) {\n        let param2 = asOrThrows(parametersOfSingleType[1], Value);\n\n        let val2 = param2 as Value<T>;\n\n        let opForType = opForTypeObj as BinaryOp<T>;\n\n        if (val1.value === null || val2.value === null)\n          return throwNullException(\"NativeFunctionCall.Call BinaryOp values\");\n        let resultVal = opForType(val1.value, val2.value);\n\n        return Value.Create(resultVal);\n      } else {\n        let opForType = opForTypeObj as UnaryOp<T>;\n\n        if (val1.value === null)\n          return throwNullException(\"NativeFunctionCall.Call UnaryOp value\");\n        let resultVal = opForType(val1.value);\n\n        // This code is different from upstream. Since JavaScript treats\n        // integers and floats as the same numbers, it's impossible\n        // to force an number to be either an integer or a float.\n        //\n        // It can be useful to force a specific number type\n        // (especially for divisions), so the result of INT() & FLOAT()\n        // is coerced to the the proper value type.\n        //\n        // Note that we also force all other unary operation to\n        // return the same value type, although this is only\n        // meaningful for numbers. See `Value.Create`.\n        if (this.name === NativeFunctionCall.Int) {\n          return Value.Create(resultVal, ValueType.Int);\n        } else if (this.name === NativeFunctionCall.Float) {\n          return Value.Create(resultVal, ValueType.Float);\n        } else {\n          return Value.Create(resultVal, param1.valueType);\n        }\n      }\n    } else {\n      throw new Error(\n        \"Unexpected number of parameters to NativeFunctionCall: \" +\n          parametersOfSingleType.length\n      );\n    }\n  }\n\n  public CallBinaryListOperation(parameters: InkObject[]) {\n    if (\n      (this.name == \"+\" || this.name == \"-\") &&\n      parameters[0] instanceof ListValue &&\n      parameters[1] instanceof IntValue\n    )\n      return this.CallListIncrementOperation(parameters);\n\n    let v1 = asOrThrows(parameters[0], Value);\n    let v2 = asOrThrows(parameters[1], Value);\n\n    if (\n      (this.name == \"&&\" || this.name == \"||\") &&\n      (v1.valueType != ValueType.List || v2.valueType != ValueType.List)\n    ) {\n      if (this._operationFuncs === null)\n        return throwNullException(\"NativeFunctionCall._operationFuncs\");\n      let op = this._operationFuncs.get(ValueType.Int) as BinaryOp<number>;\n      if (op === null)\n        return throwNullException(\n          \"NativeFunctionCall.CallBinaryListOperation op\"\n        );\n      let result = asBooleanOrThrows(\n        op(v1.isTruthy ? 1 : 0, v2.isTruthy ? 1 : 0)\n      );\n      return new BoolValue(result);\n    }\n\n    if (v1.valueType == ValueType.List && v2.valueType == ValueType.List)\n      return this.CallType<InkList>([v1, v2]);\n\n    throw new StoryException(\n      \"Can not call use \" +\n        this.name +\n        \" operation on \" +\n        ValueType[v1.valueType] +\n        \" and \" +\n        ValueType[v2.valueType]\n    );\n  }\n\n  public CallListIncrementOperation(listIntParams: InkObject[]) {\n    let listVal = asOrThrows(listIntParams[0], ListValue);\n    let intVal = asOrThrows(listIntParams[1], IntValue);\n\n    let resultInkList = new InkList();\n\n    if (listVal.value === null)\n      return throwNullException(\n        \"NativeFunctionCall.CallListIncrementOperation listVal.value\"\n      );\n    for (let [listItemKey, listItemValue] of listVal.value) {\n      let listItem = InkListItem.fromSerializedKey(listItemKey);\n\n      if (this._operationFuncs === null)\n        return throwNullException(\"NativeFunctionCall._operationFuncs\");\n      let intOp = this._operationFuncs.get(ValueType.Int) as BinaryOp<number>;\n\n      if (intVal.value === null)\n        return throwNullException(\n          \"NativeFunctionCall.CallListIncrementOperation intVal.value\"\n        );\n      let targetInt = intOp(listItemValue, intVal.value);\n\n      let itemOrigin = null;\n      if (listVal.value.origins === null)\n        return throwNullException(\n          \"NativeFunctionCall.CallListIncrementOperation listVal.value.origins\"\n        );\n      for (let origin of listVal.value.origins) {\n        if (origin.name == listItem.originName) {\n          itemOrigin = origin;\n          break;\n        }\n      }\n      if (itemOrigin != null) {\n        let incrementedItem = itemOrigin.TryGetItemWithValue(\n          targetInt,\n          InkListItem.Null\n        );\n        if (incrementedItem.exists)\n          resultInkList.Add(incrementedItem.result, targetInt);\n      }\n    }\n\n    return new ListValue(resultInkList);\n  }\n\n  public CoerceValuesToSingleType(parametersIn: InkObject[]) {\n    let valType = ValueType.Int;\n\n    let specialCaseList: null | ListValue = null;\n\n    for (let obj of parametersIn) {\n      let val = asOrThrows(obj, Value);\n      if (val.valueType > valType) {\n        valType = val.valueType;\n      }\n\n      if (val.valueType == ValueType.List) {\n        specialCaseList = asOrNull(val, ListValue);\n      }\n    }\n\n    let parametersOut = [];\n\n    if (ValueType[valType] == ValueType[ValueType.List]) {\n      for (let inkObjectVal of parametersIn) {\n        let val = asOrThrows(inkObjectVal, Value);\n        if (val.valueType == ValueType.List) {\n          parametersOut.push(val);\n        } else if (val.valueType == ValueType.Int) {\n          let intVal = parseInt(val.valueObject);\n\n          specialCaseList = asOrThrows(specialCaseList, ListValue);\n          if (specialCaseList.value === null)\n            return throwNullException(\n              \"NativeFunctionCall.CoerceValuesToSingleType specialCaseList.value\"\n            );\n          let list = specialCaseList.value.originOfMaxItem;\n\n          if (list === null)\n            return throwNullException(\n              \"NativeFunctionCall.CoerceValuesToSingleType list\"\n            );\n          let item = list.TryGetItemWithValue(intVal, InkListItem.Null);\n          if (item.exists) {\n            let castedValue = new ListValue(item.result, intVal);\n            parametersOut.push(castedValue);\n          } else\n            throw new StoryException(\n              \"Could not find List item with the value \" +\n                intVal +\n                \" in \" +\n                list.name\n            );\n        } else {\n          const key = ValueType[val.valueType];\n          throw new StoryException(\n            \"Cannot mix Lists and \" + key + \" values in this operation\"\n          );\n        }\n      }\n    } else {\n      for (let inkObjectVal of parametersIn) {\n        let val = asOrThrows(inkObjectVal, Value);\n        let castedValue = val.Cast(valType);\n        parametersOut.push(castedValue);\n      }\n    }\n\n    return parametersOut;\n  }\n\n  constructor(name: string);\n  constructor(name: string, numberOfParameters: number);\n  constructor();\n  constructor() {\n    super();\n\n    if (arguments.length === 0) {\n      NativeFunctionCall.GenerateNativeFunctionsIfNecessary();\n    } else if (arguments.length === 1) {\n      let name = arguments[0];\n      NativeFunctionCall.GenerateNativeFunctionsIfNecessary();\n      this.name = name;\n    } else if (arguments.length === 2) {\n      let name = arguments[0];\n      let numberOfParameters = arguments[1];\n\n      this._isPrototype = true;\n      this.name = name;\n      this.numberOfParameters = numberOfParameters;\n    }\n  }\n\n  public static Identity<T>(t: T): any {\n    return t;\n  }\n\n  public static GenerateNativeFunctionsIfNecessary() {\n    if (this._nativeFunctions == null) {\n      this._nativeFunctions = new Map();\n\n      // Int operations\n      this.AddIntBinaryOp(this.Add, (x, y) => x + y);\n      this.AddIntBinaryOp(this.Subtract, (x, y) => x - y);\n      this.AddIntBinaryOp(this.Multiply, (x, y) => x * y);\n      this.AddIntBinaryOp(this.Divide, (x, y) => Math.floor(x / y));\n      this.AddIntBinaryOp(this.Mod, (x, y) => x % y);\n      this.AddIntUnaryOp(this.Negate, (x) => -x);\n\n      this.AddIntBinaryOp(this.Equal, (x, y) => x == y);\n      this.AddIntBinaryOp(this.Greater, (x, y) => x > y);\n      this.AddIntBinaryOp(this.Less, (x, y) => x < y);\n      this.AddIntBinaryOp(this.GreaterThanOrEquals, (x, y) => x >= y);\n      this.AddIntBinaryOp(this.LessThanOrEquals, (x, y) => x <= y);\n      this.AddIntBinaryOp(this.NotEquals, (x, y) => x != y);\n      this.AddIntUnaryOp(this.Not, (x) => x == 0);\n\n      this.AddIntBinaryOp(this.And, (x, y) => x != 0 && y != 0);\n      this.AddIntBinaryOp(this.Or, (x, y) => x != 0 || y != 0);\n\n      this.AddIntBinaryOp(this.Max, (x, y) => Math.max(x, y));\n      this.AddIntBinaryOp(this.Min, (x, y) => Math.min(x, y));\n\n      this.AddIntBinaryOp(this.Pow, (x, y) => Math.pow(x, y));\n      this.AddIntUnaryOp(this.Floor, NativeFunctionCall.Identity);\n      this.AddIntUnaryOp(this.Ceiling, NativeFunctionCall.Identity);\n      this.AddIntUnaryOp(this.Int, NativeFunctionCall.Identity);\n      this.AddIntUnaryOp(this.Float, (x) => x);\n\n      // Float operations\n      this.AddFloatBinaryOp(this.Add, (x, y) => x + y);\n      this.AddFloatBinaryOp(this.Subtract, (x, y) => x - y);\n      this.AddFloatBinaryOp(this.Multiply, (x, y) => x * y);\n      this.AddFloatBinaryOp(this.Divide, (x, y) => x / y);\n      this.AddFloatBinaryOp(this.Mod, (x, y) => x % y);\n      this.AddFloatUnaryOp(this.Negate, (x) => -x);\n\n      this.AddFloatBinaryOp(this.Equal, (x, y) => x == y);\n      this.AddFloatBinaryOp(this.Greater, (x, y) => x > y);\n      this.AddFloatBinaryOp(this.Less, (x, y) => x < y);\n      this.AddFloatBinaryOp(this.GreaterThanOrEquals, (x, y) => x >= y);\n      this.AddFloatBinaryOp(this.LessThanOrEquals, (x, y) => x <= y);\n      this.AddFloatBinaryOp(this.NotEquals, (x, y) => x != y);\n      this.AddFloatUnaryOp(this.Not, (x) => x == 0.0);\n\n      this.AddFloatBinaryOp(this.And, (x, y) => x != 0.0 && y != 0.0);\n      this.AddFloatBinaryOp(this.Or, (x, y) => x != 0.0 || y != 0.0);\n\n      this.AddFloatBinaryOp(this.Max, (x, y) => Math.max(x, y));\n      this.AddFloatBinaryOp(this.Min, (x, y) => Math.min(x, y));\n\n      this.AddFloatBinaryOp(this.Pow, (x, y) => Math.pow(x, y));\n      this.AddFloatUnaryOp(this.Floor, (x) => Math.floor(x));\n      this.AddFloatUnaryOp(this.Ceiling, (x) => Math.ceil(x));\n      this.AddFloatUnaryOp(this.Int, (x) => Math.floor(x));\n      this.AddFloatUnaryOp(this.Float, NativeFunctionCall.Identity);\n\n      // String operations\n      this.AddStringBinaryOp(this.Add, (x, y) => x + y); // concat\n      this.AddStringBinaryOp(this.Equal, (x, y) => x === y);\n      this.AddStringBinaryOp(this.NotEquals, (x, y) => !(x === y));\n      this.AddStringBinaryOp(this.Has, (x, y) => x.includes(y));\n      this.AddStringBinaryOp(this.Hasnt, (x, y) => !x.includes(y));\n\n      this.AddListBinaryOp(this.Add, (x, y) => x.Union(y));\n      this.AddListBinaryOp(this.Subtract, (x, y) => x.Without(y));\n      this.AddListBinaryOp(this.Has, (x, y) => x.Contains(y));\n      this.AddListBinaryOp(this.Hasnt, (x, y) => !x.Contains(y));\n      this.AddListBinaryOp(this.Intersect, (x, y) => x.Intersect(y));\n\n      this.AddListBinaryOp(this.Equal, (x, y) => x.Equals(y));\n      this.AddListBinaryOp(this.Greater, (x, y) => x.GreaterThan(y));\n      this.AddListBinaryOp(this.Less, (x, y) => x.LessThan(y));\n      this.AddListBinaryOp(this.GreaterThanOrEquals, (x, y) =>\n        x.GreaterThanOrEquals(y)\n      );\n      this.AddListBinaryOp(this.LessThanOrEquals, (x, y) =>\n        x.LessThanOrEquals(y)\n      );\n      this.AddListBinaryOp(this.NotEquals, (x, y) => !x.Equals(y));\n\n      this.AddListBinaryOp(this.And, (x, y) => x.Count > 0 && y.Count > 0);\n      this.AddListBinaryOp(this.Or, (x, y) => x.Count > 0 || y.Count > 0);\n\n      this.AddListUnaryOp(this.Not, (x) => (x.Count == 0 ? 1 : 0));\n\n      this.AddListUnaryOp(this.Invert, (x) => x.inverse);\n      this.AddListUnaryOp(this.All, (x) => x.all);\n      this.AddListUnaryOp(this.ListMin, (x) => x.MinAsList());\n      this.AddListUnaryOp(this.ListMax, (x) => x.MaxAsList());\n      this.AddListUnaryOp(this.Count, (x) => x.Count);\n      this.AddListUnaryOp(this.ValueOfList, (x) => x.maxItem.Value);\n\n      let divertTargetsEqual = (d1: Path, d2: Path) => d1.Equals(d2);\n      let divertTargetsNotEqual = (d1: Path, d2: Path) => !d1.Equals(d2);\n      this.AddOpToNativeFunc(\n        this.Equal,\n        2,\n        ValueType.DivertTarget,\n        divertTargetsEqual\n      );\n      this.AddOpToNativeFunc(\n        this.NotEquals,\n        2,\n        ValueType.DivertTarget,\n        divertTargetsNotEqual\n      );\n    }\n  }\n\n  public AddOpFuncForType(\n    valType: ValueType,\n    op: UnaryOp<number | InkList> | BinaryOp<number | string | InkList | Path>\n  ): void {\n    if (this._operationFuncs == null) {\n      this._operationFuncs = new Map();\n    }\n\n    this._operationFuncs.set(valType, op);\n  }\n\n  public static AddOpToNativeFunc(\n    name: string,\n    args: number,\n    valType: ValueType,\n    op: UnaryOp<any> | BinaryOp<any>\n  ): void {\n    if (this._nativeFunctions === null)\n      return throwNullException(\"NativeFunctionCall._nativeFunctions\");\n    let nativeFunc = this._nativeFunctions.get(name);\n    if (!nativeFunc) {\n      nativeFunc = new NativeFunctionCall(name, args);\n      this._nativeFunctions.set(name, nativeFunc);\n    }\n\n    nativeFunc.AddOpFuncForType(valType, op);\n  }\n\n  public static AddIntBinaryOp(name: string, op: BinaryOp<number>) {\n    this.AddOpToNativeFunc(name, 2, ValueType.Int, op);\n  }\n  public static AddIntUnaryOp(name: string, op: UnaryOp<number>) {\n    this.AddOpToNativeFunc(name, 1, ValueType.Int, op);\n  }\n\n  public static AddFloatBinaryOp(name: string, op: BinaryOp<number>) {\n    this.AddOpToNativeFunc(name, 2, ValueType.Float, op);\n  }\n  public static AddFloatUnaryOp(name: string, op: UnaryOp<number>) {\n    this.AddOpToNativeFunc(name, 1, ValueType.Float, op);\n  }\n\n  public static AddStringBinaryOp(name: string, op: BinaryOp<string>) {\n    this.AddOpToNativeFunc(name, 2, ValueType.String, op);\n  }\n\n  public static AddListBinaryOp(name: string, op: BinaryOp<InkList>) {\n    this.AddOpToNativeFunc(name, 2, ValueType.List, op);\n  }\n  public static AddListUnaryOp(name: string, op: UnaryOp<InkList>) {\n    this.AddOpToNativeFunc(name, 1, ValueType.List, op);\n  }\n\n  public toString() {\n    return 'Native \"' + this.name + '\"';\n  }\n\n  public _prototype: NativeFunctionCall | null = null;\n  public _isPrototype: boolean = false;\n  public _operationFuncs: Map<ValueType, BinaryOp<any> | UnaryOp<any>> | null =\n    null;\n  public static _nativeFunctions: Map<string, NativeFunctionCall> | null = null;\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { Expression } from \"./Expression\";\nimport { BoolValue, FloatValue, IntValue } from \"../../../../engine/Value\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\nimport { ParsedObject } from \"../Object\";\n\n// This class is named Number in the C# codebase\n// but this conflict with the built-in Number class\nexport class NumberExpression extends Expression {\n  public value: number | boolean;\n  public subtype: \"int\" | \"float\" | \"bool\";\n\n  constructor(value: number | boolean, subtype: \"int\" | \"float\" | \"bool\") {\n    super();\n\n    if (\n      (typeof value === \"number\" && !Number.isNaN(value)) ||\n      typeof value == \"boolean\"\n    ) {\n      this.value = value;\n      this.subtype = subtype;\n    } else {\n      throw new Error(\"Unexpected object type in NumberExpression.\");\n    }\n  }\n\n  get typeName(): string {\n    return \"Number\";\n  }\n\n  public isInt = (): boolean => this.subtype == \"int\";\n\n  public isFloat = (): boolean => this.subtype == \"float\";\n\n  public isBool = (): boolean => this.subtype == \"bool\";\n\n  public readonly GenerateIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    if (this.isInt()) {\n      container.AddContent(new IntValue(this.value as number));\n    } else if (this.isFloat()) {\n      container.AddContent(new FloatValue(this.value as number));\n    } else if (this.isBool()) {\n      container.AddContent(new BoolValue(this.value as boolean));\n    }\n  };\n\n  public readonly toString = (): string => String(this.value);\n\n  public Equals(obj: ParsedObject): boolean {\n    const numberExpression = asOrNull(obj, NumberExpression);\n    if (!numberExpression) return false;\n\n    return (\n      numberExpression.subtype == this.subtype &&\n      numberExpression.value == this.value\n    );\n  }\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { Expression } from \"./Expression\";\nimport { NativeFunctionCall } from \"../../../../engine/NativeFunctionCall\";\nimport { NumberExpression } from \"./NumberExpression\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\n\nexport class UnaryExpression extends Expression {\n  get nativeNameForOp(): string {\n    // Replace \"-\" with \"_\" to make it unique (compared to subtraction)\n    if (this.op === \"-\") {\n      return \"_\";\n    } else if (this.op === \"not\") {\n      return \"!\";\n    }\n\n    return this.op;\n  }\n\n  public innerExpression: Expression;\n\n  // Attempt to flatten inner expression immediately\n  // e.g. convert (-(5)) into (-5)\n  public static readonly WithInner = (\n    inner: Expression,\n    op: string\n  ): Expression => {\n    const innerNumber = asOrNull(inner, NumberExpression);\n\n    if (innerNumber) {\n      if (op === \"-\") {\n        if (innerNumber.isInt()) {\n          return new NumberExpression(-innerNumber.value, \"int\");\n        } else if (innerNumber.isFloat()) {\n          return new NumberExpression(-innerNumber.value, \"float\");\n        }\n      } else if (op == \"!\" || op == \"not\") {\n        if (innerNumber.isInt()) {\n          return new NumberExpression(innerNumber.value == 0, \"bool\");\n        } else if (innerNumber.isFloat()) {\n          return new NumberExpression(innerNumber.value == 0.0, \"bool\");\n        } else if (innerNumber.isBool()) {\n          return new NumberExpression(!innerNumber.value, \"bool\");\n        }\n      }\n\n      throw new Error(\"Unexpected operation or number type\");\n    }\n\n    // Normal fallback\n    const unary = new UnaryExpression(inner, op);\n\n    return unary;\n  };\n\n  constructor(\n    inner: Expression,\n    public readonly op: string\n  ) {\n    super();\n\n    this.innerExpression = this.AddContent(inner) as Expression;\n  }\n\n  get typeName(): string {\n    return \"UnaryExpression\";\n  }\n\n  public readonly GenerateIntoContainer = (container: RuntimeContainer) => {\n    this.innerExpression.GenerateIntoContainer(container);\n    container.AddContent(NativeFunctionCall.CallWithName(this.nativeNameForOp));\n  };\n\n  public readonly toString = (): string =>\n    this.nativeNameForOp + this.innerExpression;\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { Expression } from \"./Expression\";\nimport { NativeFunctionCall } from \"../../../../engine/NativeFunctionCall\";\nimport { Story } from \"../Story\";\nimport { UnaryExpression } from \"./UnaryExpression\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\n\nexport class BinaryExpression extends Expression {\n  public readonly leftExpression: Expression;\n  public readonly rightExpression: Expression;\n\n  constructor(\n    left: Expression,\n    right: Expression,\n    public opName: string\n  ) {\n    super();\n\n    this.leftExpression = this.AddContent(left) as Expression;\n    this.rightExpression = this.AddContent(right) as Expression;\n\n    this.opName = opName;\n  }\n\n  get typeName(): string {\n    return \"BinaryExpression\";\n  }\n\n  public readonly GenerateIntoContainer = (container: RuntimeContainer) => {\n    this.leftExpression.GenerateIntoContainer(container);\n    this.rightExpression.GenerateIntoContainer(container);\n    this.opName = this.NativeNameForOp(this.opName);\n    container.AddContent(NativeFunctionCall.CallWithName(this.opName));\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    // Check for the following case:\n    //\n    //    (not A) ? B\n    //\n    // Since this easy to accidentally do:\n    //\n    //    not A ? B\n    //\n    // when you intend:\n    //\n    //    not (A ? B)\n    if (this.NativeNameForOp(this.opName) === \"?\") {\n      const leftUnary = asOrNull(this.leftExpression, UnaryExpression);\n      if (\n        leftUnary !== null &&\n        (leftUnary.op === \"not\" || leftUnary.op === \"!\")\n      ) {\n        this.Error(\n          `Using 'not' or '!' here negates '${leftUnary.innerExpression}' rather than the result of the '?' or 'has' operator. You need to add parentheses around the (A ? B) expression.`\n        );\n      }\n    }\n  }\n\n  public readonly NativeNameForOp = (opName: string): string => {\n    if (opName === \"and\") {\n      return \"&&\";\n    } else if (opName === \"or\") {\n      return \"||\";\n    } else if (opName === \"mod\") {\n      return \"%\";\n    } else if (opName === \"has\") {\n      return \"?\";\n    } else if (opName === \"hasnt\") {\n      return \"!?\";\n    }\n\n    return opName;\n  };\n\n  public readonly toString = (): string =>\n    `(${this.leftExpression} ${this.opName} ${this.rightExpression})`;\n}\n","export class CharacterSet {\n  public static readonly FromRange = (\n    start: string,\n    end: string\n  ): CharacterSet => new CharacterSet().AddRange(start, end);\n\n  public set: Set<string> = new Set<string>();\n\n  constructor(arg?: string | string[] | CharacterSet) {\n    if (arg) {\n      this.AddCharacters(arg);\n    }\n  }\n\n  public readonly Add = (arg: string) => this.set.add(arg);\n\n  public readonly AddRange = (start: string, end: string): CharacterSet => {\n    for (let c = start.charCodeAt(0); c <= end.charCodeAt(0); ++c) {\n      this.Add(String.fromCharCode(c));\n    }\n\n    return this;\n  };\n\n  public readonly AddCharacters = (\n    chars: string | string[] | CharacterSet\n  ): CharacterSet => {\n    if (typeof chars === \"string\" || Array.isArray(chars)) {\n      for (const c of chars) {\n        this.Add(c);\n      }\n    } else {\n      for (const c of chars.set) {\n        this.Add(c);\n      }\n    }\n\n    return this;\n  };\n}\n","import { CharacterSet } from \"./CharacterSet\";\n\n/// <summary>\n/// A class representing a character range. Allows for lazy-loading a corresponding <see cref=\"CharacterSet\">character set</see>.\n/// </summary>\nexport class CharacterRange {\n  public static Define = (\n    start: string,\n    end: string,\n    excludes: string[] | CharacterSet = []\n  ): CharacterRange => new CharacterRange(start, end, excludes);\n\n  private _correspondingCharSet: CharacterSet = new CharacterSet();\n  private _excludes = new Set<string>();\n\n  constructor(\n    private _start: string,\n    private _end: string,\n    excludes: string[] | CharacterSet = []\n  ) {\n    if (excludes instanceof CharacterSet) {\n      this._excludes = excludes.set;\n    } else {\n      for (const item of excludes) {\n        this._excludes.add(item);\n      }\n    }\n  }\n\n  get start(): string {\n    return this._start;\n  }\n\n  get end(): string {\n    return this._end;\n  }\n\n  /// <summary>\n  /// Returns a <see cref=\"CharacterSet\">character set</see> instance corresponding to the character range\n  /// represented by the current instance.\n  /// </summary>\n  /// <remarks>\n  /// The internal character set is created once and cached in memory.\n  /// </remarks>\n  /// <returns>The char set.</returns>\n  public readonly ToCharacterSet = (): CharacterSet => {\n    if (this._correspondingCharSet.set.size === 0) {\n      for (\n        let ii = this.start.charCodeAt(0), c;\n        ii <= this.end.charCodeAt(0);\n        ii += 1\n      ) {\n        c = String.fromCharCode(ii);\n        if (!this._excludes.has(c)) {\n          this._correspondingCharSet.AddCharacters(c);\n        }\n      }\n    }\n\n    return this._correspondingCharSet;\n  };\n}\n","import { InkObject } from \"./Object\";\nimport { Path } from \"./Path\";\nimport { Container } from \"./Container\";\nimport { throwNullException } from \"./NullException\";\n\nexport class ChoicePoint extends InkObject {\n  public _pathOnChoice: Path | null = null;\n  public hasCondition: boolean = false;\n  public hasStartContent: boolean = false;\n  public hasChoiceOnlyContent: boolean = false;\n  public isInvisibleDefault: boolean = false;\n  public onceOnly: boolean = true;\n\n  constructor(onceOnly: boolean = true) {\n    super();\n    this.onceOnly = onceOnly;\n  }\n  get pathOnChoice(): Path | null {\n    if (this._pathOnChoice != null && this._pathOnChoice.isRelative) {\n      let choiceTargetObj = this.choiceTarget;\n      if (choiceTargetObj) {\n        this._pathOnChoice = choiceTargetObj.path;\n      }\n    }\n    return this._pathOnChoice;\n  }\n  set pathOnChoice(value: Path | null) {\n    this._pathOnChoice = value;\n  }\n  get choiceTarget(): Container | null {\n    if (this._pathOnChoice === null)\n      return throwNullException(\"ChoicePoint._pathOnChoice\");\n    return this.ResolvePath(this._pathOnChoice).container;\n  }\n  get pathStringOnChoice(): string {\n    if (this.pathOnChoice === null)\n      return throwNullException(\"ChoicePoint.pathOnChoice\");\n    return this.CompactPathString(this.pathOnChoice);\n  }\n  set pathStringOnChoice(value: string) {\n    this.pathOnChoice = new Path(value);\n  }\n  get flags(): number {\n    let flags = 0;\n    if (this.hasCondition) flags |= 1;\n    if (this.hasStartContent) flags |= 2;\n    if (this.hasChoiceOnlyContent) flags |= 4;\n    if (this.isInvisibleDefault) flags |= 8;\n    if (this.onceOnly) flags |= 16;\n    return flags;\n  }\n  set flags(value: number) {\n    this.hasCondition = (value & 1) > 0;\n    this.hasStartContent = (value & 2) > 0;\n    this.hasChoiceOnlyContent = (value & 4) > 0;\n    this.isInvisibleDefault = (value & 8) > 0;\n    this.onceOnly = (value & 16) > 0;\n  }\n  public toString(): string {\n    if (this.pathOnChoice === null)\n      return throwNullException(\"ChoicePoint.pathOnChoice\");\n    // int? targetLineNum = DebugLineNumberOfPath (pathOnChoice);\n    let targetLineNum = null;\n    let targetString = this.pathOnChoice.toString();\n\n    if (targetLineNum != null) {\n      targetString = \" line \" + targetLineNum + \"(\" + targetString + \")\";\n    }\n\n    return \"Choice: -> \" + targetString;\n  }\n}\n","import { Path } from \"./Path\";\nimport { Container } from \"./Container\";\nimport { InkObject } from \"./Object\";\n\nexport class Pointer {\n  public container: Container | null = null;\n  public index: number = -1;\n\n  constructor();\n  constructor(container: Container | null, index: number);\n  constructor() {\n    if (arguments.length === 2) {\n      this.container = arguments[0];\n      this.index = arguments[1];\n    }\n  }\n\n  public Resolve(): InkObject | null {\n    if (this.index < 0) return this.container;\n    if (this.container == null) return null;\n    if (this.container.content.length == 0) return this.container;\n    if (this.index >= this.container.content.length) return null;\n\n    return this.container.content[this.index];\n  }\n\n  get isNull(): boolean {\n    return this.container == null;\n  }\n\n  get path(): Path | null {\n    if (this.isNull) return null;\n\n    if (this.index >= 0)\n      return this.container!.path.PathByAppendingComponent(\n        new Path.Component(this.index)\n      );\n    else return this.container!.path;\n  }\n\n  public toString(): string {\n    if (!this.container) return \"Ink Pointer (null)\";\n\n    return (\n      \"Ink Pointer -> \" +\n      this.container.path.toString() +\n      \" -- index \" +\n      this.index\n    );\n  }\n\n  // This method does not exist in the original C# code, but is here to maintain the\n  // value semantics of Pointer.\n  public copy(): Pointer {\n    return new Pointer(this.container, this.index);\n  }\n\n  public static StartOf(container: Container | null): Pointer {\n    return new Pointer(container, 0);\n  }\n\n  public static get Null(): Pointer {\n    return new Pointer(null, -1);\n  }\n}\n","import { Path } from \"./Path\";\nimport { PushPopType } from \"./PushPop\";\nimport { StringBuilder } from \"./StringBuilder\";\nimport { InkObject } from \"./Object\";\nimport { Pointer } from \"./Pointer\";\nimport { Container } from \"./Container\";\nimport { throwNullException } from \"./NullException\";\n\nexport class Divert extends InkObject {\n  get targetPath() {\n    if (this._targetPath != null && this._targetPath.isRelative) {\n      let targetObj = this.targetPointer.Resolve();\n      if (targetObj) {\n        this._targetPath = targetObj.path;\n      }\n    }\n\n    return this._targetPath;\n  }\n  set targetPath(value: Path | null) {\n    this._targetPath = value;\n    this._targetPointer = Pointer.Null;\n  }\n\n  public _targetPath: Path | null = null;\n\n  get targetPointer() {\n    if (this._targetPointer.isNull) {\n      let targetObj = this.ResolvePath(this._targetPath).obj;\n\n      if (this._targetPath === null)\n        return throwNullException(\"this._targetPath\");\n      if (this._targetPath.lastComponent === null)\n        return throwNullException(\"this._targetPath.lastComponent\");\n\n      if (this._targetPath.lastComponent.isIndex) {\n        if (targetObj === null) return throwNullException(\"targetObj\");\n        this._targetPointer.container =\n          targetObj.parent instanceof Container ? targetObj.parent : null;\n        this._targetPointer.index = this._targetPath.lastComponent.index;\n      } else {\n        this._targetPointer = Pointer.StartOf(\n          targetObj instanceof Container ? targetObj : null\n        );\n      }\n    }\n\n    return this._targetPointer.copy();\n  }\n\n  public _targetPointer: Pointer = Pointer.Null;\n\n  get targetPathString() {\n    if (this.targetPath == null) return null;\n\n    return this.CompactPathString(this.targetPath);\n  }\n  set targetPathString(value: string | null) {\n    if (value == null) {\n      this.targetPath = null;\n    } else {\n      this.targetPath = new Path(value);\n    }\n  }\n\n  public variableDivertName: string | null = null;\n  get hasVariableTarget() {\n    return this.variableDivertName != null;\n  }\n\n  public pushesToStack: boolean = false;\n  public stackPushType: PushPopType = 0;\n\n  public isExternal: boolean = false;\n  public externalArgs: number = 0;\n\n  public isConditional: boolean = false;\n\n  constructor(stackPushType?: PushPopType) {\n    super();\n    this.pushesToStack = false;\n\n    if (typeof stackPushType !== \"undefined\") {\n      this.pushesToStack = true;\n      this.stackPushType = stackPushType;\n    }\n  }\n\n  public Equals(obj: Divert | null) {\n    let otherDivert = obj;\n    if (otherDivert instanceof Divert) {\n      if (this.hasVariableTarget == otherDivert.hasVariableTarget) {\n        if (this.hasVariableTarget) {\n          return this.variableDivertName == otherDivert.variableDivertName;\n        } else {\n          if (this.targetPath === null)\n            return throwNullException(\"this.targetPath\");\n          return this.targetPath.Equals(otherDivert.targetPath);\n        }\n      }\n    }\n    return false;\n  }\n\n  public toString() {\n    if (this.hasVariableTarget) {\n      return \"Divert(variable: \" + this.variableDivertName + \")\";\n    } else if (this.targetPath == null) {\n      return \"Divert(null)\";\n    } else {\n      let sb = new StringBuilder();\n\n      let targetStr = this.targetPath.toString();\n      // int? targetLineNum = DebugLineNumberOfPath (targetPath);\n      let targetLineNum = null;\n      if (targetLineNum != null) {\n        targetStr = \"line \" + targetLineNum;\n      }\n\n      sb.Append(\"Divert\");\n\n      if (this.isConditional) sb.Append(\"?\");\n\n      if (this.pushesToStack) {\n        if (this.stackPushType == PushPopType.Function) {\n          sb.Append(\" function\");\n        } else {\n          sb.Append(\" tunnel\");\n        }\n      }\n\n      sb.Append(\" -> \");\n      sb.Append(this.targetPathString);\n\n      sb.Append(\" (\");\n      sb.Append(targetStr);\n      sb.Append(\")\");\n\n      return sb.toString();\n    }\n  }\n}\n","export enum SymbolType {\n  Knot = 0,\n  List = 1,\n  ListItem = 2,\n  Var = 3,\n  SubFlowAndWeave = 4,\n  Arg = 5,\n  Temp = 6,\n}\n","import { InkObject } from \"./Object\";\n\nexport class VariableAssignment extends InkObject {\n  public readonly variableName: string | null;\n  public readonly isNewDeclaration: boolean;\n  public isGlobal: boolean;\n\n  constructor(variableName: string | null, isNewDeclaration: boolean) {\n    super();\n    this.variableName = variableName || null;\n    this.isNewDeclaration = !!isNewDeclaration;\n    this.isGlobal = false;\n  }\n\n  public toString(): string {\n    return \"VarAssign to \" + this.variableName;\n  }\n}\n","import { ChoicePoint } from \"../../../engine/ChoicePoint\";\nimport { Container as RuntimeContainer } from \"../../../engine/Container\";\nimport { ContentList } from \"./ContentList\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../engine/ControlCommand\";\nimport { Divert as RuntimeDivert } from \"../../../engine/Divert\";\nimport { DivertTargetValue } from \"../../../engine/Value\";\nimport { INamedContent } from \"../../../engine/INamedContent\";\nimport { IWeavePoint } from \"./IWeavePoint\";\nimport { ParsedObject } from \"./Object\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\nimport { Path as RuntimePath } from \"../../../engine/Path\";\nimport { Story } from \"./Story\";\nimport { SymbolType } from \"./SymbolType\";\nimport { VariableAssignment as RuntimeVariableAssignment } from \"../../../engine/VariableAssignment\";\nimport { Expression } from \"./Expression/Expression\";\nimport { Identifier } from \"./Identifier\";\n\nexport class Choice extends ParsedObject implements IWeavePoint, INamedContent {\n  private _condition: Expression | null = null;\n  private _innerContentContainer: RuntimeContainer | null = null;\n  private _outerContainer: RuntimeContainer | null = null;\n  private _runtimeChoice: ChoicePoint | null = null;\n  get runtimeChoice(): ChoicePoint {\n    if (!this._runtimeChoice) {\n      throw new Error();\n    }\n\n    return this._runtimeChoice;\n  }\n\n  private _returnToR1: DivertTargetValue | null = null;\n  private _returnToR2: DivertTargetValue | null = null;\n  private _r1Label: RuntimeContainer | null = null;\n  private _r2Label: RuntimeContainer | null = null;\n  private _divertToStartContentOuter: RuntimeDivert | null = null;\n  private _divertToStartContentInner: RuntimeDivert | null = null;\n  private _startContentRuntimeContainer: RuntimeContainer | null = null;\n\n  public startContent: ContentList;\n  public choiceOnlyContent: ContentList;\n  public innerContent: ContentList;\n  public identifier?: Identifier;\n  get name() {\n    return this.identifier?.name || null;\n  }\n  public onceOnly: boolean;\n  public isInvisibleDefault: boolean = false;\n  public indentationDepth: number;\n  public hasWeaveStyleInlineBrackets: boolean = false;\n\n  get condition() {\n    return this._condition;\n  }\n\n  set condition(value) {\n    this._condition = value;\n    if (value) {\n      this.AddContent(value as ParsedObject);\n    }\n  }\n\n  // Required for IWeavePoint interface\n  // Choice's target container. Used by weave to append any extra\n  // nested weave content into.\n  get runtimeContainer() {\n    return this._innerContentContainer;\n  }\n\n  get innerContentContainer() {\n    return this._innerContentContainer;\n  }\n\n  get containerForCounting() {\n    return this._innerContentContainer;\n  }\n\n  // Override runtimePath to point to the Choice's target content (after it's chosen),\n  // as opposed to the default implementation which would point to the choice itself\n  // (or it's outer container), which is what runtimeObject is.\n  get runtimePath(): RuntimePath {\n    if (!this.innerContentContainer || !this.innerContentContainer.path) {\n      throw new Error();\n    }\n\n    return this.innerContentContainer.path;\n  }\n\n  constructor(\n    startContent: ContentList,\n    choiceOnlyContent: ContentList,\n    innerContent: ContentList\n  ) {\n    super();\n\n    this.startContent = startContent;\n    this.choiceOnlyContent = choiceOnlyContent;\n    this.innerContent = innerContent;\n    this.indentationDepth = 1;\n\n    if (startContent) {\n      this.AddContent(this.startContent);\n    }\n\n    if (choiceOnlyContent) {\n      this.AddContent(this.choiceOnlyContent);\n    }\n\n    if (innerContent) {\n      this.AddContent(this.innerContent);\n    }\n\n    this.onceOnly = true; // default\n  }\n\n  get typeName(): string {\n    return \"Choice\";\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    this._outerContainer = new RuntimeContainer();\n\n    // Content names for different types of choice:\n    //  * start content [choice only content] inner content\n    //  * start content   -> divert\n    //  * start content\n    //  * [choice only content]\n\n    // Hmm, this structure has become slightly insane!\n    //\n    // [\n    //     EvalStart\n    //     assign $r = $r1   -- return target = return label 1\n    //     BeginString\n    //     -> s\n    //     [(r1)]            -- return label 1 (after start content)\n    //     EndString\n    //     BeginString\n    //     ... choice only content\n    //     EndEval\n    //     Condition expression\n    //     choice: -> \"c-0\"\n    //     (s) = [\n    //         start content\n    //         -> r          -- goto return label 1 or 2\n    //     ]\n    //  ]\n    //\n    //  in parent's container: (the inner content for the choice)\n    //\n    //  (c-0) = [\n    //      EvalStart\n    //      assign $r = $r2   -- return target = return label 2\n    //      EndEval\n    //      -> s\n    //      [(r2)]            -- return label 1 (after start content)\n    //      inner content\n    //  ]\n    //\n\n    this._runtimeChoice = new ChoicePoint(this.onceOnly);\n    this._runtimeChoice.isInvisibleDefault = this.isInvisibleDefault;\n\n    if (this.startContent || this.choiceOnlyContent || this.condition) {\n      this._outerContainer.AddContent(RuntimeControlCommand.EvalStart());\n    }\n\n    // Start content is put into a named container that's referenced both\n    // when displaying the choice initially, and when generating the text\n    // when the choice is chosen.\n    if (this.startContent) {\n      // Generate start content and return\n      //  - We can't use a function since it uses a call stack element, which would\n      //    put temporary values out of scope. Instead we manually divert around.\n      //  - $r is a variable divert target contains the return point\n      this._returnToR1 = new DivertTargetValue();\n      this._outerContainer.AddContent(this._returnToR1);\n\n      const varAssign = new RuntimeVariableAssignment(\"$r\", true);\n      this._outerContainer.AddContent(varAssign);\n\n      // Mark the start of the choice text generation, so that the runtime\n      // knows where to rewind to to extract the content from the output stream.\n      this._outerContainer.AddContent(RuntimeControlCommand.BeginString());\n\n      this._divertToStartContentOuter = new RuntimeDivert();\n      this._outerContainer.AddContent(this._divertToStartContentOuter);\n\n      // Start content itself in a named container\n      this._startContentRuntimeContainer =\n        this.startContent.GenerateRuntimeObject() as RuntimeContainer;\n      this._startContentRuntimeContainer.name = \"s\";\n\n      // Effectively, the \"return\" statement - return to the point specified by $r\n      const varDivert = new RuntimeDivert();\n      varDivert.variableDivertName = \"$r\";\n      this._startContentRuntimeContainer.AddContent(varDivert);\n\n      // Add the container\n      this._outerContainer.AddToNamedContentOnly(\n        this._startContentRuntimeContainer\n      );\n\n      // This is the label to return to\n      this._r1Label = new RuntimeContainer();\n      this._r1Label.name = \"$r1\";\n      this._outerContainer.AddContent(this._r1Label);\n\n      this._outerContainer.AddContent(RuntimeControlCommand.EndString());\n\n      this._runtimeChoice.hasStartContent = true;\n    }\n\n    // Choice only content - mark the start, then generate it directly into the outer container\n    if (this.choiceOnlyContent) {\n      this._outerContainer.AddContent(RuntimeControlCommand.BeginString());\n\n      const choiceOnlyRuntimeContent =\n        this.choiceOnlyContent.GenerateRuntimeObject() as RuntimeContainer;\n      this._outerContainer.AddContentsOfContainer(choiceOnlyRuntimeContent);\n\n      this._outerContainer.AddContent(RuntimeControlCommand.EndString());\n\n      this._runtimeChoice.hasChoiceOnlyContent = true;\n    }\n\n    // Generate any condition for this choice\n    if (this.condition) {\n      this.condition.GenerateIntoContainer(this._outerContainer);\n      this._runtimeChoice.hasCondition = true;\n    }\n\n    if (this.startContent || this.choiceOnlyContent || this.condition) {\n      this._outerContainer.AddContent(RuntimeControlCommand.EvalEnd());\n    }\n\n    // Add choice itself\n    this._outerContainer.AddContent(this._runtimeChoice);\n\n    // Container that choice points to for when it's chosen\n    this._innerContentContainer = new RuntimeContainer();\n\n    // Repeat start content by diverting to its container\n    if (this.startContent) {\n      // Set the return point when jumping back into the start content\n      //  - In this case, it's the $r2 point, within the choice content \"c\".\n      this._returnToR2 = new DivertTargetValue();\n      this._innerContentContainer.AddContent(RuntimeControlCommand.EvalStart());\n      this._innerContentContainer.AddContent(this._returnToR2);\n      this._innerContentContainer.AddContent(RuntimeControlCommand.EvalEnd());\n      const varAssign = new RuntimeVariableAssignment(\"$r\", true);\n      this._innerContentContainer.AddContent(varAssign);\n\n      // Main divert into start content\n      this._divertToStartContentInner = new RuntimeDivert();\n      this._innerContentContainer.AddContent(this._divertToStartContentInner);\n\n      // Define label to return to\n      this._r2Label = new RuntimeContainer();\n      this._r2Label.name = \"$r2\";\n      this._innerContentContainer.AddContent(this._r2Label);\n    }\n\n    // Choice's own inner content\n    if (this.innerContent) {\n      const innerChoiceOnlyContent =\n        this.innerContent.GenerateRuntimeObject() as RuntimeContainer;\n      this._innerContentContainer.AddContentsOfContainer(\n        innerChoiceOnlyContent\n      );\n    }\n\n    if (this.story.countAllVisits) {\n      this._innerContentContainer.visitsShouldBeCounted = true;\n    }\n\n    this._innerContentContainer.countingAtStartOnly = true;\n\n    return this._outerContainer;\n  };\n\n  public ResolveReferences(context: Story): void {\n    // Weave style choice - target own content container\n    if (this._innerContentContainer) {\n      this.runtimeChoice.pathOnChoice = this._innerContentContainer.path;\n\n      if (this.onceOnly) {\n        this._innerContentContainer.visitsShouldBeCounted = true;\n      }\n    }\n\n    if (this._returnToR1) {\n      if (!this._r1Label) {\n        throw new Error();\n      }\n\n      this._returnToR1.targetPath = this._r1Label.path;\n    }\n\n    if (this._returnToR2) {\n      if (!this._r2Label) {\n        throw new Error();\n      }\n\n      this._returnToR2.targetPath = this._r2Label.path;\n    }\n\n    if (this._divertToStartContentOuter) {\n      if (!this._startContentRuntimeContainer) {\n        throw new Error();\n      }\n\n      this._divertToStartContentOuter.targetPath =\n        this._startContentRuntimeContainer.path;\n    }\n\n    if (this._divertToStartContentInner) {\n      if (!this._startContentRuntimeContainer) {\n        throw new Error();\n      }\n\n      this._divertToStartContentInner.targetPath =\n        this._startContentRuntimeContainer.path;\n    }\n\n    super.ResolveReferences(context);\n\n    if (this.identifier && (this.identifier?.name || \"\").length > 0) {\n      context.CheckForNamingCollisions(\n        this as ParsedObject,\n        this.identifier,\n        SymbolType.SubFlowAndWeave\n      );\n    }\n  }\n\n  public readonly toString = () => {\n    if (this.choiceOnlyContent !== null) {\n      return `* ${this.startContent}[${this.choiceOnlyContent}]...`;\n    }\n\n    return `* ${this.startContent}...`;\n  };\n}\n","export class StringParserElement {\n  public static _uniqueIdCounter: number = 1000;\n\n  public characterIndex: number = 0;\n  public characterInLineIndex: number = 0;\n  public lineIndex: number = 0;\n  public reportedErrorInScope: boolean = false;\n  public uniqueId: number = 0;\n  public customFlags: number = 0;\n\n  public readonly CopyFrom = (fromElement: StringParserElement): void => {\n    StringParserElement._uniqueIdCounter++;\n    this.uniqueId = StringParserElement._uniqueIdCounter;\n    this.characterIndex = fromElement.characterIndex;\n    this.characterInLineIndex = fromElement.characterInLineIndex;\n    this.lineIndex = fromElement.lineIndex;\n    this.customFlags = fromElement.customFlags;\n    this.reportedErrorInScope = false;\n  };\n\n  // Squash is used when succeeding from a rule,\n  // so only the state information we wanted to carry forward is\n  // retained. e.g. characterIndex and lineIndex are global,\n  // however uniqueId is specific to the individual rule,\n  // and likewise, custom flags are designed for the temporary\n  // state of the individual rule too.\n  public readonly SquashFrom = (fromElement: StringParserElement): void => {\n    this.characterIndex = fromElement.characterIndex;\n    this.characterInLineIndex = fromElement.characterInLineIndex;\n    this.lineIndex = fromElement.lineIndex;\n    this.reportedErrorInScope = fromElement.reportedErrorInScope;\n    this.customFlags = fromElement.customFlags;\n  };\n}\n","import { StringParserElement } from \"./StringParserElement\";\n\nexport class StringParserState {\n  private _stack: StringParserElement[] = [];\n  private _numElements: number = 0;\n\n  get currentElement(): StringParserElement {\n    return this._stack[this._numElements - 1];\n  }\n\n  get lineIndex(): number {\n    return this.currentElement.lineIndex;\n  }\n\n  set lineIndex(value: number) {\n    this.currentElement.lineIndex = value;\n  }\n\n  get characterIndex(): number {\n    return this.currentElement.characterIndex;\n  }\n\n  set characterIndex(value: number) {\n    this.currentElement.characterIndex = value;\n  }\n\n  get characterInLineIndex(): number {\n    return this.currentElement.characterInLineIndex;\n  }\n\n  set characterInLineIndex(value: number) {\n    this.currentElement.characterInLineIndex = value;\n  }\n\n  get customFlags(): number {\n    return this.currentElement.customFlags;\n  }\n\n  set customFlags(value: number) {\n    this.currentElement.customFlags = value;\n  }\n\n  get errorReportedAlreadyInScope(): boolean {\n    return this.currentElement.reportedErrorInScope;\n  }\n\n  get stackHeight(): number {\n    return this._numElements;\n  }\n\n  constructor() {\n    const kExpectedMaxStackDepth = 200;\n    for (let i = 0; i < kExpectedMaxStackDepth; i++) {\n      this._stack[i] = new StringParserElement();\n    }\n    this._numElements = 1;\n  }\n\n  public readonly StringParserState = (): void => {\n    const kExpectedMaxStackDepth: number = 200;\n    this._stack = new Array(kExpectedMaxStackDepth);\n\n    for (let ii = 0; ii < kExpectedMaxStackDepth; ++ii) {\n      this._stack[ii] = new StringParserElement();\n    }\n\n    this._numElements = 1;\n  };\n\n  public readonly Push = (): number => {\n    if (this._numElements >= this._stack.length && this._numElements > 0) {\n      throw new Error(\"Stack overflow in parser state.\");\n    }\n\n    const prevElement = this._stack[this._numElements - 1];\n    const newElement = this._stack[this._numElements];\n    this._numElements++;\n\n    newElement.CopyFrom(prevElement);\n\n    return newElement.uniqueId;\n  };\n\n  public readonly Pop = (expectedRuleId: number): void => {\n    if (this._numElements == 1) {\n      throw new Error(\n        \"Attempting to remove final stack element is illegal! Mismatched Begin/Succceed/Fail?\"\n      );\n    }\n\n    if (this.currentElement.uniqueId != expectedRuleId) {\n      throw new Error(\n        \"Mismatched rule IDs while Poping - do you have mismatched Begin/Succeed/Fail?\"\n      );\n    }\n\n    // Restore state\n    this._numElements -= 1;\n  };\n\n  public Peek = (expectedRuleId: number) => {\n    if (this.currentElement.uniqueId != expectedRuleId) {\n      throw new Error(\n        \"Mismatched rule IDs while Peeking - do you have mismatched Begin/Succeed/Fail?\"\n      );\n    }\n\n    return this._stack[this._numElements - 1];\n  };\n\n  public readonly PeekPenultimate = (): StringParserElement | null => {\n    if (this._numElements >= 2) {\n      return this._stack[this._numElements - 2];\n    }\n\n    return null;\n  };\n\n  // Reduce stack height while maintaining currentElement\n  // Remove second last element: i.e. \"squash last two elements together\"\n  // Used when succeeding from a rule (and ONLY when succeeding, since\n  // the state of the top element is retained).\n  public readonly Squash = (): void => {\n    if (this._numElements < 2) {\n      throw new Error(\n        \"Attempting to remove final stack element is illegal! Mismatched Begin/Succceed/Fail?\"\n      );\n    }\n\n    const penultimateEl = this._stack[this._numElements - 2];\n    const lastEl = this._stack[this._numElements - 1];\n\n    penultimateEl.SquashFrom(lastEl);\n\n    this._numElements -= 1;\n  };\n\n  public readonly NoteErrorReported = (): void => {\n    for (const el of this._stack) {\n      el.reportedErrorInScope = true;\n    }\n  };\n}\n","import { CharacterSet } from \"../CharacterSet\";\nimport { ParsedObject } from \"../ParsedHierarchy/Object\";\nimport { StringParserState } from \"./StringParserState\";\nimport { StringParserElement } from \"./StringParserElement\";\n\nexport const ParseSuccess = Symbol(\"ParseSuccessStruct\");\n\nexport type ParseRule = () => ParseRuleReturn;\n\nexport type ParseRuleReturn =\n  | object\n  | string\n  | null\n  | number\n  | (typeof StringParser)[\"ParseSuccess\"];\n\nexport type SpecificParseRule<T extends ParseRule> = T;\n\nexport class StringParser {\n  public ParseRule: ParseRule | null = null;\n\n  public static readonly ParseSuccess: typeof ParseSuccess = ParseSuccess;\n  public static readonly numbersCharacterSet = new CharacterSet(\"0123456789\");\n\n  private _chars: string[];\n\n  public errorHandler:\n    | null\n    | ((\n        message: string,\n        index: number,\n        lineIndex?: number,\n        isWarning?: boolean\n      ) => void) = null;\n  public state: StringParserState;\n  public hadError: boolean = false;\n\n  constructor(str: string) {\n    const strPreProc = this.PreProcessInputString(str);\n    this.state = new StringParserState();\n\n    if (str) {\n      this._chars = strPreProc.split(\"\");\n    } else {\n      this._chars = [];\n    }\n\n    this.inputString = strPreProc;\n  }\n\n  get currentCharacter(): string {\n    if (this.index >= 0 && this.remainingLength > 0) {\n      return this._chars[this.index];\n    }\n\n    return \"0\";\n  }\n\n  // Don't do anything by default, but provide ability for subclasses\n  // to manipulate the string before it's used as input (converted to a char array)\n  public PreProcessInputString(str: string): string {\n    return str;\n  }\n\n  //--------------------------------\n  // Parse state\n  //--------------------------------\n\n  public readonly BeginRule = (): number => this.state.Push();\n\n  public readonly FailRule = (expectedRuleId: number): ParseRuleReturn => {\n    this.state.Pop(expectedRuleId);\n    return null;\n  };\n\n  public readonly CancelRule = (expectedRuleId: number): void => {\n    this.state.Pop(expectedRuleId);\n  };\n\n  public readonly SucceedRule = (\n    expectedRuleId: number,\n    result: ParseRuleReturn = null\n  ): ParseRuleReturn => {\n    // Get state at point where this rule stared evaluating\n    const stateAtSucceedRule = this.state.Peek(expectedRuleId);\n    const stateAtBeginRule = this.state.PeekPenultimate();\n\n    // Allow subclass to receive callback\n    if (this.RuleDidSucceed) {\n      this.RuleDidSucceed(result, stateAtBeginRule, stateAtSucceedRule);\n    }\n\n    // Flatten state stack so that we maintain the same values,\n    // but remove one level in the stack.\n    this.state.Squash();\n\n    let finalResult: ParseRuleReturn = result;\n    if (finalResult === null) {\n      finalResult = StringParser.ParseSuccess;\n    }\n\n    return finalResult;\n  };\n\n  public RuleDidSucceed?: (\n    result: ParseRuleReturn,\n    startState: StringParserElement | null,\n    endState: StringParserElement\n  ) => void;\n\n  public readonly Expect = (\n    rule: ParseRule,\n    message: string | null = null,\n    recoveryRule: ParseRule | null = null\n  ): ParseRuleReturn => {\n    let result: ParseRuleReturn = this.ParseObject(rule);\n    if (result === null) {\n      if (message === null) {\n        message = rule.name;\n      }\n\n      let butSaw: string;\n      const lineRemainder: string = this.LineRemainder();\n      if (lineRemainder === null || lineRemainder.length === 0) {\n        butSaw = \"end of line\";\n      } else {\n        butSaw = `'${lineRemainder}'`;\n      }\n\n      this.Error(`Expected ${message} but saw ${butSaw}`);\n\n      if (recoveryRule !== null) {\n        result = recoveryRule();\n      }\n    }\n\n    return result;\n  };\n\n  public Error = (message: string, isWarning: boolean = false): void => {\n    this.ErrorOnLine(message, this.lineIndex + 1, isWarning);\n  };\n\n  public readonly ErrorWithParsedObject = (\n    message: string,\n    result: ParsedObject,\n    isWarning: boolean = false\n  ): void => {\n    this.ErrorOnLine(\n      message,\n      result.debugMetadata ? result.debugMetadata.startLineNumber : -1,\n      isWarning\n    );\n  };\n\n  public readonly ErrorOnLine = (\n    message: string,\n    lineNumber: number,\n    isWarning: boolean\n  ): void => {\n    if (!this.state.errorReportedAlreadyInScope) {\n      const errorType = isWarning ? \"Warning\" : \"Error\";\n\n      if (!this.errorHandler) {\n        throw new Error(`${errorType} on line ${lineNumber}: ${message}`);\n      } else {\n        this.errorHandler(message, this.index, lineNumber - 1, isWarning);\n      }\n\n      this.state.NoteErrorReported();\n    }\n\n    if (!isWarning) {\n      this.hadError = true;\n    }\n  };\n\n  public readonly Warning = (message: string): void =>\n    this.Error(message, true);\n\n  get endOfInput(): boolean {\n    return this.index >= this._chars.length;\n  }\n\n  get remainingString(): string {\n    return this._chars\n      .slice(this.index, this.index + this.remainingLength)\n      .join(\"\");\n  }\n\n  public readonly LineRemainder = (): string =>\n    this.Peek(() => this.ParseUntilCharactersFromString(\"\\n\\r\")) as string;\n\n  get remainingLength() {\n    return this._chars.length - this.index;\n  }\n\n  public inputString: string;\n\n  get lineIndex() {\n    return this.state.lineIndex;\n  }\n\n  set lineIndex(value: number) {\n    this.state.lineIndex = value;\n  }\n\n  set characterInLineIndex(value: number) {\n    this.state.characterInLineIndex = value;\n  }\n\n  get characterInLineIndex() {\n    return this.state.characterInLineIndex;\n  }\n\n  get index(): number {\n    // If we want subclass parsers to be able to set the index directly,\n    // then we would need to know what the lineIndex of the new\n    // index would be - would we have to step through manually\n    // counting the newlines to do so?\n    return this.state.characterIndex;\n  }\n\n  set index(value: number) {\n    this.state.characterIndex = value;\n  }\n\n  public readonly SetFlag = (flag: number, trueOrFalse: boolean): void => {\n    if (trueOrFalse) {\n      this.state.customFlags |= flag;\n    } else {\n      this.state.customFlags &= ~flag;\n    }\n  };\n\n  public readonly GetFlag = (flag: number): boolean =>\n    Boolean(this.state.customFlags & flag);\n\n  //--------------------------------\n  // Structuring\n  //--------------------------------\n\n  public ParseObject = (rule: ParseRule): ParseRuleReturn => {\n    const ruleId: number = this.BeginRule();\n    const stackHeightBefore = this.state.stackHeight;\n    const result = rule();\n\n    if (stackHeightBefore !== this.state.stackHeight) {\n      throw new Error(\"Mismatched Begin/Fail/Succeed rules\");\n    }\n\n    if (result === null) {\n      return this.FailRule(ruleId);\n    }\n\n    this.SucceedRule(ruleId, result);\n\n    return result;\n  };\n\n  public readonly Parse = <T extends ParseRule>(\n    rule: SpecificParseRule<T>\n  ): ParseRuleReturn => {\n    const ruleId: number = this.BeginRule();\n\n    const result: ParseRuleReturn = rule();\n    if (result === null) {\n      this.FailRule(ruleId);\n      return null;\n    }\n\n    this.SucceedRule(ruleId, result);\n\n    return result;\n  };\n\n  public readonly OneOf = (array: ParseRule[]): ParseRuleReturn => {\n    for (const rule of array) {\n      const result = this.ParseObject(rule);\n      if (result !== null) {\n        return result;\n      }\n    }\n\n    return null;\n  };\n\n  public readonly OneOrMore = (rule: ParseRule): ParseRuleReturn[] | null => {\n    const results: ParseRuleReturn[] = [];\n    let result: ParseRuleReturn = null;\n\n    do {\n      result = this.ParseObject(rule);\n      if (result !== null) {\n        results.push(result);\n      }\n    } while (result !== null);\n\n    if (results.length > 0) {\n      return results;\n    }\n\n    return null;\n  };\n\n  public readonly Optional =\n    (rule: ParseRule): ParseRule =>\n    () => {\n      const result = this.ParseObject(rule);\n      if (result === null) return StringParser.ParseSuccess;\n      return result;\n    };\n\n  // Return ParseSuccess instead the real result so that it gets excluded\n  // from result arrays (e.g. Interleave)\n  public readonly Exclude =\n    (rule: ParseRule): ParseRule =>\n    () =>\n      this.ParseObject(rule) && StringParser.ParseSuccess;\n\n  // Combination of both of the above\n  public readonly OptionalExclude =\n    (rule: ParseRule): ParseRule =>\n    () => {\n      this.ParseObject(rule);\n      return StringParser.ParseSuccess;\n    };\n\n  // Convenience method for creating more readable ParseString rules that can be combined\n  // in other structuring rules (like OneOf etc)\n  // e.g. OneOf(String(\"one\"), String(\"two\"))\n  public readonly String =\n    (str: string): ParseRule =>\n    () =>\n      this.ParseString(str);\n\n  private readonly TryAddResultToList = <T>(\n    result: ParseRuleReturn,\n    list: T[],\n    flatten: boolean = true\n  ): void => {\n    if (result === StringParser.ParseSuccess) {\n      return;\n    }\n\n    if (flatten && Array.isArray(result)) {\n      const resultCollection = result as ParseRuleReturn[];\n      if (resultCollection !== null) {\n        for (const obj of resultCollection) {\n          list.push(obj as any);\n        }\n\n        return;\n      }\n    }\n\n    list.push(result as any);\n  };\n\n  public readonly Interleave = <T>(\n    ruleA: ParseRule,\n    ruleB: ParseRule,\n    untilTerminator: ParseRule | null = null,\n    flatten: boolean = true\n  ): T[] => {\n    const ruleId: number = this.BeginRule();\n    const results: T[] = [];\n\n    // First outer padding\n    const firstA = this.ParseObject(ruleA);\n    if (firstA === null) {\n      return this.FailRule(ruleId) as any;\n    } else {\n      this.TryAddResultToList(firstA, results, flatten);\n    }\n\n    let lastMainResult: ParseRuleReturn | null = null;\n    let outerResult: ParseRuleReturn | null = null;\n    do {\n      // \"until\" condition hit?\n      if (untilTerminator !== null && this.Peek(untilTerminator) !== null) {\n        break;\n      }\n\n      // Main inner\n      lastMainResult = this.ParseObject(ruleB);\n      if (lastMainResult === null) {\n        break;\n      } else {\n        this.TryAddResultToList(lastMainResult, results, flatten);\n      }\n\n      // Outer result (i.e. last A in ABA)\n      outerResult = null;\n      if (lastMainResult !== null) {\n        outerResult = this.ParseObject(ruleA);\n\n        if (outerResult === null) {\n          break;\n        } else {\n          this.TryAddResultToList(outerResult, results, flatten);\n        }\n      }\n\n      // Stop if there are no results, or if both are the placeholder \"ParseSuccess\" (i.e. Optional success rather than a true value)\n    } while (\n      (lastMainResult !== null || outerResult !== null) &&\n      !(\n        (lastMainResult as any) === StringParser.ParseSuccess &&\n        outerResult == StringParser.ParseSuccess\n      ) &&\n      this.remainingLength > 0\n    );\n\n    if (results.length === 0) {\n      return this.FailRule(ruleId) as T[];\n    }\n\n    return this.SucceedRule(ruleId, results) as T[];\n  };\n\n  //--------------------------------\n  // Basic string parsing\n  //--------------------------------\n\n  public readonly ParseString = (str: string): string | null => {\n    if (str.length > this.remainingLength) {\n      return null;\n    }\n\n    const ruleId: number = this.BeginRule();\n\n    // Optimisation from profiling:\n    // Store in temporary local variables\n    // since they're properties that would have to access\n    // the rule stack every time otherwise.\n    let i: number = this.index;\n    let cli: number = this.characterInLineIndex;\n    let li: number = this.lineIndex;\n\n    let success: boolean = true;\n    for (let tempIdx = 0; tempIdx < str.length; tempIdx += 1) {\n      const c = str[tempIdx];\n\n      if (this._chars[i] !== c) {\n        success = false;\n        break;\n      }\n      if (c === \"\\n\") {\n        li++;\n        cli = -1;\n      }\n\n      i++;\n      cli++;\n    }\n\n    this.index = i;\n    this.characterInLineIndex = cli;\n    this.lineIndex = li;\n\n    if (success) {\n      return this.SucceedRule(ruleId, str) as any;\n    }\n\n    return this.FailRule(ruleId) as any;\n  };\n\n  public readonly ParseSingleCharacter = (): string => {\n    if (this.remainingLength > 0) {\n      const c = this._chars[this.index];\n      if (c === \"\\n\") {\n        this.lineIndex += 1;\n        this.characterInLineIndex = -1;\n      }\n\n      this.index += 1;\n      this.characterInLineIndex += 1;\n\n      return c;\n    }\n\n    return \"0\";\n  };\n\n  public readonly ParseUntilCharactersFromString = (\n    str: string,\n    maxCount: number = -1\n  ): string | null => this.ParseCharactersFromString(str, false, maxCount);\n\n  public readonly ParseUntilCharactersFromCharSet = (\n    charSet: CharacterSet,\n    maxCount: number = -1\n  ): string | null => this.ParseCharactersFromCharSet(charSet, false, maxCount);\n\n  public readonly ParseCharactersFromString = (\n    str: string,\n    maxCountOrShouldIncludeStrChars: boolean | number = -1,\n    maxCount: number = -1\n  ): string | null => {\n    const charSet = new CharacterSet(str);\n    if (typeof maxCountOrShouldIncludeStrChars === \"number\") {\n      return this.ParseCharactersFromCharSet(\n        charSet,\n        true,\n        maxCountOrShouldIncludeStrChars\n      );\n    }\n\n    return this.ParseCharactersFromCharSet(\n      charSet,\n      maxCountOrShouldIncludeStrChars,\n      maxCount\n    );\n  };\n\n  public readonly ParseCharactersFromCharSet = (\n    charSet: CharacterSet,\n    shouldIncludeChars: boolean = true,\n    maxCount: number = -1\n  ): string | null => {\n    if (maxCount === -1) {\n      maxCount = Number.MAX_SAFE_INTEGER;\n    }\n\n    const startIndex: number = this.index;\n\n    // Optimisation from profiling:\n    // Store in temporary local variables\n    // since they're properties that would have to access\n    // the rule stack every time otherwise.\n    let ii: number = this.index;\n    let cli: number = this.characterInLineIndex;\n    let li: number = this.lineIndex;\n    let count: number = 0;\n    while (\n      ii < this._chars.length &&\n      charSet.set.has(this._chars[ii]) === shouldIncludeChars &&\n      count < maxCount\n    ) {\n      if (this._chars[ii] === \"\\n\") {\n        li += 1;\n        cli = -1;\n      }\n\n      ii += 1;\n      cli += 1;\n      count += 1;\n    }\n\n    this.index = ii;\n    this.characterInLineIndex = cli;\n    this.lineIndex = li;\n\n    const lastCharIndex: number = this.index;\n    if (lastCharIndex > startIndex) {\n      return this._chars.slice(startIndex, this.index).join(\"\");\n    }\n\n    return null;\n  };\n\n  public readonly Peek = (rule: ParseRule): ParseRuleReturn => {\n    const ruleId: number = this.BeginRule();\n    const result: ParseRuleReturn = rule();\n    this.CancelRule(ruleId);\n\n    return result;\n  };\n\n  public ParseUntil(\n    stopRule: ParseRule,\n    pauseCharacters: CharacterSet | null = null,\n    endCharacters: CharacterSet | null = null\n  ): string {\n    const ruleId: number = this.BeginRule();\n    const pauseAndEnd: CharacterSet = new CharacterSet();\n    if (pauseCharacters !== null) {\n      pauseAndEnd.set = new Set([\n        ...pauseAndEnd.set.values(),\n        ...pauseCharacters.set.values(),\n      ]);\n    }\n\n    if (endCharacters !== null) {\n      pauseAndEnd.set = new Set([\n        ...pauseAndEnd.set.values(),\n        ...endCharacters.set.values(),\n      ]);\n    }\n\n    let parsedString = \"\";\n    let ruleResultAtPause: ParseRuleReturn | null = null;\n\n    // Keep attempting to parse strings up to the pause (and end) points.\n    //  - At each of the pause points, attempt to parse according to the rule\n    //  - When the end point is reached (or EOF), we're done\n    do {\n      // TODO: Perhaps if no pause or end characters are passed, we should check *every* character for stopRule?\n      const partialParsedString: string | null =\n        this.ParseUntilCharactersFromCharSet(pauseAndEnd);\n\n      if (partialParsedString) {\n        parsedString += partialParsedString;\n      }\n\n      // Attempt to run the parse rule at this pause point\n      ruleResultAtPause = this.Peek(stopRule);\n\n      // Rule completed - we're done\n      if (ruleResultAtPause !== null) {\n        break;\n      } else {\n        if (this.endOfInput) {\n          break;\n        }\n\n        // Reached a pause point, but rule failed. Step past and continue parsing string\n        const pauseCharacter: string = this.currentCharacter;\n        if (\n          pauseCharacters !== null &&\n          pauseCharacters.set.has(pauseCharacter)\n        ) {\n          parsedString += pauseCharacter;\n          if (pauseCharacter === \"\\n\") {\n            this.lineIndex += 1;\n            this.characterInLineIndex = -1;\n          }\n\n          this.index += 1;\n          this.characterInLineIndex += 1;\n\n          continue;\n        } else {\n          break;\n        }\n      }\n    } while (true);\n\n    if (parsedString.length > 0) {\n      return this.SucceedRule(ruleId, String(parsedString)) as string;\n    }\n\n    return this.FailRule(ruleId) as string;\n  }\n\n  // No need to Begin/End rule since we never parse a newline, so keeping oldIndex is good enough\n  public readonly ParseInt = (): number | null => {\n    const oldIndex: number = this.index;\n    const oldCharacterInLineIndex: number = this.characterInLineIndex;\n    const negative: boolean = this.ParseString(\"-\") !== null;\n\n    // Optional whitespace\n    this.ParseCharactersFromString(\" \\t\");\n\n    const parsedString = this.ParseCharactersFromCharSet(\n      StringParser.numbersCharacterSet\n    );\n    if (parsedString === null) {\n      // Roll back and fail\n      this.index = oldIndex;\n      this.characterInLineIndex = oldCharacterInLineIndex;\n\n      return null;\n    }\n\n    let parsedInt: number;\n    if (!Number.isNaN(Number(parsedString))) {\n      parsedInt = Number(parsedString);\n      return negative ? -parsedInt : parsedInt;\n    }\n\n    this.Error(\n      \"Failed to read integer value: \" +\n        parsedString +\n        \". Perhaps it's out of the range of acceptable numbers ink supports? (\" +\n        Number.MIN_SAFE_INTEGER +\n        \" to \" +\n        Number.MAX_SAFE_INTEGER +\n        \")\"\n    );\n\n    return null;\n  };\n\n  // No need to Begin/End rule since we never parse a newline, so keeping oldIndex is good enough\n  public readonly ParseFloat = (): number | null => {\n    const oldIndex: number = this.index;\n    const oldCharacterInLineIndex: number = this.characterInLineIndex;\n\n    const leadingInt: number | null = this.ParseInt();\n    if (leadingInt !== null) {\n      if (this.ParseString(\".\") !== null) {\n        const afterDecimalPointStr = this.ParseCharactersFromCharSet(\n          StringParser.numbersCharacterSet\n        );\n\n        return Number(`${leadingInt}.${afterDecimalPointStr}`);\n      }\n    }\n\n    // Roll back and fail\n    this.index = oldIndex;\n    this.characterInLineIndex = oldCharacterInLineIndex;\n\n    return null;\n  };\n\n  public readonly ParseNewline = (): string => {\n    const ruleId: number = this.BeginRule();\n\n    // Optional \\r, definite \\n to support Windows (\\r\\n) and Mac/Unix (\\n)\n    // 2nd May 2016: Always collapse \\r\\n to just \\n\n    this.ParseString(\"\\r\");\n\n    if (this.ParseString(\"\\n\") === null) {\n      return this.FailRule(ruleId) as string;\n    }\n\n    return this.SucceedRule(ruleId, \"\\n\") as string;\n  };\n}\n","import { CharacterSet } from \"./CharacterSet\";\nimport { StringParser } from \"./StringParser/StringParser\";\n\n/// <summary>\n/// Pre-pass before main ink parser runs. It actually performs two main tasks:\n///  - comment elimination to simplify the parse rules in the main parser\n///  - Conversion of Windows line endings (\\r\\n) to the simpler Unix style (\\n), so\n///    we don't have to worry about them later.\n/// </summary>\nexport class CommentEliminator extends StringParser {\n  public _commentOrNewlineStartCharacter = new CharacterSet(\"/\\r\\n\");\n  public _commentBlockEndCharacter = new CharacterSet(\"*\");\n  public _newlineCharacters = new CharacterSet(\"\\n\\r\");\n\n  public readonly Process = (): string => {\n    // Make both comments and non-comments optional to handle trivial empty file case (or *only* comments)\n    const stringList: string[] = this.Interleave<string>(\n      this.Optional(this.CommentsAndNewlines),\n      this.Optional(this.MainInk)\n    );\n\n    if (stringList !== null) {\n      return stringList.join(\"\");\n    } else {\n      return \"\";\n    }\n  };\n\n  public readonly MainInk = () =>\n    this.ParseUntil(\n      this.CommentsAndNewlines,\n      this._commentOrNewlineStartCharacter,\n      null\n    );\n\n  public readonly CommentsAndNewlines = () => {\n    let newLines: string[] = this.Interleave<string>(\n      this.Optional(this.ParseNewline),\n      this.Optional(this.ParseSingleComment)\n    );\n\n    if (newLines !== null) {\n      return newLines.join(\"\");\n    }\n\n    return null;\n  };\n\n  // Valid comments always return either an empty string or pure newlines,\n  // which we want to keep so that line numbers stay the same\n  public readonly ParseSingleComment = () =>\n    this.OneOf([this.EndOfLineComment, this.BlockComment]);\n\n  public readonly EndOfLineComment = () => {\n    if (this.ParseString(\"//\") === null) {\n      return null;\n    }\n\n    this.ParseUntilCharactersFromCharSet(this._newlineCharacters);\n\n    return \"\";\n  };\n\n  public readonly BlockComment = () => {\n    if (this.ParseString(\"/*\") === null) {\n      return null;\n    }\n\n    const startLineIndex: number = this.lineIndex;\n    const commentResult = this.ParseUntil(\n      this.String(\"*/\"),\n      this._commentBlockEndCharacter,\n      null\n    );\n\n    if (!this.endOfInput) {\n      this.ParseString(\"*/\");\n    }\n\n    // Count the number of lines that were inside the block, and replicate them as newlines\n    // so that the line indexing still works from the original source\n    if (commentResult != null) {\n      return \"\\n\".repeat(this.lineIndex - startLineIndex);\n    }\n\n    // No comment at all\n    return null;\n  };\n\n  public PreProcessInputString(str: string): string {\n    return str;\n  }\n}\n","import { ConditionalSingleBranch } from \"./ConditionalSingleBranch\";\nimport { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../../engine/ControlCommand\";\nimport { Expression } from \"../Expression/Expression\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { Story } from \"../Story\";\n\nexport class Conditional extends ParsedObject {\n  private _reJoinTarget: RuntimeControlCommand | null = null;\n\n  constructor(\n    public initialCondition: Expression,\n    public branches: ConditionalSingleBranch[]\n  ) {\n    super();\n\n    if (this.initialCondition) {\n      this.AddContent(this.initialCondition);\n    }\n\n    if (this.branches !== null) {\n      this.AddContent(this.branches);\n    }\n  }\n\n  get typeName(): string {\n    return \"Conditional\";\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    const container = new RuntimeContainer();\n\n    // Initial condition\n    if (this.initialCondition) {\n      container.AddContent(this.initialCondition.runtimeObject);\n    }\n\n    // Individual branches\n    for (const branch of this.branches) {\n      const branchContainer = branch.runtimeObject;\n      container.AddContent(branchContainer);\n    }\n\n    // If it's a switch-like conditional, each branch\n    // will have a \"duplicate\" operation for the original\n    // switched value. If there's no final else clause\n    // and we fall all the way through, we need to clean up.\n    // (An else clause doesn't dup but it *does* pop)\n    if (\n      this.initialCondition !== null &&\n      this.branches[0].ownExpression !== null &&\n      !this.branches[this.branches.length - 1].isElse\n    ) {\n      container.AddContent(RuntimeControlCommand.PopEvaluatedValue());\n    }\n\n    // Target for branches to rejoin to\n    this._reJoinTarget = RuntimeControlCommand.NoOp();\n    container.AddContent(this._reJoinTarget);\n\n    return container;\n  };\n\n  public ResolveReferences(context: Story): void {\n    const pathToReJoin = this._reJoinTarget!.path;\n\n    for (const branch of this.branches) {\n      if (!branch.returnDivert) {\n        throw new Error();\n      }\n\n      branch.returnDivert.targetPath = pathToReJoin;\n    }\n\n    super.ResolveReferences(context);\n  }\n}\n","import { ParsedObject } from \"./Object\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\nimport { StringValue } from \"../../../engine/Value\";\n\nexport class Text extends ParsedObject {\n  constructor(public text: string) {\n    super();\n  }\n  get typeName(): string {\n    return \"Text\";\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject =>\n    new StringValue(this.text);\n\n  public readonly toString = (): string => this.text;\n}\n","import { Expression } from \"../Expression/Expression\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { Story } from \"../Story\";\nimport { SymbolType } from \"../SymbolType\";\nimport { Identifier } from \"../Identifier\";\n\nexport class ConstantDeclaration extends ParsedObject {\n  get constantName(): string | undefined {\n    return this.constantIdentifier?.name;\n  }\n  public constantIdentifier: Identifier;\n\n  private _expression: Expression | null = null;\n\n  get expression(): Expression {\n    if (!this._expression) {\n      throw new Error();\n    }\n\n    return this._expression;\n  }\n\n  constructor(name: Identifier, assignedExpression: Expression) {\n    super();\n\n    this.constantIdentifier = name;\n\n    // Defensive programming in case parsing of assignedExpression failed\n    if (assignedExpression) {\n      this._expression = this.AddContent(assignedExpression) as Expression;\n    }\n  }\n\n  get typeName(): string {\n    return \"CONST\";\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject | null => {\n    // Global declarations don't generate actual procedural\n    // runtime objects, but instead add a global variable to the story itself.\n    // The story then initialises them all in one go at the start of the game.\n    return null;\n  };\n\n  public ResolveReferences(context: Story) {\n    super.ResolveReferences(context);\n    context.CheckForNamingCollisions(\n      this,\n      this.constantIdentifier,\n      SymbolType.Var\n    );\n  }\n}\n","export enum FlowLevel {\n  Story, // 0\n  Knot, // 1\n  Stitch, // 2\n  // not actually a FlowBase, but used for diverts\n  WeavePoint, // 3\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { INamedContent } from \"../../../../engine/INamedContent\";\nimport { IWeavePoint } from \"../IWeavePoint\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { Story } from \"../Story\";\nimport { SymbolType } from \"../SymbolType\";\nimport { Identifier } from \"../Identifier\";\n\nexport class Gather extends ParsedObject implements INamedContent, IWeavePoint {\n  get name(): string | null {\n    return this.identifier?.name || null;\n  }\n  public identifier?: Identifier;\n\n  get runtimeContainer(): RuntimeContainer {\n    return this.runtimeObject as RuntimeContainer;\n  }\n\n  constructor(\n    identifier: Identifier | null,\n    public readonly indentationDepth: number\n  ) {\n    super();\n\n    if (identifier) this.identifier = identifier;\n  }\n\n  get typeName(): string {\n    return \"Gather\";\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    const container = new RuntimeContainer();\n    container.name = this.name;\n\n    if (this.story.countAllVisits) {\n      container.visitsShouldBeCounted = true;\n    }\n\n    container.countingAtStartOnly = true;\n\n    // A gather can have null content, e.g. it's just purely a line with \"-\"\n    if (this.content) {\n      for (const c of this.content) {\n        container.AddContent(c.runtimeObject);\n      }\n    }\n\n    return container;\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    if (this.identifier && (this.identifier.name || \"\").length > 0) {\n      context.CheckForNamingCollisions(\n        this,\n        this.identifier,\n        SymbolType.SubFlowAndWeave\n      );\n    }\n  }\n\n  public readonly toString = (): string =>\n    `- ${this.identifier?.name ? \"(\" + this.identifier?.name + \")\" : \"gather\"}`;\n}\n","import { asOrNull, filterUndef } from \"../../../engine/TypeAssertion\";\nimport { FlowBase } from \"./Flow/FlowBase\";\nimport { FlowLevel } from \"./Flow/FlowLevel\";\nimport { Identifier } from \"./Identifier\";\nimport { ParsedObject } from \"./Object\";\nimport { Weave } from \"./Weave\";\n\nexport class Path {\n  private _baseTargetLevel: FlowLevel | null;\n  private components: Identifier[] | null;\n\n  get baseTargetLevel() {\n    if (this.baseLevelIsAmbiguous) {\n      return FlowLevel.Story;\n    }\n\n    return this._baseTargetLevel;\n  }\n\n  get baseLevelIsAmbiguous(): boolean {\n    return !this._baseTargetLevel;\n  }\n\n  get firstComponent(): string | null {\n    if (this.components == null || !this.components.length) {\n      return null;\n    }\n\n    return this.components[0].name;\n  }\n\n  get numberOfComponents(): number {\n    return this.components ? this.components.length : 0;\n  }\n\n  private _dotSeparatedComponents: string | null = null;\n\n  get dotSeparatedComponents(): string {\n    if (this._dotSeparatedComponents == null) {\n      this._dotSeparatedComponents = (this.components ? this.components : [])\n        .map((c) => c.name)\n        .filter(filterUndef)\n        .join(\".\");\n    }\n    return this._dotSeparatedComponents;\n  }\n\n  constructor(\n    argOne: FlowLevel | Identifier[] | Identifier,\n    argTwo?: Identifier[]\n  ) {\n    if (Object.values(FlowLevel).includes(argOne as FlowLevel)) {\n      this._baseTargetLevel = argOne as FlowLevel;\n      this.components = argTwo || [];\n    } else if (Array.isArray(argOne)) {\n      this._baseTargetLevel = null;\n      this.components = argOne || [];\n    } else {\n      this._baseTargetLevel = null;\n      this.components = [argOne as Identifier];\n    }\n  }\n\n  get typeName(): string {\n    return \"Path\";\n  }\n\n  public readonly toString = (): string => {\n    if (this.components === null || this.components.length === 0) {\n      if (this.baseTargetLevel === FlowLevel.WeavePoint) {\n        return \"-> <next gather point>\";\n      }\n\n      return \"<invalid Path>\";\n    }\n\n    return `-> ${this.dotSeparatedComponents}`;\n  };\n\n  public readonly ResolveFromContext = (\n    context: ParsedObject\n  ): ParsedObject | null => {\n    if (this.components == null || this.components.length == 0) {\n      return null;\n    }\n\n    // Find base target of path from current context. e.g.\n    //   ==> BASE.sub.sub\n    let baseTargetObject = this.ResolveBaseTarget(context);\n    if (baseTargetObject === null) {\n      return null;\n    }\n\n    // Given base of path, resolve final target by working deeper into hierarchy\n    //  e.g. ==> base.mid.FINAL\n    if (this.components.length > 1) {\n      return this.ResolveTailComponents(baseTargetObject);\n    }\n\n    return baseTargetObject;\n  };\n\n  // Find the root object from the base, i.e. root from:\n  //    root.sub1.sub2\n  public readonly ResolveBaseTarget = (\n    originalContext: ParsedObject\n  ): ParsedObject | null => {\n    const firstComp = this.firstComponent;\n\n    // Work up the ancestry to find the node that has the named object\n    let ancestorContext: ParsedObject | null = originalContext;\n    while (ancestorContext) {\n      // Only allow deep search when searching deeper from original context.\n      // Don't allow search upward *then* downward, since that's searching *everywhere*!\n      // Allowed examples:\n      //  - From an inner gather of a stitch, you should search up to find a knot called 'x'\n      //    at the root of a story, but not a stitch called 'x' in that knot.\n      //  - However, from within a knot, you should be able to find a gather/choice\n      //    anywhere called 'x'\n      // (that latter example is quite loose, but we allow it)\n      const deepSearch: boolean = ancestorContext === originalContext;\n\n      const foundBase = this.GetChildFromContext(\n        ancestorContext,\n        firstComp,\n        null,\n        deepSearch\n      );\n\n      if (foundBase) {\n        return foundBase;\n      }\n\n      ancestorContext = ancestorContext.parent;\n    }\n\n    return null;\n  };\n\n  // Find the final child from path given root, i.e.:\n  //   root.sub.finalChild\n  public readonly ResolveTailComponents = (\n    rootTarget: ParsedObject\n  ): ParsedObject | null => {\n    let foundComponent: ParsedObject | null = rootTarget;\n\n    if (!this.components) return null;\n\n    for (let ii = 1; ii < this.components.length; ++ii) {\n      const compName = this.components[ii].name;\n\n      let minimumExpectedLevel: FlowLevel;\n      let foundFlow = asOrNull(foundComponent, FlowBase);\n      if (foundFlow !== null) {\n        minimumExpectedLevel = (foundFlow.flowLevel + 1) as FlowLevel;\n      } else {\n        minimumExpectedLevel = FlowLevel.WeavePoint;\n      }\n\n      foundComponent = this.GetChildFromContext(\n        foundComponent,\n        compName,\n        minimumExpectedLevel\n      );\n\n      if (foundComponent === null) {\n        break;\n      }\n    }\n\n    return foundComponent;\n  };\n\n  // See whether \"context\" contains a child with a given name at a given flow level\n  // Can either be a named knot/stitch (a FlowBase) or a weave point within a Weave (Choice or Gather)\n  // This function also ignores any other object types that are neither FlowBase nor Weave.\n  // Called from both ResolveBase (force deep) and ResolveTail for the individual components.\n  public readonly GetChildFromContext = (\n    context: ParsedObject,\n    childName: string | null,\n    minimumLevel: FlowLevel | null,\n    forceDeepSearch: boolean = false\n  ): ParsedObject | null => {\n    // null childLevel means that we don't know where to find it\n    const ambiguousChildLevel: boolean = minimumLevel === null;\n\n    // Search for WeavePoint within Weave\n    const weaveContext = asOrNull(context, Weave);\n    if (\n      childName &&\n      weaveContext !== null &&\n      (ambiguousChildLevel || minimumLevel === FlowLevel.WeavePoint)\n    ) {\n      return weaveContext.WeavePointNamed(childName) as ParsedObject;\n    }\n\n    // Search for content within Flow (either a sub-Flow or a WeavePoint)\n    let flowContext = asOrNull(context, FlowBase);\n    if (childName && flowContext !== null) {\n      // When searching within a Knot, allow a deep searches so that\n      // named weave points (choices and gathers) can be found within any stitch\n      // Otherwise, we just search within the immediate object.\n      const shouldDeepSearch =\n        forceDeepSearch || flowContext.flowLevel === FlowLevel.Knot;\n\n      return flowContext.ContentWithNameAtLevel(\n        childName,\n        minimumLevel,\n        shouldDeepSearch\n      );\n    }\n\n    return null;\n  };\n}\n","import { Expression } from \"./Expression/Expression\";\nimport { ParsedObject } from \"./Object\";\nimport { Container as RuntimeContainer } from \"../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../engine/ControlCommand\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\nimport { Void } from \"../../../engine/Void\";\n\nexport class ReturnType extends ParsedObject {\n  public returnedExpression: Expression | null = null;\n\n  constructor(returnedExpression: Expression | null = null) {\n    super();\n\n    if (returnedExpression) {\n      this.returnedExpression = this.AddContent(\n        returnedExpression\n      ) as Expression;\n    }\n  }\n\n  get typeName(): string {\n    return \"ReturnType\";\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    const container = new RuntimeContainer();\n\n    if (this.returnedExpression) {\n      // Evaluate expression\n      container.AddContent(this.returnedExpression.runtimeObject);\n    } else {\n      // Return Runtime.Void when there's no expression to evaluate\n      // (This evaluation will just add the Void object to the evaluation stack)\n      container.AddContent(RuntimeControlCommand.EvalStart());\n      container.AddContent(new Void());\n      container.AddContent(RuntimeControlCommand.EvalEnd());\n    }\n\n    // Then pop the call stack\n    // (the evaluated expression will leave the return value on the evaluation stack)\n    container.AddContent(RuntimeControlCommand.PopFunction());\n\n    return container;\n  };\n}\n","// import { FlowBase } from './FlowBase';\n\nexport function ClosestFlowBase(obj: any): any | null {\n  let ancestor = obj.parent;\n  while (ancestor) {\n    if (ancestor.hasOwnProperty(\"iamFlowbase\") && ancestor.iamFlowbase()) {\n      return ancestor as any;\n    }\n\n    ancestor = ancestor.parent;\n  }\n\n  return null;\n}\n","import { DebugMetadata } from \"../../../engine/DebugMetadata\";\n\nexport class Identifier {\n  public name: string;\n  public debugMetadata: DebugMetadata | null = null;\n\n  constructor(name: string) {\n    this.name = name;\n  }\n\n  get typeName(): string {\n    return \"Identifier\";\n  }\n\n  public static Done(): Identifier {\n    return new Identifier(\"DONE\");\n  }\n\n  public readonly toString = (): string => this.name || \"undefined identifer\";\n}\n","import { Argument } from \"../Argument\";\nimport { Choice } from \"../Choice\";\nimport { Divert } from \"../Divert/Divert\";\nimport { DivertTarget } from \"../Divert/DivertTarget\";\nimport { FlowLevel } from \"./FlowLevel\";\nimport { Gather } from \"../Gather/Gather\";\nimport { INamedContent } from \"../../../../engine/INamedContent\";\n// import { Knot } from '../Knot';\nimport { ParsedObject } from \"../Object\";\nimport { Path } from \"../Path\";\nimport { ReturnType } from \"../ReturnType\";\nimport { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { Divert as RuntimeDivert } from \"../../../../engine/Divert\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { VariableAssignment as RuntimeVariableAssignment } from \"../../../../engine/VariableAssignment\";\n//import { Story } from '../Story';\nimport { SymbolType } from \"../SymbolType\";\nimport { VariableAssignment } from \"../Variable/VariableAssignment\";\nimport { Weave } from \"../Weave\";\nimport { ClosestFlowBase } from \"./ClosestFlowBase\";\nimport { Identifier } from \"../Identifier\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\n\ntype VariableResolveResult = {\n  found: boolean;\n  isGlobal: boolean;\n  isArgument: boolean;\n  isTemporary: boolean;\n  ownerFlow: FlowBase;\n};\n\n// Base class for Knots and Stitches\nexport abstract class FlowBase extends ParsedObject implements INamedContent {\n  public abstract readonly flowLevel: FlowLevel;\n\n  public _rootWeave: Weave | null = null;\n  public _subFlowsByName: Map<string, FlowBase> = new Map();\n  public _startingSubFlowDivert: RuntimeDivert | null = null;\n  public _startingSubFlowRuntime: RuntimeObject | null = null;\n  public _firstChildFlow: FlowBase | null = null;\n  public variableDeclarations: Map<string, VariableAssignment> = new Map();\n\n  get hasParameters() {\n    return this.args !== null && this.args.length > 0;\n  }\n\n  get subFlowsByName() {\n    return this._subFlowsByName;\n  }\n\n  get typeName(): string {\n    if (this.isFunction) {\n      return \"Function\";\n    }\n\n    return String(this.flowLevel);\n  }\n\n  get name(): string | null {\n    return this.identifier?.name || null;\n  }\n\n  public identifier: Identifier | null = null;\n  public args: Argument[] | null = null;\n\n  constructor(\n    identifier: Identifier | null,\n    topLevelObjects: ParsedObject[] | null = null,\n    args: Argument[] | null = null,\n    public readonly isFunction: boolean = false,\n    isIncludedStory: boolean = false\n  ) {\n    super();\n\n    this.identifier = identifier;\n    this.args = args;\n\n    if (topLevelObjects === null) {\n      topLevelObjects = [];\n    }\n\n    // Used by story to add includes\n    this.PreProcessTopLevelObjects(topLevelObjects);\n\n    topLevelObjects = this.SplitWeaveAndSubFlowContent(\n      topLevelObjects,\n      this.GetType() == \"Story\" && !isIncludedStory\n    );\n\n    this.AddContent(topLevelObjects);\n  }\n\n  public iamFlowbase = () => true;\n\n  public readonly SplitWeaveAndSubFlowContent = (\n    contentObjs: ParsedObject[],\n    isRootStory: boolean\n  ): ParsedObject[] => {\n    const weaveObjs: ParsedObject[] = [];\n    const subFlowObjs: ParsedObject[] = [];\n\n    this._subFlowsByName = new Map();\n\n    for (const obj of contentObjs) {\n      const subFlow = asOrNull(obj, FlowBase);\n      if (subFlow) {\n        if (this._firstChildFlow === null) {\n          this._firstChildFlow = subFlow;\n        }\n\n        subFlowObjs.push(obj);\n        if (subFlow.identifier?.name) {\n          this._subFlowsByName.set(subFlow.identifier?.name, subFlow);\n        }\n      } else {\n        weaveObjs.push(obj);\n      }\n    }\n\n    // Implicit final gather in top level story for ending without warning that you run out of content\n    if (isRootStory) {\n      weaveObjs.push(\n        new Gather(null, 1),\n        new Divert(new Path(Identifier.Done()))\n      );\n    }\n\n    const finalContent: ParsedObject[] = [];\n\n    if (weaveObjs.length > 0) {\n      this._rootWeave = new Weave(weaveObjs, 0);\n      finalContent.push(this._rootWeave);\n    }\n\n    if (subFlowObjs.length > 0) {\n      finalContent.push(...subFlowObjs);\n    }\n    return finalContent;\n  };\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public PreProcessTopLevelObjects(_: ParsedObject[]): void {\n    // empty by default, used by Story to process included file references\n  }\n\n  public VariableResolveResult?: VariableResolveResult | null | undefined;\n\n  public ResolveVariableWithName = (\n    varName: string,\n    fromNode: ParsedObject\n  ): VariableResolveResult => {\n    const result: VariableResolveResult = {} as any;\n\n    // Search in the stitch / knot that owns the node first\n    const ownerFlow = fromNode === null ? this : ClosestFlowBase(fromNode);\n\n    if (ownerFlow) {\n      // Argument\n      if (ownerFlow.args !== null) {\n        for (const arg of ownerFlow.args) {\n          if (arg.identifier?.name === varName) {\n            result.found = true;\n            result.isArgument = true;\n            result.ownerFlow = ownerFlow;\n            return result;\n          }\n        }\n      }\n\n      // Temp\n      if (\n        ownerFlow !== this.story &&\n        ownerFlow.variableDeclarations.has(varName)\n      ) {\n        result.found = true;\n        result.ownerFlow = ownerFlow;\n        result.isTemporary = true;\n\n        return result;\n      }\n    }\n\n    // Global\n    if (this.story.variableDeclarations.has(varName)) {\n      result.found = true;\n      result.ownerFlow = this.story;\n      result.isGlobal = true;\n\n      return result;\n    }\n\n    result.found = false;\n\n    return result;\n  };\n\n  public AddNewVariableDeclaration = (varDecl: VariableAssignment): void => {\n    const varName = varDecl.variableName;\n    if (this.variableDeclarations.has(varName)) {\n      const varab = this.variableDeclarations.get(varName)!;\n      let prevDeclError = \"\";\n      const debugMetadata = varab.debugMetadata;\n      if (debugMetadata) {\n        prevDeclError = ` (${varab.debugMetadata})`;\n      }\n\n      this.Error(\n        `found declaration variable '${varName}' that was already declared${prevDeclError}`,\n        varDecl,\n        false\n      );\n\n      return;\n    }\n\n    this.variableDeclarations.set(varDecl.variableName, varDecl);\n  };\n\n  public ResolveWeavePointNaming = (): void => {\n    // Find all weave points and organise them by name ready for\n    // diverting. Also detect naming collisions.\n    if (this._rootWeave) {\n      this._rootWeave.ResolveWeavePointNaming();\n    }\n\n    for (const [, value] of this._subFlowsByName) {\n      if (value.hasOwnProperty(\"ResolveWeavePointNaming\")) {\n        value.ResolveWeavePointNaming();\n      }\n    }\n  };\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    let foundReturn: ReturnType | null = null;\n    if (this.isFunction) {\n      this.CheckForDisallowedFunctionFlowControl();\n    } else if (\n      this.flowLevel === FlowLevel.Knot ||\n      this.flowLevel === FlowLevel.Stitch\n    ) {\n      // Non-functon: Make sure knots and stitches don't attempt to use Return statement\n      foundReturn = this.Find(ReturnType)();\n\n      if (foundReturn !== null) {\n        this.Error(\n          `Return statements can only be used in knots that are declared as functions: == function ${this.identifier} ==`,\n          foundReturn\n        );\n      }\n    }\n\n    const container = new RuntimeContainer();\n    container.name = this.identifier?.name as string;\n\n    if (this.story.countAllVisits) {\n      container.visitsShouldBeCounted = true;\n    }\n\n    this.GenerateArgumentVariableAssignments(container);\n\n    // Run through content defined for this knot/stitch:\n    //  - First of all, any initial content before a sub-stitch\n    //    or any weave content is added to the main content container\n    //  - The first inner knot/stitch is automatically entered, while\n    //    the others are only accessible by an explicit divert\n    //       - The exception to this rule is if the knot/stitch takes\n    //         parameters, in which case it can't be auto-entered.\n    //  - Any Choices and Gathers (i.e. IWeavePoint) found are\n    //    processsed by GenerateFlowContent.\n    let contentIdx: number = 0;\n    while (this.content !== null && contentIdx < this.content.length) {\n      const obj: ParsedObject = this.content[contentIdx];\n\n      // Inner knots and stitches\n      if (obj instanceof FlowBase) {\n        const childFlow: FlowBase = obj;\n        const childFlowRuntime = childFlow.runtimeObject;\n\n        // First inner stitch - automatically step into it\n        // 20/09/2016 - let's not auto step into knots\n        if (\n          contentIdx === 0 &&\n          !childFlow.hasParameters &&\n          this.flowLevel === FlowLevel.Knot\n        ) {\n          this._startingSubFlowDivert = new RuntimeDivert();\n          container.AddContent(this._startingSubFlowDivert);\n          this._startingSubFlowRuntime = childFlowRuntime;\n        }\n\n        // Check for duplicate knots/stitches with same name\n        const namedChild = childFlowRuntime as RuntimeObject & INamedContent;\n        const existingChild: INamedContent | null =\n          container.namedContent.get(namedChild.name!) || null;\n\n        if (existingChild) {\n          const errorMsg = `${this.GetType()} already contains flow named '${\n            namedChild.name\n          }' (at ${(existingChild as any as RuntimeObject).debugMetadata})`;\n          this.Error(errorMsg, childFlow);\n        }\n\n        container.AddToNamedContentOnly(namedChild);\n      } else if (obj) {\n        // Other content (including entire Weaves that were grouped in the constructor)\n        // At the time of writing, all FlowBases have a maximum of one piece of \"other content\"\n        // and it's always the root Weave\n        container.AddContent(obj.runtimeObject);\n      }\n\n      contentIdx += 1;\n    }\n\n    // CHECK FOR FINAL LOOSE ENDS!\n    // Notes:\n    //  - Functions don't need to terminate - they just implicitly return\n    //  - If return statement was found, don't continue finding warnings for missing control flow,\n    // since it's likely that a return statement has been used instead of a ->-> or something,\n    // or the writer failed to mark the knot as a function.\n    //  - _rootWeave may be null if it's a knot that only has stitches\n    if (\n      this.flowLevel !== FlowLevel.Story &&\n      !this.isFunction &&\n      this._rootWeave !== null &&\n      foundReturn === null\n    ) {\n      this._rootWeave.ValidateTermination(this.WarningInTermination);\n    }\n\n    return container;\n  };\n\n  public readonly GenerateArgumentVariableAssignments = (\n    container: RuntimeContainer\n  ): void => {\n    if (this.args === null || this.args.length === 0) {\n      return;\n    }\n\n    // Assign parameters in reverse since they'll be popped off the evaluation stack\n    // No need to generate EvalStart and EvalEnd since there's nothing being pushed\n    // back onto the evaluation stack.\n    for (let ii = this.args.length - 1; ii >= 0; --ii) {\n      const paramName = this.args[ii].identifier?.name || null;\n      const assign = new RuntimeVariableAssignment(paramName, true);\n      container.AddContent(assign);\n    }\n  };\n\n  public readonly ContentWithNameAtLevel = (\n    name: string,\n    level: FlowLevel | null = null,\n    deepSearch: boolean = false\n  ): ParsedObject | null => {\n    // Referencing self?\n    if (level === this.flowLevel || level === null) {\n      if (name === this.identifier?.name) {\n        return this;\n      }\n    }\n\n    if (level === FlowLevel.WeavePoint || level === null) {\n      let weavePointResult: ParsedObject | null = null;\n\n      if (this._rootWeave) {\n        weavePointResult = this._rootWeave.WeavePointNamed(\n          name\n        ) as ParsedObject;\n        if (weavePointResult) {\n          return weavePointResult;\n        }\n      }\n\n      // Stop now if we only wanted a result if it's a weave point?\n      if (level === FlowLevel.WeavePoint) {\n        return deepSearch ? this.DeepSearchForAnyLevelContent(name) : null;\n      }\n    }\n\n    // If this flow would be incapable of containing the requested level, early out\n    // (e.g. asking for a Knot from a Stitch)\n    if (level !== null && level < this.flowLevel) {\n      return null;\n    }\n\n    let subFlow: FlowBase | null = this._subFlowsByName.get(name) || null;\n\n    if (subFlow && (level === null || level === subFlow.flowLevel)) {\n      return subFlow;\n    }\n\n    return deepSearch ? this.DeepSearchForAnyLevelContent(name) : null;\n  };\n\n  public readonly DeepSearchForAnyLevelContent = (name: string) => {\n    const weaveResultSelf = this.ContentWithNameAtLevel(\n      name,\n      FlowLevel.WeavePoint,\n      false\n    );\n\n    if (weaveResultSelf) {\n      return weaveResultSelf;\n    }\n\n    for (const [, value] of this._subFlowsByName) {\n      const deepResult = value.ContentWithNameAtLevel(name, null, true);\n\n      if (deepResult) {\n        return deepResult;\n      }\n    }\n\n    return null;\n  };\n\n  public ResolveReferences(context: any): void {\n    if (this._startingSubFlowDivert) {\n      if (!this._startingSubFlowRuntime) {\n        throw new Error();\n      }\n\n      this._startingSubFlowDivert.targetPath =\n        this._startingSubFlowRuntime.path;\n    }\n\n    super.ResolveReferences(context);\n\n    // Check validity of parameter names\n    if (this.args !== null) {\n      for (const arg of this.args) {\n        context.CheckForNamingCollisions(\n          this,\n          arg.identifier,\n          SymbolType.Arg,\n          \"argument\"\n        );\n      }\n\n      // Separately, check for duplicate arugment names, since they aren't Parsed.Objects,\n      // so have to be checked independently.\n      for (let ii = 0; ii < this.args.length; ii += 1) {\n        for (let jj = ii + 1; jj < this.args.length; jj += 1) {\n          if (\n            this.args[ii].identifier?.name == this.args[jj].identifier?.name\n          ) {\n            this.Error(\n              `Multiple arguments with the same name: '${this.args[ii].identifier}'`\n            );\n          }\n        }\n      }\n    }\n\n    // Check naming collisions for knots and stitches\n    if (this.flowLevel !== FlowLevel.Story) {\n      // Weave points aren't FlowBases, so this will only be knot or stitch\n      const symbolType =\n        this.flowLevel === FlowLevel.Knot\n          ? SymbolType.Knot\n          : SymbolType.SubFlowAndWeave;\n\n      context.CheckForNamingCollisions(this, this.identifier, symbolType);\n    }\n  }\n\n  public readonly CheckForDisallowedFunctionFlowControl = (): void => {\n    // if (!(this instanceof Knot)) { // cannont use Knot here because of circular dependancy\n    if (this.flowLevel !== FlowLevel.Knot) {\n      this.Error(\n        \"Functions cannot be stitches - i.e. they should be defined as '== function myFunc ==' rather than internal to another knot.\"\n      );\n    }\n\n    // Not allowed sub-flows\n    for (const [key, value] of this._subFlowsByName) {\n      this.Error(\n        `Functions may not contain stitches, but saw '${key}' within the function '${this.identifier}'`,\n        value\n      );\n    }\n\n    if (!this._rootWeave) {\n      throw new Error();\n    }\n\n    const allDiverts = this._rootWeave.FindAll<Divert>(Divert)();\n    for (const divert of allDiverts) {\n      if (!divert.isFunctionCall && !(divert.parent instanceof DivertTarget)) {\n        this.Error(\n          `Functions may not contain diverts, but saw '${divert}'`,\n          divert\n        );\n      }\n    }\n\n    const allChoices = this._rootWeave.FindAll<Choice>(Choice)();\n    for (const choice of allChoices) {\n      this.Error(\n        `Functions may not contain choices, but saw '${choice}'`,\n        choice\n      );\n    }\n  };\n\n  public readonly WarningInTermination = (terminatingObject: ParsedObject) => {\n    let message: string =\n      \"Apparent loose end exists where the flow runs out. Do you need a '-> DONE' statement, choice or divert?\";\n    if (terminatingObject.parent === this._rootWeave && this._firstChildFlow) {\n      message = `${message} Note that if you intend to enter '${this._firstChildFlow.identifier}' next, you need to divert to it explicitly.`;\n    }\n\n    const terminatingDivert = asOrNull(terminatingObject, Divert);\n    if (terminatingDivert && terminatingDivert.isTunnel) {\n      message += ` When final tunnel to '${terminatingDivert.target} ->' returns it won't have anywhere to go.`;\n    }\n\n    this.Warning(message, terminatingObject);\n  };\n\n  public readonly toString = (): string =>\n    `${this.typeName} '${this.identifier}'`;\n}\n","import { Container as RuntimeContainer } from \"../../../engine/Container\";\nimport { ParsedObject } from \"./Object\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\nimport { Text } from \"./Text\";\nimport { asOrNull } from \"../../../engine/TypeAssertion\";\n\nexport class ContentList extends ParsedObject {\n  public dontFlatten: boolean = false;\n\n  get runtimeContainer(): RuntimeContainer {\n    return this.runtimeObject as RuntimeContainer;\n  }\n\n  constructor(objects?: ParsedObject[], ...moreObjects: ParsedObject[]) {\n    super();\n\n    if (objects) {\n      this.AddContent(objects);\n    }\n\n    if (moreObjects) {\n      this.AddContent(moreObjects);\n    }\n  }\n\n  get typeName(): string {\n    return \"ContentList\";\n  }\n\n  public readonly TrimTrailingWhitespace = (): void => {\n    for (let ii = this.content.length - 1; ii >= 0; --ii) {\n      const text = asOrNull(this.content[ii], Text);\n      if (text === null) {\n        break;\n      }\n\n      text.text = text.text.replace(new RegExp(/[ \\t]/g), \"\");\n      if (text.text.length === 0) {\n        this.content.splice(ii, 1);\n      } else {\n        break;\n      }\n    }\n  };\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    const container = new RuntimeContainer();\n    if (this.content !== null) {\n      for (const obj of this.content) {\n        const contentObjRuntime = obj.runtimeObject;\n\n        // Some objects (e.g. author warnings) don't generate runtime objects\n        if (contentObjRuntime) {\n          container.AddContent(contentObjRuntime);\n        }\n      }\n    }\n\n    if (this.dontFlatten) {\n      this.story.DontFlattenContainer(container);\n    }\n\n    return container;\n  };\n\n  public toString = (): string => `ContentList(${this.content.join(\", \")})`;\n}\n","import { InkObject } from \"./Object\";\nimport { Path } from \"./Path\";\n\nexport class VariableReference extends InkObject {\n  public name: string | null;\n  public pathForCount: Path | null = null;\n\n  get containerForCount() {\n    if (this.pathForCount === null) return null;\n    return this.ResolvePath(this.pathForCount).container;\n  }\n  get pathStringForCount() {\n    if (this.pathForCount === null) return null;\n\n    return this.CompactPathString(this.pathForCount);\n  }\n  set pathStringForCount(value: string | null) {\n    if (value === null) this.pathForCount = null;\n    else this.pathForCount = new Path(value);\n  }\n\n  constructor(name: string | null = null) {\n    super();\n    this.name = name;\n  }\n\n  public toString() {\n    if (this.name != null) {\n      return \"var(\" + this.name + \")\";\n    } else {\n      let pathStr = this.pathStringForCount;\n      return \"read_count(\" + pathStr + \")\";\n    }\n  }\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ContentList } from \"../ContentList\";\nimport { Expression } from \"../Expression/Expression\";\nimport { FlowBase } from \"../Flow/FlowBase\";\nimport { ParsedObject } from \"../Object\";\nimport { Path } from \"../Path\";\nimport { Story } from \"../Story\";\nimport { VariableReference as RuntimeVariableReference } from \"../../../../engine/VariableReference\";\nimport { Weave } from \"../Weave\";\nimport { Identifier } from \"../Identifier\";\nimport { asOrNull, filterUndef } from \"../../../../engine/TypeAssertion\";\n\nexport class VariableReference extends Expression {\n  private _runtimeVarRef: RuntimeVariableReference | null = null;\n\n  // - Normal variables have a single item in their \"path\"\n  // - Knot/stitch names for read counts are actual dot-separated paths\n  //   (though this isn't actually used at time of writing)\n  // - List names are dot separated: listName.itemName (or just itemName)\n  get name() {\n    return this.path.join(\".\");\n  }\n\n  get path(): string[] {\n    return this.pathIdentifiers.map((id) => id.name!).filter(filterUndef);\n  }\n\n  get identifier(): Identifier | null {\n    if (!this.pathIdentifiers || this.pathIdentifiers.length == 0) {\n      return null;\n    }\n    const name = this.path.join(\".\");\n    const id = new Identifier(name);\n\n    return id;\n  }\n\n  // Only known after GenerateIntoContainer has run\n  public isConstantReference: boolean = false;\n  public isListItemReference: boolean = false;\n\n  get runtimeVarRef() {\n    return this._runtimeVarRef;\n  }\n\n  constructor(public readonly pathIdentifiers: Identifier[]) {\n    super();\n  }\n\n  get typeName(): string {\n    return \"ref\";\n  }\n\n  public readonly GenerateIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    let constantValue: Expression | null | undefined = this.story.constants.get(\n      this.name\n    );\n\n    // If it's a constant reference, just generate the literal expression value\n    // It's okay to access the constants at code generation time, since the\n    // first thing the ExportRuntime function does it search for all the constants\n    // in the story hierarchy, so they're all available.\n    if (constantValue) {\n      constantValue.GenerateConstantIntoContainer(container);\n      this.isConstantReference = true;\n\n      return;\n    }\n\n    this._runtimeVarRef = new RuntimeVariableReference(this.name);\n\n    // List item reference?\n    // Path might be to a list (listName.listItemName or just listItemName)\n    if (this.path.length === 1 || this.path.length === 2) {\n      let listItemName: string = \"\";\n      let listName: string = \"\";\n\n      if (this.path.length === 1) {\n        listItemName = this.path[0];\n      } else {\n        listName = this.path[0];\n        listItemName = this.path[1];\n      }\n\n      const listItem = this.story.ResolveListItem(listName, listItemName, this);\n\n      if (listItem) {\n        this.isListItemReference = true;\n      }\n    }\n\n    container.AddContent(this._runtimeVarRef);\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    // Work is already done if it's a constant or list item reference\n    if (this.isConstantReference || this.isListItemReference) {\n      return;\n    }\n\n    // Is it a read count?\n    const parsedPath = new Path(this.pathIdentifiers);\n    const targetForCount: ParsedObject | null =\n      parsedPath.ResolveFromContext(this);\n    if (targetForCount) {\n      if (!targetForCount.containerForCounting) {\n        throw new Error();\n      }\n\n      targetForCount.containerForCounting.visitsShouldBeCounted = true;\n\n      // If this is an argument to a function that wants a variable to be\n      // passed by reference, then the Parsed.Divert will have generated a\n      // Runtime.VariablePointerValue instead of allowing this object\n      // to generate its RuntimeVariableReference. This only happens under\n      // error condition since we shouldn't be passing a read count by\n      // reference, but we don't want it to crash!\n      if (this._runtimeVarRef === null) {\n        return;\n      }\n\n      this._runtimeVarRef.pathForCount = targetForCount.runtimePath;\n      this._runtimeVarRef.name = null;\n\n      // Check for very specific writer error: getting read count and\n      // printing it as content rather than as a piece of logic\n      // e.g. Writing {myFunc} instead of {myFunc()}\n      let targetFlow = asOrNull(targetForCount, FlowBase);\n      if (targetFlow && targetFlow.isFunction) {\n        // Is parent context content rather than logic?\n        if (\n          this.parent instanceof Weave ||\n          this.parent instanceof ContentList ||\n          this.parent instanceof FlowBase\n        ) {\n          this.Warning(\n            `'${targetFlow.identifier}' being used as read count rather than being called as function. Perhaps you intended to write ${targetFlow.identifier}()`\n          );\n        }\n      }\n\n      return;\n    }\n\n    // Couldn't find this multi-part path at all, whether as a divert\n    // target or as a list item reference.\n    if (this.path.length > 1) {\n      let errorMsg = `Could not find target for read count: ${parsedPath}`;\n      if (this.path.length <= 2) {\n        errorMsg += `, or couldn't find list item with the name ${this.path.join(\n          \",\"\n        )}`;\n      }\n\n      this.Error(errorMsg);\n\n      return;\n    }\n\n    if (!context.ResolveVariableWithName(this.name, this).found) {\n      this.Error(`Unresolved variable: ${this.name}`, this);\n    }\n  }\n\n  public readonly toString = (): string => `{${this.path.join(\".\")}}`;\n}\n","import { Container as RuntimeContainer } from \"../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../engine/ControlCommand\";\nimport { Divert } from \"./Divert/Divert\";\nimport { Divert as RuntimeDivert } from \"../../../engine/Divert\";\nimport { DivertTarget } from \"./Divert/DivertTarget\";\nimport { Expression } from \"./Expression/Expression\";\nimport { InkList as RuntimeInkList } from \"../../../engine/InkList\";\nimport { ListValue } from \"../../../engine/Value\";\nimport { NativeFunctionCall } from \"../../../engine/NativeFunctionCall\";\nimport { NumberExpression } from \"./Expression/NumberExpression\";\nimport { Path } from \"./Path\";\nimport { Story } from \"./Story\";\nimport { StringValue } from \"../../../engine/Value\";\nimport { VariableReference } from \"./Variable/VariableReference\";\nimport { Identifier } from \"./Identifier\";\nimport { asOrNull } from \"../../../engine/TypeAssertion\";\n\nexport class FunctionCall extends Expression {\n  public static readonly IsBuiltIn = (name: string): boolean => {\n    if (NativeFunctionCall.CallExistsWithName(name)) {\n      return true;\n    }\n\n    return (\n      name === \"CHOICE_COUNT\" ||\n      name === \"TURNS_SINCE\" ||\n      name === \"TURNS\" ||\n      name === \"RANDOM\" ||\n      name === \"SEED_RANDOM\" ||\n      name === \"LIST_VALUE\" ||\n      name === \"LIST_RANDOM\" ||\n      name === \"READ_COUNT\"\n    );\n  };\n\n  private _proxyDivert: Divert;\n  get proxyDivert(): Divert {\n    return this._proxyDivert;\n  }\n  private _divertTargetToCount: DivertTarget | null = null;\n  private _variableReferenceToCount: VariableReference | null = null;\n\n  get name(): string {\n    return (this._proxyDivert.target as Path).firstComponent || \"\";\n  }\n\n  get args(): Expression[] {\n    return this._proxyDivert.args;\n  }\n\n  get runtimeDivert(): RuntimeDivert {\n    return this._proxyDivert.runtimeDivert;\n  }\n\n  get isChoiceCount(): boolean {\n    return this.name === \"CHOICE_COUNT\";\n  }\n\n  get isTurns(): boolean {\n    return this.name === \"TURNS\";\n  }\n\n  get isTurnsSince(): boolean {\n    return this.name === \"TURNS_SINCE\";\n  }\n\n  get isRandom(): boolean {\n    return this.name === \"RANDOM\";\n  }\n\n  get isSeedRandom(): boolean {\n    return this.name === \"SEED_RANDOM\";\n  }\n\n  get isListRange(): boolean {\n    return this.name === \"LIST_RANGE\";\n  }\n\n  get isListRandom(): boolean {\n    return this.name === \"LIST_RANDOM\";\n  }\n\n  get isReadCount(): boolean {\n    return this.name === \"READ_COUNT\";\n  }\n\n  public shouldPopReturnedValue: boolean = false;\n\n  constructor(functionName: Identifier, args: Expression[]) {\n    super();\n\n    this._proxyDivert = new Divert(new Path(functionName), args);\n    this._proxyDivert.isFunctionCall = true;\n    this.AddContent(this._proxyDivert);\n  }\n\n  get typeName(): string {\n    return \"FunctionCall\";\n  }\n\n  public readonly GenerateIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    const foundList = this.story.ResolveList(this.name);\n\n    let usingProxyDivert: boolean = false;\n\n    if (this.isChoiceCount) {\n      if (this.args.length > 0) {\n        this.Error(\"The CHOICE_COUNT() function shouldn't take any arguments\");\n      }\n\n      container.AddContent(RuntimeControlCommand.ChoiceCount());\n    } else if (this.isTurns) {\n      if (this.args.length > 0) {\n        this.Error(\"The TURNS() function shouldn't take any arguments\");\n      }\n\n      container.AddContent(RuntimeControlCommand.Turns());\n    } else if (this.isTurnsSince || this.isReadCount) {\n      const divertTarget = asOrNull(this.args[0], DivertTarget);\n      const variableDivertTarget = asOrNull(this.args[0], VariableReference);\n\n      if (\n        this.args.length !== 1 ||\n        (divertTarget === null && variableDivertTarget === null)\n      ) {\n        this.Error(\n          `The ${this.name}() function should take one argument: a divert target to the target knot, stitch, gather or choice you want to check. e.g. TURNS_SINCE(-> myKnot)`\n        );\n        return;\n      }\n\n      if (divertTarget) {\n        this._divertTargetToCount = divertTarget;\n        this.AddContent(this._divertTargetToCount);\n\n        this._divertTargetToCount.GenerateIntoContainer(container);\n      } else if (variableDivertTarget) {\n        this._variableReferenceToCount = variableDivertTarget;\n        this.AddContent(this._variableReferenceToCount);\n\n        this._variableReferenceToCount.GenerateIntoContainer(container);\n      }\n\n      if (this.isTurnsSince) {\n        container.AddContent(RuntimeControlCommand.TurnsSince());\n      } else {\n        container.AddContent(RuntimeControlCommand.ReadCount());\n      }\n    } else if (this.isRandom) {\n      if (this.args.length !== 2) {\n        this.Error(\n          \"RANDOM should take 2 parameters: a minimum and a maximum integer\"\n        );\n      }\n\n      // We can type check single values, but not complex expressions\n      for (let ii = 0; ii < this.args.length; ii += 1) {\n        const num = asOrNull(this.args[ii], NumberExpression);\n        if (num && !num.isInt()) {\n          const paramName: string = ii === 0 ? \"minimum\" : \"maximum\";\n          this.Error(`RANDOM's ${paramName} parameter should be an integer`);\n        }\n\n        this.args[ii].GenerateIntoContainer(container);\n      }\n\n      container.AddContent(RuntimeControlCommand.Random());\n    } else if (this.isSeedRandom) {\n      if (this.args.length !== 1) {\n        this.Error(\"SEED_RANDOM should take 1 parameter - an integer seed\");\n      }\n\n      const num = asOrNull(this.args[0], NumberExpression);\n      if (num && !num.isInt()) {\n        this.Error(\"SEED_RANDOM's parameter should be an integer seed\");\n      }\n\n      this.args[0].GenerateIntoContainer(container);\n\n      container.AddContent(RuntimeControlCommand.SeedRandom());\n    } else if (this.isListRange) {\n      if (this.args.length !== 3) {\n        this.Error(\n          \"LIST_RANGE should take 3 parameters - a list, a min and a max\"\n        );\n      }\n\n      for (let ii = 0; ii < this.args.length; ii += 1) {\n        this.args[ii].GenerateIntoContainer(container);\n      }\n\n      container.AddContent(RuntimeControlCommand.ListRange());\n    } else if (this.isListRandom) {\n      if (this.args.length !== 1) {\n        this.Error(\"LIST_RANDOM should take 1 parameter - a list\");\n      }\n\n      this.args[0].GenerateIntoContainer(container);\n\n      container.AddContent(RuntimeControlCommand.ListRandom());\n    } else if (NativeFunctionCall.CallExistsWithName(this.name)) {\n      const nativeCall = NativeFunctionCall.CallWithName(this.name);\n      if (nativeCall.numberOfParameters !== this.args.length) {\n        let msg = `${FunctionCall.name} should take ${nativeCall.numberOfParameters} parameter`;\n        if (nativeCall.numberOfParameters > 1) {\n          msg += \"s\";\n        }\n\n        this.Error(msg);\n      }\n\n      for (let ii = 0; ii < this.args.length; ii += 1) {\n        this.args[ii].GenerateIntoContainer(container);\n      }\n\n      container.AddContent(NativeFunctionCall.CallWithName(this.name));\n    } else if (foundList !== null) {\n      if (this.args.length > 1) {\n        this.Error(\n          \"Can currently only construct a list from one integer (or an empty list from a given list definition)\"\n        );\n      }\n\n      // List item from given int\n      if (this.args.length === 1) {\n        container.AddContent(new StringValue(this.name));\n        this.args[0].GenerateIntoContainer(container);\n        container.AddContent(RuntimeControlCommand.ListFromInt());\n      } else {\n        // Empty list with given origin.\n        const list = new RuntimeInkList();\n        list.SetInitialOriginName(this.name);\n        container.AddContent(new ListValue(list));\n      }\n    } else {\n      // Normal function call\n      container.AddContent(this._proxyDivert.runtimeObject);\n      usingProxyDivert = true;\n    }\n\n    // Don't attempt to resolve as a divert if we're not doing a normal function call\n    if (!usingProxyDivert) {\n      this.content.splice(this.content.indexOf(this._proxyDivert), 1);\n    }\n\n    // Function calls that are used alone on a tilda-based line:\n    //  ~ func()\n    // Should tidy up any returned value from the evaluation stack,\n    // since it's unused.\n    if (this.shouldPopReturnedValue) {\n      container.AddContent(RuntimeControlCommand.PopEvaluatedValue());\n    }\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    // If we aren't using the proxy divert after all (e.g. if\n    // it's a native function call), but we still have arguments,\n    // we need to make sure they get resolved since the proxy divert\n    // is no longer in the content array.\n    if (!this.content.includes(this._proxyDivert) && this.args !== null) {\n      for (const arg of this.args) {\n        arg.ResolveReferences(context);\n      }\n    }\n\n    if (this._divertTargetToCount) {\n      const divert = this._divertTargetToCount.divert;\n      const attemptingTurnCountOfVariableTarget =\n        divert.runtimeDivert.variableDivertName != null;\n\n      if (attemptingTurnCountOfVariableTarget) {\n        this.Error(\n          `When getting the TURNS_SINCE() of a variable target, remove the '->' - i.e. it should just be TURNS_SINCE(${divert.runtimeDivert.variableDivertName})`\n        );\n\n        return;\n      }\n\n      const targetObject = divert.targetContent;\n      if (targetObject === null) {\n        if (!attemptingTurnCountOfVariableTarget) {\n          this.Error(\n            `Failed to find target for TURNS_SINCE: '${divert.target}'`\n          );\n        }\n      } else {\n        if (!targetObject.containerForCounting) {\n          throw new Error();\n        }\n\n        targetObject.containerForCounting.turnIndexShouldBeCounted = true;\n      }\n    } else if (this._variableReferenceToCount) {\n      const runtimeVarRef = this._variableReferenceToCount.runtimeVarRef;\n      if (!runtimeVarRef) {\n        throw new Error();\n      }\n\n      if (runtimeVarRef.pathForCount !== null) {\n        this.Error(\n          `Should be '${FunctionCall.name}'(-> '${this._variableReferenceToCount.name}). Usage without the '->' only makes sense for variable targets.`\n        );\n      }\n    }\n  }\n\n  public readonly toString = (): string => {\n    const strArgs = this.args.join(\", \");\n    return `${this.name}(${strArgs})`;\n  };\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { Expression } from \"./Expression\";\nimport { NativeFunctionCall } from \"../../../../engine/NativeFunctionCall\";\n\nexport class MultipleConditionExpression extends Expression {\n  get subExpressions(): Expression[] {\n    return this.content as Expression[];\n  }\n\n  constructor(conditionExpressions: Expression[]) {\n    super();\n\n    this.AddContent(conditionExpressions);\n  }\n\n  get typeName(): string {\n    return \"MultipleConditionExpression\";\n  }\n\n  public readonly GenerateIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    //    A && B && C && D\n    // => (((A B &&) C &&) D &&) etc\n    let isFirst: boolean = true;\n    for (const conditionExpr of this.subExpressions) {\n      conditionExpr.GenerateIntoContainer(container);\n\n      if (!isFirst) {\n        container.AddContent(NativeFunctionCall.CallWithName(\"&&\"));\n      }\n\n      isFirst = false;\n    }\n  };\n}\n","import { BinaryExpression } from \"../Expression/BinaryExpression\";\nimport { Choice } from \"../Choice\";\nimport { Conditional } from \"../Conditional/Conditional\";\nimport { ConditionalSingleBranch } from \"../Conditional/ConditionalSingleBranch\";\nimport { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ParsedObject } from \"../Object\";\nimport { Divert } from \"./Divert\";\nimport { Divert as RuntimeDivert } from \"../../../../engine/Divert\";\nimport { DivertTargetValue } from \"../../../../engine/Value\";\nimport { Expression } from \"../Expression/Expression\";\nimport { FlowBase } from \"../Flow/FlowBase\";\nimport { FunctionCall } from \"../FunctionCall\";\nimport { MultipleConditionExpression } from \"../Expression/MultipleConditionExpression\";\nimport { Story } from \"../Story\";\nimport { VariableReference } from \"../Variable/VariableReference\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\n\nexport class DivertTarget extends Expression {\n  private _runtimeDivert: RuntimeDivert | null = null;\n  get runtimeDivert(): RuntimeDivert {\n    if (!this._runtimeDivert) {\n      throw new Error();\n    }\n\n    return this._runtimeDivert;\n  }\n\n  private _runtimeDivertTargetValue: DivertTargetValue | null = null;\n  get runtimeDivertTargetValue(): DivertTargetValue {\n    if (!this._runtimeDivertTargetValue) {\n      throw new Error();\n    }\n\n    return this._runtimeDivertTargetValue;\n  }\n\n  public divert: Divert;\n\n  constructor(divert: Divert) {\n    super();\n\n    this.divert = this.AddContent(divert) as Divert;\n  }\n\n  get typeName(): string {\n    return \"DivertTarget\";\n  }\n\n  public readonly GenerateIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    this.divert.GenerateRuntimeObject();\n\n    this._runtimeDivert = this.divert.runtimeDivert as RuntimeDivert;\n    this._runtimeDivertTargetValue = new DivertTargetValue();\n\n    container.AddContent(this.runtimeDivertTargetValue);\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    if (this.divert.isDone || this.divert.isEnd) {\n      this.Error(\n        `Can't use -> DONE or -> END as variable divert targets`,\n        this\n      );\n\n      return;\n    }\n\n    let usageContext: ParsedObject | null = this;\n    while (usageContext && usageContext instanceof Expression) {\n      let badUsage: boolean = false;\n      let foundUsage: boolean = false;\n\n      const usageParent: any = (usageContext as Expression).parent;\n      if (usageParent instanceof BinaryExpression) {\n        // Only allowed to compare for equality\n\n        const binaryExprParent = usageParent;\n        if (\n          binaryExprParent.opName !== \"==\" &&\n          binaryExprParent.opName !== \"!=\"\n        ) {\n          badUsage = true;\n        } else {\n          if (\n            !(\n              binaryExprParent.leftExpression instanceof DivertTarget ||\n              binaryExprParent.leftExpression instanceof VariableReference\n            )\n          ) {\n            badUsage = true;\n          } else if (\n            !(\n              binaryExprParent.rightExpression instanceof DivertTarget ||\n              binaryExprParent.rightExpression instanceof VariableReference\n            )\n          ) {\n            badUsage = true;\n          }\n        }\n\n        foundUsage = true;\n      } else if (usageParent instanceof FunctionCall) {\n        const funcCall = usageParent;\n        if (!funcCall.isTurnsSince && !funcCall.isReadCount) {\n          badUsage = true;\n        }\n\n        foundUsage = true;\n      } else if (usageParent instanceof Expression) {\n        badUsage = true;\n        foundUsage = true;\n      } else if (usageParent instanceof MultipleConditionExpression) {\n        badUsage = true;\n        foundUsage = true;\n      } else if (\n        usageParent instanceof Choice &&\n        (usageParent as Choice).condition === usageContext\n      ) {\n        badUsage = true;\n        foundUsage = true;\n      } else if (\n        usageParent instanceof Conditional ||\n        usageParent instanceof ConditionalSingleBranch\n      ) {\n        badUsage = true;\n        foundUsage = true;\n      }\n\n      if (badUsage) {\n        this.Error(\n          `Can't use a divert target like that. Did you intend to call '${this.divert.target}' as a function: likeThis(), or check the read count: likeThis, with no arrows?`,\n          this\n        );\n      }\n\n      if (foundUsage) {\n        break;\n      }\n\n      usageContext = usageParent;\n    }\n\n    // Example ink for this case:\n    //\n    //     VAR x = -> blah\n    //\n    // ...which means that \"blah\" is expected to be a literal stitch target rather\n    // than a variable name. We can't really intelligently recover from this (e.g. if blah happens to\n    // contain a divert target itself) since really we should be generating a variable reference\n    // rather than a concrete DivertTarget, so we list it as an error.\n    if (this.runtimeDivert.hasVariableTarget) {\n      if (!this.divert.target) {\n        throw new Error();\n      }\n\n      this.Error(\n        `Since '${this.divert.target.dotSeparatedComponents}' is a variable, it shouldn't be preceded by '->' here.`\n      );\n    }\n\n    // Main resolve\n    this.runtimeDivert.targetPath &&\n      (this.runtimeDivertTargetValue.targetPath =\n        this.runtimeDivert.targetPath);\n\n    // Tell hard coded (yet variable) divert targets that they also need to be counted\n    // TODO: Only detect DivertTargets that are values rather than being used directly for\n    // read or turn counts. Should be able to detect this by looking for other uses of containerForCounting\n    let targetContent = this.divert.targetContent;\n    if (targetContent !== null) {\n      let target = targetContent.containerForCounting;\n      if (target !== null) {\n        // Purpose is known: used directly in TURNS_SINCE(-> divTarg)\n        const parentFunc = asOrNull(this.parent, FunctionCall);\n        if (parentFunc && parentFunc.isTurnsSince) {\n          target.turnIndexShouldBeCounted = true;\n        } else {\n          // Unknown purpose, count everything\n          target.visitsShouldBeCounted = true;\n          target.turnIndexShouldBeCounted = true;\n        }\n      }\n\n      // Unfortunately not possible:\n      // https://github.com/inkle/ink/issues/538\n      //\n      // VAR func = -> double\n      //\n      // === function double(ref x)\n      //    ~ x = x * 2\n      //\n      // Because when generating the parameters for a function\n      // to be called, it needs to know ahead of time when\n      // compiling whether to pass a variable reference or value.\n      //\n      let targetFlow = asOrNull(targetContent, FlowBase);\n      if (targetFlow != null && targetFlow.args !== null) {\n        for (const arg of targetFlow.args) {\n          if (arg.isByReference) {\n            this.Error(\n              `Can't store a divert target to a knot or function that has by-reference arguments ('${targetFlow.identifier}' has 'ref ${arg.identifier}').`\n            );\n          }\n        }\n      }\n    }\n  }\n\n  // Equals override necessary in order to check for CONST multiple definition equality\n  public readonly Equals = (obj: ParsedObject): boolean => {\n    const otherDivTarget = asOrNull(obj, DivertTarget);\n    if (\n      !otherDivTarget ||\n      !this.divert.target ||\n      !otherDivTarget.divert.target\n    ) {\n      return false;\n    }\n\n    const targetStr = this.divert.target.dotSeparatedComponents;\n    const otherTargetStr = otherDivTarget.divert.target.dotSeparatedComponents;\n\n    return targetStr === otherTargetStr;\n  };\n}\n","import { Argument } from \"../Argument\";\nimport { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../../engine/ControlCommand\";\nimport { Divert as RuntimeDivert } from \"../../../../engine/Divert\";\nimport { DivertTarget } from \"./DivertTarget\";\nimport { Expression } from \"../Expression/Expression\";\nimport { FlowBase } from \"../Flow/FlowBase\";\nimport { FunctionCall } from \"../FunctionCall\";\nimport { ParsedObject } from \"../Object\";\nimport { Path } from \"../Path\";\nimport { Path as RuntimePath } from \"../../../../engine/Path\";\nimport { PushPopType } from \"../../../../engine/PushPop\";\nimport { Story } from \"../Story\";\nimport { VariablePointerValue } from \"../../../../engine/Value\";\nimport { VariableReference } from \"../Variable/VariableReference\";\nimport { ClosestFlowBase } from \"../Flow/ClosestFlowBase\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\n\nexport class Divert extends ParsedObject {\n  public readonly args: Expression[] = [];\n\n  public readonly target: Path | null = null;\n  public targetContent: ParsedObject | null = null;\n  private _runtimeDivert: RuntimeDivert | null = null;\n  get runtimeDivert(): RuntimeDivert {\n    if (!this._runtimeDivert) {\n      throw new Error();\n    }\n\n    return this._runtimeDivert;\n  }\n\n  set runtimeDivert(value: RuntimeDivert) {\n    this._runtimeDivert = value;\n  }\n\n  public isFunctionCall: boolean = false;\n  public isEmpty: boolean = false;\n  public isTunnel: boolean = false;\n  public isThread: boolean = false;\n\n  get isEnd(): boolean {\n    return Boolean(this.target && this.target.dotSeparatedComponents === \"END\");\n  }\n\n  get isDone(): boolean {\n    return Boolean(\n      this.target && this.target.dotSeparatedComponents === \"DONE\"\n    );\n  }\n\n  constructor(target?: Path | null | undefined, args?: Expression[]) {\n    super();\n\n    if (target) {\n      this.target = target;\n    }\n\n    if (args) {\n      this.args = args;\n      this.AddContent(args);\n    }\n  }\n\n  get typeName(): string {\n    return \"Divert\";\n  }\n\n  public readonly GenerateRuntimeObject = () => {\n    // End = end flow immediately\n    // Done = return from thread or instruct the flow that it's safe to exit\n    if (this.isEnd) {\n      return RuntimeControlCommand.End();\n    } else if (this.isDone) {\n      return RuntimeControlCommand.Done();\n    }\n\n    this.runtimeDivert = new RuntimeDivert();\n\n    // Normally we resolve the target content during the\n    // Resolve phase, since we expect all runtime objects to\n    // be available in order to find the final runtime path for\n    // the destination. However, we need to resolve the target\n    // (albeit without the runtime target) early so that\n    // we can get information about the arguments - whether\n    // they're by reference - since it affects the code we\n    // generate here.\n    this.ResolveTargetContent();\n\n    this.CheckArgumentValidity();\n\n    // Passing arguments to the knot\n    const requiresArgCodeGen = this.args !== null && this.args.length > 0;\n    if (\n      requiresArgCodeGen ||\n      this.isFunctionCall ||\n      this.isTunnel ||\n      this.isThread\n    ) {\n      const container = new RuntimeContainer();\n\n      // Generate code for argument evaluation\n      // This argument generation is coded defensively - it should\n      // attempt to generate the code for all the parameters, even if\n      // they don't match the expected arguments. This is so that the\n      // parameter objects themselves are generated correctly and don't\n      // get into a state of attempting to resolve references etc\n      // without being generated.\n      if (requiresArgCodeGen) {\n        // Function calls already in an evaluation context\n        if (!this.isFunctionCall) {\n          container.AddContent(RuntimeControlCommand.EvalStart());\n        }\n\n        let targetArguments: Argument[] | null = null;\n        if (this.targetContent) {\n          targetArguments = (this.targetContent as FlowBase).args;\n        }\n\n        for (let ii = 0; ii < this.args.length; ++ii) {\n          const argToPass: Expression = this.args[ii];\n          let argExpected: Argument | null = null;\n          if (targetArguments && ii < targetArguments.length) {\n            argExpected = targetArguments[ii];\n          }\n\n          // Pass by reference: argument needs to be a variable reference\n          if (argExpected && argExpected.isByReference) {\n            const varRef = asOrNull(argToPass, VariableReference);\n            if (!varRef) {\n              this.Error(\n                `Expected variable name to pass by reference to 'ref ${argExpected.identifier}' but saw ${argToPass}`\n              );\n\n              break;\n            }\n\n            // Check that we're not attempting to pass a read count by reference\n            const targetPath = new Path(varRef.pathIdentifiers);\n            const targetForCount: ParsedObject | null =\n              targetPath.ResolveFromContext(this);\n            if (targetForCount) {\n              this.Error(\n                `can't pass a read count by reference. '${\n                  targetPath.dotSeparatedComponents\n                }' is a knot/stitch/label, but '${\n                  this.target!.dotSeparatedComponents\n                }' requires the name of a VAR to be passed.`\n              );\n\n              break;\n            }\n\n            const varPointer = new VariablePointerValue(varRef.name);\n            container.AddContent(varPointer);\n          } else {\n            // Normal value being passed: evaluate it as normal\n            argToPass.GenerateIntoContainer(container);\n          }\n        }\n\n        // Function calls were already in an evaluation context\n        if (!this.isFunctionCall) {\n          container.AddContent(RuntimeControlCommand.EvalEnd());\n        }\n      }\n\n      // Starting a thread? A bit like a push to the call stack below... but not.\n      // It sort of puts the call stack on a thread stack (argh!) - forks the full flow.\n      if (this.isThread) {\n        container.AddContent(RuntimeControlCommand.StartThread());\n      } else if (this.isFunctionCall || this.isTunnel) {\n        // If this divert is a function call, tunnel, we push to the call stack\n        // so we can return again\n        this.runtimeDivert.pushesToStack = true;\n        this.runtimeDivert.stackPushType = this.isFunctionCall\n          ? PushPopType.Function\n          : PushPopType.Tunnel;\n      }\n\n      // Jump into the \"function\" (knot/stitch)\n      container.AddContent(this.runtimeDivert);\n\n      return container;\n    }\n\n    // Simple divert\n    return this.runtimeDivert;\n  };\n\n  // When the divert is to a target that's actually a variable name\n  // rather than an explicit knot/stitch name, try interpretting it\n  // as such by getting the variable name.\n  public readonly PathAsVariableName = () =>\n    this.target ? this.target.firstComponent : null;\n\n  public readonly ResolveTargetContent = (): void => {\n    if (this.isEmpty || this.isEnd) {\n      return;\n    }\n\n    if (this.targetContent === null) {\n      // Is target of this divert a variable name that will be de-referenced\n      // at runtime? If so, there won't be any further reference resolution\n      // we can do at this point.\n      let variableTargetName = this.PathAsVariableName();\n      if (variableTargetName !== null) {\n        const flowBaseScope = asOrNull(ClosestFlowBase(this), FlowBase);\n        if (flowBaseScope) {\n          const resolveResult = flowBaseScope.ResolveVariableWithName(\n            variableTargetName,\n            this\n          );\n\n          if (resolveResult.found) {\n            // Make sure that the flow was typed correctly, given that we know that this\n            // is meant to be a divert target\n            if (\n              resolveResult.isArgument &&\n              resolveResult.ownerFlow &&\n              resolveResult.ownerFlow.args\n            ) {\n              let argument = resolveResult.ownerFlow.args.find(\n                (a) => a.identifier?.name == variableTargetName\n              );\n\n              if (argument && !argument.isDivertTarget) {\n                this.Error(\n                  `Since '${argument.identifier}' is used as a variable divert target (on ${this.debugMetadata}), it should be marked as: -> ${argument.identifier}`,\n                  resolveResult.ownerFlow\n                );\n              }\n            }\n\n            this.runtimeDivert.variableDivertName = variableTargetName;\n            return;\n          }\n        }\n      }\n\n      if (!this.target) {\n        throw new Error();\n      }\n\n      this.targetContent = this.target.ResolveFromContext(this);\n    }\n  };\n\n  public ResolveReferences(context: Story): void {\n    if (this.isEmpty || this.isEnd || this.isDone) {\n      return;\n    } else if (!this.runtimeDivert) {\n      throw new Error();\n    }\n\n    if (this.targetContent) {\n      this.runtimeDivert.targetPath = this.targetContent.runtimePath;\n    }\n\n    // Resolve children (the arguments)\n    super.ResolveReferences(context);\n\n    // May be null if it's a built in function (e.g. TURNS_SINCE)\n    // or if it's a variable target.\n    let targetFlow = asOrNull(this.targetContent, FlowBase);\n    if (targetFlow) {\n      if (!targetFlow.isFunction && this.isFunctionCall) {\n        super.Error(\n          `${targetFlow.identifier} hasn't been marked as a function, but it's being called as one. Do you need to declare the knot as '== function ${targetFlow.identifier} =='?`\n        );\n      } else if (\n        targetFlow.isFunction &&\n        !this.isFunctionCall &&\n        !(this.parent instanceof DivertTarget)\n      ) {\n        super.Error(\n          targetFlow.identifier +\n            \" can't be diverted to. It can only be called as a function since it's been marked as such: '\" +\n            targetFlow.identifier +\n            \"(...)'\"\n        );\n      }\n    }\n\n    // Check validity of target content\n    const targetWasFound = this.targetContent !== null;\n    let isBuiltIn: boolean = false;\n    let isExternal: boolean = false;\n\n    if (!this.target) {\n      throw new Error();\n    } else if (this.target.numberOfComponents === 1) {\n      if (!this.target.firstComponent) {\n        throw new Error();\n      }\n\n      // BuiltIn means TURNS_SINCE, CHOICE_COUNT, RANDOM or SEED_RANDOM\n      isBuiltIn = FunctionCall.IsBuiltIn(this.target.firstComponent);\n\n      // Client-bound function?\n      isExternal = context.IsExternal(this.target.firstComponent);\n\n      if (isBuiltIn || isExternal) {\n        if (!this.isFunctionCall) {\n          super.Error(\n            `${this.target.firstComponent} must be called as a function: ~ ${this.target.firstComponent}()`\n          );\n        }\n\n        if (isExternal) {\n          this.runtimeDivert.isExternal = true;\n          if (this.args !== null) {\n            this.runtimeDivert.externalArgs = this.args.length;\n          }\n\n          this.runtimeDivert.pushesToStack = false;\n          this.runtimeDivert.targetPath = new RuntimePath(\n            this.target.firstComponent\n          );\n\n          this.CheckExternalArgumentValidity(context);\n        }\n\n        return;\n      }\n    }\n\n    // Variable target?\n    if (this.runtimeDivert.variableDivertName != null) {\n      return;\n    }\n\n    if (!targetWasFound && !isBuiltIn && !isExternal) {\n      this.Error(`target not found: '${this.target}'`);\n    }\n  }\n\n  // Returns false if there's an error\n  public readonly CheckArgumentValidity = (): void => {\n    if (this.isEmpty) {\n      return;\n    }\n\n    // Argument passing: Check for errors in number of arguments\n    let numArgs = 0;\n    if (this.args !== null && this.args.length > 0) {\n      numArgs = this.args.length;\n    }\n\n    // Missing content?\n    // Can't check arguments properly. It'll be due to some\n    // other error though, so although there's a problem and\n    // we report false, we don't need to report a specific error.\n    // It may also be because it's a valid call to an external\n    // function, that we check at the resolve stage.\n    if (this.targetContent === null) {\n      return;\n    }\n\n    const targetFlow = asOrNull(this.targetContent, FlowBase);\n\n    // No error, crikey!\n    if (numArgs === 0 && (targetFlow === null || !targetFlow.hasParameters)) {\n      return;\n    } else if (targetFlow === null && numArgs > 0) {\n      this.Error(\n        \"target needs to be a knot or stitch in order to pass arguments\"\n      );\n      return;\n    } else if (\n      targetFlow !== null &&\n      (targetFlow.args === null || (!targetFlow.args && numArgs > 0))\n    ) {\n      this.Error(`target (${targetFlow.name}) doesn't take parameters`);\n      return;\n    } else if (this.parent instanceof DivertTarget) {\n      if (numArgs > 0) {\n        this.Error(`can't store arguments in a divert target variable`);\n      }\n\n      return;\n    }\n\n    const paramCount = targetFlow!.args!.length;\n    if (paramCount !== numArgs) {\n      let butClause: string;\n      if (numArgs === 0) {\n        butClause = \"but there weren't any passed to it\";\n      } else if (numArgs < paramCount) {\n        butClause = `but only got ${numArgs}`;\n      } else {\n        butClause = `but got ${numArgs}`;\n      }\n\n      this.Error(\n        `to '${\n          targetFlow!.identifier\n        }' requires ${paramCount} arguments, ${butClause}`\n      );\n\n      return;\n    }\n\n    // Light type-checking for divert target arguments\n    for (let ii = 0; ii < paramCount; ++ii) {\n      const flowArg: Argument = targetFlow!.args![ii];\n      const divArgExpr: Expression = this.args[ii];\n\n      // Expecting a divert target as an argument, let's do some basic type checking\n      if (flowArg.isDivertTarget) {\n        // Not passing a divert target or any kind of variable reference?\n        let varRef = asOrNull(divArgExpr, VariableReference);\n        if (!(divArgExpr instanceof DivertTarget) && varRef === null) {\n          this.Error(\n            `Target '${\n              targetFlow!.identifier\n            }' expects a divert target for the parameter named -> ${\n              flowArg.identifier\n            } but saw ${divArgExpr}`,\n            divArgExpr\n          );\n        } else if (varRef) {\n          // Passing 'a' instead of '-> a'?\n          // i.e. read count instead of divert target\n          // Unfortunately have to manually resolve here since we're still in code gen\n          const knotCountPath = new Path(varRef.pathIdentifiers);\n          const targetForCount: ParsedObject | null =\n            knotCountPath.ResolveFromContext(varRef);\n          if (targetForCount) {\n            this.Error(\n              `Passing read count of '${knotCountPath.dotSeparatedComponents}' instead of a divert target. You probably meant '${knotCountPath}'`\n            );\n          }\n        }\n      }\n    }\n\n    if (targetFlow === null) {\n      this.Error(\n        \"Can't call as a function or with arguments unless it's a knot or stitch\"\n      );\n      return;\n    }\n\n    return;\n  };\n\n  public readonly CheckExternalArgumentValidity = (context: Story): void => {\n    const externalName: string | null = this.target\n      ? this.target.firstComponent\n      : null;\n    const external = context.externals.get(externalName as string);\n    if (!external) {\n      throw new Error(\"external not found\");\n    }\n\n    const externalArgCount: number = external.argumentNames.length;\n    let ownArgCount = 0;\n    if (this.args) {\n      ownArgCount = this.args.length;\n    }\n\n    if (ownArgCount !== externalArgCount) {\n      this.Error(\n        `incorrect number of arguments sent to external function '${externalName}'. Expected ${externalArgCount} but got ${ownArgCount}`\n      );\n    }\n  };\n\n  public Error(\n    message: string,\n    source: ParsedObject | null = null,\n    isWarning: boolean = false\n  ): void {\n    // Could be getting an error from a nested Divert\n    if (source !== this && source) {\n      super.Error(message, source);\n      return;\n    }\n\n    if (this.isFunctionCall) {\n      super.Error(`Function call ${message}`, source, isWarning);\n    } else {\n      super.Error(`Divert ${message}`, source, isWarning);\n    }\n  }\n\n  public toString = (): string => {\n    let returnString = \"\";\n    if (this.target !== null) {\n      returnString += this.target.toString();\n    } else {\n      return \"-> <empty divert>\";\n    }\n\n    if (this.isTunnel) {\n      returnString += \" ->\";\n    }\n    if (this.isFunctionCall) {\n      returnString += \" ()\";\n    }\n\n    return returnString;\n  };\n}\n","import { Divert as RuntimeDivert } from \"../../../../engine/Divert\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\n\nexport class GatherPointToResolve {\n  constructor(\n    public divert: RuntimeDivert,\n    public targetRuntimeObj: RuntimeObject\n  ) {}\n}\n","import { Divert as RuntimeDivert } from \"../../../../engine/Divert\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\n\nexport class SequenceDivertToResolve {\n  constructor(\n    public divert: RuntimeDivert,\n    public targetContent: RuntimeObject\n  ) {}\n}\n","export enum SequenceType {\n  Stopping = 1, // default\n  Cycle = 2,\n  Shuffle = 4,\n  Once = 8,\n}\n","import { ContentList } from \"../ContentList\";\nimport { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../../engine/ControlCommand\";\nimport { Divert as RuntimeDivert } from \"../../../../engine/Divert\";\nimport { IntValue } from \"../../../../engine/Value\";\nimport { NativeFunctionCall } from \"../../../../engine/NativeFunctionCall\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { SequenceDivertToResolve } from \"./SequenceDivertToResolve\";\nimport { SequenceType } from \"./SequenceType\";\nimport { Story } from \"../Story\";\nimport { Weave } from \"../Weave\";\n\nexport class Sequence extends ParsedObject {\n  private _sequenceDivertsToResolve: SequenceDivertToResolve[] = [];\n\n  public sequenceElements: ParsedObject[];\n\n  constructor(\n    elementContentLists: ContentList[],\n    public readonly sequenceType: SequenceType\n  ) {\n    super();\n\n    this.sequenceType = sequenceType;\n    this.sequenceElements = [];\n\n    for (const elementContentList of elementContentLists) {\n      const contentObjs = elementContentList.content;\n      let seqElObject: ParsedObject | null = null;\n\n      // Don't attempt to create a weave for the sequence element\n      // if the content list is empty. Weaves don't like it!\n      if (contentObjs === null || contentObjs.length === 0) {\n        seqElObject = elementContentList;\n      } else {\n        seqElObject = new Weave(contentObjs);\n      }\n\n      this.sequenceElements.push(seqElObject);\n      this.AddContent(seqElObject);\n    }\n  }\n\n  get typeName(): string {\n    return \"Sequence\";\n  }\n\n  // Generate runtime code that looks like:\n  //\n  //   chosenIndex = MIN(sequence counter, num elements) e.g. for \"Stopping\"\n  //   if chosenIndex == 0, divert to s0\n  //   if chosenIndex == 1, divert to s1  [etc]\n  //\n  //   - s0:\n  //      <content for sequence element>\n  //      divert to no-op\n  //   - s1:\n  //      <content for sequence element>\n  //      divert to no-op\n  //   - s2:\n  //      empty branch if using \"once\"\n  //      divert to no-op\n  //\n  //    no-op\n  //\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    const container = new RuntimeContainer();\n    container.visitsShouldBeCounted = true;\n    container.countingAtStartOnly = true;\n\n    this._sequenceDivertsToResolve = [];\n\n    // Get sequence read count\n    container.AddContent(RuntimeControlCommand.EvalStart());\n    container.AddContent(RuntimeControlCommand.VisitIndex());\n\n    const once: boolean = (this.sequenceType & SequenceType.Once) > 0;\n    const cycle: boolean = (this.sequenceType & SequenceType.Cycle) > 0;\n    const stopping: boolean = (this.sequenceType & SequenceType.Stopping) > 0;\n    const shuffle: boolean = (this.sequenceType & SequenceType.Shuffle) > 0;\n\n    let seqBranchCount = this.sequenceElements.length;\n    if (once) {\n      seqBranchCount += 1;\n    }\n\n    // Chosen sequence index:\n    //  - Stopping: take the MIN(read count, num elements - 1)\n    //  - Once: take the MIN(read count, num elements)\n    //    (the last one being empty)\n    if (stopping || once) {\n      //var limit = stopping ? seqBranchCount-1 : seqBranchCount;\n      container.AddContent(new IntValue(seqBranchCount - 1));\n      container.AddContent(NativeFunctionCall.CallWithName(\"MIN\"));\n    } else if (cycle) {\n      // - Cycle: take (read count % num elements)\n      container.AddContent(new IntValue(this.sequenceElements.length));\n      container.AddContent(NativeFunctionCall.CallWithName(\"%\"));\n    }\n\n    // Shuffle\n    if (shuffle) {\n      // Create point to return to when sequence is complete\n      const postShuffleNoOp = RuntimeControlCommand.NoOp();\n\n      // When visitIndex == lastIdx, we skip the shuffle\n      if (once || stopping) {\n        // if( visitIndex == lastIdx ) -> skipShuffle\n        const lastIdx = stopping\n          ? this.sequenceElements.length - 1\n          : this.sequenceElements.length;\n\n        container.AddContent(RuntimeControlCommand.Duplicate());\n        container.AddContent(new IntValue(lastIdx));\n        container.AddContent(NativeFunctionCall.CallWithName(\"==\"));\n\n        const skipShuffleDivert = new RuntimeDivert();\n        skipShuffleDivert.isConditional = true;\n        container.AddContent(skipShuffleDivert);\n\n        this.AddDivertToResolve(skipShuffleDivert, postShuffleNoOp);\n      }\n\n      // This one's a bit more complex! Choose the index at runtime.\n      let elementCountToShuffle = this.sequenceElements.length;\n      if (stopping) {\n        elementCountToShuffle -= 1;\n      }\n\n      container.AddContent(new IntValue(elementCountToShuffle));\n      container.AddContent(RuntimeControlCommand.SequenceShuffleIndex());\n      if (once || stopping) {\n        container.AddContent(postShuffleNoOp);\n      }\n    }\n\n    container.AddContent(RuntimeControlCommand.EvalEnd());\n\n    // Create point to return to when sequence is complete\n    const postSequenceNoOp = RuntimeControlCommand.NoOp();\n\n    // Each of the main sequence branches, and one extra empty branch if\n    // we have a \"once\" sequence.\n    for (let elIndex = 0; elIndex < seqBranchCount; elIndex += 1) {\n      // This sequence element:\n      //  if( chosenIndex == this index ) divert to this sequence element\n      // duplicate chosen sequence index, since it'll be consumed by \"==\"\n      container.AddContent(RuntimeControlCommand.EvalStart());\n      container.AddContent(RuntimeControlCommand.Duplicate());\n      container.AddContent(new IntValue(elIndex));\n      container.AddContent(NativeFunctionCall.CallWithName(\"==\"));\n      container.AddContent(RuntimeControlCommand.EvalEnd());\n\n      // Divert branch for this sequence element\n      const sequenceDivert = new RuntimeDivert();\n      sequenceDivert.isConditional = true;\n      container.AddContent(sequenceDivert);\n\n      let contentContainerForSequenceBranch: RuntimeContainer;\n\n      // Generate content for this sequence element\n      if (elIndex < this.sequenceElements.length) {\n        const el = this.sequenceElements[elIndex];\n        contentContainerForSequenceBranch =\n          el.runtimeObject as RuntimeContainer;\n      } else {\n        // Final empty branch for \"once\" sequences\n        contentContainerForSequenceBranch = new RuntimeContainer();\n      }\n\n      contentContainerForSequenceBranch.name = `s${elIndex}`;\n      contentContainerForSequenceBranch.InsertContent(\n        RuntimeControlCommand.PopEvaluatedValue(),\n        0\n      );\n\n      // When sequence element is complete, divert back to end of sequence\n      const seqBranchCompleteDivert = new RuntimeDivert();\n      contentContainerForSequenceBranch.AddContent(seqBranchCompleteDivert);\n      container.AddToNamedContentOnly(contentContainerForSequenceBranch);\n\n      // Save the diverts for reference resolution later (in ResolveReferences)\n      this.AddDivertToResolve(\n        sequenceDivert,\n        contentContainerForSequenceBranch\n      );\n      this.AddDivertToResolve(seqBranchCompleteDivert, postSequenceNoOp);\n    }\n\n    container.AddContent(postSequenceNoOp);\n\n    return container;\n  };\n\n  public readonly AddDivertToResolve = (\n    divert: RuntimeDivert,\n    targetContent: RuntimeObject\n  ) => {\n    this._sequenceDivertsToResolve.push(\n      new SequenceDivertToResolve(divert, targetContent)\n    );\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    for (const toResolve of this._sequenceDivertsToResolve) {\n      toResolve.divert.targetPath = toResolve.targetContent.path;\n    }\n  }\n}\n","import { Container as RuntimeContainer } from \"../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../engine/ControlCommand\";\nimport { Divert } from \"./Divert/Divert\";\nimport { Divert as RuntimeDivert } from \"../../../engine/Divert\";\nimport { DivertTargetValue } from \"../../../engine/Value\";\nimport { ParsedObject } from \"./Object\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\nimport { Story } from \"./Story\";\nimport { Void } from \"../../../engine/Void\";\nimport { asOrNull } from \"../../../engine/TypeAssertion\";\nimport { VariableReference } from \"../../../engine/VariableReference\";\n\nexport class TunnelOnwards extends ParsedObject {\n  private _overrideDivertTarget: DivertTargetValue | null = null;\n\n  private _divertAfter: Divert | null = null;\n  get divertAfter() {\n    return this._divertAfter;\n  }\n\n  set divertAfter(value) {\n    this._divertAfter = value;\n    if (this._divertAfter) {\n      this.AddContent(this._divertAfter);\n    }\n  }\n\n  get typeName(): string {\n    return \"TunnelOnwards\";\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    const container = new RuntimeContainer();\n\n    // Set override path for tunnel onwards (or nothing)\n    container.AddContent(RuntimeControlCommand.EvalStart());\n\n    if (this.divertAfter) {\n      // Generate runtime object's generated code and steal the arguments runtime code\n      const returnRuntimeObj = this.divertAfter.GenerateRuntimeObject();\n      const returnRuntimeContainer = returnRuntimeObj as RuntimeContainer;\n      if (returnRuntimeContainer) {\n        // Steal all code for generating arguments from the divert\n        const args = this.divertAfter.args;\n        if (args !== null && args.length > 0) {\n          // Steal everything betwen eval start and eval end\n          let evalStart = -1;\n          let evalEnd = -1;\n          for (\n            let ii = 0;\n            ii < returnRuntimeContainer.content.length;\n            ii += 1\n          ) {\n            const cmd = returnRuntimeContainer.content[\n              ii\n            ] as RuntimeControlCommand;\n            if (cmd) {\n              if (\n                evalStart == -1 &&\n                cmd.commandType === RuntimeControlCommand.CommandType.EvalStart\n              ) {\n                evalStart = ii;\n              } else if (\n                cmd.commandType === RuntimeControlCommand.CommandType.EvalEnd\n              ) {\n                evalEnd = ii;\n              }\n            }\n          }\n\n          for (let ii = evalStart + 1; ii < evalEnd; ii += 1) {\n            const obj = returnRuntimeContainer.content[ii];\n            obj.parent = null; // prevent error of being moved between owners\n            container.AddContent(returnRuntimeContainer.content[ii]);\n          }\n        }\n      }\n      // Supply the divert target for the tunnel onwards target, either variable or more commonly, the explicit name\n      // var returnDivertObj = returnRuntimeObj as Runtime.Divert;\n      let returnDivertObj = asOrNull(returnRuntimeObj, RuntimeDivert);\n      if (returnDivertObj != null && returnDivertObj.hasVariableTarget) {\n        let runtimeVarRef = new VariableReference(\n          returnDivertObj.variableDivertName\n        );\n        container.AddContent(runtimeVarRef);\n      } else {\n        this._overrideDivertTarget = new DivertTargetValue();\n        container.AddContent(this._overrideDivertTarget);\n      }\n    } else {\n      // No divert after tunnel onwards\n      container.AddContent(new Void());\n    }\n\n    container.AddContent(RuntimeControlCommand.EvalEnd());\n    container.AddContent(RuntimeControlCommand.PopTunnel());\n\n    return container;\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    if (this.divertAfter && this.divertAfter.targetContent) {\n      this._overrideDivertTarget!.targetPath =\n        this.divertAfter.targetContent.runtimePath;\n    }\n  }\n\n  public toString = (): string => {\n    return ` -> ${this._divertAfter}`;\n  };\n}\n","import { InkListItem, SerializedInkListItem } from \"./InkList\";\nimport { TryGetResult } from \"./TryGetResult\";\n\nexport class ListDefinition {\n  public _name: string;\n  public _items: Map<SerializedInkListItem, number> | null;\n  public _itemNameToValues: Map<string, number>;\n\n  constructor(name: string, items: Map<string, number> | null) {\n    this._name = name || \"\";\n    this._items = null;\n    this._itemNameToValues = items || new Map();\n  }\n  get name() {\n    return this._name;\n  }\n  get items() {\n    if (this._items == null) {\n      this._items = new Map();\n      for (let [key, value] of this._itemNameToValues) {\n        let item = new InkListItem(this.name, key);\n        this._items.set(item.serialized(), value);\n      }\n    }\n\n    return this._items;\n  }\n\n  public ValueForItem(item: InkListItem) {\n    if (!item.itemName) return 0;\n\n    let intVal = this._itemNameToValues.get(item.itemName);\n    if (typeof intVal !== \"undefined\") return intVal;\n    else return 0;\n  }\n  public ContainsItem(item: InkListItem) {\n    if (!item.itemName) return false;\n    if (item.originName != this.name) return false;\n\n    return this._itemNameToValues.has(item.itemName);\n  }\n  public ContainsItemWithName(itemName: string) {\n    return this._itemNameToValues.has(itemName);\n  }\n  public TryGetItemWithValue(\n    val: number,\n    /* out */ item: InkListItem\n  ): TryGetResult<InkListItem> {\n    for (let [key, value] of this._itemNameToValues) {\n      if (value == val) {\n        item = new InkListItem(this.name, key);\n        return { result: item, exists: true };\n      }\n    }\n\n    item = InkListItem.Null;\n    return { result: item, exists: false };\n  }\n\n  public TryGetValueForItem(\n    item: InkListItem,\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    /* out */ intVal: number\n  ): TryGetResult<number> {\n    if (!item.itemName) return { result: 0, exists: false };\n    let value = this._itemNameToValues.get(item.itemName);\n\n    if (!value) return { result: 0, exists: false };\n    return { result: value, exists: true };\n  }\n}\n","import { InkList as RuntimeInkList } from \"../../../../engine/InkList\";\nimport { InkListItem as RuntimeInkListItem } from \"../../../../engine/InkList\";\nimport { ListDefinition as RuntimeListDefinition } from \"../../../../engine/ListDefinition\";\nimport { ListElementDefinition } from \"./ListElementDefinition\";\nimport { ListValue } from \"../../../../engine/Value\";\nimport { ParsedObject } from \"../Object\";\nimport { Story } from \"../Story\";\nimport { SymbolType } from \"../SymbolType\";\nimport { VariableAssignment } from \"../Variable/VariableAssignment\";\nimport { Identifier } from \"../Identifier\";\n\nexport class ListDefinition extends ParsedObject {\n  public identifier: Identifier | null = null;\n  public variableAssignment: VariableAssignment | null = null;\n\n  get typeName() {\n    return \"ListDefinition\";\n  }\n\n  private _elementsByName: Map<string, ListElementDefinition> | null = null;\n\n  get runtimeListDefinition(): RuntimeListDefinition {\n    const allItems: Map<string, number> = new Map();\n    for (const e of this.itemDefinitions) {\n      if (!allItems.has(e.name!)) {\n        allItems.set(e.name!, e.seriesValue);\n      } else {\n        this.Error(\n          `List '${this.identifier}' contains duplicate items called '${e.name}'`\n        );\n      }\n    }\n\n    return new RuntimeListDefinition(this.identifier?.name || \"\", allItems);\n  }\n\n  public readonly ItemNamed = (\n    itemName: string\n  ): ListElementDefinition | null => {\n    if (this._elementsByName === null) {\n      this._elementsByName = new Map();\n\n      for (const el of this.itemDefinitions) {\n        this._elementsByName.set(el.name!, el);\n      }\n    }\n\n    const foundElement = this._elementsByName.get(itemName) || null;\n\n    return foundElement;\n  };\n\n  constructor(public itemDefinitions: ListElementDefinition[]) {\n    super();\n\n    let currentValue = 1;\n    for (const e of this.itemDefinitions) {\n      if (e.explicitValue !== null) {\n        currentValue = e.explicitValue;\n      }\n\n      e.seriesValue = currentValue;\n\n      currentValue += 1;\n    }\n\n    this.AddContent(itemDefinitions as any);\n  }\n\n  public readonly GenerateRuntimeObject = (): ListValue => {\n    const initialValues = new RuntimeInkList();\n    for (const itemDef of this.itemDefinitions) {\n      if (itemDef.inInitialList) {\n        const item = new RuntimeInkListItem(\n          this.identifier?.name || null,\n          itemDef.name || null\n        );\n        initialValues.Add(item, itemDef.seriesValue);\n      }\n    }\n\n    // Set origin name, so\n    initialValues.SetInitialOriginName(this.identifier?.name || \"\");\n\n    return new ListValue(initialValues);\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n    context.CheckForNamingCollisions(this, this.identifier!, SymbolType.List);\n  }\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { Expression } from \"../Expression/Expression\";\nimport { FlowBase } from \"../Flow/FlowBase\";\nimport { ClosestFlowBase } from \"../Flow/ClosestFlowBase\";\nimport { ListDefinition } from \"../List/ListDefinition\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { Story } from \"../Story\";\nimport { SymbolType } from \"../SymbolType\";\nimport { VariableAssignment as RuntimeVariableAssignment } from \"../../../../engine/VariableAssignment\";\nimport { VariableReference } from \"./VariableReference\";\nimport { Identifier } from \"../Identifier\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\n\nexport class VariableAssignment extends ParsedObject {\n  private _runtimeAssignment: RuntimeVariableAssignment | null = null;\n\n  get variableName(): string {\n    return this.variableIdentifier.name!;\n  }\n  public readonly variableIdentifier: Identifier;\n  public readonly expression: Expression | null = null;\n  public readonly listDefinition: ListDefinition | null = null;\n  public readonly isGlobalDeclaration: boolean;\n  public readonly isNewTemporaryDeclaration: boolean;\n\n  get typeName() {\n    if (this.isNewTemporaryDeclaration) {\n      return \"temp\";\n    } else if (this.isGlobalDeclaration) {\n      if (this.listDefinition !== null) {\n        return \"LIST\";\n      }\n      return \"VAR\";\n    }\n\n    return \"variable assignment\";\n  }\n\n  get isDeclaration(): boolean {\n    return this.isGlobalDeclaration || this.isNewTemporaryDeclaration;\n  }\n\n  constructor({\n    assignedExpression,\n    isGlobalDeclaration,\n    isTemporaryNewDeclaration,\n    listDef,\n    variableIdentifier,\n  }: {\n    readonly assignedExpression?: Expression;\n    readonly isGlobalDeclaration?: boolean;\n    readonly isTemporaryNewDeclaration?: boolean;\n    readonly listDef?: ListDefinition;\n    readonly variableIdentifier: Identifier;\n  }) {\n    super();\n\n    this.variableIdentifier = variableIdentifier;\n    this.isGlobalDeclaration = Boolean(isGlobalDeclaration);\n    this.isNewTemporaryDeclaration = Boolean(isTemporaryNewDeclaration);\n\n    // Defensive programming in case parsing of assignedExpression failed\n    if (listDef instanceof ListDefinition) {\n      this.listDefinition = this.AddContent(listDef) as ListDefinition;\n      this.listDefinition.variableAssignment = this;\n\n      // List definitions are always global\n      this.isGlobalDeclaration = true;\n    } else if (assignedExpression) {\n      this.expression = this.AddContent(assignedExpression) as Expression;\n    }\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject | null => {\n    let newDeclScope: FlowBase | null | undefined = null;\n    if (this.isGlobalDeclaration) {\n      newDeclScope = this.story;\n    } else if (this.isNewTemporaryDeclaration) {\n      newDeclScope = ClosestFlowBase(this);\n    }\n\n    if (newDeclScope) {\n      newDeclScope.AddNewVariableDeclaration(this);\n    }\n\n    // Global declarations don't generate actual procedural\n    // runtime objects, but instead add a global variable to the story itself.\n    // The story then initialises them all in one go at the start of the game.\n    if (this.isGlobalDeclaration) {\n      return null;\n    }\n\n    const container = new RuntimeContainer();\n\n    // The expression's runtimeObject is actually another nested container\n    if (this.expression) {\n      container.AddContent(this.expression.runtimeObject);\n    } else if (this.listDefinition) {\n      container.AddContent(this.listDefinition.runtimeObject);\n    }\n\n    this._runtimeAssignment = new RuntimeVariableAssignment(\n      this.variableName,\n      this.isNewTemporaryDeclaration\n    );\n\n    container.AddContent(this._runtimeAssignment);\n\n    return container;\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    // List definitions are checked for conflicts separately\n    if (this.isDeclaration && this.listDefinition === null) {\n      context.CheckForNamingCollisions(\n        this,\n        this.variableIdentifier,\n        this.isGlobalDeclaration ? SymbolType.Var : SymbolType.Temp\n      );\n    }\n\n    // Initial VAR x = [intialValue] declaration, not re-assignment\n    if (this.isGlobalDeclaration) {\n      const variableReference = asOrNull(this.expression, VariableReference);\n      if (\n        variableReference &&\n        !variableReference.isConstantReference &&\n        !variableReference.isListItemReference\n      ) {\n        this.Error(\n          \"global variable assignments cannot refer to other variables, only literal values, constants and list items\"\n        );\n      }\n    }\n\n    if (!this.isNewTemporaryDeclaration) {\n      const resolvedVarAssignment = context.ResolveVariableWithName(\n        this.variableName,\n        this\n      );\n\n      if (!resolvedVarAssignment.found) {\n        if (this.variableName in this.story.constants) {\n          this.Error(\n            `Can't re-assign to a constant (do you need to use VAR when declaring '${this.variableName}'?)`,\n            this\n          );\n        } else {\n          this.Error(\n            `Variable could not be found to assign to: '${this.variableName}'`,\n            this\n          );\n        }\n      }\n\n      // A runtime assignment may not have been generated if it's the initial global declaration,\n      // since these are hoisted out and handled specially in Story.ExportRuntime.\n      if (this._runtimeAssignment) {\n        this._runtimeAssignment.isGlobal = resolvedVarAssignment.isGlobal;\n      }\n    }\n  }\n\n  public readonly toString = (): string =>\n    `${\n      this.isGlobalDeclaration\n        ? \"VAR\"\n        : this.isNewTemporaryDeclaration\n          ? \"~ temp\"\n          : \"\"\n    } ${this.variableName}`;\n}\n","import { AuthorWarning } from \"./AuthorWarning\";\nimport { Choice } from \"./Choice\";\nimport { Conditional } from \"./Conditional/Conditional\";\nimport { ConstantDeclaration } from \"./Declaration/ConstantDeclaration\";\nimport { Container as RuntimeContainer } from \"../../../engine/Container\";\nimport { Divert } from \"./Divert/Divert\";\nimport { Divert as RuntimeDivert } from \"../../../engine/Divert\";\nimport { DivertTarget } from \"./Divert/DivertTarget\";\nimport { FlowBase } from \"./Flow/FlowBase\";\nimport { Gather } from \"./Gather/Gather\";\nimport { GatherPointToResolve } from \"./Gather/GatherPointToResolve\";\nimport { IWeavePoint } from \"./IWeavePoint\";\nimport { ParsedObject } from \"./Object\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\nimport { Sequence } from \"./Sequence/Sequence\";\nimport { Story } from \"./Story\";\nimport { Text } from \"./Text\";\nimport { TunnelOnwards } from \"./TunnelOnwards\";\nimport { VariableAssignment } from \"./Variable/VariableAssignment\";\nimport { asOrNull } from \"../../../engine/TypeAssertion\";\n\ntype BadTerminationHandler = (terminatingObj: ParsedObject) => void;\n\n// Used by the FlowBase when constructing the weave flow from\n// a flat list of content objects.\nexport class Weave extends ParsedObject {\n  // Containers can be chained as multiple gather points\n  // get created as the same indentation level.\n  // rootContainer is always the first in the chain, while\n  // currentContainer is the latest.\n  get rootContainer(): RuntimeContainer {\n    if (!this._rootContainer) {\n      this._rootContainer = this.GenerateRuntimeObject();\n    }\n\n    return this._rootContainer;\n  }\n\n  // Keep track of previous weave point (Choice or Gather)\n  // at the current indentation level:\n  //  - to add ordinary content to be nested under it\n  //  - to add nested content under it when it's indented\n  //  - to remove it from the list of loose ends when\n  //     - it has indented content since it's no longer a loose end\n  //     - it's a gather and it has a choice added to it\n  public previousWeavePoint: IWeavePoint | null = null;\n  public addContentToPreviousWeavePoint: boolean = false;\n\n  // Used for determining whether the next Gather should auto-enter\n  public hasSeenChoiceInSection: boolean = false;\n\n  public currentContainer: RuntimeContainer | null = null;\n  public baseIndentIndex: number;\n\n  private _unnamedGatherCount: number = 0;\n  private _choiceCount: number = 0;\n  private _rootContainer: RuntimeContainer | null = null;\n  private _namedWeavePoints: Map<string, IWeavePoint> = new Map();\n  get namedWeavePoints() {\n    return this._namedWeavePoints;\n  }\n\n  // Loose ends are:\n  //  - Choices or Gathers that need to be joined up\n  //  - Explicit Divert to gather points (i.e. \"->\" without a target)\n  public looseEnds: IWeavePoint[] = [];\n\n  public gatherPointsToResolve: GatherPointToResolve[] = [];\n\n  get lastParsedSignificantObject(): ParsedObject | null {\n    if (this.content.length === 0) {\n      return null;\n    }\n\n    // Don't count extraneous newlines or VAR/CONST declarations,\n    // since they're \"empty\" statements outside of the main flow.\n    let lastObject: ParsedObject | null = null;\n    for (let ii = this.content.length - 1; ii >= 0; --ii) {\n      lastObject = this.content[ii];\n\n      let lastText = asOrNull(lastObject, Text);\n      if (lastText && lastText.text === \"\\n\") {\n        continue;\n      }\n\n      if (this.IsGlobalDeclaration(lastObject)) {\n        continue;\n      }\n\n      break;\n    }\n\n    const lastWeave = asOrNull(lastObject, Weave);\n    if (lastWeave) {\n      lastObject = lastWeave.lastParsedSignificantObject;\n    }\n\n    return lastObject;\n  }\n\n  constructor(cont: ParsedObject[], indentIndex: number = -1) {\n    super();\n\n    if (indentIndex == -1) {\n      this.baseIndentIndex = this.DetermineBaseIndentationFromContent(cont);\n    } else {\n      this.baseIndentIndex = indentIndex;\n    }\n\n    this.AddContent(cont);\n\n    this.ConstructWeaveHierarchyFromIndentation();\n  }\n\n  get typeName(): string {\n    return \"Weave\";\n  }\n\n  public readonly ResolveWeavePointNaming = (): void => {\n    const namedWeavePoints = [\n      ...this.FindAll<IWeavePoint>(Gather)(\n        (w) => !(w.name === null || w.name === undefined)\n      ),\n      ...this.FindAll<IWeavePoint>(Choice)(\n        (w) => !(w.name === null || w.name === undefined)\n      ),\n    ];\n    this._namedWeavePoints = new Map();\n\n    for (const weavePoint of namedWeavePoints) {\n      // Check for weave point naming collisions\n      const existingWeavePoint: IWeavePoint | null | undefined =\n        this.namedWeavePoints.get(weavePoint.identifier?.name || \"\");\n\n      if (existingWeavePoint) {\n        const typeName =\n          existingWeavePoint instanceof Gather ? \"gather\" : \"choice\";\n        const existingObj: ParsedObject = existingWeavePoint;\n\n        this.Error(\n          `A ${typeName} with the same label name '${\n            weavePoint.name\n          }' already exists in this context on line ${\n            existingObj.debugMetadata\n              ? existingObj.debugMetadata.startLineNumber\n              : \"NO DEBUG METADATA AVAILABLE\"\n          }`,\n          weavePoint as ParsedObject\n        );\n      }\n      if (weavePoint.identifier?.name) {\n        this.namedWeavePoints.set(weavePoint.identifier?.name, weavePoint);\n      }\n    }\n  };\n\n  public readonly ConstructWeaveHierarchyFromIndentation = (): void => {\n    // Find nested indentation and convert to a proper object hierarchy\n    // (i.e. indented content is replaced with a Weave object that contains\n    // that nested content)\n    let contentIdx = 0;\n    while (contentIdx < this.content.length) {\n      const obj: ParsedObject = this.content[contentIdx];\n\n      // Choice or Gather\n      if (obj instanceof Choice || obj instanceof Gather) {\n        const weavePoint: IWeavePoint = obj;\n        const weaveIndentIdx = weavePoint.indentationDepth - 1;\n\n        // Inner level indentation - recurse\n        if (weaveIndentIdx > this.baseIndentIndex) {\n          // Step through content until indent jumps out again\n          let innerWeaveStartIdx = contentIdx;\n          while (contentIdx < this.content.length) {\n            const innerWeaveObj =\n              asOrNull(this.content[contentIdx], Choice) ||\n              asOrNull(this.content[contentIdx], Gather);\n            if (innerWeaveObj !== null) {\n              const innerIndentIdx = innerWeaveObj.indentationDepth - 1;\n              if (innerIndentIdx <= this.baseIndentIndex) {\n                break;\n              }\n            }\n\n            contentIdx += 1;\n          }\n\n          const weaveContentCount = contentIdx - innerWeaveStartIdx;\n          const weaveContent = this.content.slice(\n            innerWeaveStartIdx,\n            innerWeaveStartIdx + weaveContentCount\n          );\n\n          this.content.splice(innerWeaveStartIdx, weaveContentCount);\n\n          const weave = new Weave(weaveContent, weaveIndentIdx);\n          this.InsertContent(innerWeaveStartIdx, weave);\n\n          // Continue iteration from this point\n          contentIdx = innerWeaveStartIdx;\n        }\n      }\n\n      contentIdx += 1;\n    }\n  };\n\n  // When the indentation wasn't told to us at construction time using\n  // a choice point with a known indentation level, we may be told to\n  // determine the indentation level by incrementing from our closest ancestor.\n  public readonly DetermineBaseIndentationFromContent = (\n    contentList: ParsedObject[]\n  ): number => {\n    for (const obj of contentList) {\n      if (obj instanceof Choice || obj instanceof Gather) {\n        return obj.indentationDepth - 1;\n      }\n    }\n\n    // No weave points, so it doesn't matter\n    return 0;\n  };\n\n  public readonly GenerateRuntimeObject = (): RuntimeContainer => {\n    this._rootContainer = new RuntimeContainer();\n    this.currentContainer = this._rootContainer;\n    this.looseEnds = [];\n    this.gatherPointsToResolve = [];\n\n    // Iterate through content for the block at this level of indentation\n    //  - Normal content is nested under Choices and Gathers\n    //  - Blocks that are further indented cause recursion\n    //  - Keep track of loose ends so that they can be diverted to Gathers\n    for (const obj of this.content) {\n      // Choice or Gather\n      if (obj instanceof Choice || obj instanceof Gather) {\n        this.AddRuntimeForWeavePoint(obj as IWeavePoint);\n      } else {\n        // Non-weave point\n        if (obj instanceof Weave) {\n          // Nested weave\n          const weave = obj;\n          this.AddRuntimeForNestedWeave(weave);\n          this.gatherPointsToResolve.splice(\n            0,\n            0,\n            ...weave.gatherPointsToResolve\n          );\n        } else {\n          // Other object\n          // May be complex object that contains statements - e.g. a multi-line conditional\n          this.AddGeneralRuntimeContent(obj.runtimeObject);\n        }\n      }\n    }\n\n    // Pass any loose ends up the hierarhcy\n    this.PassLooseEndsToAncestors();\n\n    return this._rootContainer;\n  };\n\n  // Found gather point:\n  //  - gather any loose ends\n  //  - set the gather as the main container to dump new content in\n  public readonly AddRuntimeForGather = (gather: Gather): void => {\n    // Determine whether this Gather should be auto-entered:\n    //  - It is auto-entered if there were no choices in the last section\n    //  - A section is \"since the previous gather\" - so reset now\n    const autoEnter = !this.hasSeenChoiceInSection;\n    this.hasSeenChoiceInSection = false;\n\n    const gatherContainer = gather.runtimeContainer;\n\n    if (!gather.name) {\n      // Use disallowed character so it's impossible to have a name collision\n      gatherContainer.name = `g-${this._unnamedGatherCount}`;\n      this._unnamedGatherCount += 1;\n    }\n\n    if (autoEnter) {\n      if (!this.currentContainer) {\n        throw new Error();\n      }\n\n      // Auto-enter: include in main content\n      this.currentContainer.AddContent(gatherContainer);\n    } else {\n      // Don't auto-enter:\n      // Add this gather to the main content, but only accessible\n      // by name so that it isn't stepped into automatically, but only via\n      // a divert from a loose end.\n      this.rootContainer.AddToNamedContentOnly(gatherContainer);\n    }\n\n    // Consume loose ends: divert them to this gather\n    for (const looseEndWeavePoint of this.looseEnds) {\n      const looseEnd = looseEndWeavePoint as ParsedObject;\n\n      // Skip gather loose ends that are at the same level\n      // since they'll be handled by the auto-enter code below\n      // that only jumps into the gather if (current runtime choices == 0)\n      if (looseEnd instanceof Gather) {\n        const prevGather = looseEnd;\n        if (prevGather.indentationDepth == gather.indentationDepth) {\n          continue;\n        }\n      }\n\n      let divert: RuntimeDivert | null = null;\n      if (looseEnd instanceof Divert) {\n        divert = looseEnd.runtimeObject as RuntimeDivert;\n      } else {\n        divert = new RuntimeDivert();\n        const looseWeavePoint = looseEnd as IWeavePoint;\n        if (!looseWeavePoint.runtimeContainer) {\n          throw new Error();\n        }\n\n        looseWeavePoint.runtimeContainer.AddContent(divert);\n      }\n\n      // Pass back knowledge of this loose end being diverted\n      // to the FlowBase so that it can maintain a list of them,\n      // and resolve the divert references later\n      this.gatherPointsToResolve.push(\n        new GatherPointToResolve(divert, gatherContainer)\n      );\n    }\n\n    this.looseEnds = [];\n\n    // Replace the current container itself\n    this.currentContainer = gatherContainer;\n  };\n\n  public readonly AddRuntimeForWeavePoint = (weavePoint: IWeavePoint): void => {\n    // Current level Gather\n    if (weavePoint instanceof Gather) {\n      this.AddRuntimeForGather(weavePoint);\n    }\n\n    // Current level choice\n    else if (weavePoint instanceof Choice) {\n      if (!this.currentContainer) {\n        throw new Error();\n      }\n\n      // Gathers that contain choices are no longer loose ends\n      // (same as when weave points get nested content)\n      if (this.previousWeavePoint instanceof Gather) {\n        this.looseEnds.splice(\n          this.looseEnds.indexOf(this.previousWeavePoint),\n          1\n        );\n      }\n\n      // Add choice point content\n      const choice = weavePoint; //, Choice);\n\n      this.currentContainer.AddContent(choice.runtimeObject);\n      if (!choice.innerContentContainer) {\n        throw new Error();\n      } //guaranteed not to happen\n\n      // Add choice's inner content to self\n      choice.innerContentContainer.name = `c-${this._choiceCount}`;\n      this.currentContainer.AddToNamedContentOnly(choice.innerContentContainer);\n      this._choiceCount += 1;\n\n      this.hasSeenChoiceInSection = true;\n    }\n\n    // Keep track of loose ends\n    this.addContentToPreviousWeavePoint = false; // default\n    if (this.WeavePointHasLooseEnd(weavePoint)) {\n      this.looseEnds.push(weavePoint);\n\n      const looseChoice = asOrNull(weavePoint, Choice);\n      if (looseChoice) {\n        this.addContentToPreviousWeavePoint = true;\n      }\n    }\n\n    this.previousWeavePoint = weavePoint;\n  };\n\n  // Add nested block at a greater indentation level\n  public readonly AddRuntimeForNestedWeave = (nestedResult: Weave): void => {\n    // Add this inner block to current container\n    // (i.e. within the main container, or within the last defined Choice/Gather)\n    this.AddGeneralRuntimeContent(nestedResult.rootContainer);\n\n    // Now there's a deeper indentation level, the previous weave point doesn't\n    // count as a loose end (since it will have content to go to)\n    if (this.previousWeavePoint !== null) {\n      this.looseEnds.splice(this.looseEnds.indexOf(this.previousWeavePoint), 1);\n\n      this.addContentToPreviousWeavePoint = false;\n    }\n  };\n\n  // Normal content gets added into the latest Choice or Gather by default,\n  // unless there hasn't been one yet.\n  public readonly AddGeneralRuntimeContent = (content: RuntimeObject): void => {\n    // Content is allowed to evaluate runtimeObject to null\n    // (e.g. AuthorWarning, which doesn't make it into the runtime)\n    if (content === null) {\n      return;\n    }\n\n    if (this.addContentToPreviousWeavePoint) {\n      if (\n        !this.previousWeavePoint ||\n        !this.previousWeavePoint.runtimeContainer\n      ) {\n        throw new Error();\n      }\n\n      this.previousWeavePoint.runtimeContainer.AddContent(content);\n    } else {\n      if (!this.currentContainer) {\n        throw new Error();\n      }\n\n      this.currentContainer.AddContent(content);\n    }\n  };\n\n  public readonly PassLooseEndsToAncestors = () => {\n    if (this.looseEnds.length === 0) {\n      return;\n    }\n\n    // Search for Weave ancestor to pass loose ends to for gathering.\n    // There are two types depending on whether the current weave\n    // is separated by a conditional or sequence.\n    //  - An \"inner\" weave is one that is directly connected to the current\n    //    weave - i.e. you don't have to pass through a conditional or\n    //    sequence to get to it. We're allowed to pass all loose ends to\n    //    one of these.\n    //  - An \"outer\" weave is one that is outside of a conditional/sequence\n    //    that the current weave is nested within. We're only allowed to\n    //    pass gathers (i.e. 'normal flow') loose ends up there, not normal\n    //    choices. The rule is that choices have to be diverted explicitly\n    //    by the author since it's ambiguous where flow should go otherwise.\n    //\n    // e.g.:\n    //\n    //   - top                       <- e.g. outer weave\n    //   {true:\n    //       * choice                <- e.g. inner weave\n    //         * * choice 2\n    //             more content      <- e.g. current weave\n    //       * choice 2\n    //   }\n    //   - more of outer weave\n    //\n    let closestInnerWeaveAncestor: Weave | null = null;\n    let closestOuterWeaveAncestor: Weave | null = null;\n\n    // Find inner and outer ancestor weaves as defined above.\n    let nested = false;\n    for (\n      let ancestor = this.parent;\n      ancestor !== null;\n      ancestor = ancestor.parent\n    ) {\n      // Found ancestor?\n      const weaveAncestor = asOrNull(ancestor, Weave);\n      if (weaveAncestor) {\n        if (!nested && closestInnerWeaveAncestor === null) {\n          closestInnerWeaveAncestor = weaveAncestor;\n        }\n\n        if (nested && closestOuterWeaveAncestor === null) {\n          closestOuterWeaveAncestor = weaveAncestor;\n        }\n      }\n\n      // Weaves nested within Sequences or Conditionals are\n      // \"sealed\" - any loose ends require explicit diverts.\n      if (ancestor instanceof Sequence || ancestor instanceof Conditional) {\n        nested = true;\n      }\n    }\n\n    // No weave to pass loose ends to at all?\n    if (\n      closestInnerWeaveAncestor === null &&\n      closestOuterWeaveAncestor === null\n    ) {\n      return;\n    }\n\n    // Follow loose end passing logic as defined above\n    for (let ii = this.looseEnds.length - 1; ii >= 0; ii -= 1) {\n      const looseEnd = this.looseEnds[ii];\n      let received = false;\n\n      if (nested) {\n        // This weave is nested within a conditional or sequence:\n        //  - choices can only be passed up to direct ancestor (\"inner\") weaves\n        //  - gathers can be passed up to either, but favour the closer (inner) weave\n        //    if there is one\n        if (looseEnd instanceof Choice && closestInnerWeaveAncestor !== null) {\n          closestInnerWeaveAncestor.ReceiveLooseEnd(looseEnd);\n          received = true;\n        } else if (!(looseEnd instanceof Choice)) {\n          const receivingWeave =\n            closestInnerWeaveAncestor || closestOuterWeaveAncestor;\n          if (receivingWeave !== null) {\n            receivingWeave.ReceiveLooseEnd(looseEnd);\n            received = true;\n          }\n        }\n      } else {\n        // No nesting, all loose ends can be safely passed up\n        if (closestInnerWeaveAncestor?.hasOwnProperty(\"ReceiveLooseEnd\")) {\n          closestInnerWeaveAncestor!.ReceiveLooseEnd(looseEnd);\n        }\n        received = true;\n      }\n\n      if (received) {\n        this.looseEnds.splice(ii, 1);\n      }\n    }\n  };\n\n  public readonly ReceiveLooseEnd = (childWeaveLooseEnd: IWeavePoint): void => {\n    this.looseEnds.push(childWeaveLooseEnd);\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    // Check that choices nested within conditionals and sequences are terminated\n    if (this.looseEnds !== null && this.looseEnds.length > 0) {\n      let isNestedWeave = false;\n      for (\n        let ancestor = this.parent;\n        ancestor !== null;\n        ancestor = ancestor.parent\n      ) {\n        if (ancestor instanceof Sequence || ancestor instanceof Conditional) {\n          isNestedWeave = true;\n          break;\n        }\n      }\n\n      if (isNestedWeave) {\n        this.ValidateTermination(this.BadNestedTerminationHandler);\n      }\n    }\n\n    for (const gatherPoint of this.gatherPointsToResolve) {\n      gatherPoint.divert.targetPath = gatherPoint.targetRuntimeObj.path;\n    }\n\n    this.CheckForWeavePointNamingCollisions();\n  }\n\n  public readonly WeavePointNamed = (name: string): IWeavePoint | null => {\n    if (!this.namedWeavePoints) {\n      return null;\n    }\n\n    let weavePointResult: IWeavePoint | null | undefined =\n      this.namedWeavePoints.get(name);\n    if (weavePointResult) {\n      return weavePointResult;\n    }\n\n    return null;\n  };\n\n  // Global VARs and CONSTs are treated as \"outside of the flow\"\n  // when iterating over content that follows loose ends\n  public readonly IsGlobalDeclaration = (obj: ParsedObject) => {\n    const varAss = asOrNull(obj, VariableAssignment);\n    if (varAss && varAss.isGlobalDeclaration && varAss.isDeclaration) {\n      return true;\n    }\n\n    const constDecl = asOrNull(obj, ConstantDeclaration);\n    if (constDecl) {\n      return true;\n    }\n\n    return false;\n  };\n\n  // While analysing final loose ends, we look to see whether there\n  // are any diverts etc which choices etc divert from\n  public readonly ContentThatFollowsWeavePoint = (\n    weavePoint: IWeavePoint\n  ): ParsedObject[] => {\n    const returned = [];\n    const obj = weavePoint as ParsedObject;\n\n    // Inner content first (e.g. for a choice)\n    if (obj.content !== null) {\n      for (const contentObj of obj.content) {\n        // Global VARs and CONSTs are treated as \"outside of the flow\"\n        if (this.IsGlobalDeclaration(contentObj)) {\n          continue;\n        }\n\n        returned.push(contentObj);\n      }\n    }\n\n    const parentWeave = asOrNull(obj.parent, Weave);\n    if (parentWeave === null) {\n      throw new Error(\"Expected weave point parent to be weave?\");\n    }\n\n    const weavePointIdx = parentWeave.content.indexOf(obj);\n    for (let ii = weavePointIdx + 1; ii < parentWeave.content.length; ii += 1) {\n      const laterObj = parentWeave.content[ii];\n\n      // Global VARs and CONSTs are treated as \"outside of the flow\"\n      if (this.IsGlobalDeclaration(laterObj)) {\n        continue;\n      }\n\n      // End of the current flow\n      // if (laterObj instanceof IWeavePoint) // cannot test on interface in ts\n      if (laterObj instanceof Choice || laterObj instanceof Gather) {\n        break;\n      }\n\n      // Other weaves will be have their own loose ends\n      if (laterObj instanceof Weave) {\n        break;\n      }\n\n      returned.push(laterObj);\n    }\n\n    return returned;\n  };\n\n  public readonly ValidateTermination = (\n    badTerminationHandler: BadTerminationHandler\n  ): void => {\n    // Don't worry if the last object in the flow is a \"TODO\",\n    // even if there are other loose ends in other places\n    if (this.lastParsedSignificantObject instanceof AuthorWarning) {\n      return;\n    }\n\n    // By now, any sub-weaves will have passed loose ends up to the root weave (this).\n    // So there are 2 possible situations:\n    //  - There are loose ends from somewhere in the flow.\n    //    These aren't necessarily \"real\" loose ends - they're weave points\n    //    that don't connect to any lower weave points, so we just\n    //    have to check that they terminate properly.\n    //  - This weave is just a list of content with no actual weave points,\n    //    so we just need to check that the list of content terminates.\n\n    const hasLooseEnds: boolean =\n      this.looseEnds !== null && this.looseEnds.length > 0;\n\n    if (hasLooseEnds) {\n      for (const looseEnd of this.looseEnds) {\n        const looseEndFlow = this.ContentThatFollowsWeavePoint(looseEnd);\n        this.ValidateFlowOfObjectsTerminates(\n          looseEndFlow,\n          looseEnd as ParsedObject,\n          badTerminationHandler\n        );\n      }\n    } else {\n      // No loose ends... is there any inner weaving at all?\n      // If not, make sure the single content stream is terminated correctly\n      //\n      // If there's any actual weaving, assume that content is\n      // terminated correctly since we would've had a loose end otherwise\n      for (const obj of this.content) {\n        if (obj instanceof Choice || obj instanceof Divert) {\n          return;\n        }\n      }\n\n      // Straight linear flow? Check it terminates\n      this.ValidateFlowOfObjectsTerminates(\n        this.content,\n        this,\n        badTerminationHandler\n      );\n    }\n  };\n\n  readonly BadNestedTerminationHandler: BadTerminationHandler = (\n    terminatingObj\n  ) => {\n    let conditional: Conditional | null = null;\n    for (\n      let ancestor = terminatingObj.parent;\n      ancestor !== null;\n      ancestor = ancestor.parent\n    ) {\n      if (ancestor instanceof Sequence || ancestor instanceof Conditional) {\n        conditional = asOrNull(ancestor, Conditional);\n        break;\n      }\n    }\n\n    let errorMsg =\n      \"Choices nested in conditionals or sequences need to explicitly divert afterwards.\";\n\n    // Tutorialise proper choice syntax if this looks like a single choice within a condition, e.g.\n    // { condition:\n    //      * choice\n    // }\n    if (conditional !== null) {\n      let numChoices = conditional.FindAll<Choice>(Choice)().length;\n      if (numChoices === 1) {\n        errorMsg = `Choices with conditions should be written: '* {condition} choice'. Otherwise, ${errorMsg.toLowerCase()}`;\n      }\n    }\n\n    this.Error(errorMsg, terminatingObj);\n  };\n\n  public readonly ValidateFlowOfObjectsTerminates = (\n    objFlow: ParsedObject[],\n    defaultObj: ParsedObject,\n    badTerminationHandler: BadTerminationHandler\n  ) => {\n    let terminated = false;\n    let terminatingObj: ParsedObject = defaultObj;\n    for (const flowObj of objFlow) {\n      const divert = flowObj.Find(Divert)(\n        (d) =>\n          !d.isThread &&\n          !d.isTunnel &&\n          !d.isFunctionCall &&\n          !(d.parent instanceof DivertTarget)\n      );\n\n      if (divert !== null) {\n        terminated = true;\n      }\n\n      if (flowObj.Find(TunnelOnwards)() != null) {\n        terminated = true;\n        break;\n      }\n\n      terminatingObj = flowObj;\n    }\n\n    if (!terminated) {\n      // Author has left a note to self here - clearly we don't need\n      // to leave them with another warning since they know what they're doing.\n      if (terminatingObj instanceof AuthorWarning) {\n        return;\n      }\n\n      badTerminationHandler(terminatingObj);\n    }\n  };\n\n  public readonly WeavePointHasLooseEnd = (\n    weavePoint: IWeavePoint\n  ): boolean => {\n    // No content, must be a loose end.\n    if (weavePoint.content === null) {\n      return true;\n    }\n\n    // If a weave point is diverted from, it doesn't have a loose end.\n    // Detect a divert object within a weavePoint's main content\n    // Work backwards since we're really interested in the end,\n    // although it doesn't actually make a difference!\n    // (content after a divert will simply be inaccessible)\n    for (let ii = weavePoint.content.length - 1; ii >= 0; --ii) {\n      let innerDivert = asOrNull(weavePoint.content[ii], Divert);\n      if (innerDivert) {\n        const willReturn =\n          innerDivert.isThread ||\n          innerDivert.isTunnel ||\n          innerDivert.isFunctionCall;\n        if (!willReturn) {\n          return false;\n        }\n      }\n    }\n\n    return true;\n  };\n\n  // Enforce rule that weave points must not have the same\n  // name as any stitches or knots upwards in the hierarchy\n  public readonly CheckForWeavePointNamingCollisions = (): void => {\n    if (!this.namedWeavePoints) {\n      return;\n    }\n\n    const ancestorFlows = [];\n    for (const obj of this.ancestry) {\n      const flow = asOrNull(obj, FlowBase);\n      if (flow) {\n        ancestorFlows.push(flow);\n      } else {\n        break;\n      }\n    }\n\n    for (const [weavePointName, weavePoint] of this.namedWeavePoints) {\n      for (const flow of ancestorFlows) {\n        // Shallow search\n        const otherContentWithName =\n          flow.ContentWithNameAtLevel(weavePointName);\n        if (otherContentWithName && otherContentWithName !== weavePoint) {\n          const errorMsg = `${weavePoint.GetType()} '${weavePointName}' has the same label name as a ${otherContentWithName.GetType()} (on ${\n            otherContentWithName.debugMetadata\n          })`;\n          this.Error(errorMsg, weavePoint);\n        }\n      }\n    }\n  };\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../../engine/ControlCommand\";\nimport { Divert as RuntimeDivert } from \"../../../../engine/Divert\";\nimport { Expression } from \"../Expression/Expression\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { NativeFunctionCall } from \"../../../../engine/NativeFunctionCall\";\nimport { StringValue } from \"../../../../engine/Value\";\nimport { Story } from \"../Story\";\nimport { Text } from \"../Text\";\nimport { Weave } from \"../Weave\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\n\nexport class ConditionalSingleBranch extends ParsedObject {\n  public _contentContainer: RuntimeContainer | null = null;\n  public _conditionalDivert: RuntimeDivert | null = null;\n  public _ownExpression: Expression | null = null;\n  public _innerWeave: Weave | null = null;\n  // bool condition, e.g.:\n  // { 5 == 4:\n  //   - the true branch\n  //   - the false branch\n  // }\n  public isTrueBranch: boolean = false;\n\n  // When each branch has its own expression like a switch statement,\n  // this is non-null. e.g.\n  // { x:\n  //    - 4: the value of x is four (ownExpression is the value 4)\n  //    - 3: the value of x is three\n  // }\n  get ownExpression() {\n    return this._ownExpression;\n  }\n\n  set ownExpression(value) {\n    this._ownExpression = value;\n    if (this._ownExpression) {\n      this.AddContent(this._ownExpression);\n    }\n  }\n\n  // In the above example, match equality of x with 4 for the first branch.\n  // This is as opposed to simply evaluating boolean equality for each branch,\n  // example when shouldMatchEquality is FALSE:\n  // {\n  //    3 > 2:  This will happen\n  //    2 > 3:  This won't happen\n  // }\n  public matchingEquality: boolean = false;\n\n  public isElse: boolean = false;\n  public isInline: boolean = false;\n\n  public returnDivert: RuntimeDivert | null = null;\n\n  constructor(content?: ParsedObject[] | null | undefined) {\n    super();\n\n    // Branches are allowed to be empty\n    if (content) {\n      this._innerWeave = new Weave(content);\n      this.AddContent(this._innerWeave);\n    }\n  }\n\n  get typeName(): string {\n    return \"ConditionalSingleBranch\";\n  }\n\n  // Runtime content can be summarised as follows:\n  //  - Evaluate an expression if necessary to branch on\n  //  - Branch to a named container if true\n  //       - Divert back to main flow\n  //         (owner Conditional is in control of this target point)\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    // Check for common mistake, of putting \"else:\" instead of \"- else:\"\n    if (this._innerWeave) {\n      for (const c of this._innerWeave.content) {\n        const text = asOrNull(c, Text);\n        if (text) {\n          // Don't need to trim at the start since the parser handles that already\n          if (text.text.startsWith(\"else:\")) {\n            this.Warning(\n              \"Saw the text 'else:' which is being treated as content. Did you mean '- else:'?\",\n              text\n            );\n          }\n        }\n      }\n    }\n\n    const container = new RuntimeContainer();\n\n    // Are we testing against a condition that's used for more than just this\n    // branch? If so, the first thing we need to do is replicate the value that's\n    // on the evaluation stack so that we don't fully consume it, in case other\n    // branches need to use it.\n    const duplicatesStackValue: boolean = this.matchingEquality && !this.isElse;\n\n    if (duplicatesStackValue) {\n      container.AddContent(RuntimeControlCommand.Duplicate());\n    }\n\n    this._conditionalDivert = new RuntimeDivert();\n\n    // else clause is unconditional catch-all, otherwise the divert is conditional\n    this._conditionalDivert.isConditional = !this.isElse;\n\n    // Need extra evaluation?\n    if (!this.isTrueBranch && !this.isElse) {\n      const needsEval: boolean = this.ownExpression !== null;\n      if (needsEval) {\n        container.AddContent(RuntimeControlCommand.EvalStart());\n      }\n\n      if (this.ownExpression) {\n        this.ownExpression.GenerateIntoContainer(container);\n      }\n\n      // Uses existing duplicated value\n      if (this.matchingEquality) {\n        container.AddContent(NativeFunctionCall.CallWithName(\"==\"));\n      }\n\n      if (needsEval) {\n        container.AddContent(RuntimeControlCommand.EvalEnd());\n      }\n    }\n\n    // Will pop from stack if conditional\n    container.AddContent(this._conditionalDivert);\n\n    this._contentContainer = this.GenerateRuntimeForContent();\n    this._contentContainer.name = \"b\";\n\n    // Multi-line conditionals get a newline at the start of each branch\n    // (as opposed to the start of the multi-line conditional since the condition\n    //  may evaluate to false.)\n    if (!this.isInline) {\n      this._contentContainer.InsertContent(new StringValue(\"\\n\"), 0);\n    }\n\n    if (duplicatesStackValue || (this.isElse && this.matchingEquality)) {\n      this._contentContainer.InsertContent(\n        RuntimeControlCommand.PopEvaluatedValue(),\n        0\n      );\n    }\n\n    container.AddToNamedContentOnly(this._contentContainer);\n\n    this.returnDivert = new RuntimeDivert();\n    this._contentContainer.AddContent(this.returnDivert);\n\n    return container;\n  };\n\n  public readonly GenerateRuntimeForContent = (): RuntimeContainer => {\n    // Empty branch - create empty container\n    if (this._innerWeave === null) {\n      return new RuntimeContainer();\n    }\n\n    return this._innerWeave.rootContainer;\n  };\n\n  public ResolveReferences(context: Story): void {\n    if (!this._conditionalDivert || !this._contentContainer) {\n      throw new Error();\n    }\n\n    this._conditionalDivert.targetPath = this._contentContainer.path;\n    super.ResolveReferences(context);\n  }\n}\n","export enum CustomFlags {\n  ParsingString = 0x1,\n  TagActive = 0x2,\n}\n","export class DebugMetadata {\n  public startLineNumber: number = 0;\n  public endLineNumber: number = 0;\n  public startCharacterNumber: number = 0;\n  public endCharacterNumber: number = 0;\n  public fileName: string | null = null;\n  public sourceName: string | null = null;\n\n  public Merge(dm: DebugMetadata) {\n    let newDebugMetadata = new DebugMetadata();\n\n    newDebugMetadata.fileName = this.fileName;\n    newDebugMetadata.sourceName = this.sourceName;\n\n    if (this.startLineNumber < dm.startLineNumber) {\n      newDebugMetadata.startLineNumber = this.startLineNumber;\n      newDebugMetadata.startCharacterNumber = this.startCharacterNumber;\n    } else if (this.startLineNumber > dm.startLineNumber) {\n      newDebugMetadata.startLineNumber = dm.startLineNumber;\n      newDebugMetadata.startCharacterNumber = dm.startCharacterNumber;\n    } else {\n      newDebugMetadata.startLineNumber = this.startLineNumber;\n      newDebugMetadata.startCharacterNumber = Math.min(\n        this.startCharacterNumber,\n        dm.startCharacterNumber\n      );\n    }\n\n    if (this.endLineNumber > dm.endLineNumber) {\n      newDebugMetadata.endLineNumber = this.endLineNumber;\n      newDebugMetadata.endCharacterNumber = this.endCharacterNumber;\n    } else if (this.endLineNumber < dm.endLineNumber) {\n      newDebugMetadata.endLineNumber = dm.endLineNumber;\n      newDebugMetadata.endCharacterNumber = dm.endCharacterNumber;\n    } else {\n      newDebugMetadata.endLineNumber = this.endLineNumber;\n      newDebugMetadata.endCharacterNumber = Math.max(\n        this.endCharacterNumber,\n        dm.endCharacterNumber\n      );\n    }\n\n    return newDebugMetadata;\n  }\n\n  public toString() {\n    if (this.fileName !== null) {\n      return `line ${this.startLineNumber} of ${this.fileName}\"`;\n    } else {\n      return \"line \" + this.startLineNumber;\n    }\n  }\n}\n","import { INamedContent } from \"../../../../engine/INamedContent\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { Identifier } from \"../Identifier\";\n\nexport class ExternalDeclaration extends ParsedObject implements INamedContent {\n  public get name(): string | null {\n    return this.identifier?.name || null;\n  }\n\n  constructor(\n    public readonly identifier: Identifier,\n    public readonly argumentNames: string[]\n  ) {\n    super();\n  }\n\n  get typeName(): string {\n    return \"EXTERNAL\";\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject | null => {\n    this.story.AddExternal(this);\n\n    // No runtime code exists for an external, only metadata\n    return null;\n  };\n\n  public toString(): string {\n    return `EXTERNAL ${this.identifier?.name}`;\n  }\n}\n","import { Argument } from \"./ParsedHierarchy/Argument\";\nimport { Identifier } from \"./ParsedHierarchy/Identifier\";\n\nexport class FlowDecl {\n  constructor(\n    public readonly name: Identifier,\n    public readonly args: Argument[],\n    public readonly isFunction: boolean\n  ) {}\n}\n","import { ParsedObject } from \"./Object\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\n\nexport class Wrap<T extends RuntimeObject> extends ParsedObject {\n  constructor(private _objToWrap: T) {\n    super();\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => this._objToWrap;\n}\n","import { Glue as RuntimeGlue } from \"../../../engine/Glue\";\nimport { Wrap } from \"./Wrap\";\n\nexport class Glue extends Wrap<RuntimeGlue> {\n  constructor(glue: RuntimeGlue) {\n    super(glue);\n  }\n\n  get typeName(): string {\n    return \"Glue\";\n  }\n}\n","import { InkObject } from \"./Object\";\n\nexport class Glue extends InkObject {\n  public toString() {\n    return \"Glue\";\n  }\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ContentList } from \"../ContentList\";\nimport { Expression } from \"./Expression\";\nimport { FlowBase } from \"../Flow/FlowBase\";\nimport { NativeFunctionCall } from \"../../../../engine/NativeFunctionCall\";\nimport { IntValue } from \"../../../../engine/Value\";\nimport { Story } from \"../Story\";\nimport { VariableAssignment as RuntimeVariableAssignment } from \"../../../../engine/VariableAssignment\";\nimport { VariableReference as RuntimeVariableReference } from \"../../../../engine/VariableReference\";\nimport { Weave } from \"../Weave\";\nimport { Identifier } from \"../Identifier\";\n\nexport class IncDecExpression extends Expression {\n  private _runtimeAssignment: RuntimeVariableAssignment | null = null;\n\n  public isInc: boolean;\n  public expression: Expression | null = null;\n\n  constructor(\n    public readonly varIdentifier: Identifier | null,\n    isIncOrExpression: boolean | Expression,\n    isInc?: boolean\n  ) {\n    super();\n\n    if (isIncOrExpression instanceof Expression) {\n      this.expression = isIncOrExpression;\n      this.AddContent(this.expression);\n      this.isInc = Boolean(isInc);\n    } else {\n      this.isInc = isIncOrExpression as boolean;\n    }\n  }\n\n  get typeName(): string {\n    return \"IncDecExpression\";\n  }\n\n  public readonly GenerateIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    // x = x + y\n    // ^^^ ^ ^ ^\n    //  4  1 3 2\n    // Reverse polish notation: (x 1 +) (assign to x)\n\n    // 1.\n    container.AddContent(\n      new RuntimeVariableReference(this.varIdentifier?.name || null)\n    );\n\n    // 2.\n    // - Expression used in the form ~ x += y\n    // - Simple version: ~ x++\n    if (this.expression) {\n      this.expression.GenerateIntoContainer(container);\n    } else {\n      container.AddContent(new IntValue(1));\n    }\n\n    // 3.\n    container.AddContent(\n      NativeFunctionCall.CallWithName(this.isInc ? \"+\" : \"-\")\n    );\n\n    // 4.\n    this._runtimeAssignment = new RuntimeVariableAssignment(\n      this.varIdentifier?.name || null,\n      false\n    );\n    container.AddContent(this._runtimeAssignment);\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    const varResolveResult = context.ResolveVariableWithName(\n      this.varIdentifier?.name || \"\",\n      this\n    );\n\n    if (!varResolveResult.found) {\n      this.Error(\n        `variable for ${this.incrementDecrementWord} could not be found: '${this.varIdentifier}' after searching: {this.descriptionOfScope}`\n      );\n    }\n\n    if (!this._runtimeAssignment) {\n      throw new Error();\n    }\n\n    this._runtimeAssignment.isGlobal = varResolveResult.isGlobal;\n\n    if (\n      !(this.parent instanceof Weave) &&\n      !(this.parent instanceof FlowBase) &&\n      !(this.parent instanceof ContentList)\n    ) {\n      this.Error(`Can't use ${this.incrementDecrementWord} as sub-expression`);\n    }\n  }\n\n  get incrementDecrementWord(): \"increment\" | \"decrement\" {\n    if (this.isInc) {\n      return \"increment\";\n    }\n\n    return \"decrement\";\n  }\n\n  public readonly toString = (): string => {\n    if (this.expression) {\n      return `${this.varIdentifier?.name}${this.isInc ? \" += \" : \" -= \"}${\n        this.expression\n      }`;\n    }\n\n    return `${this.varIdentifier?.name}` + (this.isInc ? \"++\" : \"--\");\n  };\n}\n","import { ParsedObject } from \"./Object\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\nimport { Story } from \"./Story\";\n\nexport class IncludedFile extends ParsedObject {\n  constructor(public readonly includedStory: Story | null) {\n    super();\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject | null => {\n    // Left to the main story to process\n    return null;\n  };\n\n  get typeName(): string {\n    return \"IncludedFile\";\n  }\n}\n","export class InfixOperator {\n  constructor(\n    public readonly type: string,\n    public readonly precedence: number,\n    public readonly requireWhitespace: boolean\n  ) {}\n\n  public readonly toString = (): string => this.type;\n}\n","import { Argument } from \"./Argument\";\nimport { FlowBase } from \"./Flow/FlowBase\";\nimport { FlowLevel } from \"./Flow/FlowLevel\";\nimport { Identifier } from \"./Identifier\";\nimport { ParsedObject } from \"./Object\";\nimport { Story } from \"./Story\";\n\nexport class Knot extends FlowBase {\n  get flowLevel(): FlowLevel {\n    return FlowLevel.Knot;\n  }\n\n  constructor(\n    name: Identifier,\n    topLevelObjects: ParsedObject[],\n    args: Argument[],\n    isFunction: boolean\n  ) {\n    super(name, topLevelObjects, args, isFunction);\n  }\n\n  get typeName(): string {\n    return this.isFunction ? \"Function\" : \"Knot\";\n  }\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n\n    let parentStory = this.story;\n\n    // Enforce rule that stitches must not have the same\n    // name as any knots that exist in the story\n    for (const stitchName in this.subFlowsByName) {\n      const knotWithStitchName = parentStory.ContentWithNameAtLevel(\n        stitchName,\n        FlowLevel.Knot,\n        false\n      );\n\n      if (knotWithStitchName) {\n        const stitch = this.subFlowsByName.get(stitchName);\n        const errorMsg = `Stitch '${\n          stitch ? stitch.name : \"NO STITCH FOUND\"\n        }' has the same name as a knot (on ${\n          knotWithStitchName.debugMetadata\n        })`;\n        this.Error(errorMsg, stitch);\n      }\n    }\n  }\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { Expression } from \"../Expression/Expression\";\nimport { InkList as RuntimeInkList } from \"../../../../engine/InkList\";\nimport { InkListItem as RuntimeInkListItem } from \"../../../../engine/InkList\";\nimport { ListElementDefinition } from \"./ListElementDefinition\";\nimport { ListValue } from \"../../../../engine/Value\";\nimport { Identifier } from \"../Identifier\";\n\nexport class List extends Expression {\n  constructor(public readonly itemIdentifierList: Identifier[]) {\n    super();\n  }\n\n  get typeName(): string {\n    return \"List\";\n  }\n\n  public readonly GenerateIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    const runtimeRawList = new RuntimeInkList();\n\n    if (this.itemIdentifierList != null) {\n      for (const itemIdentifier of this.itemIdentifierList) {\n        const nameParts = itemIdentifier?.name?.split(\".\") || [];\n\n        let listName: string | null = null;\n        let listItemName: string = \"\";\n        if (nameParts.length > 1) {\n          listName = nameParts[0];\n          listItemName = nameParts[1];\n        } else {\n          listItemName = nameParts[0];\n        }\n\n        const listItem = this.story.ResolveListItem(\n          listName,\n          listItemName,\n          this\n        ) as ListElementDefinition;\n\n        if (listItem === null) {\n          if (listName === null) {\n            this.Error(\n              `Could not find list definition that contains item '${itemIdentifier}'`\n            );\n          } else {\n            this.Error(`Could not find list item ${itemIdentifier}`);\n          }\n        } else {\n          if (listItem.parent == null) {\n            this.Error(\n              `Could not find list definition for item ${itemIdentifier}`\n            );\n            return;\n          }\n          if (!listName) {\n            listName = listItem.parent.identifier?.name || null;\n          }\n\n          const item = new RuntimeInkListItem(listName, listItem.name || null);\n\n          if (runtimeRawList.has(item.serialized())) {\n            this.Warning(`Duplicate of item '${itemIdentifier}' in list.`);\n          } else {\n            runtimeRawList.Add(item, listItem.seriesValue);\n          }\n        }\n      }\n    }\n\n    container.AddContent(new ListValue(runtimeRawList));\n  };\n}\n","import { ListDefinition } from \"./ListDefinition\";\nimport { ParsedObject } from \"../Object\";\nimport { InkObject as RuntimeObject } from \"../../../../engine/Object\";\nimport { Story } from \"../Story\";\nimport { SymbolType } from \"../SymbolType\";\nimport { Identifier } from \"../Identifier\";\n\nexport class ListElementDefinition extends ParsedObject {\n  public seriesValue: number = 0;\n\n  public parent: ListDefinition | null = null;\n\n  get fullName(): string {\n    const parentList = this.parent;\n    if (parentList === null) {\n      throw new Error(\"Can't get full name without a parent list.\");\n    }\n\n    return `${parentList.identifier?.name}.${this.name}`;\n  }\n\n  get typeName(): string {\n    return \"ListElement\";\n  }\n\n  get name(): string | null {\n    return this.indentifier?.name || null;\n  }\n\n  constructor(\n    public readonly indentifier: Identifier,\n    public readonly inInitialList: boolean,\n    public readonly explicitValue: number | null = null\n  ) {\n    super();\n    this.parent = this.parent as ListDefinition;\n  }\n\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    throw new Error(\"Not implemented.\");\n  };\n\n  public ResolveReferences(context: Story): void {\n    super.ResolveReferences(context);\n    context.CheckForNamingCollisions(\n      this,\n      this.indentifier,\n      SymbolType.ListItem\n    );\n  }\n\n  public readonly toString = (): string => this.fullName;\n}\n","export enum StatementLevel {\n  InnerBlock,\n  Stitch,\n  Knot,\n  Top,\n}\n","import { Argument } from \"./Argument\";\nimport { FlowBase } from \"./Flow/FlowBase\";\nimport { FlowLevel } from \"./Flow/FlowLevel\";\nimport { Identifier } from \"./Identifier\";\nimport { ParsedObject } from \"./Object\";\n\nexport class Stitch extends FlowBase {\n  get flowLevel(): FlowLevel {\n    return FlowLevel.Stitch;\n  }\n\n  constructor(\n    name: Identifier,\n    topLevelObjects: ParsedObject[],\n    args: Argument[],\n    isFunction: boolean\n  ) {\n    super(name, topLevelObjects, args, isFunction);\n  }\n\n  get typeName(): string {\n    return \"Stitch\";\n  }\n\n  // Fixes TS issue with not being able to access the prototype via `super` in functions\n  // attached to the class as properties.\n  private baseToString = this.toString;\n\n  public toString = (): string => {\n    return `${\n      this.parent !== null ? this.parent + \" > \" : \"\"\n    }${this.baseToString()}`;\n  };\n}\n","import { InkObject } from \"./Object\";\n\n// New version of tags is dynamic - it constructs the tags\n// at runtime based on BeginTag and EndTag control commands.\n// Plain text that's in the output stream is turned into tags\n// when you do story.currentTags.\n// The only place this is used is when flattening tags down\n// to string in advance, during dynamic string generation if\n// there's a tag embedded in it. See how ControlCommand.EndString\n// is implemented in Story.cs for more details + comment\nexport class Tag extends InkObject {\n  public readonly text: string;\n\n  constructor(tagText: string) {\n    super();\n    this.text = tagText.toString() || \"\";\n  }\n\n  public toString(): string {\n    return \"# \" + this.text;\n  }\n}\n","import { Path } from \"./Path\";\nimport { CallStack } from \"./CallStack\";\nimport { throwNullException } from \"./NullException\";\nimport { InkObject } from \"./Object\";\n\nexport class Choice extends InkObject {\n  public text: string = \"\";\n  public index: number = 0;\n  public threadAtGeneration: CallStack.Thread | null = null;\n  public sourcePath: string = \"\";\n  public targetPath: Path | null = null;\n  public isInvisibleDefault: boolean = false;\n  public tags: string[] | null = null;\n  public originalThreadIndex: number = 0;\n\n  get pathStringOnChoice(): string {\n    if (this.targetPath === null)\n      return throwNullException(\"Choice.targetPath\");\n    return this.targetPath.toString();\n  }\n  set pathStringOnChoice(value: string) {\n    this.targetPath = new Path(value);\n  }\n\n  public Clone() {\n    let copy = new Choice();\n    copy.text = this.text;\n    copy.sourcePath = this.sourcePath;\n    copy.index = this.index;\n    copy.targetPath = this.targetPath;\n    copy.originalThreadIndex = this.originalThreadIndex;\n    copy.isInvisibleDefault = this.isInvisibleDefault;\n    if (this.threadAtGeneration !== null)\n      copy.threadAtGeneration = this.threadAtGeneration.Copy();\n\n    return copy;\n  }\n}\n","import { InkListItem } from \"./InkList\";\nimport { ListValue } from \"./Value\";\nimport { ListDefinition } from \"./ListDefinition\";\nimport { TryGetResult } from \"./TryGetResult\";\nimport { throwNullException } from \"./NullException\";\n\nexport class ListDefinitionsOrigin {\n  protected _lists: Map<string, ListDefinition>;\n  protected _allUnambiguousListValueCache: Map<string, ListValue>;\n\n  constructor(lists: ListDefinition[]) {\n    this._lists = new Map();\n    this._allUnambiguousListValueCache = new Map();\n\n    for (let list of lists) {\n      this._lists.set(list.name, list);\n\n      for (let [key, val] of list.items) {\n        let item = InkListItem.fromSerializedKey(key);\n        let listValue = new ListValue(item, val);\n\n        if (!item.itemName) {\n          throw new Error(\"item.itemName is null or undefined.\");\n        }\n\n        this._allUnambiguousListValueCache.set(item.itemName, listValue);\n        this._allUnambiguousListValueCache.set(item.fullName, listValue);\n      }\n    }\n  }\n  get lists(): ListDefinition[] {\n    let listOfLists: ListDefinition[] = [];\n\n    for (let [, value] of this._lists) {\n      listOfLists.push(value);\n    }\n\n    return listOfLists;\n  }\n  public TryListGetDefinition(\n    name: string | null,\n    /* out */ def: ListDefinition | null\n  ): TryGetResult<ListDefinition | null> {\n    if (name === null) {\n      return { result: def, exists: false };\n    }\n    // initially, this function returns a boolean and the second parameter is an out.\n    let definition = this._lists.get(name);\n    if (!definition) return { result: def, exists: false };\n\n    return { result: definition, exists: true };\n  }\n  public FindSingleItemListWithName(name: string | null) {\n    if (name === null) {\n      return throwNullException(\"name\");\n    }\n    let val = this._allUnambiguousListValueCache.get(name);\n\n    if (typeof val !== \"undefined\") {\n      return val;\n    }\n\n    return null;\n  }\n}\n","import { Container } from \"./Container\";\nimport {\n  Value,\n  IntValue,\n  FloatValue,\n  StringValue,\n  DivertTargetValue,\n  VariablePointerValue,\n  ListValue,\n  BoolValue,\n} from \"./Value\";\nimport { Glue } from \"./Glue\";\nimport { ControlCommand } from \"./ControlCommand\";\nimport { PushPopType } from \"./PushPop\";\nimport { Divert } from \"./Divert\";\nimport { ChoicePoint } from \"./ChoicePoint\";\nimport { VariableReference } from \"./VariableReference\";\nimport { VariableAssignment } from \"./VariableAssignment\";\nimport { NativeFunctionCall } from \"./NativeFunctionCall\";\nimport { Void } from \"./Void\";\nimport { Tag } from \"./Tag\";\nimport { Path } from \"./Path\";\nimport { Choice } from \"./Choice\";\nimport { ListDefinition } from \"./ListDefinition\";\nimport { ListDefinitionsOrigin } from \"./ListDefinitionsOrigin\";\nimport { InkListItem, InkList } from \"./InkList\";\nimport { InkObject } from \"./Object\";\nimport { asOrNull } from \"./TypeAssertion\";\nimport { throwNullException } from \"./NullException\";\nimport { SimpleJson } from \"./SimpleJson\";\n\nexport class JsonSerialisation {\n  public static JArrayToRuntimeObjList(\n    jArray: any[],\n    skipLast: boolean = false\n  ) {\n    let count = jArray.length;\n    if (skipLast) count--;\n\n    let list: InkObject[] = [];\n\n    for (let i = 0; i < count; i++) {\n      let jTok = jArray[i];\n      let runtimeObj = this.JTokenToRuntimeObject(jTok);\n      if (runtimeObj === null) {\n        return throwNullException(\"runtimeObj\");\n      }\n      list.push(runtimeObj);\n    }\n\n    return list;\n  }\n\n  public static WriteDictionaryRuntimeObjs(\n    writer: SimpleJson.Writer,\n    dictionary: Map<string, InkObject>\n  ) {\n    writer.WriteObjectStart();\n    for (let [key, value] of dictionary) {\n      writer.WritePropertyStart(key);\n      this.WriteRuntimeObject(writer, value);\n      writer.WritePropertyEnd();\n    }\n    writer.WriteObjectEnd();\n  }\n\n  public static WriteListRuntimeObjs(\n    writer: SimpleJson.Writer,\n    list: InkObject[]\n  ) {\n    writer.WriteArrayStart();\n    for (let value of list) {\n      this.WriteRuntimeObject(writer, value);\n    }\n    writer.WriteArrayEnd();\n  }\n\n  public static WriteIntDictionary(\n    writer: SimpleJson.Writer,\n    dict: Map<string, number>\n  ) {\n    writer.WriteObjectStart();\n    for (let [key, value] of dict) {\n      writer.WriteIntProperty(key, value);\n    }\n    writer.WriteObjectEnd();\n  }\n\n  public static WriteRuntimeObject(\n    writer: SimpleJson.Writer,\n    obj: InkObject\n  ): void {\n    let container = asOrNull(obj, Container);\n    if (container) {\n      this.WriteRuntimeContainer(writer, container);\n      return;\n    }\n\n    let divert = asOrNull(obj, Divert);\n    if (divert) {\n      let divTypeKey = \"->\";\n      if (divert.isExternal) {\n        divTypeKey = \"x()\";\n      } else if (divert.pushesToStack) {\n        if (divert.stackPushType == PushPopType.Function) {\n          divTypeKey = \"f()\";\n        } else if (divert.stackPushType == PushPopType.Tunnel) {\n          divTypeKey = \"->t->\";\n        }\n      }\n\n      let targetStr;\n      if (divert.hasVariableTarget) {\n        targetStr = divert.variableDivertName;\n      } else {\n        targetStr = divert.targetPathString;\n      }\n\n      writer.WriteObjectStart();\n      writer.WriteProperty(divTypeKey, targetStr);\n\n      if (divert.hasVariableTarget) {\n        writer.WriteProperty(\"var\", true);\n      }\n\n      if (divert.isConditional) {\n        writer.WriteProperty(\"c\", true);\n      }\n\n      if (divert.externalArgs > 0) {\n        writer.WriteIntProperty(\"exArgs\", divert.externalArgs);\n      }\n\n      writer.WriteObjectEnd();\n      return;\n    }\n\n    let choicePoint = asOrNull(obj, ChoicePoint);\n    if (choicePoint) {\n      writer.WriteObjectStart();\n      writer.WriteProperty(\"*\", choicePoint.pathStringOnChoice);\n      writer.WriteIntProperty(\"flg\", choicePoint.flags);\n      writer.WriteObjectEnd();\n      return;\n    }\n\n    let boolVal = asOrNull(obj, BoolValue);\n    if (boolVal) {\n      writer.WriteBool(boolVal.value);\n      return;\n    }\n\n    let intVal = asOrNull(obj, IntValue);\n    if (intVal) {\n      writer.WriteInt(intVal.value);\n      return;\n    }\n\n    let floatVal = asOrNull(obj, FloatValue);\n    if (floatVal) {\n      writer.WriteFloat(floatVal.value);\n      return;\n    }\n\n    let strVal = asOrNull(obj, StringValue);\n    if (strVal) {\n      if (strVal.isNewline) {\n        writer.Write(\"\\n\", false);\n      } else {\n        writer.WriteStringStart();\n        writer.WriteStringInner(\"^\");\n        writer.WriteStringInner(strVal.value);\n        writer.WriteStringEnd();\n      }\n      return;\n    }\n\n    let listVal = asOrNull(obj, ListValue);\n    if (listVal) {\n      this.WriteInkList(writer, listVal);\n      return;\n    }\n\n    let divTargetVal = asOrNull(obj, DivertTargetValue);\n    if (divTargetVal) {\n      writer.WriteObjectStart();\n      if (divTargetVal.value === null) {\n        return throwNullException(\"divTargetVal.value\");\n      }\n      writer.WriteProperty(\"^->\", divTargetVal.value.componentsString);\n      writer.WriteObjectEnd();\n\n      return;\n    }\n\n    let varPtrVal = asOrNull(obj, VariablePointerValue);\n    if (varPtrVal) {\n      writer.WriteObjectStart();\n      writer.WriteProperty(\"^var\", varPtrVal.value);\n      writer.WriteIntProperty(\"ci\", varPtrVal.contextIndex);\n      writer.WriteObjectEnd();\n      return;\n    }\n\n    let glue = asOrNull(obj, Glue);\n    if (glue) {\n      writer.Write(\"<>\");\n      return;\n    }\n\n    let controlCmd = asOrNull(obj, ControlCommand);\n    if (controlCmd) {\n      writer.Write(\n        JsonSerialisation._controlCommandNames[controlCmd.commandType]\n      );\n      return;\n    }\n\n    let nativeFunc = asOrNull(obj, NativeFunctionCall);\n    if (nativeFunc) {\n      let name = nativeFunc.name;\n\n      if (name == \"^\") name = \"L^\";\n\n      writer.Write(name);\n      return;\n    }\n\n    let varRef = asOrNull(obj, VariableReference);\n    if (varRef) {\n      writer.WriteObjectStart();\n      let readCountPath = varRef.pathStringForCount;\n      if (readCountPath != null) {\n        writer.WriteProperty(\"CNT?\", readCountPath);\n      } else {\n        writer.WriteProperty(\"VAR?\", varRef.name);\n      }\n\n      writer.WriteObjectEnd();\n      return;\n    }\n\n    let varAss = asOrNull(obj, VariableAssignment);\n    if (varAss) {\n      writer.WriteObjectStart();\n\n      let key = varAss.isGlobal ? \"VAR=\" : \"temp=\";\n      writer.WriteProperty(key, varAss.variableName);\n\n      // Reassignment?\n      if (!varAss.isNewDeclaration) writer.WriteProperty(\"re\", true);\n\n      writer.WriteObjectEnd();\n\n      return;\n    }\n\n    let voidObj = asOrNull(obj, Void);\n    if (voidObj) {\n      writer.Write(\"void\");\n      return;\n    }\n\n    let tag = asOrNull(obj, Tag);\n    if (tag) {\n      writer.WriteObjectStart();\n      writer.WriteProperty(\"#\", tag.text);\n      writer.WriteObjectEnd();\n      return;\n    }\n\n    let choice = asOrNull(obj, Choice);\n    if (choice) {\n      this.WriteChoice(writer, choice);\n      return;\n    }\n\n    throw new Error(\"Failed to convert runtime object to Json token: \" + obj);\n  }\n\n  public static JObjectToDictionaryRuntimeObjs(jObject: Record<string, any>) {\n    let dict: Map<string, InkObject> = new Map();\n\n    for (let key in jObject) {\n      if (jObject.hasOwnProperty(key)) {\n        let inkObject = this.JTokenToRuntimeObject(jObject[key]);\n        if (inkObject === null) {\n          return throwNullException(\"inkObject\");\n        }\n        dict.set(key, inkObject);\n      }\n    }\n\n    return dict;\n  }\n\n  public static JObjectToIntDictionary(jObject: Record<string, any>) {\n    let dict: Map<string, number> = new Map();\n    for (let key in jObject) {\n      if (jObject.hasOwnProperty(key)) {\n        dict.set(key, parseInt(jObject[key]));\n      }\n    }\n    return dict;\n  }\n\n  public static JTokenToRuntimeObject(token: any): InkObject | null {\n    if (\n      (typeof token === \"number\" && !isNaN(token)) ||\n      typeof token === \"boolean\"\n    ) {\n      return Value.Create(token);\n    }\n\n    if (typeof token === \"string\") {\n      let str = token.toString();\n\n      //Explicit float value of the form \"123.00f\"\n      const floatRepresentation = /^([0-9]+.[0-9]+f)$/.exec(str);\n      if (floatRepresentation) {\n        return new FloatValue(parseFloat(floatRepresentation[0]));\n      }\n\n      // String value\n      let firstChar = str[0];\n      if (firstChar == \"^\") return new StringValue(str.substring(1));\n      else if (firstChar == \"\\n\" && str.length == 1)\n        return new StringValue(\"\\n\");\n\n      // Glue\n      if (str == \"<>\") return new Glue();\n\n      // Control commands (would looking up in a hash set be faster?)\n      for (let i = 0; i < JsonSerialisation._controlCommandNames.length; ++i) {\n        let cmdName = JsonSerialisation._controlCommandNames[i];\n        if (str == cmdName) {\n          return new ControlCommand(i);\n        }\n      }\n\n      // Native functions\n      if (str == \"L^\") str = \"^\";\n      if (NativeFunctionCall.CallExistsWithName(str))\n        return NativeFunctionCall.CallWithName(str);\n\n      // Pop\n      if (str == \"->->\") return ControlCommand.PopTunnel();\n      else if (str == \"~ret\") return ControlCommand.PopFunction();\n\n      // Void\n      if (str == \"void\") return new Void();\n    }\n\n    if (typeof token === \"object\" && !Array.isArray(token)) {\n      let obj = token as Record<string, any>;\n      let propValue;\n\n      // Divert target value to path\n      if (obj[\"^->\"]) {\n        propValue = obj[\"^->\"];\n        return new DivertTargetValue(new Path(propValue.toString()));\n      }\n\n      // VariablePointerValue\n      if (obj[\"^var\"]) {\n        propValue = obj[\"^var\"];\n        let varPtr = new VariablePointerValue(propValue.toString());\n        if (\"ci\" in obj) {\n          propValue = obj[\"ci\"];\n          varPtr.contextIndex = parseInt(propValue);\n        }\n        return varPtr;\n      }\n\n      // Divert\n      let isDivert = false;\n      let pushesToStack = false;\n      let divPushType = PushPopType.Function;\n      let external = false;\n      if ((propValue = obj[\"->\"])) {\n        isDivert = true;\n      } else if ((propValue = obj[\"f()\"])) {\n        isDivert = true;\n        pushesToStack = true;\n        divPushType = PushPopType.Function;\n      } else if ((propValue = obj[\"->t->\"])) {\n        isDivert = true;\n        pushesToStack = true;\n        divPushType = PushPopType.Tunnel;\n      } else if ((propValue = obj[\"x()\"])) {\n        isDivert = true;\n        external = true;\n        pushesToStack = false;\n        divPushType = PushPopType.Function;\n      }\n\n      if (isDivert) {\n        let divert = new Divert();\n        divert.pushesToStack = pushesToStack;\n        divert.stackPushType = divPushType;\n        divert.isExternal = external;\n\n        let target = propValue.toString();\n\n        if ((propValue = obj[\"var\"])) divert.variableDivertName = target;\n        else divert.targetPathString = target;\n\n        divert.isConditional = !!obj[\"c\"];\n\n        if (external) {\n          if ((propValue = obj[\"exArgs\"]))\n            divert.externalArgs = parseInt(propValue);\n        }\n\n        return divert;\n      }\n\n      // Choice\n      if ((propValue = obj[\"*\"])) {\n        let choice = new ChoicePoint();\n        choice.pathStringOnChoice = propValue.toString();\n\n        if ((propValue = obj[\"flg\"])) choice.flags = parseInt(propValue);\n\n        return choice;\n      }\n\n      // Variable reference\n      if ((propValue = obj[\"VAR?\"])) {\n        return new VariableReference(propValue.toString());\n      } else if ((propValue = obj[\"CNT?\"])) {\n        let readCountVarRef = new VariableReference();\n        readCountVarRef.pathStringForCount = propValue.toString();\n        return readCountVarRef;\n      }\n\n      // Variable assignment\n      let isVarAss = false;\n      let isGlobalVar = false;\n      if ((propValue = obj[\"VAR=\"])) {\n        isVarAss = true;\n        isGlobalVar = true;\n      } else if ((propValue = obj[\"temp=\"])) {\n        isVarAss = true;\n        isGlobalVar = false;\n      }\n      if (isVarAss) {\n        let varName = propValue.toString();\n        let isNewDecl = !obj[\"re\"];\n        let varAss = new VariableAssignment(varName, isNewDecl);\n        varAss.isGlobal = isGlobalVar;\n        return varAss;\n      }\n      if (obj[\"#\"] !== undefined) {\n        propValue = obj[\"#\"];\n        return new Tag(propValue.toString());\n      }\n\n      // List value\n      if ((propValue = obj[\"list\"])) {\n        // var listContent = (Dictionary<string, object>)propValue;\n        let listContent = propValue as Record<string, any>;\n        let rawList = new InkList();\n        if ((propValue = obj[\"origins\"])) {\n          // var namesAsObjs = (List<object>)propValue;\n          let namesAsObjs = propValue as string[];\n          // rawList.SetInitialOriginNames(namesAsObjs.Cast<string>().ToList());\n          rawList.SetInitialOriginNames(namesAsObjs);\n        }\n\n        for (let key in listContent) {\n          if (listContent.hasOwnProperty(key)) {\n            let nameToVal = listContent[key];\n            let item = new InkListItem(key);\n            let val = parseInt(nameToVal);\n            rawList.Add(item, val);\n          }\n        }\n\n        return new ListValue(rawList);\n      }\n\n      if (obj[\"originalChoicePath\"] != null) return this.JObjectToChoice(obj);\n    }\n\n    // Array is always a Runtime.Container\n    if (Array.isArray(token)) {\n      return this.JArrayToContainer(token);\n    }\n\n    if (token === null || token === undefined) return null;\n\n    throw new Error(\n      \"Failed to convert token to runtime object: \" +\n        this.toJson(token, [\"parent\"])\n    );\n  }\n\n  public static toJson<T>(\n    me: T,\n    removes?: (keyof T)[],\n    space?: number\n  ): string {\n    return JSON.stringify(\n      me,\n      (k, v) => (removes?.some((r) => r === k) ? undefined : v),\n      space\n    );\n  }\n\n  public static WriteRuntimeContainer(\n    writer: SimpleJson.Writer,\n    container: Container | null,\n    withoutName: boolean = false\n  ) {\n    writer.WriteArrayStart();\n    if (container === null) {\n      return throwNullException(\"container\");\n    }\n    for (let c of container.content) this.WriteRuntimeObject(writer, c);\n\n    let namedOnlyContent = container.namedOnlyContent;\n    let countFlags = container.countFlags;\n    let hasNameProperty = container.name != null && !withoutName;\n\n    let hasTerminator =\n      namedOnlyContent != null || countFlags > 0 || hasNameProperty;\n    if (hasTerminator) {\n      writer.WriteObjectStart();\n    }\n\n    if (namedOnlyContent != null) {\n      for (let [key, value] of namedOnlyContent) {\n        let name = key;\n        let namedContainer = asOrNull(value, Container);\n        writer.WritePropertyStart(name);\n        this.WriteRuntimeContainer(writer, namedContainer, true);\n        writer.WritePropertyEnd();\n      }\n    }\n\n    if (countFlags > 0) writer.WriteIntProperty(\"#f\", countFlags);\n\n    if (hasNameProperty) writer.WriteProperty(\"#n\", container.name);\n\n    if (hasTerminator) writer.WriteObjectEnd();\n    else writer.WriteNull();\n\n    writer.WriteArrayEnd();\n  }\n\n  public static JArrayToContainer(jArray: any[]) {\n    let container = new Container();\n    container.content = this.JArrayToRuntimeObjList(jArray, true);\n\n    let terminatingObj = jArray[jArray.length - 1] as Record<string, any>;\n    if (terminatingObj != null) {\n      let namedOnlyContent = new Map();\n\n      for (let key in terminatingObj) {\n        if (key == \"#f\") {\n          container.countFlags = parseInt(terminatingObj[key]);\n        } else if (key == \"#n\") {\n          container.name = terminatingObj[key].toString();\n        } else {\n          let namedContentItem = this.JTokenToRuntimeObject(\n            terminatingObj[key]\n          );\n          // var namedSubContainer = namedContentItem as Container;\n          let namedSubContainer = asOrNull(namedContentItem, Container);\n          if (namedSubContainer) namedSubContainer.name = key;\n          namedOnlyContent.set(key, namedContentItem);\n        }\n      }\n\n      container.namedOnlyContent = namedOnlyContent;\n    }\n\n    return container;\n  }\n\n  public static JObjectToChoice(jObj: Record<string, any>) {\n    let choice = new Choice();\n    choice.text = jObj[\"text\"].toString();\n    choice.index = parseInt(jObj[\"index\"]);\n    choice.sourcePath = jObj[\"originalChoicePath\"].toString();\n    choice.originalThreadIndex = parseInt(jObj[\"originalThreadIndex\"]);\n    choice.pathStringOnChoice = jObj[\"targetPath\"].toString();\n    choice.tags = this.JArrayToTags(jObj);\n    choice.isInvisibleDefault = !!jObj[\"isInvisibleDefault\"];\n    return choice;\n  }\n\n  public static JArrayToTags(jObj: Record<string, any>) {\n    if (jObj[\"tags\"]) {\n      return jObj[\"tags\"];\n    } else {\n      return null;\n    }\n  }\n\n  public static WriteChoice(writer: SimpleJson.Writer, choice: Choice) {\n    writer.WriteObjectStart();\n    writer.WriteProperty(\"text\", choice.text);\n    writer.WriteIntProperty(\"index\", choice.index);\n    writer.WriteProperty(\"originalChoicePath\", choice.sourcePath);\n    writer.WriteIntProperty(\"originalThreadIndex\", choice.originalThreadIndex);\n    writer.WriteProperty(\"targetPath\", choice.pathStringOnChoice);\n    writer.WriteProperty(\"isInvisibleDefault\", choice.isInvisibleDefault);\n    this.WriteChoiceTags(writer, choice);\n    writer.WriteObjectEnd();\n  }\n\n  public static WriteChoiceTags(writer: SimpleJson.Writer, choice: Choice) {\n    if (choice.tags && choice.tags.length > 0) {\n      writer.WritePropertyStart(\"tags\");\n      writer.WriteArrayStart();\n      for (const tag of choice.tags!) {\n        writer.Write(tag);\n      }\n      writer.WriteArrayEnd();\n      writer.WritePropertyEnd();\n    }\n  }\n\n  public static WriteInkList(writer: SimpleJson.Writer, listVal: ListValue) {\n    let rawList = listVal.value;\n    if (rawList === null) {\n      return throwNullException(\"rawList\");\n    }\n\n    writer.WriteObjectStart();\n    writer.WritePropertyStart(\"list\");\n    writer.WriteObjectStart();\n\n    for (let [key, val] of rawList) {\n      let item = InkListItem.fromSerializedKey(key);\n      let itemVal = val;\n\n      if (item.itemName === null) {\n        return throwNullException(\"item.itemName\");\n      }\n\n      writer.WritePropertyNameStart();\n      writer.WritePropertyNameInner(item.originName ? item.originName : \"?\");\n      writer.WritePropertyNameInner(\".\");\n      writer.WritePropertyNameInner(item.itemName);\n      writer.WritePropertyNameEnd();\n\n      writer.Write(itemVal);\n\n      writer.WritePropertyEnd();\n    }\n\n    writer.WriteObjectEnd();\n\n    writer.WritePropertyEnd();\n\n    if (\n      rawList.Count == 0 &&\n      rawList.originNames != null &&\n      rawList.originNames.length > 0\n    ) {\n      writer.WritePropertyStart(\"origins\");\n      writer.WriteArrayStart();\n      for (let name of rawList.originNames) writer.Write(name);\n      writer.WriteArrayEnd();\n      writer.WritePropertyEnd();\n    }\n\n    writer.WriteObjectEnd();\n  }\n\n  public static ListDefinitionsToJToken(origin: ListDefinitionsOrigin) {\n    let result: Record<string, any> = {};\n\n    for (let def of origin.lists) {\n      let listDefJson: Record<string, any> = {};\n\n      for (let [key, val] of def.items) {\n        let item = InkListItem.fromSerializedKey(key);\n        if (item.itemName === null) {\n          return throwNullException(\"item.itemName\");\n        }\n        listDefJson[item.itemName] = val;\n      }\n\n      result[def.name] = listDefJson;\n    }\n\n    return result;\n  }\n\n  public static JTokenToListDefinitions(obj: Record<string, any>) {\n    // var defsObj = (Dictionary<string, object>)obj;\n    let defsObj = obj;\n\n    let allDefs: ListDefinition[] = [];\n\n    for (let key in defsObj) {\n      if (defsObj.hasOwnProperty(key)) {\n        let name = key.toString();\n        // var listDefJson = (Dictionary<string, object>)kv.Value;\n        let listDefJson = defsObj[key] as Record<string, any>;\n\n        // Cast (string, object) to (string, int) for items\n        let items: Map<string, number> = new Map();\n\n        for (let nameValueKey in listDefJson) {\n          if (defsObj.hasOwnProperty(key)) {\n            let nameValue = listDefJson[nameValueKey];\n            items.set(nameValueKey, parseInt(nameValue));\n          }\n        }\n\n        let def = new ListDefinition(name, items);\n        allDefs.push(def);\n      }\n    }\n\n    return new ListDefinitionsOrigin(allDefs);\n  }\n\n  private static _controlCommandNames = (() => {\n    let _controlCommandNames: string[] = [];\n\n    _controlCommandNames[ControlCommand.CommandType.EvalStart] = \"ev\";\n    _controlCommandNames[ControlCommand.CommandType.EvalOutput] = \"out\";\n    _controlCommandNames[ControlCommand.CommandType.EvalEnd] = \"/ev\";\n    _controlCommandNames[ControlCommand.CommandType.Duplicate] = \"du\";\n    _controlCommandNames[ControlCommand.CommandType.PopEvaluatedValue] = \"pop\";\n    _controlCommandNames[ControlCommand.CommandType.PopFunction] = \"~ret\";\n    _controlCommandNames[ControlCommand.CommandType.PopTunnel] = \"->->\";\n    _controlCommandNames[ControlCommand.CommandType.BeginString] = \"str\";\n    _controlCommandNames[ControlCommand.CommandType.EndString] = \"/str\";\n    _controlCommandNames[ControlCommand.CommandType.NoOp] = \"nop\";\n    _controlCommandNames[ControlCommand.CommandType.ChoiceCount] = \"choiceCnt\";\n    _controlCommandNames[ControlCommand.CommandType.Turns] = \"turn\";\n    _controlCommandNames[ControlCommand.CommandType.TurnsSince] = \"turns\";\n    _controlCommandNames[ControlCommand.CommandType.ReadCount] = \"readc\";\n    _controlCommandNames[ControlCommand.CommandType.Random] = \"rnd\";\n    _controlCommandNames[ControlCommand.CommandType.SeedRandom] = \"srnd\";\n    _controlCommandNames[ControlCommand.CommandType.VisitIndex] = \"visit\";\n    _controlCommandNames[ControlCommand.CommandType.SequenceShuffleIndex] =\n      \"seq\";\n    _controlCommandNames[ControlCommand.CommandType.StartThread] = \"thread\";\n    _controlCommandNames[ControlCommand.CommandType.Done] = \"done\";\n    _controlCommandNames[ControlCommand.CommandType.End] = \"end\";\n    _controlCommandNames[ControlCommand.CommandType.ListFromInt] = \"listInt\";\n    _controlCommandNames[ControlCommand.CommandType.ListRange] = \"range\";\n    _controlCommandNames[ControlCommand.CommandType.ListRandom] = \"lrnd\";\n    _controlCommandNames[ControlCommand.CommandType.BeginTag] = \"#\";\n    _controlCommandNames[ControlCommand.CommandType.EndTag] = \"/#\";\n\n    for (let i = 0; i < ControlCommand.CommandType.TOTAL_VALUES; ++i) {\n      if (_controlCommandNames[i] == null)\n        throw new Error(\"Control command not accounted for in serialisation\");\n    }\n\n    return _controlCommandNames;\n  })();\n}\n","import { PushPopType } from \"./PushPop\";\nimport { Path } from \"./Path\";\nimport { Story } from \"./Story\";\nimport { JsonSerialisation } from \"./JsonSerialisation\";\nimport { ListValue } from \"./Value\";\nimport { StringBuilder } from \"./StringBuilder\";\nimport { Pointer } from \"./Pointer\";\nimport { InkObject } from \"./Object\";\nimport { Debug } from \"./Debug\";\nimport { tryGetValueFromMap } from \"./TryGetResult\";\nimport { throwNullException } from \"./NullException\";\nimport { SimpleJson } from \"./SimpleJson\";\n\nexport class CallStack {\n  get elements() {\n    return this.callStack;\n  }\n\n  get depth() {\n    return this.elements.length;\n  }\n\n  get currentElement() {\n    let thread = this._threads[this._threads.length - 1];\n    let cs = thread.callstack;\n    return cs[cs.length - 1];\n  }\n\n  get currentElementIndex() {\n    return this.callStack.length - 1;\n  }\n\n  get currentThread(): CallStack.Thread {\n    return this._threads[this._threads.length - 1];\n  }\n  set currentThread(value: CallStack.Thread) {\n    Debug.Assert(\n      this._threads.length == 1,\n      \"Shouldn't be directly setting the current thread when we have a stack of them\"\n    );\n\n    this._threads.length = 0;\n    this._threads.push(value);\n  }\n\n  get canPop() {\n    return this.callStack.length > 1;\n  }\n\n  constructor(storyContext: Story);\n  constructor(toCopy: CallStack);\n  constructor() {\n    if (arguments[0] instanceof Story) {\n      let storyContext = arguments[0] as Story;\n\n      this._startOfRoot = Pointer.StartOf(storyContext.rootContentContainer);\n      this.Reset();\n    } else {\n      let toCopy = arguments[0] as CallStack;\n\n      this._threads = [];\n      for (let otherThread of toCopy._threads) {\n        this._threads.push(otherThread.Copy());\n      }\n      this._threadCounter = toCopy._threadCounter;\n      this._startOfRoot = toCopy._startOfRoot.copy();\n    }\n  }\n\n  public Reset() {\n    this._threads = [];\n    this._threads.push(new CallStack.Thread());\n\n    this._threads[0].callstack.push(\n      new CallStack.Element(PushPopType.Tunnel, this._startOfRoot)\n    );\n  }\n\n  public SetJsonToken(jObject: Record<string, any>, storyContext: Story) {\n    this._threads.length = 0;\n\n    // TODO: (List<object>) jObject [\"threads\"];\n    let jThreads: any[] = jObject[\"threads\"];\n\n    for (let jThreadTok of jThreads) {\n      // TODO: var jThreadObj = (Dictionary<string, object>)jThreadTok;\n      let jThreadObj = jThreadTok;\n      let thread = new CallStack.Thread(jThreadObj, storyContext);\n      this._threads.push(thread);\n    }\n\n    // TODO: (int)jObject [\"threadCounter\"];\n    this._threadCounter = parseInt(jObject[\"threadCounter\"]);\n    this._startOfRoot = Pointer.StartOf(storyContext.rootContentContainer);\n  }\n  public WriteJson(w: SimpleJson.Writer) {\n    w.WriteObject((writer) => {\n      writer.WritePropertyStart(\"threads\");\n      writer.WriteArrayStart();\n\n      for (let thread of this._threads) {\n        thread.WriteJson(writer);\n      }\n\n      writer.WriteArrayEnd();\n      writer.WritePropertyEnd();\n\n      writer.WritePropertyStart(\"threadCounter\");\n      writer.WriteInt(this._threadCounter);\n      writer.WritePropertyEnd();\n    });\n  }\n\n  public PushThread() {\n    let newThread = this.currentThread.Copy();\n    this._threadCounter++;\n    newThread.threadIndex = this._threadCounter;\n    this._threads.push(newThread);\n  }\n\n  public ForkThread() {\n    let forkedThread = this.currentThread.Copy();\n    this._threadCounter++;\n    forkedThread.threadIndex = this._threadCounter;\n    return forkedThread;\n  }\n\n  public PopThread() {\n    if (this.canPopThread) {\n      this._threads.splice(this._threads.indexOf(this.currentThread), 1); // should be equivalent to a pop()\n    } else {\n      throw new Error(\"Can't pop thread\");\n    }\n  }\n\n  get canPopThread() {\n    return this._threads.length > 1 && !this.elementIsEvaluateFromGame;\n  }\n\n  get elementIsEvaluateFromGame() {\n    return this.currentElement.type == PushPopType.FunctionEvaluationFromGame;\n  }\n\n  public Push(\n    type: PushPopType,\n    externalEvaluationStackHeight: number = 0,\n    outputStreamLengthWithPushed: number = 0\n  ) {\n    let element = new CallStack.Element(\n      type,\n      this.currentElement.currentPointer,\n      false\n    );\n\n    element.evaluationStackHeightWhenPushed = externalEvaluationStackHeight;\n    element.functionStartInOutputStream = outputStreamLengthWithPushed;\n\n    this.callStack.push(element);\n  }\n\n  public CanPop(type: PushPopType | null = null) {\n    if (!this.canPop) return false;\n\n    if (type == null) return true;\n\n    return this.currentElement.type == type;\n  }\n\n  public Pop(type: PushPopType | null = null) {\n    if (this.CanPop(type)) {\n      this.callStack.pop();\n      return;\n    } else {\n      throw new Error(\"Mismatched push/pop in Callstack\");\n    }\n  }\n\n  public GetTemporaryVariableWithName(\n    name: string | null,\n    contextIndex: number = -1\n  ) {\n    // contextIndex 0 means global, so index is actually 1-based\n    if (contextIndex == -1) contextIndex = this.currentElementIndex + 1;\n\n    let contextElement = this.callStack[contextIndex - 1];\n\n    let varValue = tryGetValueFromMap(\n      contextElement.temporaryVariables,\n      name,\n      null\n    );\n    if (varValue.exists) {\n      return varValue.result;\n    } else {\n      return null;\n    }\n  }\n\n  public SetTemporaryVariable(\n    name: string,\n    value: any,\n    declareNew: boolean,\n    contextIndex: number = -1\n  ) {\n    if (contextIndex == -1) contextIndex = this.currentElementIndex + 1;\n\n    let contextElement = this.callStack[contextIndex - 1];\n\n    if (!declareNew && !contextElement.temporaryVariables.get(name)) {\n      throw new Error(\"Could not find temporary variable to set: \" + name);\n    }\n\n    let oldValue = tryGetValueFromMap(\n      contextElement.temporaryVariables,\n      name,\n      null\n    );\n    if (oldValue.exists)\n      ListValue.RetainListOriginsForAssignment(oldValue.result, value);\n\n    contextElement.temporaryVariables.set(name, value);\n  }\n\n  public ContextForVariableNamed(name: string) {\n    if (this.currentElement.temporaryVariables.get(name)) {\n      return this.currentElementIndex + 1;\n    } else {\n      return 0;\n    }\n  }\n\n  public ThreadWithIndex(index: number) {\n    let filtered = this._threads.filter((t) => {\n      if (t.threadIndex == index) return t;\n    });\n\n    return filtered.length > 0 ? filtered[0] : null;\n  }\n\n  get callStack() {\n    return this.currentThread.callstack;\n  }\n\n  get callStackTrace() {\n    let sb = new StringBuilder();\n\n    for (let t = 0; t < this._threads.length; t++) {\n      let thread = this._threads[t];\n      let isCurrent = t == this._threads.length - 1;\n      sb.AppendFormat(\n        \"=== THREAD {0}/{1} {2}===\\n\",\n        t + 1,\n        this._threads.length,\n        isCurrent ? \"(current) \" : \"\"\n      );\n\n      for (let i = 0; i < thread.callstack.length; i++) {\n        if (thread.callstack[i].type == PushPopType.Function)\n          sb.Append(\"  [FUNCTION] \");\n        else sb.Append(\"  [TUNNEL] \");\n\n        let pointer = thread.callstack[i].currentPointer;\n        if (!pointer.isNull) {\n          sb.Append(\"<SOMEWHERE IN \");\n          if (pointer.container === null) {\n            return throwNullException(\"pointer.container\");\n          }\n          sb.Append(pointer.container.path.toString());\n          sb.AppendLine(\">\");\n        }\n      }\n    }\n\n    return sb.toString();\n  }\n\n  public _threads!: CallStack.Thread[]; // Banged because it's initialized in Reset().\n  public _threadCounter: number = 0;\n  public _startOfRoot: Pointer = Pointer.Null;\n}\n\nexport namespace CallStack {\n  export class Element {\n    public currentPointer: Pointer;\n    public inExpressionEvaluation: boolean;\n    public temporaryVariables: Map<string, InkObject>;\n    public type: PushPopType;\n\n    public evaluationStackHeightWhenPushed: number = 0;\n    public functionStartInOutputStream: number = 0;\n\n    constructor(\n      type: PushPopType,\n      pointer: Pointer,\n      inExpressionEvaluation: boolean = false\n    ) {\n      this.currentPointer = pointer.copy();\n      this.inExpressionEvaluation = inExpressionEvaluation;\n      this.temporaryVariables = new Map();\n      this.type = type;\n    }\n\n    public Copy() {\n      let copy = new Element(\n        this.type,\n        this.currentPointer,\n        this.inExpressionEvaluation\n      );\n      copy.temporaryVariables = new Map(this.temporaryVariables);\n      copy.evaluationStackHeightWhenPushed =\n        this.evaluationStackHeightWhenPushed;\n      copy.functionStartInOutputStream = this.functionStartInOutputStream;\n      return copy;\n    }\n  }\n\n  export class Thread {\n    public callstack: Element[];\n    public threadIndex: number = 0;\n    public previousPointer: Pointer = Pointer.Null;\n\n    constructor();\n    constructor(jThreadObj: any, storyContext: Story);\n    constructor() {\n      this.callstack = [];\n\n      if (arguments[0] && arguments[1]) {\n        let jThreadObj = arguments[0];\n        let storyContext = arguments[1];\n\n        // TODO: (int) jThreadObj['threadIndex'] can raise;\n        this.threadIndex = parseInt(jThreadObj[\"threadIndex\"]);\n\n        let jThreadCallstack = jThreadObj[\"callstack\"];\n\n        for (let jElTok of jThreadCallstack) {\n          let jElementObj = jElTok;\n\n          // TODO: (int) jElementObj['type'] can raise;\n          let pushPopType: PushPopType = parseInt(jElementObj[\"type\"]);\n\n          let pointer = Pointer.Null;\n\n          let currentContainerPathStr: string;\n          // TODO: jElementObj.TryGetValue (\"cPath\", out currentContainerPathStrToken);\n          let currentContainerPathStrToken = jElementObj[\"cPath\"];\n          if (typeof currentContainerPathStrToken !== \"undefined\") {\n            currentContainerPathStr = currentContainerPathStrToken.toString();\n\n            let threadPointerResult = storyContext.ContentAtPath(\n              new Path(currentContainerPathStr)\n            );\n            pointer.container = threadPointerResult.container;\n            pointer.index = parseInt(jElementObj[\"idx\"]);\n\n            if (threadPointerResult.obj == null)\n              throw new Error(\n                \"When loading state, internal story location couldn't be found: \" +\n                  currentContainerPathStr +\n                  \". Has the story changed since this save data was created?\"\n              );\n            else if (threadPointerResult.approximate) {\n              if (pointer.container !== null) {\n                storyContext.Warning(\n                  \"When loading state, exact internal story location couldn't be found: '\" +\n                    currentContainerPathStr +\n                    \"', so it was approximated to '\" +\n                    pointer.container.path.toString() +\n                    \"' to recover. Has the story changed since this save data was created?\"\n                );\n              } else {\n                storyContext.Warning(\n                  \"When loading state, exact internal story location couldn't be found: '\" +\n                    currentContainerPathStr +\n                    \"' and it may not be recoverable. Has the story changed since this save data was created?\"\n                );\n              }\n            }\n          }\n\n          let inExpressionEvaluation = !!jElementObj[\"exp\"];\n\n          let el = new Element(pushPopType, pointer, inExpressionEvaluation);\n\n          let temps = jElementObj[\"temp\"];\n          if (typeof temps !== \"undefined\") {\n            el.temporaryVariables =\n              JsonSerialisation.JObjectToDictionaryRuntimeObjs(temps);\n          } else {\n            el.temporaryVariables.clear();\n          }\n\n          this.callstack.push(el);\n        }\n\n        let prevContentObjPath = jThreadObj[\"previousContentObject\"];\n        if (typeof prevContentObjPath !== \"undefined\") {\n          let prevPath = new Path(prevContentObjPath.toString());\n          this.previousPointer = storyContext.PointerAtPath(prevPath);\n        }\n      }\n    }\n\n    public Copy() {\n      let copy = new Thread();\n      copy.threadIndex = this.threadIndex;\n      for (let e of this.callstack) {\n        copy.callstack.push(e.Copy());\n      }\n      copy.previousPointer = this.previousPointer.copy();\n      return copy;\n    }\n\n    public WriteJson(writer: SimpleJson.Writer) {\n      writer.WriteObjectStart();\n\n      writer.WritePropertyStart(\"callstack\");\n      writer.WriteArrayStart();\n      for (let el of this.callstack) {\n        writer.WriteObjectStart();\n        if (!el.currentPointer.isNull) {\n          if (el.currentPointer.container === null) {\n            return throwNullException(\"el.currentPointer.container\");\n          }\n          writer.WriteProperty(\n            \"cPath\",\n            el.currentPointer.container.path.componentsString\n          );\n          writer.WriteIntProperty(\"idx\", el.currentPointer.index);\n        }\n\n        writer.WriteProperty(\"exp\", el.inExpressionEvaluation);\n        writer.WriteIntProperty(\"type\", el.type);\n\n        if (el.temporaryVariables.size > 0) {\n          writer.WritePropertyStart(\"temp\");\n          JsonSerialisation.WriteDictionaryRuntimeObjs(\n            writer,\n            el.temporaryVariables\n          );\n          writer.WritePropertyEnd();\n        }\n\n        writer.WriteObjectEnd();\n      }\n      writer.WriteArrayEnd();\n      writer.WritePropertyEnd();\n\n      writer.WriteIntProperty(\"threadIndex\", this.threadIndex);\n\n      if (!this.previousPointer.isNull) {\n        let resolvedPointer = this.previousPointer.Resolve();\n        if (resolvedPointer === null) {\n          return throwNullException(\"this.previousPointer.Resolve()\");\n        }\n        writer.WriteProperty(\n          \"previousContentObject\",\n          resolvedPointer.path.toString()\n        );\n      }\n\n      writer.WriteObjectEnd();\n    }\n  }\n}\n","import {\n  AbstractValue,\n  Value,\n  VariablePointerValue,\n  ListValue,\n  IntValue,\n  FloatValue,\n  BoolValue,\n} from \"./Value\";\nimport { VariableAssignment } from \"./VariableAssignment\";\nimport { InkObject } from \"./Object\";\nimport { ListDefinitionsOrigin } from \"./ListDefinitionsOrigin\";\nimport { StoryException } from \"./StoryException\";\nimport { JsonSerialisation } from \"./JsonSerialisation\";\nimport { asOrThrows, asOrNull, isEquatable } from \"./TypeAssertion\";\nimport { tryGetValueFromMap } from \"./TryGetResult\";\nimport { throwNullException } from \"./NullException\";\nimport { CallStack } from \"./CallStack\";\nimport { StatePatch } from \"./StatePatch\";\nimport { SimpleJson } from \"./SimpleJson\";\nimport { InkList } from \"./Story\";\nimport { Path } from \"./Path\";\n\n// Fake class wrapper around VariableState to have correct typing\n// when using the Proxy syntax in typescript\nfunction VariablesStateAccessor<T>(): new () => Pick<T, keyof T> {\n  return class {} as any;\n}\n\ntype VariableStateValue = boolean | string | number | InkList | Path | null;\n\nexport class VariablesState extends VariablesStateAccessor<\n  Record<string, any>\n>() {\n  // The way variableChangedEvent is a bit different than the reference implementation.\n  // Originally it uses the C# += operator to add delegates, but in js we need to maintain\n  // an actual collection of delegates (ie. callbacks) to register a new one, there is a\n  // special ObserveVariableChange method below.\n  public variableChangedEventCallbacks: Array<\n    (variableName: string, newValue: InkObject) => void\n  > = [];\n  public variableChangedEvent(variableName: string, newValue: InkObject): void {\n    for (let callback of this.variableChangedEventCallbacks) {\n      callback(variableName, newValue);\n    }\n  }\n\n  public patch: StatePatch | null = null;\n\n  public StartVariableObservation() {\n    this._batchObservingVariableChanges = true;\n    this._changedVariablesForBatchObs = new Set();\n  }\n\n  public CompleteVariableObservation(): Map<string, any> {\n    this._batchObservingVariableChanges = false;\n    let changedVars = new Map<string, any>();\n    if (this._changedVariablesForBatchObs != null) {\n      for (let variableName of this._changedVariablesForBatchObs) {\n        let currentValue = this._globalVariables.get(variableName) as InkObject;\n        this.variableChangedEvent(variableName, currentValue);\n      }\n    }\n    // Patch may still be active - e.g. if we were in the middle of a background save\n    if (this.patch != null) {\n      for (let variableName of this.patch.changedVariables) {\n        let patchedVal = this.patch.TryGetGlobal(variableName, null);\n        if (patchedVal.exists) changedVars.set(variableName, patchedVal);\n      }\n    }\n    this._changedVariablesForBatchObs = null;\n    return changedVars;\n  }\n\n  public NotifyObservers(changedVars: Map<string, any>) {\n    for (const [key, value] of changedVars) {\n      this.variableChangedEvent(key, value);\n    }\n  }\n\n  get callStack() {\n    return this._callStack;\n  }\n  set callStack(callStack) {\n    this._callStack = callStack;\n  }\n\n  // the original code uses a magic getter and setter for global variables,\n  // allowing things like variableState['varname]. This is not quite possible\n  // in js without a Proxy, so it is replaced with this $ function.\n  public $(variableName: string): VariableStateValue;\n  public $(variableName: string, value: VariableStateValue): void;\n  public $(variableName: string, value?: any) {\n    if (typeof value === \"undefined\") {\n      let varContents = null;\n\n      if (this.patch !== null) {\n        varContents = this.patch.TryGetGlobal(variableName, null);\n        if (varContents.exists)\n          return (varContents.result as AbstractValue).valueObject;\n      }\n\n      varContents = this._globalVariables.get(variableName);\n\n      if (typeof varContents === \"undefined\") {\n        varContents = this._defaultGlobalVariables.get(variableName);\n      }\n\n      if (typeof varContents !== \"undefined\")\n        return (varContents as AbstractValue).valueObject;\n      else return null;\n    } else {\n      if (typeof this._defaultGlobalVariables.get(variableName) === \"undefined\")\n        throw new StoryException(\n          \"Cannot assign to a variable (\" +\n            variableName +\n            \") that hasn't been declared in the story\"\n        );\n\n      let val = Value.Create(value);\n      if (val == null) {\n        if (value == null) {\n          throw new Error(\"Cannot pass null to VariableState\");\n        } else {\n          throw new Error(\n            \"Invalid value passed to VariableState: \" + value.toString()\n          );\n        }\n      }\n\n      this.SetGlobal(variableName, val);\n    }\n  }\n\n  constructor(\n    callStack: CallStack,\n    listDefsOrigin: ListDefinitionsOrigin | null\n  ) {\n    super();\n    this._globalVariables = new Map();\n    this._callStack = callStack;\n    this._listDefsOrigin = listDefsOrigin;\n\n    // if es6 proxies are available, use them.\n    try {\n      // the proxy is used to allow direct manipulation of global variables.\n      // It first tries to access the objects own property, and if none is\n      // found it delegates the call to the $ method, defined below\n      let p = new Proxy(this, {\n        get(target: any, name) {\n          return name in target ? target[name] : target.$(name);\n        },\n        set(target: any, name, value) {\n          if (name in target) target[name] = value;\n          else target.$(name, value);\n          return true; // returning a falsy value make the trap fail\n        },\n        ownKeys(target: any) {\n          return [\n            ...new Set([\n              ...target._defaultGlobalVariables.keys(),\n              ...target._globalVariables.keys(),\n            ]),\n          ];\n        },\n        getOwnPropertyDescriptor(target, name) {\n          // called for every property\n          return {\n            enumerable: true,\n            configurable: true,\n            value: target.$(name),\n          };\n        },\n      });\n\n      return p;\n    } catch (e) {\n      // the proxy object is not available in this context. we should warn the\n      // dev but writing to the console feels a bit intrusive.\n      // console.log(\"ES6 Proxy not available - direct manipulation of global variables can't work, use $() instead.\");\n    }\n  }\n\n  public ApplyPatch() {\n    if (this.patch === null) {\n      return throwNullException(\"this.patch\");\n    }\n\n    for (let [namedVarKey, namedVarValue] of this.patch.globals) {\n      this._globalVariables.set(namedVarKey, namedVarValue);\n    }\n\n    if (this._changedVariablesForBatchObs !== null) {\n      for (let name of this.patch.changedVariables) {\n        this._changedVariablesForBatchObs.add(name);\n      }\n    }\n\n    this.patch = null;\n  }\n\n  public SetJsonToken(jToken: Record<string, any>) {\n    this._globalVariables.clear();\n\n    for (let [varValKey, varValValue] of this._defaultGlobalVariables) {\n      let loadedToken = jToken[varValKey];\n      if (typeof loadedToken !== \"undefined\") {\n        let tokenInkObject =\n          JsonSerialisation.JTokenToRuntimeObject(loadedToken);\n        if (tokenInkObject === null) {\n          return throwNullException(\"tokenInkObject\");\n        }\n        this._globalVariables.set(varValKey, tokenInkObject);\n      } else {\n        this._globalVariables.set(varValKey, varValValue);\n      }\n    }\n  }\n\n  public static dontSaveDefaultValues: boolean = true;\n\n  public WriteJson(writer: SimpleJson.Writer) {\n    writer.WriteObjectStart();\n    for (let [keyValKey, keyValValue] of this._globalVariables) {\n      let name = keyValKey;\n      let val = keyValValue;\n\n      if (VariablesState.dontSaveDefaultValues) {\n        if (this._defaultGlobalVariables.has(name)) {\n          let defaultVal = this._defaultGlobalVariables.get(name)!;\n          if (this.RuntimeObjectsEqual(val, defaultVal)) continue;\n        }\n      }\n\n      writer.WritePropertyStart(name);\n      JsonSerialisation.WriteRuntimeObject(writer, val);\n      writer.WritePropertyEnd();\n    }\n    writer.WriteObjectEnd();\n  }\n\n  public RuntimeObjectsEqual(\n    obj1: InkObject | null,\n    obj2: InkObject | null\n  ): boolean {\n    if (obj1 === null) {\n      return throwNullException(\"obj1\");\n    }\n    if (obj2 === null) {\n      return throwNullException(\"obj2\");\n    }\n\n    if (obj1.constructor !== obj2.constructor) return false;\n\n    let boolVal = asOrNull(obj1, BoolValue);\n    if (boolVal !== null) {\n      return boolVal.value === asOrThrows(obj2, BoolValue).value;\n    }\n\n    let intVal = asOrNull(obj1, IntValue);\n    if (intVal !== null) {\n      return intVal.value === asOrThrows(obj2, IntValue).value;\n    }\n\n    let floatVal = asOrNull(obj1, FloatValue);\n    if (floatVal !== null) {\n      return floatVal.value === asOrThrows(obj2, FloatValue).value;\n    }\n\n    let val1 = asOrNull(obj1, Value);\n    let val2 = asOrNull(obj2, Value);\n    if (val1 !== null && val2 !== null) {\n      if (isEquatable(val1.valueObject) && isEquatable(val2.valueObject)) {\n        return val1.valueObject.Equals(val2.valueObject);\n      } else {\n        return val1.valueObject === val2.valueObject;\n      }\n    }\n\n    throw new Error(\n      \"FastRoughDefinitelyEquals: Unsupported runtime object type: \" +\n        obj1.constructor.name\n    );\n  }\n\n  public GetVariableWithName(\n    name: string | null,\n    contextIndex: number = -1\n  ): InkObject | null {\n    let varValue = this.GetRawVariableWithName(name, contextIndex);\n\n    // var varPointer = varValue as VariablePointerValue;\n    let varPointer = asOrNull(varValue, VariablePointerValue);\n    if (varPointer !== null) {\n      varValue = this.ValueAtVariablePointer(varPointer);\n    }\n\n    return varValue;\n  }\n\n  public TryGetDefaultVariableValue(name: string | null): InkObject | null {\n    let val = tryGetValueFromMap(this._defaultGlobalVariables, name, null);\n    return val.exists ? val.result : null;\n  }\n\n  public GlobalVariableExistsWithName(name: string) {\n    return (\n      this._globalVariables.has(name) ||\n      (this._defaultGlobalVariables !== null &&\n        this._defaultGlobalVariables.has(name))\n    );\n  }\n\n  public GetRawVariableWithName(name: string | null, contextIndex: number) {\n    let varValue: InkObject | null = null;\n\n    if (contextIndex == 0 || contextIndex == -1) {\n      let variableValue = null;\n      if (this.patch !== null) {\n        variableValue = this.patch.TryGetGlobal(name, null);\n        if (variableValue.exists) return variableValue.result!;\n      }\n\n      // this is a conditional assignment\n      variableValue = tryGetValueFromMap(this._globalVariables, name, null);\n      if (variableValue.exists) return variableValue.result;\n\n      if (this._defaultGlobalVariables !== null) {\n        variableValue = tryGetValueFromMap(\n          this._defaultGlobalVariables,\n          name,\n          null\n        );\n        if (variableValue.exists) return variableValue.result;\n      }\n\n      if (this._listDefsOrigin === null)\n        return throwNullException(\"VariablesState._listDefsOrigin\");\n      let listItemValue = this._listDefsOrigin.FindSingleItemListWithName(name);\n      if (listItemValue) return listItemValue;\n    }\n\n    varValue = this._callStack.GetTemporaryVariableWithName(name, contextIndex);\n\n    return varValue;\n  }\n\n  public ValueAtVariablePointer(pointer: VariablePointerValue) {\n    return this.GetVariableWithName(pointer.variableName, pointer.contextIndex);\n  }\n\n  public Assign(varAss: VariableAssignment, value: InkObject) {\n    let name = varAss.variableName;\n    if (name === null) {\n      return throwNullException(\"name\");\n    }\n    let contextIndex = -1;\n\n    let setGlobal = false;\n    if (varAss.isNewDeclaration) {\n      setGlobal = varAss.isGlobal;\n    } else {\n      setGlobal = this.GlobalVariableExistsWithName(name);\n    }\n\n    if (varAss.isNewDeclaration) {\n      // var varPointer = value as VariablePointerValue;\n      let varPointer = asOrNull(value, VariablePointerValue);\n      if (varPointer !== null) {\n        let fullyResolvedVariablePointer =\n          this.ResolveVariablePointer(varPointer);\n        value = fullyResolvedVariablePointer;\n      }\n    } else {\n      let existingPointer = null;\n      do {\n        // existingPointer = GetRawVariableWithName (name, contextIndex) as VariablePointerValue;\n        existingPointer = asOrNull(\n          this.GetRawVariableWithName(name, contextIndex),\n          VariablePointerValue\n        );\n        if (existingPointer != null) {\n          name = existingPointer.variableName;\n          contextIndex = existingPointer.contextIndex;\n          setGlobal = contextIndex == 0;\n        }\n      } while (existingPointer != null);\n    }\n\n    if (setGlobal) {\n      this.SetGlobal(name, value);\n    } else {\n      this._callStack.SetTemporaryVariable(\n        name,\n        value,\n        varAss.isNewDeclaration,\n        contextIndex\n      );\n    }\n  }\n\n  public SnapshotDefaultGlobals() {\n    this._defaultGlobalVariables = new Map(this._globalVariables);\n  }\n\n  public RetainListOriginsForAssignment(\n    oldValue: InkObject,\n    newValue: InkObject\n  ) {\n    let oldList = asOrThrows(oldValue, ListValue);\n    let newList = asOrThrows(newValue, ListValue);\n\n    if (oldList.value && newList.value && newList.value.Count == 0) {\n      newList.value.SetInitialOriginNames(oldList.value.originNames);\n    }\n  }\n\n  public SetGlobal(variableName: string | null, value: InkObject) {\n    let oldValue = null;\n\n    if (this.patch === null) {\n      oldValue = tryGetValueFromMap(this._globalVariables, variableName, null);\n    }\n\n    if (this.patch !== null) {\n      oldValue = this.patch.TryGetGlobal(variableName, null);\n      if (!oldValue.exists) {\n        oldValue = tryGetValueFromMap(\n          this._globalVariables,\n          variableName,\n          null\n        );\n      }\n    }\n\n    ListValue.RetainListOriginsForAssignment(oldValue!.result!, value);\n\n    if (variableName === null) {\n      return throwNullException(\"variableName\");\n    }\n\n    if (this.patch !== null) {\n      this.patch.SetGlobal(variableName, value);\n    } else {\n      this._globalVariables.set(variableName, value);\n    }\n\n    // TODO: Not sure !== is equivalent to !value.Equals(oldValue)\n    if (\n      this.variableChangedEvent !== null &&\n      oldValue !== null &&\n      value !== oldValue.result\n    ) {\n      if (this._batchObservingVariableChanges) {\n        if (this._changedVariablesForBatchObs === null) {\n          return throwNullException(\"this._changedVariablesForBatchObs\");\n        }\n\n        if (this.patch !== null) {\n          this.patch.AddChangedVariable(variableName);\n        } else if (this._changedVariablesForBatchObs !== null) {\n          this._changedVariablesForBatchObs.add(variableName);\n        }\n      } else {\n        this.variableChangedEvent(variableName, value);\n      }\n    }\n  }\n\n  public ResolveVariablePointer(varPointer: VariablePointerValue) {\n    let contextIndex = varPointer.contextIndex;\n\n    if (contextIndex == -1)\n      contextIndex = this.GetContextIndexOfVariableNamed(\n        varPointer.variableName\n      );\n\n    let valueOfVariablePointedTo = this.GetRawVariableWithName(\n      varPointer.variableName,\n      contextIndex\n    );\n\n    // var doubleRedirectionPointer = valueOfVariablePointedTo as VariablePointerValue;\n    let doubleRedirectionPointer = asOrNull(\n      valueOfVariablePointedTo,\n      VariablePointerValue\n    );\n    if (doubleRedirectionPointer != null) {\n      return doubleRedirectionPointer;\n    } else {\n      return new VariablePointerValue(varPointer.variableName, contextIndex);\n    }\n  }\n\n  public GetContextIndexOfVariableNamed(varName: string) {\n    if (this.GlobalVariableExistsWithName(varName)) return 0;\n\n    return this._callStack.currentElementIndex;\n  }\n\n  /**\n   * This function is specific to the js version of ink. It allows to register a\n   * callback that will be called when a variable changes. The original code uses\n   * `state.variableChangedEvent += callback` instead.\n   *\n   * @param {function} callback\n   */\n  public ObserveVariableChange(\n    callback: (variableName: string, newValue: InkObject) => void\n  ) {\n    this.variableChangedEventCallbacks.push(callback);\n  }\n\n  private _globalVariables: Map<string, InkObject>;\n  private _defaultGlobalVariables: Map<string, InkObject> = new Map();\n\n  private _callStack: CallStack;\n  private _changedVariablesForBatchObs: Set<string> | null = new Set();\n  private _listDefsOrigin: ListDefinitionsOrigin | null;\n\n  private _batchObservingVariableChanges: boolean = false;\n}\n","// Taken from https://gist.github.com/blixt/f17b47c62508be59987b\n// Ink uses a seedable PRNG of which there is none in native javascript.\nexport class PRNG {\n  private seed: number;\n\n  constructor(seed: number) {\n    this.seed = seed % 2147483647;\n    if (this.seed <= 0) this.seed += 2147483646;\n  }\n  public next(): number {\n    return (this.seed = (this.seed * 48271) % 2147483647);\n  }\n  public nextFloat(): number {\n    return (this.next() - 1) / 2147483646;\n  }\n}\n","import { InkObject } from \"./Object\";\nimport { Container } from \"./Container\";\n\nexport class StatePatch {\n  get globals() {\n    return this._globals;\n  }\n  get changedVariables() {\n    return this._changedVariables;\n  }\n  get visitCounts() {\n    return this._visitCounts;\n  }\n  get turnIndices() {\n    return this._turnIndices;\n  }\n\n  constructor();\n  constructor(toCopy: StatePatch | null);\n  constructor() {\n    if (arguments.length === 1 && arguments[0] !== null) {\n      let toCopy = arguments[0] as StatePatch;\n      this._globals = new Map(toCopy._globals);\n      this._changedVariables = new Set(toCopy._changedVariables);\n      this._visitCounts = new Map(toCopy._visitCounts);\n      this._turnIndices = new Map(toCopy._turnIndices);\n    } else {\n      this._globals = new Map();\n      this._changedVariables = new Set();\n      this._visitCounts = new Map();\n      this._turnIndices = new Map();\n    }\n  }\n\n  public TryGetGlobal(name: string | null, /* out */ value: InkObject | null) {\n    if (name !== null && this._globals.has(name)) {\n      return { result: this._globals.get(name), exists: true };\n    }\n\n    return { result: value, exists: false };\n  }\n\n  public SetGlobal(name: string, value: InkObject) {\n    this._globals.set(name, value);\n  }\n\n  public AddChangedVariable(name: string) {\n    return this._changedVariables.add(name);\n  }\n\n  public TryGetVisitCount(container: Container, /* out */ count: number) {\n    if (this._visitCounts.has(container)) {\n      return { result: this._visitCounts.get(container), exists: true };\n    }\n\n    return { result: count, exists: false };\n  }\n\n  public SetVisitCount(container: Container, count: number) {\n    this._visitCounts.set(container, count);\n  }\n\n  public SetTurnIndex(container: Container, index: number) {\n    this._turnIndices.set(container, index);\n  }\n\n  public TryGetTurnIndex(container: Container, /* out */ index: number) {\n    if (this._turnIndices.has(container)) {\n      return { result: this._turnIndices.get(container), exists: true };\n    }\n\n    return { result: index, exists: false };\n  }\n\n  private _globals: Map<string, InkObject>;\n  private _changedVariables: Set<string> = new Set();\n  private _visitCounts: Map<Container, number> = new Map();\n  private _turnIndices: Map<Container, number> = new Map();\n}\n","export class SimpleJson {\n  public static TextToDictionary(text: string) {\n    return new SimpleJson.Reader(text).ToDictionary();\n  }\n\n  public static TextToArray(text: string) {\n    return new SimpleJson.Reader(text).ToArray();\n  }\n}\n\nexport namespace SimpleJson {\n  export class Reader {\n    constructor(text: string) {\n      // Before parsing the JSON, all floats of the form \"123.0\" are transformed into \"123.0f\"\n      // so that they are recognized as FLOAT in the ink runtime\n      const nativeFloatParsing = JSON.parse(\n        \"0\",\n        // @ts-expect-error : typing\n        (_, __, context) => context != null\n      );\n\n      if (!nativeFloatParsing) {\n        // When the nativeFloatParsing argument is false,\n        // we aggressively replace using a regexp\n        // At time of writing : only happen for Safari iOS and Mac\n        const jsonWithExplicitFloat = text.replace(\n          /(,\\s*)([0-9]+\\.[0]+)([,]*)/g,\n          '$1\"$2f\"$3'\n        );\n        this._rootObject = JSON.parse(jsonWithExplicitFloat);\n      } else {\n        // @ts-expect-error : typing\n        const explicitFloatReviver = (_, value, context) => {\n          // When the nativeFloatParsing argument is true,\n          // we use a custom reviver function\n          //see https://github.com/y-lohse/inkjs/pull/1100#issuecomment-2733148441\n          if (Number.isInteger(value) && context.source.endsWith(\".0\")) {\n            return context.source + \"f\";\n          }\n          return value;\n        };\n        // @ts-expect-error : typing\n        this._rootObject = JSON.parse(text, explicitFloatReviver);\n      }\n    }\n\n    public ToDictionary() {\n      return this._rootObject as Record<string, any>;\n    }\n\n    public ToArray() {\n      return this._rootObject as any[];\n    }\n\n    private _rootObject: any[] | Record<string, any>;\n  }\n\n  // In C#, this class writes json tokens directly to a StringWriter or\n  // another stream. Here, a temporary hierarchy is created in the form\n  // of a javascript object, which is serialised in the `toString` method.\n  // See individual methods and properties for more information.\n  export class Writer {\n    public WriteObject(inner: (w: Writer) => void) {\n      this.WriteObjectStart();\n      inner(this);\n      this.WriteObjectEnd();\n    }\n\n    // Add a new object.\n    public WriteObjectStart() {\n      this.StartNewObject(true);\n\n      let newObject: Record<string, any> = {};\n\n      if (this.state === SimpleJson.Writer.State.Property) {\n        // This object is created as the value of a property,\n        // inside an other object.\n        this.Assert(this.currentCollection !== null);\n        this.Assert(this.currentPropertyName !== null);\n\n        let propertyName = this._propertyNameStack.pop();\n        this.currentCollection![propertyName!] = newObject;\n        this._collectionStack.push(newObject);\n      } else if (this.state === SimpleJson.Writer.State.Array) {\n        // This object is created as the child of an array.\n        this.Assert(this.currentCollection !== null);\n\n        this.currentCollection!.push(newObject);\n        this._collectionStack.push(newObject);\n      } else {\n        // This object is the root object.\n        this.Assert(this.state === SimpleJson.Writer.State.None);\n        this._jsonObject = newObject;\n        this._collectionStack.push(newObject);\n      }\n\n      this._stateStack.push(\n        new SimpleJson.Writer.StateElement(SimpleJson.Writer.State.Object)\n      );\n    }\n\n    public WriteObjectEnd() {\n      this.Assert(this.state === SimpleJson.Writer.State.Object);\n      this._collectionStack.pop();\n      this._stateStack.pop();\n    }\n\n    // Write a property name / value pair to the current object.\n    public WriteProperty(\n      name: any,\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      innerOrContent: ((w: Writer) => void) | string | boolean | null\n    ) {\n      this.WritePropertyStart(name);\n      if (arguments[1] instanceof Function) {\n        let inner = arguments[1];\n        inner(this);\n      } else {\n        let content: string | boolean | null = arguments[1];\n        this.Write(content);\n      }\n      this.WritePropertyEnd();\n    }\n\n    // Int and Float are separate calls, since there both are\n    // numbers in JavaScript, but need to be handled differently.\n\n    public WriteIntProperty(name: any, content: number) {\n      this.WritePropertyStart(name);\n      this.WriteInt(content);\n      this.WritePropertyEnd();\n    }\n\n    public WriteFloatProperty(name: any, content: number) {\n      this.WritePropertyStart(name);\n      this.WriteFloat(content);\n      this.WritePropertyEnd();\n    }\n\n    // Prepare a new property name, which will be use to add the\n    // new object when calling _addToCurrentObject() from a Write\n    // method.\n    public WritePropertyStart(name: any) {\n      this.Assert(this.state === SimpleJson.Writer.State.Object);\n      this._propertyNameStack.push(name);\n\n      this.IncrementChildCount();\n\n      this._stateStack.push(\n        new SimpleJson.Writer.StateElement(SimpleJson.Writer.State.Property)\n      );\n    }\n\n    public WritePropertyEnd() {\n      this.Assert(this.state === SimpleJson.Writer.State.Property);\n      this.Assert(this.childCount === 1);\n      this._stateStack.pop();\n    }\n\n    // Prepare a new property name, except this time, the property name\n    // will be created by concatenating all the strings passed to\n    // WritePropertyNameInner.\n    public WritePropertyNameStart() {\n      this.Assert(this.state === SimpleJson.Writer.State.Object);\n      this.IncrementChildCount();\n\n      this._currentPropertyName = \"\";\n\n      this._stateStack.push(\n        new SimpleJson.Writer.StateElement(SimpleJson.Writer.State.Property)\n      );\n      this._stateStack.push(\n        new SimpleJson.Writer.StateElement(SimpleJson.Writer.State.PropertyName)\n      );\n    }\n\n    public WritePropertyNameEnd() {\n      this.Assert(this.state === SimpleJson.Writer.State.PropertyName);\n      this.Assert(this._currentPropertyName !== null);\n      this._propertyNameStack.push(this._currentPropertyName!);\n      this._currentPropertyName = null;\n      this._stateStack.pop();\n    }\n\n    public WritePropertyNameInner(str: string) {\n      this.Assert(this.state === SimpleJson.Writer.State.PropertyName);\n      this.Assert(this._currentPropertyName !== null);\n      this._currentPropertyName += str;\n    }\n\n    // Add a new array.\n    public WriteArrayStart() {\n      this.StartNewObject(true);\n\n      let newObject: any[] = [];\n\n      if (this.state === SimpleJson.Writer.State.Property) {\n        // This array is created as the value of a property,\n        // inside an object.\n        this.Assert(this.currentCollection !== null);\n        this.Assert(this.currentPropertyName !== null);\n\n        let propertyName = this._propertyNameStack.pop();\n        this.currentCollection![propertyName!] = newObject;\n        this._collectionStack.push(newObject);\n      } else if (this.state === SimpleJson.Writer.State.Array) {\n        // This array is created as the child of another array.\n        this.Assert(this.currentCollection !== null);\n\n        this.currentCollection!.push(newObject);\n        this._collectionStack.push(newObject);\n      } else {\n        // This array is the root object.\n        this.Assert(this.state === SimpleJson.Writer.State.None);\n        this._jsonObject = newObject;\n        this._collectionStack.push(newObject);\n      }\n\n      this._stateStack.push(\n        new SimpleJson.Writer.StateElement(SimpleJson.Writer.State.Array)\n      );\n    }\n\n    public WriteArrayEnd() {\n      this.Assert(this.state === SimpleJson.Writer.State.Array);\n      this._collectionStack.pop();\n      this._stateStack.pop();\n    }\n\n    // Add the value to the appropriate collection (array / object), given the current\n    // context.\n    public Write(\n      value: number | string | boolean | null,\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      escape: boolean = true\n    ) {\n      if (value === null) {\n        console.error(\"Warning: trying to write a null value\");\n        return;\n      }\n\n      this.StartNewObject(false);\n      this._addToCurrentObject(value);\n    }\n\n    public WriteBool(value: boolean | null) {\n      if (value === null) {\n        return;\n      }\n\n      this.StartNewObject(false);\n      this._addToCurrentObject(value);\n    }\n\n    public WriteInt(value: number | null) {\n      if (value === null) {\n        return;\n      }\n\n      this.StartNewObject(false);\n\n      // Math.floor is used as a precaution:\n      //     1. to ensure that the value is written as an integer\n      //        (without a fractional part -> 1 instead of 1.0), even\n      //        though it should be the default behaviour of\n      //        JSON.serialize;\n      //     2. to ensure that if a floating number is passed\n      //        accidentally, it's converted to an integer.\n      //\n      // This guarantees savegame compatibility with the reference\n      // implementation.\n      this._addToCurrentObject(Math.floor(value));\n    }\n\n    // Since JSON doesn't support NaN and Infinity, these values\n    // are converted here.\n    public WriteFloat(value: number | null) {\n      if (value === null) {\n        return;\n      }\n\n      this.StartNewObject(false);\n      if (value == Number.POSITIVE_INFINITY) {\n        this._addToCurrentObject(3.4e38);\n      } else if (value == Number.NEGATIVE_INFINITY) {\n        this._addToCurrentObject(-3.4e38);\n      } else if (isNaN(value)) {\n        this._addToCurrentObject(0.0);\n      } else {\n        this._addToCurrentObject(value);\n      }\n    }\n\n    public WriteNull() {\n      this.StartNewObject(false);\n      this._addToCurrentObject(null);\n    }\n\n    // Prepare a string before adding it to the current collection in\n    // WriteStringEnd(). The string will be a concatenation of all the\n    // strings passed to WriteStringInner.\n    public WriteStringStart() {\n      this.StartNewObject(false);\n      this._currentString = \"\";\n      this._stateStack.push(\n        new SimpleJson.Writer.StateElement(SimpleJson.Writer.State.String)\n      );\n    }\n\n    public WriteStringEnd() {\n      this.Assert(this.state == SimpleJson.Writer.State.String);\n      this._stateStack.pop();\n      this._addToCurrentObject(this._currentString);\n      this._currentString = null;\n    }\n\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    public WriteStringInner(str: string | null, escape: boolean = true) {\n      this.Assert(this.state === SimpleJson.Writer.State.String);\n\n      if (str === null) {\n        console.error(\"Warning: trying to write a null string\");\n        return;\n      }\n\n      this._currentString += str;\n    }\n\n    // Serialise the root object into a JSON string.\n    public toString() {\n      if (this._jsonObject === null) {\n        return \"\";\n      }\n\n      return JSON.stringify(this._jsonObject);\n    }\n\n    // Prepare the state stack when adding new objects / values.\n    private StartNewObject(container: boolean) {\n      if (container) {\n        this.Assert(\n          this.state === SimpleJson.Writer.State.None ||\n            this.state === SimpleJson.Writer.State.Property ||\n            this.state === SimpleJson.Writer.State.Array\n        );\n      } else {\n        this.Assert(\n          this.state === SimpleJson.Writer.State.Property ||\n            this.state === SimpleJson.Writer.State.Array\n        );\n      }\n\n      if (this.state === SimpleJson.Writer.State.Property) {\n        this.Assert(this.childCount === 0);\n      }\n\n      if (\n        this.state === SimpleJson.Writer.State.Array ||\n        this.state === SimpleJson.Writer.State.Property\n      ) {\n        this.IncrementChildCount();\n      }\n    }\n\n    // These getters peek all the different stacks.\n\n    private get state() {\n      if (this._stateStack.length > 0) {\n        return this._stateStack[this._stateStack.length - 1].type;\n      } else {\n        return SimpleJson.Writer.State.None;\n      }\n    }\n\n    private get childCount() {\n      if (this._stateStack.length > 0) {\n        return this._stateStack[this._stateStack.length - 1].childCount;\n      } else {\n        return 0;\n      }\n    }\n\n    private get currentCollection(): Record<string, any> | null {\n      if (this._collectionStack.length > 0) {\n        return this._collectionStack[this._collectionStack.length - 1];\n      } else {\n        return null;\n      }\n    }\n\n    private get currentPropertyName() {\n      if (this._propertyNameStack.length > 0) {\n        return this._propertyNameStack[this._propertyNameStack.length - 1];\n      } else {\n        return null;\n      }\n    }\n\n    private IncrementChildCount() {\n      this.Assert(this._stateStack.length > 0);\n      let currEl = this._stateStack.pop()!;\n      currEl.childCount++;\n      this._stateStack.push(currEl);\n    }\n\n    private Assert(condition: boolean) {\n      if (!condition) throw Error(\"Assert failed while writing JSON\");\n    }\n\n    // This method did not exist in the original C# code. It adds\n    // the given value to the current collection (used by Write methods).\n    private _addToCurrentObject(value: number | string | boolean | null) {\n      this.Assert(this.currentCollection !== null);\n      if (this.state === SimpleJson.Writer.State.Array) {\n        this.Assert(Array.isArray(this.currentCollection));\n        (this.currentCollection as any[]).push(value);\n      } else if (this.state === SimpleJson.Writer.State.Property) {\n        this.Assert(!Array.isArray(this.currentCollection));\n        this.Assert(this.currentPropertyName !== null);\n        (this.currentCollection as Record<string, any>)[\n          this.currentPropertyName!\n        ] = value;\n        this._propertyNameStack.pop();\n      }\n    }\n\n    // In addition to `_stateStack` present in the original code,\n    // this implementation of SimpleJson use two other stacks and two\n    // temporary variables holding the current context.\n\n    // Used to keep track of the current property name being built\n    // with `WritePropertyNameStart`, `WritePropertyNameInner` and\n    // `WritePropertyNameEnd`.\n    private _currentPropertyName: string | null = null;\n\n    // Used to keep track of the current string value being built\n    // with `WriteStringStart`, `WriteStringInner` and\n    // `WriteStringEnd`.\n    private _currentString: string | null = null;\n\n    private _stateStack: SimpleJson.Writer.StateElement[] = [];\n\n    // Keep track of the current collection being built (either an array\n    // or an object). For instance, at the '?' step during the hiarchy\n    // creation, this hierarchy:\n    // [3, {a: [b, ?]}] will have this corresponding stack:\n    // (bottom) [Array, Object, Array] (top)\n    private _collectionStack: Array<any[] | Record<string, any>> = [];\n\n    // Keep track of the current property being assigned. For instance, at\n    // the '?' step during the hiarchy creation, this hierarchy:\n    // [3, {a: [b, {c: ?}]}] will have this corresponding stack:\n    // (bottom) [a, c] (top)\n    private _propertyNameStack: string[] = [];\n\n    // Object containing the entire hiearchy.\n    private _jsonObject: Record<string, any> | any[] | null = null;\n  }\n\n  export namespace Writer {\n    export enum State {\n      None,\n      Object,\n      Array,\n      Property,\n      PropertyName,\n      String,\n    }\n\n    export class StateElement {\n      public type: SimpleJson.Writer.State = SimpleJson.Writer.State.None;\n      public childCount: number = 0;\n\n      constructor(type: SimpleJson.Writer.State) {\n        this.type = type;\n      }\n    }\n  }\n}\n","import { CallStack } from \"./CallStack\";\nimport { Choice } from \"./Choice\";\nimport { JsonSerialisation } from \"./JsonSerialisation\";\nimport { InkObject } from \"./Object\";\nimport { SimpleJson } from \"./SimpleJson\";\nimport { Story } from \"./Story\";\nimport { throwNullException } from \"./NullException\";\n\nexport class Flow {\n  public name: string;\n  public callStack: CallStack;\n  public outputStream: InkObject[];\n  public currentChoices: Choice[];\n\n  constructor(name: String, story: Story);\n  constructor(name: String, story: Story, jObject: Record<string, any>);\n  constructor() {\n    let name = arguments[0] as string;\n    let story = arguments[1] as Story;\n\n    this.name = name;\n    this.callStack = new CallStack(story);\n\n    if (arguments[2]) {\n      let jObject = arguments[2] as Record<string, any>;\n\n      this.callStack.SetJsonToken(jObject[\"callstack\"], story);\n      this.outputStream = JsonSerialisation.JArrayToRuntimeObjList(\n        jObject[\"outputStream\"]\n      );\n      this.currentChoices = JsonSerialisation.JArrayToRuntimeObjList(\n        jObject[\"currentChoices\"]\n      ) as Choice[];\n\n      let jChoiceThreadsObj = jObject[\"choiceThreads\"];\n      if (typeof jChoiceThreadsObj !== \"undefined\") {\n        this.LoadFlowChoiceThreads(jChoiceThreadsObj, story);\n      }\n    } else {\n      this.outputStream = [];\n      this.currentChoices = [];\n    }\n  }\n\n  public WriteJson(writer: SimpleJson.Writer) {\n    writer.WriteObjectStart();\n\n    writer.WriteProperty(\"callstack\", (w) => this.callStack.WriteJson(w));\n    writer.WriteProperty(\"outputStream\", (w) =>\n      JsonSerialisation.WriteListRuntimeObjs(w, this.outputStream)\n    );\n\n    let hasChoiceThreads = false;\n    for (let c of this.currentChoices) {\n      if (c.threadAtGeneration === null)\n        return throwNullException(\"c.threadAtGeneration\");\n\n      c.originalThreadIndex = c.threadAtGeneration.threadIndex;\n\n      if (this.callStack.ThreadWithIndex(c.originalThreadIndex) === null) {\n        if (!hasChoiceThreads) {\n          hasChoiceThreads = true;\n          writer.WritePropertyStart(\"choiceThreads\");\n          writer.WriteObjectStart();\n        }\n\n        writer.WritePropertyStart(c.originalThreadIndex);\n        c.threadAtGeneration.WriteJson(writer);\n        writer.WritePropertyEnd();\n      }\n    }\n\n    if (hasChoiceThreads) {\n      writer.WriteObjectEnd();\n      writer.WritePropertyEnd();\n    }\n\n    writer.WriteProperty(\"currentChoices\", (w) => {\n      w.WriteArrayStart();\n      for (let c of this.currentChoices) {\n        JsonSerialisation.WriteChoice(w, c);\n      }\n      w.WriteArrayEnd();\n    });\n\n    writer.WriteObjectEnd();\n  }\n\n  public LoadFlowChoiceThreads(\n    jChoiceThreads: Record<string, any>,\n    story: Story\n  ) {\n    for (let choice of this.currentChoices) {\n      let foundActiveThread = this.callStack.ThreadWithIndex(\n        choice.originalThreadIndex\n      );\n      if (foundActiveThread !== null) {\n        choice.threadAtGeneration = foundActiveThread.Copy();\n      } else {\n        let jSavedChoiceThread =\n          jChoiceThreads[`${choice.originalThreadIndex}`];\n        choice.threadAtGeneration = new CallStack.Thread(\n          jSavedChoiceThread,\n          story\n        );\n      }\n    }\n  }\n}\n","import { CallStack } from \"./CallStack\";\nimport { VariablesState } from \"./VariablesState\";\nimport { ValueType, Value, StringValue, ListValue } from \"./Value\";\nimport { PushPopType } from \"./PushPop\";\nimport { Tag } from \"./Tag\";\nimport { Glue } from \"./Glue\";\nimport { Path } from \"./Path\";\nimport { ControlCommand } from \"./ControlCommand\";\nimport { StringBuilder } from \"./StringBuilder\";\nimport { JsonSerialisation } from \"./JsonSerialisation\";\nimport { PRNG } from \"./PRNG\";\nimport { Void } from \"./Void\";\nimport { Pointer } from \"./Pointer\";\nimport { tryGetValueFromMap } from \"./TryGetResult\";\nimport { Choice } from \"./Choice\";\nimport { asOrNull, asOrThrows, nullIfUndefined } from \"./TypeAssertion\";\nimport { Debug } from \"./Debug\";\nimport { Container } from \"./Container\";\nimport { InkObject } from \"./Object\";\nimport { throwNullException } from \"./NullException\";\nimport { Story } from \"./Story\";\nimport { StatePatch } from \"./StatePatch\";\nimport { SimpleJson } from \"./SimpleJson\";\nimport { Flow } from \"./Flow\";\nimport { InkList } from \"./InkList\";\n\nexport class StoryState {\n  // Backward compatible changes since v8:\n  // v10: dynamic tags\n  // v9:  multi-flows\n  public readonly kInkSaveStateVersion = 10;\n  public readonly kMinCompatibleLoadVersion = 8;\n\n  public onDidLoadState: (() => void) | null = null;\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public ToJson(indented: boolean = false) {\n    let writer = new SimpleJson.Writer();\n    this.WriteJson(writer);\n    return writer.toString();\n  }\n  public toJson(indented: boolean = false) {\n    return this.ToJson(indented);\n  }\n\n  public LoadJson(json: string) {\n    let jObject = SimpleJson.TextToDictionary(json);\n    this.LoadJsonObj(jObject);\n    if (this.onDidLoadState !== null) this.onDidLoadState();\n  }\n\n  public VisitCountAtPathString(pathString: string) {\n    let visitCountOut;\n\n    if (this._patch !== null) {\n      let container = this.story.ContentAtPath(new Path(pathString)).container;\n      if (container === null)\n        throw new Error(\"Content at path not found: \" + pathString);\n\n      visitCountOut = this._patch.TryGetVisitCount(container, 0);\n      if (visitCountOut.exists) return visitCountOut.result;\n    }\n\n    visitCountOut = tryGetValueFromMap(this._visitCounts, pathString, null);\n    if (visitCountOut.exists) return visitCountOut.result;\n\n    return 0;\n  }\n\n  public VisitCountForContainer(container: Container | null): number {\n    if (container === null) {\n      return throwNullException(\"container\");\n    }\n    if (!container.visitsShouldBeCounted) {\n      this.story.Error(\n        \"Read count for target (\" +\n          container.name +\n          \" - on \" +\n          container.debugMetadata +\n          \") unknown. The story may need to be compiled with countAllVisits flag (-c).\"\n      );\n      return 0;\n    }\n\n    if (this._patch !== null) {\n      let count = this._patch.TryGetVisitCount(container, 0);\n      if (count.exists) {\n        return count.result!;\n      }\n    }\n\n    let containerPathStr = container.path.toString();\n    let count2 = tryGetValueFromMap(this._visitCounts, containerPathStr, null);\n    if (count2.exists) {\n      return count2.result!;\n    }\n\n    return 0;\n  }\n\n  public IncrementVisitCountForContainer(container: Container) {\n    if (this._patch !== null) {\n      let currCount = this.VisitCountForContainer(container);\n      currCount++;\n      this._patch.SetVisitCount(container, currCount);\n      return;\n    }\n\n    let containerPathStr = container.path.toString();\n    let count = tryGetValueFromMap(this._visitCounts, containerPathStr, null);\n    if (count.exists) {\n      this._visitCounts.set(containerPathStr, count.result! + 1);\n    } else {\n      this._visitCounts.set(containerPathStr, 1);\n    }\n  }\n\n  public RecordTurnIndexVisitToContainer(container: Container) {\n    if (this._patch !== null) {\n      this._patch.SetTurnIndex(container, this.currentTurnIndex);\n      return;\n    }\n\n    let containerPathStr = container.path.toString();\n    this._turnIndices.set(containerPathStr, this.currentTurnIndex);\n  }\n\n  public TurnsSinceForContainer(container: Container) {\n    if (!container.turnIndexShouldBeCounted) {\n      this.story.Error(\n        \"TURNS_SINCE() for target (\" +\n          container.name +\n          \" - on \" +\n          container.debugMetadata +\n          \") unknown. The story may need to be compiled with countAllVisits flag (-c).\"\n      );\n    }\n\n    if (this._patch !== null) {\n      let index = this._patch.TryGetTurnIndex(container, 0);\n      if (index.exists) {\n        return this.currentTurnIndex - index.result!;\n      }\n    }\n\n    let containerPathStr = container.path.toString();\n    let index2 = tryGetValueFromMap(this._turnIndices, containerPathStr, 0);\n    if (index2.exists) {\n      return this.currentTurnIndex - index2.result!;\n    } else {\n      return -1;\n    }\n  }\n\n  get callstackDepth() {\n    return this.callStack.depth;\n  }\n\n  get outputStream() {\n    return this._currentFlow.outputStream;\n  }\n\n  get currentChoices() {\n    // If we can continue generating text content rather than choices,\n    // then we reflect the choice list as being empty, since choices\n    // should always come at the end.\n    if (this.canContinue) return [];\n    return this._currentFlow.currentChoices;\n  }\n\n  get generatedChoices() {\n    return this._currentFlow.currentChoices;\n  }\n\n  get currentErrors() {\n    return this._currentErrors;\n  }\n  private _currentErrors: string[] | null = null;\n\n  get currentWarnings() {\n    return this._currentWarnings;\n  }\n  private _currentWarnings: string[] | null = null;\n\n  get variablesState() {\n    return this._variablesState;\n  }\n  set variablesState(value) {\n    this._variablesState = value;\n  }\n  private _variablesState: VariablesState;\n\n  get callStack() {\n    return this._currentFlow.callStack;\n  }\n\n  get evaluationStack() {\n    return this._evaluationStack;\n  }\n  private _evaluationStack: InkObject[];\n\n  public divertedPointer: Pointer = Pointer.Null;\n\n  get currentTurnIndex() {\n    return this._currentTurnIndex;\n  }\n  set currentTurnIndex(value) {\n    this._currentTurnIndex = value;\n  }\n  private _currentTurnIndex: number = 0;\n\n  public storySeed: number = 0;\n  public previousRandom: number = 0;\n  public didSafeExit: boolean = false;\n\n  public story: Story;\n\n  get currentPathString() {\n    let pointer = this.currentPointer;\n    if (pointer.isNull) {\n      return null;\n    } else {\n      if (pointer.path === null) {\n        return throwNullException(\"pointer.path\");\n      }\n      return pointer.path.toString();\n    }\n  }\n\n  get previousPathString() {\n    let pointer = this.previousPointer;\n    if (pointer.isNull) {\n      return null;\n    } else {\n      if (pointer.path === null) {\n        return throwNullException(\"previousPointer.path\");\n      }\n      return pointer.path.toString();\n    }\n  }\n\n  get currentPointer() {\n    return this.callStack.currentElement.currentPointer.copy();\n  }\n\n  set currentPointer(value) {\n    this.callStack.currentElement.currentPointer = value.copy();\n  }\n\n  get previousPointer() {\n    return this.callStack.currentThread.previousPointer.copy();\n  }\n\n  set previousPointer(value) {\n    this.callStack.currentThread.previousPointer = value.copy();\n  }\n\n  get canContinue() {\n    return !this.currentPointer.isNull && !this.hasError;\n  }\n\n  get hasError() {\n    return this.currentErrors != null && this.currentErrors.length > 0;\n  }\n\n  get hasWarning() {\n    return this.currentWarnings != null && this.currentWarnings.length > 0;\n  }\n\n  get currentText() {\n    if (this._outputStreamTextDirty) {\n      let sb = new StringBuilder();\n\n      let inTag: boolean = false;\n\n      for (let outputObj of this.outputStream) {\n        // var textContent = outputObj as StringValue;\n        let textContent = asOrNull(outputObj, StringValue);\n        if (!inTag && textContent !== null) {\n          sb.Append(textContent.value);\n        } else {\n          let controlCommand = asOrNull(outputObj, ControlCommand);\n          if (controlCommand !== null) {\n            if (\n              controlCommand.commandType == ControlCommand.CommandType.BeginTag\n            ) {\n              inTag = true;\n            } else if (\n              controlCommand.commandType == ControlCommand.CommandType.EndTag\n            ) {\n              inTag = false;\n            }\n          }\n        }\n      }\n\n      this._currentText = this.CleanOutputWhitespace(sb.toString());\n      this._outputStreamTextDirty = false;\n    }\n\n    return this._currentText;\n  }\n  private _currentText: string | null = null;\n\n  public CleanOutputWhitespace(str: string) {\n    let sb = new StringBuilder();\n\n    let currentWhitespaceStart = -1;\n    let startOfLine = 0;\n\n    for (let i = 0; i < str.length; i++) {\n      let c = str.charAt(i);\n\n      let isInlineWhitespace = c == \" \" || c == \"\\t\";\n\n      if (isInlineWhitespace && currentWhitespaceStart == -1)\n        currentWhitespaceStart = i;\n\n      if (!isInlineWhitespace) {\n        if (\n          c != \"\\n\" &&\n          currentWhitespaceStart > 0 &&\n          currentWhitespaceStart != startOfLine\n        ) {\n          sb.Append(\" \");\n        }\n        currentWhitespaceStart = -1;\n      }\n\n      if (c == \"\\n\") startOfLine = i + 1;\n\n      if (!isInlineWhitespace) sb.Append(c);\n    }\n\n    return sb.toString();\n  }\n\n  get currentTags() {\n    if (this._outputStreamTagsDirty) {\n      this._currentTags = [];\n      let inTag: boolean = false;\n      let sb = new StringBuilder();\n\n      for (let outputObj of this.outputStream) {\n        let controlCommand = asOrNull(outputObj, ControlCommand);\n        if (controlCommand != null) {\n          if (\n            controlCommand.commandType == ControlCommand.CommandType.BeginTag\n          ) {\n            if (inTag && sb.Length > 0) {\n              let txt = this.CleanOutputWhitespace(sb.toString());\n              this._currentTags.push(txt);\n              sb.Clear();\n            }\n            inTag = true;\n          } else if (\n            controlCommand.commandType == ControlCommand.CommandType.EndTag\n          ) {\n            if (sb.Length > 0) {\n              let txt = this.CleanOutputWhitespace(sb.toString());\n              this._currentTags.push(txt);\n              sb.Clear();\n            }\n            inTag = false;\n          }\n        } else if (inTag) {\n          let strVal = asOrNull(outputObj, StringValue);\n          if (strVal !== null) {\n            sb.Append(strVal.value);\n          }\n        } else {\n          let tag = asOrNull(outputObj, Tag);\n          if (tag != null && tag.text != null && tag.text.length > 0) {\n            this._currentTags.push(tag.text); // tag.text has whitespae already cleaned\n          }\n        }\n      }\n\n      if (sb.Length > 0) {\n        let txt = this.CleanOutputWhitespace(sb.toString());\n        this._currentTags.push(txt);\n        sb.Clear();\n      }\n\n      this._outputStreamTagsDirty = false;\n    }\n\n    return this._currentTags;\n  }\n  private _currentTags: string[] | null = null;\n\n  get currentFlowName() {\n    return this._currentFlow.name;\n  }\n\n  get currentFlowIsDefaultFlow() {\n    return this._currentFlow.name == this.kDefaultFlowName;\n  }\n\n  get aliveFlowNames() {\n    if (this._aliveFlowNamesDirty) {\n      this._aliveFlowNames = [];\n\n      if (this._namedFlows != null) {\n        for (let flowName of this._namedFlows.keys()) {\n          if (flowName != this.kDefaultFlowName) {\n            this._aliveFlowNames.push(flowName);\n          }\n        }\n      }\n\n      this._aliveFlowNamesDirty = false;\n    }\n\n    return this._aliveFlowNames;\n  }\n\n  get inExpressionEvaluation() {\n    return this.callStack.currentElement.inExpressionEvaluation;\n  }\n  set inExpressionEvaluation(value) {\n    this.callStack.currentElement.inExpressionEvaluation = value;\n  }\n\n  constructor(story: Story) {\n    this.story = story;\n\n    this._currentFlow = new Flow(this.kDefaultFlowName, story);\n    this.OutputStreamDirty();\n\n    this._aliveFlowNamesDirty = true;\n    this._evaluationStack = [];\n\n    this._variablesState = new VariablesState(\n      this.callStack,\n      story.listDefinitions\n    );\n\n    this._visitCounts = new Map();\n    this._turnIndices = new Map();\n    this.currentTurnIndex = -1;\n\n    let timeSeed = new Date().getTime();\n    this.storySeed = new PRNG(timeSeed).next() % 100;\n    this.previousRandom = 0;\n\n    this.GoToStart();\n  }\n\n  public GoToStart() {\n    this.callStack.currentElement.currentPointer = Pointer.StartOf(\n      this.story.mainContentContainer\n    );\n  }\n\n  public SwitchFlow_Internal(flowName: string | null) {\n    if (flowName === null)\n      throw new Error(\"Must pass a non-null string to Story.SwitchFlow\");\n\n    if (this._namedFlows === null) {\n      this._namedFlows = new Map();\n      this._namedFlows.set(this.kDefaultFlowName, this._currentFlow);\n    }\n\n    if (flowName === this._currentFlow.name) {\n      return;\n    }\n\n    let flow: Flow;\n    let content = tryGetValueFromMap(this._namedFlows, flowName, null);\n    if (content.exists) {\n      flow = content.result!;\n    } else {\n      flow = new Flow(flowName, this.story);\n      this._namedFlows.set(flowName, flow);\n      this._aliveFlowNamesDirty = true;\n    }\n\n    this._currentFlow = flow;\n    this.variablesState.callStack = this._currentFlow.callStack;\n\n    this.OutputStreamDirty();\n  }\n\n  public SwitchToDefaultFlow_Internal() {\n    if (this._namedFlows === null) return;\n    this.SwitchFlow_Internal(this.kDefaultFlowName);\n  }\n\n  public RemoveFlow_Internal(flowName: string | null) {\n    if (flowName === null)\n      throw new Error(\"Must pass a non-null string to Story.DestroyFlow\");\n    if (flowName === this.kDefaultFlowName)\n      throw new Error(\"Cannot destroy default flow\");\n\n    if (this._currentFlow.name === flowName) {\n      this.SwitchToDefaultFlow_Internal();\n    }\n\n    if (this._namedFlows === null)\n      return throwNullException(\"this._namedFlows\");\n    this._namedFlows.delete(flowName);\n    this._aliveFlowNamesDirty = true;\n  }\n\n  public CopyAndStartPatching(forBackgroundSave: boolean) {\n    let copy = new StoryState(this.story);\n\n    copy._patch = new StatePatch(this._patch);\n\n    copy._currentFlow.name = this._currentFlow.name;\n    copy._currentFlow.callStack = new CallStack(this._currentFlow.callStack);\n    copy._currentFlow.outputStream.push(...this._currentFlow.outputStream);\n    copy.OutputStreamDirty();\n\n    // When background saving we need to make copies of choices since they each have\n    // a snapshot of the thread at the time of generation since the game could progress\n    // significantly and threads modified during the save process.\n    // However, when doing internal saving and restoring of snapshots this isn't an issue,\n    // and we can simply ref-copy the choices with their existing threads.\n\n    if (forBackgroundSave) {\n      for (let choice of this._currentFlow.currentChoices) {\n        copy._currentFlow.currentChoices.push(choice.Clone());\n      }\n    } else {\n      copy._currentFlow.currentChoices.push(\n        ...this._currentFlow.currentChoices\n      );\n    }\n\n    if (this._namedFlows !== null) {\n      copy._namedFlows = new Map();\n      for (let [namedFlowKey, namedFlowValue] of this._namedFlows) {\n        copy._namedFlows.set(namedFlowKey, namedFlowValue);\n        copy._aliveFlowNamesDirty = true;\n      }\n      copy._namedFlows.set(this._currentFlow.name, copy._currentFlow);\n    }\n\n    if (this.hasError) {\n      copy._currentErrors = [];\n      copy._currentErrors.push(...(this.currentErrors || []));\n    }\n\n    if (this.hasWarning) {\n      copy._currentWarnings = [];\n      copy._currentWarnings.push(...(this.currentWarnings || []));\n    }\n\n    copy.variablesState = this.variablesState;\n    copy.variablesState.callStack = copy.callStack;\n    copy.variablesState.patch = copy._patch;\n\n    copy.evaluationStack.push(...this.evaluationStack);\n\n    if (!this.divertedPointer.isNull)\n      copy.divertedPointer = this.divertedPointer.copy();\n\n    copy.previousPointer = this.previousPointer.copy();\n\n    copy._visitCounts = this._visitCounts;\n    copy._turnIndices = this._turnIndices;\n\n    copy.currentTurnIndex = this.currentTurnIndex;\n    copy.storySeed = this.storySeed;\n    copy.previousRandom = this.previousRandom;\n\n    copy.didSafeExit = this.didSafeExit;\n\n    return copy;\n  }\n\n  public RestoreAfterPatch() {\n    this.variablesState.callStack = this.callStack;\n    this.variablesState.patch = this._patch;\n  }\n\n  public ApplyAnyPatch() {\n    if (this._patch === null) return;\n\n    this.variablesState.ApplyPatch();\n\n    for (let [key, value] of this._patch.visitCounts)\n      this.ApplyCountChanges(key, value, true);\n\n    for (let [key, value] of this._patch.turnIndices)\n      this.ApplyCountChanges(key, value, false);\n\n    this._patch = null;\n  }\n\n  public ApplyCountChanges(\n    container: Container,\n    newCount: number,\n    isVisit: boolean\n  ) {\n    let counts = isVisit ? this._visitCounts : this._turnIndices;\n    counts.set(container.path.toString(), newCount);\n  }\n\n  public WriteJson(writer: SimpleJson.Writer) {\n    writer.WriteObjectStart();\n\n    writer.WritePropertyStart(\"flows\");\n    writer.WriteObjectStart();\n\n    // NOTE: Never pass `WriteJson` directly as an argument to `WriteProperty`.\n    // Call it inside a function to make sure `this` is correctly bound\n    // and passed down the call hierarchy.\n\n    if (this._namedFlows !== null) {\n      for (let [namedFlowKey, namedFlowValue] of this._namedFlows) {\n        writer.WriteProperty(namedFlowKey, (w) => namedFlowValue.WriteJson(w));\n      }\n    } else {\n      writer.WriteProperty(this._currentFlow.name, (w) =>\n        this._currentFlow.WriteJson(w)\n      );\n    }\n\n    writer.WriteObjectEnd();\n    writer.WritePropertyEnd();\n\n    writer.WriteProperty(\"currentFlowName\", this._currentFlow.name);\n\n    writer.WriteProperty(\"variablesState\", (w) =>\n      this.variablesState.WriteJson(w)\n    );\n\n    writer.WriteProperty(\"evalStack\", (w) =>\n      JsonSerialisation.WriteListRuntimeObjs(w, this.evaluationStack)\n    );\n\n    if (!this.divertedPointer.isNull) {\n      if (this.divertedPointer.path === null) {\n        return throwNullException(\"divertedPointer\");\n      }\n      writer.WriteProperty(\n        \"currentDivertTarget\",\n        this.divertedPointer.path.componentsString\n      );\n    }\n\n    writer.WriteProperty(\"visitCounts\", (w) =>\n      JsonSerialisation.WriteIntDictionary(w, this._visitCounts)\n    );\n    writer.WriteProperty(\"turnIndices\", (w) =>\n      JsonSerialisation.WriteIntDictionary(w, this._turnIndices)\n    );\n\n    writer.WriteIntProperty(\"turnIdx\", this.currentTurnIndex);\n    writer.WriteIntProperty(\"storySeed\", this.storySeed);\n    writer.WriteIntProperty(\"previousRandom\", this.previousRandom);\n\n    writer.WriteIntProperty(\"inkSaveVersion\", this.kInkSaveStateVersion);\n\n    writer.WriteIntProperty(\"inkFormatVersion\", Story.inkVersionCurrent);\n\n    writer.WriteObjectEnd();\n  }\n\n  public LoadJsonObj(value: Record<string, any>) {\n    let jObject = value;\n\n    let jSaveVersion = jObject[\"inkSaveVersion\"];\n    if (jSaveVersion == null) {\n      throw new Error(\"ink save format incorrect, can't load.\");\n    } else if (parseInt(jSaveVersion) < this.kMinCompatibleLoadVersion) {\n      throw new Error(\n        \"Ink save format isn't compatible with the current version (saw '\" +\n          jSaveVersion +\n          \"', but minimum is \" +\n          this.kMinCompatibleLoadVersion +\n          \"), so can't load.\"\n      );\n    }\n\n    let flowsObj = jObject[\"flows\"];\n    if (flowsObj != null) {\n      let flowsObjDict = flowsObj as Record<string, any>;\n\n      // Single default flow\n      if (Object.keys(flowsObjDict).length === 1) {\n        this._namedFlows = null;\n      } else if (this._namedFlows === null) {\n        this._namedFlows = new Map();\n      } else {\n        this._namedFlows.clear();\n      }\n\n      let flowsObjDictEntries = Object.entries(flowsObjDict);\n      for (let [namedFlowObjKey, namedFlowObjValue] of flowsObjDictEntries) {\n        let name = namedFlowObjKey;\n        let flowObj = namedFlowObjValue as Record<string, any>;\n\n        let flow = new Flow(name, this.story, flowObj);\n\n        if (Object.keys(flowsObjDict).length === 1) {\n          this._currentFlow = new Flow(name, this.story, flowObj);\n        } else {\n          if (this._namedFlows === null)\n            return throwNullException(\"this._namedFlows\");\n          this._namedFlows.set(name, flow);\n        }\n      }\n\n      if (this._namedFlows != null && this._namedFlows.size > 1) {\n        let currFlowName = jObject[\"currentFlowName\"] as string;\n        // Adding a bang at the end, because we're trusting the save, as\n        // done in upstream.  If the save is corrupted, the execution\n        // is undefined.\n        this._currentFlow = this._namedFlows.get(currFlowName)!;\n      }\n    } else {\n      this._namedFlows = null;\n      this._currentFlow.name = this.kDefaultFlowName;\n      this._currentFlow.callStack.SetJsonToken(\n        jObject[\"callstackThreads\"] as Record<string, any>,\n        this.story\n      );\n      this._currentFlow.outputStream = JsonSerialisation.JArrayToRuntimeObjList(\n        jObject[\"outputStream\"] as any[]\n      );\n      this._currentFlow.currentChoices =\n        JsonSerialisation.JArrayToRuntimeObjList(\n          jObject[\"currentChoices\"] as any[]\n        ) as Choice[];\n\n      let jChoiceThreadsObj = jObject[\"choiceThreads\"];\n      this._currentFlow.LoadFlowChoiceThreads(jChoiceThreadsObj, this.story);\n    }\n\n    this.OutputStreamDirty();\n    this._aliveFlowNamesDirty = true;\n\n    this.variablesState.SetJsonToken(jObject[\"variablesState\"]);\n    this.variablesState.callStack = this._currentFlow.callStack;\n\n    this._evaluationStack = JsonSerialisation.JArrayToRuntimeObjList(\n      jObject[\"evalStack\"]\n    );\n\n    let currentDivertTargetPath = jObject[\"currentDivertTarget\"];\n    if (currentDivertTargetPath != null) {\n      let divertPath = new Path(currentDivertTargetPath.toString());\n      this.divertedPointer = this.story.PointerAtPath(divertPath);\n    }\n\n    this._visitCounts = JsonSerialisation.JObjectToIntDictionary(\n      jObject[\"visitCounts\"]\n    );\n    this._turnIndices = JsonSerialisation.JObjectToIntDictionary(\n      jObject[\"turnIndices\"]\n    );\n    this.currentTurnIndex = parseInt(jObject[\"turnIdx\"]);\n    this.storySeed = parseInt(jObject[\"storySeed\"]);\n    this.previousRandom = parseInt(jObject[\"previousRandom\"]);\n  }\n\n  public ResetErrors() {\n    this._currentErrors = null;\n    this._currentWarnings = null;\n  }\n  public ResetOutput(objs: InkObject[] | null = null) {\n    this.outputStream.length = 0;\n    if (objs !== null) this.outputStream.push(...objs);\n    this.OutputStreamDirty();\n  }\n\n  public PushToOutputStream(obj: InkObject | null) {\n    // var text = obj as StringValue;\n    let text = asOrNull(obj, StringValue);\n    if (text !== null) {\n      let listText = this.TrySplittingHeadTailWhitespace(text);\n      if (listText !== null) {\n        for (let textObj of listText) {\n          this.PushToOutputStreamIndividual(textObj);\n        }\n        this.OutputStreamDirty();\n        return;\n      }\n    }\n\n    this.PushToOutputStreamIndividual(obj);\n    this.OutputStreamDirty();\n  }\n\n  public PopFromOutputStream(count: number) {\n    this.outputStream.splice(this.outputStream.length - count, count);\n    this.OutputStreamDirty();\n  }\n\n  public TrySplittingHeadTailWhitespace(single: StringValue) {\n    let str = single.value;\n    if (str === null) {\n      return throwNullException(\"single.value\");\n    }\n\n    let headFirstNewlineIdx = -1;\n    let headLastNewlineIdx = -1;\n    for (let i = 0; i < str.length; i++) {\n      let c = str[i];\n      if (c == \"\\n\") {\n        if (headFirstNewlineIdx == -1) headFirstNewlineIdx = i;\n        headLastNewlineIdx = i;\n      } else if (c == \" \" || c == \"\\t\") continue;\n      else break;\n    }\n\n    let tailLastNewlineIdx = -1;\n    let tailFirstNewlineIdx = -1;\n    for (let i = str.length - 1; i >= 0; i--) {\n      let c = str[i];\n      if (c == \"\\n\") {\n        if (tailLastNewlineIdx == -1) tailLastNewlineIdx = i;\n        tailFirstNewlineIdx = i;\n      } else if (c == \" \" || c == \"\\t\") continue;\n      else break;\n    }\n\n    // No splitting to be done?\n    if (headFirstNewlineIdx == -1 && tailLastNewlineIdx == -1) return null;\n\n    let listTexts: StringValue[] = [];\n    let innerStrStart = 0;\n    let innerStrEnd = str.length;\n\n    if (headFirstNewlineIdx != -1) {\n      if (headFirstNewlineIdx > 0) {\n        let leadingSpaces = new StringValue(\n          str.substring(0, headFirstNewlineIdx)\n        );\n        listTexts.push(leadingSpaces);\n      }\n      listTexts.push(new StringValue(\"\\n\"));\n      innerStrStart = headLastNewlineIdx + 1;\n    }\n\n    if (tailLastNewlineIdx != -1) {\n      innerStrEnd = tailFirstNewlineIdx;\n    }\n\n    if (innerStrEnd > innerStrStart) {\n      let innerStrText = str.substring(innerStrStart, innerStrEnd);\n      listTexts.push(new StringValue(innerStrText));\n    }\n\n    if (tailLastNewlineIdx != -1 && tailFirstNewlineIdx > headLastNewlineIdx) {\n      listTexts.push(new StringValue(\"\\n\"));\n      if (tailLastNewlineIdx < str.length - 1) {\n        let numSpaces = str.length - tailLastNewlineIdx - 1;\n        let trailingSpaces = new StringValue(\n          str.substring(\n            tailLastNewlineIdx + 1,\n            tailLastNewlineIdx + 1 + numSpaces\n          )\n        );\n        listTexts.push(trailingSpaces);\n      }\n    }\n\n    return listTexts;\n  }\n\n  public PushToOutputStreamIndividual(obj: InkObject | null) {\n    let glue = asOrNull(obj, Glue);\n    let text = asOrNull(obj, StringValue);\n\n    let includeInOutput = true;\n\n    if (glue) {\n      this.TrimNewlinesFromOutputStream();\n      includeInOutput = true;\n    } else if (text) {\n      let functionTrimIndex = -1;\n      let currEl = this.callStack.currentElement;\n      if (currEl.type == PushPopType.Function) {\n        functionTrimIndex = currEl.functionStartInOutputStream;\n      }\n\n      let glueTrimIndex = -1;\n      for (let i = this.outputStream.length - 1; i >= 0; i--) {\n        let o = this.outputStream[i];\n        let c = o instanceof ControlCommand ? o : null;\n        let g = o instanceof Glue ? o : null;\n\n        if (g != null) {\n          glueTrimIndex = i;\n          break;\n        } else if (\n          c != null &&\n          c.commandType == ControlCommand.CommandType.BeginString\n        ) {\n          if (i >= functionTrimIndex) {\n            functionTrimIndex = -1;\n          }\n          break;\n        }\n      }\n\n      let trimIndex = -1;\n      if (glueTrimIndex != -1 && functionTrimIndex != -1)\n        trimIndex = Math.min(functionTrimIndex, glueTrimIndex);\n      else if (glueTrimIndex != -1) trimIndex = glueTrimIndex;\n      else trimIndex = functionTrimIndex;\n\n      if (trimIndex != -1) {\n        if (text.isNewline) {\n          includeInOutput = false;\n        } else if (text.isNonWhitespace) {\n          if (glueTrimIndex > -1) this.RemoveExistingGlue();\n\n          if (functionTrimIndex > -1) {\n            let callStackElements = this.callStack.elements;\n            for (let i = callStackElements.length - 1; i >= 0; i--) {\n              let el = callStackElements[i];\n              if (el.type == PushPopType.Function) {\n                el.functionStartInOutputStream = -1;\n              } else {\n                break;\n              }\n            }\n          }\n        }\n      } else if (text.isNewline) {\n        if (this.outputStreamEndsInNewline || !this.outputStreamContainsContent)\n          includeInOutput = false;\n      }\n    }\n\n    if (includeInOutput) {\n      if (obj === null) {\n        return throwNullException(\"obj\");\n      }\n      this.outputStream.push(obj);\n      this.OutputStreamDirty();\n    }\n  }\n\n  public TrimNewlinesFromOutputStream() {\n    let removeWhitespaceFrom = -1;\n\n    let i = this.outputStream.length - 1;\n    while (i >= 0) {\n      let obj = this.outputStream[i];\n      let cmd = asOrNull(obj, ControlCommand);\n      let txt = asOrNull(obj, StringValue);\n\n      if (cmd != null || (txt != null && txt.isNonWhitespace)) {\n        break;\n      } else if (txt != null && txt.isNewline) {\n        removeWhitespaceFrom = i;\n      }\n      i--;\n    }\n\n    // Remove the whitespace\n    if (removeWhitespaceFrom >= 0) {\n      i = removeWhitespaceFrom;\n      while (i < this.outputStream.length) {\n        let text = asOrNull(this.outputStream[i], StringValue);\n        if (text) {\n          this.outputStream.splice(i, 1);\n        } else {\n          i++;\n        }\n      }\n    }\n\n    this.OutputStreamDirty();\n  }\n\n  public RemoveExistingGlue() {\n    for (let i = this.outputStream.length - 1; i >= 0; i--) {\n      let c = this.outputStream[i];\n      if (c instanceof Glue) {\n        this.outputStream.splice(i, 1);\n      } else if (c instanceof ControlCommand) {\n        break;\n      }\n    }\n\n    this.OutputStreamDirty();\n  }\n\n  get outputStreamEndsInNewline() {\n    if (this.outputStream.length > 0) {\n      for (let i = this.outputStream.length - 1; i >= 0; i--) {\n        let obj = this.outputStream[i];\n        if (obj instanceof ControlCommand) break;\n        let text = this.outputStream[i];\n        if (text instanceof StringValue) {\n          if (text.isNewline) return true;\n          else if (text.isNonWhitespace) break;\n        }\n      }\n    }\n\n    return false;\n  }\n\n  get outputStreamContainsContent() {\n    for (let content of this.outputStream) {\n      if (content instanceof StringValue) return true;\n    }\n    return false;\n  }\n\n  get inStringEvaluation() {\n    for (let i = this.outputStream.length - 1; i >= 0; i--) {\n      let cmd = asOrNull(this.outputStream[i], ControlCommand);\n      if (\n        cmd instanceof ControlCommand &&\n        cmd.commandType == ControlCommand.CommandType.BeginString\n      ) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  public PushEvaluationStack(obj: InkObject | null) {\n    // var listValue = obj as ListValue;\n    let listValue = asOrNull(obj, ListValue);\n    if (listValue) {\n      // Update origin when list is has something to indicate the list origin\n      let rawList = listValue.value;\n      if (rawList === null) {\n        return throwNullException(\"rawList\");\n      }\n\n      if (rawList.originNames != null) {\n        if (!rawList.origins) rawList.origins = [];\n        rawList.origins.length = 0;\n\n        for (let n of rawList.originNames) {\n          if (this.story.listDefinitions === null)\n            return throwNullException(\"StoryState.story.listDefinitions\");\n          let def = this.story.listDefinitions.TryListGetDefinition(n, null);\n          if (def.result === null)\n            return throwNullException(\"StoryState def.result\");\n          if (rawList.origins.indexOf(def.result) < 0)\n            rawList.origins.push(def.result);\n        }\n      }\n    }\n\n    if (obj === null) {\n      return throwNullException(\"obj\");\n    }\n    this.evaluationStack.push(obj);\n  }\n\n  public PopEvaluationStack(): InkObject;\n  public PopEvaluationStack(numberOfObjects: number): InkObject[];\n  public PopEvaluationStack(numberOfObjects?: number) {\n    if (typeof numberOfObjects === \"undefined\") {\n      let obj = this.evaluationStack.pop();\n      return nullIfUndefined(obj);\n    } else {\n      if (numberOfObjects > this.evaluationStack.length) {\n        throw new Error(\"trying to pop too many objects\");\n      }\n\n      let popped = this.evaluationStack.splice(\n        this.evaluationStack.length - numberOfObjects,\n        numberOfObjects\n      );\n      return nullIfUndefined(popped);\n    }\n  }\n\n  public PeekEvaluationStack() {\n    return this.evaluationStack[this.evaluationStack.length - 1];\n  }\n\n  public ForceEnd() {\n    this.callStack.Reset();\n\n    this._currentFlow.currentChoices.length = 0;\n\n    this.currentPointer = Pointer.Null;\n    this.previousPointer = Pointer.Null;\n\n    this.didSafeExit = true;\n  }\n\n  public TrimWhitespaceFromFunctionEnd() {\n    Debug.Assert(this.callStack.currentElement.type == PushPopType.Function);\n    let functionStartPoint =\n      this.callStack.currentElement.functionStartInOutputStream;\n\n    if (functionStartPoint == -1) {\n      functionStartPoint = 0;\n    }\n\n    for (let i = this.outputStream.length - 1; i >= functionStartPoint; i--) {\n      let obj = this.outputStream[i];\n      let txt = asOrNull(obj, StringValue);\n      let cmd = asOrNull(obj, ControlCommand);\n\n      if (txt == null) continue;\n      if (cmd) break;\n\n      if (txt.isNewline || txt.isInlineWhitespace) {\n        this.outputStream.splice(i, 1);\n        this.OutputStreamDirty();\n      } else {\n        break;\n      }\n    }\n  }\n\n  public PopCallStack(popType: PushPopType | null = null) {\n    if (this.callStack.currentElement.type == PushPopType.Function)\n      this.TrimWhitespaceFromFunctionEnd();\n\n    this.callStack.Pop(popType);\n  }\n\n  public SetChosenPath(path: Path, incrementingTurnIndex: boolean) {\n    // Changing direction, assume we need to clear current set of choices\n    this._currentFlow.currentChoices.length = 0;\n\n    let newPointer = this.story.PointerAtPath(path);\n    if (!newPointer.isNull && newPointer.index == -1) newPointer.index = 0;\n\n    this.currentPointer = newPointer;\n\n    if (incrementingTurnIndex) {\n      this.currentTurnIndex++;\n    }\n  }\n\n  public StartFunctionEvaluationFromGame(\n    funcContainer: Container,\n    args: any[]\n  ) {\n    this.callStack.Push(\n      PushPopType.FunctionEvaluationFromGame,\n      this.evaluationStack.length\n    );\n    this.callStack.currentElement.currentPointer =\n      Pointer.StartOf(funcContainer);\n\n    this.PassArgumentsToEvaluationStack(args);\n  }\n\n  public PassArgumentsToEvaluationStack(args: any[] | null) {\n    if (args !== null) {\n      for (let i = 0; i < args.length; i++) {\n        if (\n          !(\n            typeof args[i] === \"number\" ||\n            typeof args[i] === \"string\" ||\n            typeof args[i] === \"boolean\" ||\n            args[i] instanceof InkList\n          )\n        ) {\n          throw new Error(\n            \"ink arguments when calling EvaluateFunction / ChoosePathStringWithParameters must be\" +\n              \"number, string, bool or InkList. Argument was \" +\n              (nullIfUndefined(args[i]) === null\n                ? \"null\"\n                : args[i].constructor.name)\n          );\n        }\n\n        this.PushEvaluationStack(Value.Create(args[i]));\n      }\n    }\n  }\n\n  public TryExitFunctionEvaluationFromGame() {\n    if (\n      this.callStack.currentElement.type ==\n      PushPopType.FunctionEvaluationFromGame\n    ) {\n      this.currentPointer = Pointer.Null;\n      this.didSafeExit = true;\n      return true;\n    }\n\n    return false;\n  }\n\n  public CompleteFunctionEvaluationFromGame() {\n    if (\n      this.callStack.currentElement.type !=\n      PushPopType.FunctionEvaluationFromGame\n    ) {\n      throw new Error(\n        \"Expected external function evaluation to be complete. Stack trace: \" +\n          this.callStack.callStackTrace\n      );\n    }\n\n    let originalEvaluationStackHeight =\n      this.callStack.currentElement.evaluationStackHeightWhenPushed;\n\n    let returnedObj: InkObject | null = null;\n    while (this.evaluationStack.length > originalEvaluationStackHeight) {\n      let poppedObj = this.PopEvaluationStack();\n      if (returnedObj === null) returnedObj = poppedObj;\n    }\n\n    this.PopCallStack(PushPopType.FunctionEvaluationFromGame);\n\n    if (returnedObj) {\n      if (returnedObj instanceof Void) return null;\n\n      // Some kind of value, if not void\n      // var returnVal = returnedObj as Runtime.Value;\n      let returnVal = asOrThrows(returnedObj, Value);\n\n      // DivertTargets get returned as the string of components\n      // (rather than a Path, which isn't public)\n      if (returnVal.valueType == ValueType.DivertTarget) {\n        return \"-> \" + returnVal.valueObject.toString();\n      }\n\n      // Other types can just have their exact object type:\n      // int, float, string. VariablePointers get returned as strings.\n      return returnVal.valueObject;\n    }\n\n    return null;\n  }\n\n  public AddError(message: string, isWarning: boolean) {\n    if (!isWarning) {\n      if (this._currentErrors == null) this._currentErrors = [];\n      this._currentErrors.push(message);\n    } else {\n      if (this._currentWarnings == null) this._currentWarnings = [];\n      this._currentWarnings.push(message);\n    }\n  }\n\n  public OutputStreamDirty() {\n    this._outputStreamTextDirty = true;\n    this._outputStreamTagsDirty = true;\n  }\n\n  private _visitCounts: Map<string, number>;\n  private _turnIndices: Map<string, number>;\n\n  private _outputStreamTextDirty = true;\n  private _outputStreamTagsDirty = true;\n\n  private _patch: StatePatch | null = null;\n\n  private _currentFlow: Flow;\n  private _aliveFlowNames: string[] | null = null;\n  private _namedFlows: Map<string, Flow> | null = null;\n  private readonly kDefaultFlowName = \"DEFAULT_FLOW\";\n  private _aliveFlowNamesDirty: boolean = true;\n}\n","// This is simple replacement of the Stopwatch class from the .NET Framework.\n// The original class can count time with much more accuracy than the Javascript version.\n// It might be worth considering using `window.performance` in the browser\n// or `process.hrtime()` in node.\nexport class Stopwatch {\n  private startTime: number | undefined;\n\n  constructor() {\n    this.startTime = undefined;\n  }\n\n  get ElapsedMilliseconds(): number {\n    if (typeof this.startTime === \"undefined\") {\n      return 0;\n    }\n    return new Date().getTime() - this.startTime;\n  }\n\n  public Start() {\n    this.startTime = new Date().getTime();\n  }\n  public Stop() {\n    this.startTime = undefined;\n  }\n}\n","// TODO: Unify with Compiler.\n\nexport type ErrorHandler = (message: string, type: ErrorType) => void;\n\nexport enum ErrorType {\n  Author,\n  Warning,\n  Error,\n}\n","import { Container } from \"./Container\";\nimport { InkObject } from \"./Object\";\nimport { JsonSerialisation } from \"./JsonSerialisation\";\nimport { StoryState } from \"./StoryState\";\nimport { ControlCommand } from \"./ControlCommand\";\nimport { PushPopType } from \"./PushPop\";\nimport { ChoicePoint } from \"./ChoicePoint\";\nimport { Choice } from \"./Choice\";\nimport { Divert } from \"./Divert\";\nimport {\n  Value,\n  StringValue,\n  IntValue,\n  DivertTargetValue,\n  VariablePointerValue,\n  ListValue,\n} from \"./Value\";\nimport { Path } from \"./Path\";\nimport { Void } from \"./Void\";\nimport { Tag } from \"./Tag\";\nimport { VariableAssignment } from \"./VariableAssignment\";\nimport { VariableReference } from \"./VariableReference\";\nimport { NativeFunctionCall } from \"./NativeFunctionCall\";\nimport { StoryException } from \"./StoryException\";\nimport { PRNG } from \"./PRNG\";\nimport { StringBuilder } from \"./StringBuilder\";\nimport { ListDefinitionsOrigin } from \"./ListDefinitionsOrigin\";\nimport { ListDefinition } from \"./ListDefinition\";\nimport { Stopwatch } from \"./StopWatch\";\nimport { Pointer } from \"./Pointer\";\nimport { InkList, InkListItem, KeyValuePair } from \"./InkList\";\nimport { asOrNull, asOrThrows } from \"./TypeAssertion\";\nimport { DebugMetadata } from \"./DebugMetadata\";\nimport { throwNullException } from \"./NullException\";\nimport { SimpleJson } from \"./SimpleJson\";\nimport { ErrorHandler, ErrorType } from \"./Error\";\n\nexport { InkList } from \"./InkList\";\n\nif (!Number.isInteger) {\n  Number.isInteger = function isInteger(nVal: any) {\n    return (\n      typeof nVal === \"number\" &&\n      isFinite(nVal) &&\n      nVal > -9007199254740992 &&\n      nVal < 9007199254740992 &&\n      Math.floor(nVal) === nVal\n    );\n  };\n}\n\nexport class Story extends InkObject {\n  public static inkVersionCurrent = 21;\n\n  public inkVersionMinimumCompatible = 18;\n\n  get currentChoices() {\n    let choices: Choice[] = [];\n\n    if (this._state === null) {\n      return throwNullException(\"this._state\");\n    }\n    for (let c of this._state.currentChoices) {\n      if (!c.isInvisibleDefault) {\n        c.index = choices.length;\n        choices.push(c);\n      }\n    }\n\n    return choices;\n  }\n\n  get currentText() {\n    this.IfAsyncWeCant(\"call currentText since it's a work in progress\");\n    return this.state.currentText;\n  }\n\n  get currentTags() {\n    this.IfAsyncWeCant(\"call currentTags since it's a work in progress\");\n    return this.state.currentTags;\n  }\n\n  get currentErrors() {\n    return this.state.currentErrors;\n  }\n\n  get currentWarnings() {\n    return this.state.currentWarnings;\n  }\n\n  get currentFlowName() {\n    return this.state.currentFlowName;\n  }\n\n  get currentFlowIsDefaultFlow() {\n    return this.state.currentFlowIsDefaultFlow;\n  }\n\n  get aliveFlowNames() {\n    return this.state.aliveFlowNames;\n  }\n\n  get hasError() {\n    return this.state.hasError;\n  }\n\n  get hasWarning() {\n    return this.state.hasWarning;\n  }\n\n  get variablesState() {\n    return this.state.variablesState;\n  }\n\n  get listDefinitions() {\n    return this._listDefinitions;\n  }\n\n  get state() {\n    return this._state;\n  }\n\n  public onError: ErrorHandler | null = null;\n\n  public onDidContinue: (() => void) | null = null;\n\n  public onMakeChoice: ((arg1: Choice) => void) | null = null;\n\n  public onEvaluateFunction: ((arg1: string, arg2: any[]) => void) | null =\n    null;\n\n  public onCompleteEvaluateFunction:\n    | ((arg1: string, arg2: any[], arg3: string, arg4: any) => void)\n    | null = null;\n\n  public onChoosePathString: ((arg1: string, arg2: any[]) => void) | null =\n    null;\n\n  // TODO: Implement Profiler\n  public StartProfiling() {\n    /* */\n  }\n  public EndProfiling() {\n    /* */\n  }\n\n  constructor(contentContainer: Container, lists: ListDefinition[] | null);\n  constructor(jsonString: string);\n  constructor(json: Record<string, any>);\n  constructor() {\n    super();\n\n    // Discrimination between constructors\n    let contentContainer: Container;\n    let lists: ListDefinition[] | null = null;\n    let json: Record<string, any> | null = null;\n\n    if (arguments[0] instanceof Container) {\n      contentContainer = arguments[0] as Container;\n\n      if (typeof arguments[1] !== \"undefined\") {\n        lists = arguments[1] as ListDefinition[];\n      }\n\n      // ------ Story (Container contentContainer, List<Runtime.ListDefinition> lists = null)\n      this._mainContentContainer = contentContainer;\n      // ------\n    } else {\n      if (typeof arguments[0] === \"string\") {\n        let jsonString = arguments[0] as string;\n\n        json = SimpleJson.TextToDictionary(jsonString);\n      } else {\n        json = arguments[0] as Record<string, any>;\n      }\n    }\n\n    // ------ Story (Container contentContainer, List<Runtime.ListDefinition> lists = null)\n    if (lists != null) this._listDefinitions = new ListDefinitionsOrigin(lists);\n\n    this._externals = new Map();\n    // ------\n\n    // ------ Story(string jsonString) : this((Container)null)\n    if (json !== null) {\n      let rootObject: Record<string, any> = json;\n\n      let versionObj = rootObject[\"inkVersion\"];\n      if (versionObj == null)\n        throw new Error(\n          \"ink version number not found. Are you sure it's a valid .ink.json file?\"\n        );\n\n      let formatFromFile = parseInt(versionObj);\n      if (formatFromFile > Story.inkVersionCurrent) {\n        throw new Error(\n          \"Version of ink used to build story was newer than the current version of the engine\"\n        );\n      } else if (formatFromFile < this.inkVersionMinimumCompatible) {\n        throw new Error(\n          \"Version of ink used to build story is too old to be loaded by this version of the engine\"\n        );\n      } else if (formatFromFile != Story.inkVersionCurrent) {\n        console.warn(\n          `WARNING: Version of ink ${Story.inkVersionCurrent} used to build story doesn't match current version of engine (${formatFromFile}). Non-critical, but recommend synchronising.`\n        );\n      }\n\n      let rootToken = rootObject[\"root\"];\n      if (rootToken == null)\n        throw new Error(\n          \"Root node for ink not found. Are you sure it's a valid .ink.json file?\"\n        );\n\n      let listDefsObj;\n      if ((listDefsObj = rootObject[\"listDefs\"])) {\n        this._listDefinitions =\n          JsonSerialisation.JTokenToListDefinitions(listDefsObj);\n      }\n\n      this._mainContentContainer = asOrThrows(\n        JsonSerialisation.JTokenToRuntimeObject(rootToken),\n        Container\n      );\n\n      this.ResetState();\n    }\n    // ------\n  }\n\n  // Merge together `public string ToJson()` and `void ToJson(SimpleJson.Writer writer)`.\n  // Will only return a value if writer was not provided.\n  public ToJson(writer?: SimpleJson.Writer): string | void {\n    let shouldReturn = false;\n\n    if (!writer) {\n      shouldReturn = true;\n      writer = new SimpleJson.Writer();\n    }\n\n    writer.WriteObjectStart();\n\n    writer.WriteIntProperty(\"inkVersion\", Story.inkVersionCurrent);\n\n    writer.WriteProperty(\"root\", (w) =>\n      JsonSerialisation.WriteRuntimeContainer(w, this._mainContentContainer)\n    );\n\n    if (this._listDefinitions != null) {\n      writer.WritePropertyStart(\"listDefs\");\n      writer.WriteObjectStart();\n\n      for (let def of this._listDefinitions.lists) {\n        writer.WritePropertyStart(def.name);\n        writer.WriteObjectStart();\n\n        for (let [key, value] of def.items) {\n          let item = InkListItem.fromSerializedKey(key);\n          let val = value;\n          writer.WriteIntProperty(item.itemName, val);\n        }\n\n        writer.WriteObjectEnd();\n        writer.WritePropertyEnd();\n      }\n\n      writer.WriteObjectEnd();\n      writer.WritePropertyEnd();\n    }\n\n    writer.WriteObjectEnd();\n\n    if (shouldReturn) return writer.toString();\n  }\n\n  public ResetState() {\n    this.IfAsyncWeCant(\"ResetState\");\n\n    this._state = new StoryState(this);\n    this._state.variablesState.ObserveVariableChange(\n      this.VariableStateDidChangeEvent.bind(this)\n    );\n\n    this.ResetGlobals();\n  }\n\n  public ResetErrors() {\n    if (this._state === null) {\n      return throwNullException(\"this._state\");\n    }\n    this._state.ResetErrors();\n  }\n\n  public ResetCallstack() {\n    this.IfAsyncWeCant(\"ResetCallstack\");\n    if (this._state === null) {\n      return throwNullException(\"this._state\");\n    }\n    this._state.ForceEnd();\n  }\n\n  public ResetGlobals() {\n    if (this._mainContentContainer.namedContent.get(\"global decl\")) {\n      let originalPointer = this.state.currentPointer.copy();\n\n      this.ChoosePath(new Path(\"global decl\"), false);\n\n      this.ContinueInternal();\n\n      this.state.currentPointer = originalPointer;\n    }\n\n    this.state.variablesState.SnapshotDefaultGlobals();\n  }\n\n  public SwitchFlow(flowName: string) {\n    this.IfAsyncWeCant(\"switch flow\");\n    if (this._asyncSaving) {\n      throw new Error(\n        \"Story is already in background saving mode, can't switch flow to \" +\n          flowName\n      );\n    }\n\n    this.state.SwitchFlow_Internal(flowName);\n  }\n\n  public RemoveFlow(flowName: string) {\n    this.state.RemoveFlow_Internal(flowName);\n  }\n\n  public SwitchToDefaultFlow() {\n    this.state.SwitchToDefaultFlow_Internal();\n  }\n\n  public Continue() {\n    this.ContinueAsync(0);\n    return this.currentText;\n  }\n\n  get canContinue() {\n    return this.state.canContinue;\n  }\n\n  get asyncContinueComplete() {\n    return !this._asyncContinueActive;\n  }\n\n  public ContinueAsync(millisecsLimitAsync: number) {\n    if (!this._hasValidatedExternals) this.ValidateExternalBindings();\n\n    this.ContinueInternal(millisecsLimitAsync);\n  }\n\n  public ContinueInternal(millisecsLimitAsync = 0) {\n    if (this._profiler != null) this._profiler.PreContinue();\n\n    let isAsyncTimeLimited = millisecsLimitAsync > 0;\n    this._recursiveContinueCount++;\n\n    if (!this._asyncContinueActive) {\n      this._asyncContinueActive = isAsyncTimeLimited;\n\n      if (!this.canContinue) {\n        throw new Error(\n          \"Can't continue - should check canContinue before calling Continue\"\n        );\n      }\n\n      this._state.didSafeExit = false;\n      this._state.ResetOutput();\n\n      if (this._recursiveContinueCount == 1)\n        this._state.variablesState.StartVariableObservation();\n    } else if (this._asyncContinueActive && !isAsyncTimeLimited) {\n      this._asyncContinueActive = false;\n    }\n\n    let durationStopwatch = new Stopwatch();\n    durationStopwatch.Start();\n\n    let outputStreamEndsInNewline = false;\n    this._sawLookaheadUnsafeFunctionAfterNewline = false;\n    do {\n      try {\n        outputStreamEndsInNewline = this.ContinueSingleStep();\n      } catch (e) {\n        if (!(e instanceof StoryException)) throw e;\n\n        this.AddError(e.message, undefined, e.useEndLineNumber);\n        break;\n      }\n\n      if (outputStreamEndsInNewline) break;\n\n      if (\n        this._asyncContinueActive &&\n        durationStopwatch.ElapsedMilliseconds > millisecsLimitAsync\n      ) {\n        break;\n      }\n    } while (this.canContinue);\n\n    durationStopwatch.Stop();\n\n    let changedVariablesToObserve: Map<string, any> | null = null;\n\n    if (outputStreamEndsInNewline || !this.canContinue) {\n      if (this._stateSnapshotAtLastNewline !== null) {\n        this.RestoreStateSnapshot();\n      }\n\n      if (!this.canContinue) {\n        if (this.state.callStack.canPopThread)\n          this.AddError(\n            \"Thread available to pop, threads should always be flat by the end of evaluation?\"\n          );\n\n        if (\n          this.state.generatedChoices.length == 0 &&\n          !this.state.didSafeExit &&\n          this._temporaryEvaluationContainer == null\n        ) {\n          if (this.state.callStack.CanPop(PushPopType.Tunnel))\n            this.AddError(\n              \"unexpectedly reached end of content. Do you need a '->->' to return from a tunnel?\"\n            );\n          else if (this.state.callStack.CanPop(PushPopType.Function))\n            this.AddError(\n              \"unexpectedly reached end of content. Do you need a '~ return'?\"\n            );\n          else if (!this.state.callStack.canPop)\n            this.AddError(\n              \"ran out of content. Do you need a '-> DONE' or '-> END'?\"\n            );\n          else\n            this.AddError(\n              \"unexpectedly reached end of content for unknown reason. Please debug compiler!\"\n            );\n        }\n      }\n\n      this.state.didSafeExit = false;\n      this._sawLookaheadUnsafeFunctionAfterNewline = false;\n\n      if (this._recursiveContinueCount == 1)\n        changedVariablesToObserve =\n          this._state.variablesState.CompleteVariableObservation();\n\n      this._asyncContinueActive = false;\n      if (this.onDidContinue !== null) this.onDidContinue();\n    }\n\n    this._recursiveContinueCount--;\n\n    if (this._profiler != null) this._profiler.PostContinue();\n\n    // In the following code, we're masking a lot of non-null assertion,\n    // because testing for against `hasError` or `hasWarning` makes sure\n    // the arrays are present and contain at least one element.\n    if (this.state.hasError || this.state.hasWarning) {\n      if (this.onError !== null) {\n        if (this.state.hasError) {\n          for (let err of this.state.currentErrors!) {\n            this.onError(err, ErrorType.Error);\n          }\n        }\n        if (this.state.hasWarning) {\n          for (let err of this.state.currentWarnings!) {\n            this.onError(err, ErrorType.Warning);\n          }\n        }\n        this.ResetErrors();\n      } else {\n        let sb = new StringBuilder();\n        sb.Append(\"Ink had \");\n        if (this.state.hasError) {\n          sb.Append(`${this.state.currentErrors!.length}`);\n          sb.Append(\n            this.state.currentErrors!.length == 1 ? \" error\" : \" errors\"\n          );\n          if (this.state.hasWarning) sb.Append(\" and \");\n        }\n        if (this.state.hasWarning) {\n          sb.Append(`${this.state.currentWarnings!.length}`);\n          sb.Append(\n            this.state.currentWarnings!.length == 1 ? \" warning\" : \" warnings\"\n          );\n          if (this.state.hasWarning) sb.Append(\" and \");\n        }\n        sb.Append(\n          \". It is strongly suggested that you assign an error handler to story.onError. The first issue was: \"\n        );\n        sb.Append(\n          this.state.hasError\n            ? this.state.currentErrors![0]\n            : this.state.currentWarnings![0]\n        );\n\n        throw new StoryException(sb.toString());\n      }\n    }\n    if (\n      changedVariablesToObserve != null &&\n      Object.keys(changedVariablesToObserve).length > 0\n    ) {\n      this._state.variablesState.NotifyObservers(changedVariablesToObserve);\n    }\n  }\n\n  public ContinueSingleStep() {\n    if (this._profiler != null) this._profiler.PreStep();\n\n    this.Step();\n\n    if (this._profiler != null) this._profiler.PostStep();\n\n    if (!this.canContinue && !this.state.callStack.elementIsEvaluateFromGame) {\n      this.TryFollowDefaultInvisibleChoice();\n    }\n\n    if (this._profiler != null) this._profiler.PreSnapshot();\n\n    if (!this.state.inStringEvaluation) {\n      if (this._stateSnapshotAtLastNewline !== null) {\n        if (this._stateSnapshotAtLastNewline.currentTags === null) {\n          return throwNullException(\"this._stateAtLastNewline.currentTags\");\n        }\n        if (this.state.currentTags === null) {\n          return throwNullException(\"this.state.currentTags\");\n        }\n\n        let change = this.CalculateNewlineOutputStateChange(\n          this._stateSnapshotAtLastNewline.currentText,\n          this.state.currentText,\n          this._stateSnapshotAtLastNewline.currentTags.length,\n          this.state.currentTags.length\n        );\n\n        if (\n          change == Story.OutputStateChange.ExtendedBeyondNewline ||\n          this._sawLookaheadUnsafeFunctionAfterNewline\n        ) {\n          this.RestoreStateSnapshot();\n\n          return true;\n        } else if (change == Story.OutputStateChange.NewlineRemoved) {\n          this.DiscardSnapshot();\n        }\n      }\n\n      if (this.state.outputStreamEndsInNewline) {\n        if (this.canContinue) {\n          if (this._stateSnapshotAtLastNewline == null) this.StateSnapshot();\n        } else {\n          this.DiscardSnapshot();\n        }\n      }\n    }\n\n    if (this._profiler != null) this._profiler.PostSnapshot();\n\n    return false;\n  }\n\n  public CalculateNewlineOutputStateChange(\n    prevText: string | null,\n    currText: string | null,\n    prevTagCount: number,\n    currTagCount: number\n  ) {\n    if (prevText === null) {\n      return throwNullException(\"prevText\");\n    }\n    if (currText === null) {\n      return throwNullException(\"currText\");\n    }\n\n    let newlineStillExists =\n      currText.length >= prevText.length &&\n      prevText.length > 0 &&\n      currText.charAt(prevText.length - 1) == \"\\n\";\n    if (\n      prevTagCount == currTagCount &&\n      prevText.length == currText.length &&\n      newlineStillExists\n    )\n      return Story.OutputStateChange.NoChange;\n\n    if (!newlineStillExists) {\n      return Story.OutputStateChange.NewlineRemoved;\n    }\n\n    if (currTagCount > prevTagCount)\n      return Story.OutputStateChange.ExtendedBeyondNewline;\n\n    for (let i = prevText.length; i < currText.length; i++) {\n      let c = currText.charAt(i);\n      if (c != \" \" && c != \"\\t\") {\n        return Story.OutputStateChange.ExtendedBeyondNewline;\n      }\n    }\n\n    return Story.OutputStateChange.NoChange;\n  }\n\n  public ContinueMaximally() {\n    this.IfAsyncWeCant(\"ContinueMaximally\");\n\n    let sb = new StringBuilder();\n\n    while (this.canContinue) {\n      sb.Append(this.Continue());\n    }\n\n    return sb.toString();\n  }\n\n  public ContentAtPath(path: Path) {\n    return this.mainContentContainer.ContentAtPath(path);\n  }\n\n  public KnotContainerWithName(name: string) {\n    let namedContainer = this.mainContentContainer.namedContent.get(name);\n    if (namedContainer instanceof Container) return namedContainer;\n    else return null;\n  }\n\n  public PointerAtPath(path: Path) {\n    if (path.length == 0) return Pointer.Null;\n\n    let p = new Pointer();\n\n    let pathLengthToUse = path.length;\n\n    let result = null;\n    if (path.lastComponent === null) {\n      return throwNullException(\"path.lastComponent\");\n    }\n\n    if (path.lastComponent.isIndex) {\n      pathLengthToUse = path.length - 1;\n      result = this.mainContentContainer.ContentAtPath(\n        path,\n        undefined,\n        pathLengthToUse\n      );\n      p.container = result.container;\n      p.index = path.lastComponent.index;\n    } else {\n      result = this.mainContentContainer.ContentAtPath(path);\n      p.container = result.container;\n      p.index = -1;\n    }\n\n    if (\n      result.obj == null ||\n      (result.obj == this.mainContentContainer && pathLengthToUse > 0)\n    ) {\n      this.Error(\n        \"Failed to find content at path '\" +\n          path +\n          \"', and no approximation of it was possible.\"\n      );\n    } else if (result.approximate)\n      this.Warning(\n        \"Failed to find content at path '\" +\n          path +\n          \"', so it was approximated to: '\" +\n          result.obj.path +\n          \"'.\"\n      );\n\n    return p;\n  }\n\n  public StateSnapshot() {\n    this._stateSnapshotAtLastNewline = this._state;\n    this._state = this._state.CopyAndStartPatching(false);\n  }\n\n  public RestoreStateSnapshot() {\n    if (this._stateSnapshotAtLastNewline === null) {\n      throwNullException(\"_stateSnapshotAtLastNewline\");\n    }\n    this._stateSnapshotAtLastNewline.RestoreAfterPatch();\n\n    this._state = this._stateSnapshotAtLastNewline;\n    this._stateSnapshotAtLastNewline = null;\n\n    if (!this._asyncSaving) {\n      this._state.ApplyAnyPatch();\n    }\n  }\n\n  public DiscardSnapshot() {\n    if (!this._asyncSaving) this._state.ApplyAnyPatch();\n\n    this._stateSnapshotAtLastNewline = null;\n  }\n\n  public CopyStateForBackgroundThreadSave() {\n    this.IfAsyncWeCant(\"start saving on a background thread\");\n\n    if (this._asyncSaving)\n      throw new Error(\n        \"Story is already in background saving mode, can't call CopyStateForBackgroundThreadSave again!\"\n      );\n\n    let stateToSave = this._state;\n    this._state = this._state.CopyAndStartPatching(true);\n    this._asyncSaving = true;\n    return stateToSave;\n  }\n\n  public BackgroundSaveComplete() {\n    if (this._stateSnapshotAtLastNewline === null) {\n      this._state.ApplyAnyPatch();\n    }\n\n    this._asyncSaving = false;\n  }\n\n  public Step() {\n    let shouldAddToStream = true;\n\n    let pointer = this.state.currentPointer.copy();\n    if (pointer.isNull) {\n      return;\n    }\n\n    // Container containerToEnter = pointer.Resolve () as Container;\n    let containerToEnter = asOrNull(pointer.Resolve(), Container);\n\n    while (containerToEnter) {\n      this.VisitContainer(containerToEnter, true);\n\n      // No content? the most we can do is step past it\n      if (containerToEnter.content.length == 0) {\n        break;\n      }\n\n      pointer = Pointer.StartOf(containerToEnter);\n      // containerToEnter = pointer.Resolve() as Container;\n      containerToEnter = asOrNull(pointer.Resolve(), Container);\n    }\n\n    this.state.currentPointer = pointer.copy();\n\n    if (this._profiler != null) this._profiler.Step(this.state.callStack);\n\n    // Is the current content object:\n    //  - Normal content\n    //  - Or a logic/flow statement - if so, do it\n    // Stop flow if we hit a stack pop when we're unable to pop (e.g. return/done statement in knot\n    // that was diverted to rather than called as a function)\n    let currentContentObj = pointer.Resolve();\n    let isLogicOrFlowControl =\n      this.PerformLogicAndFlowControl(currentContentObj);\n\n    // Has flow been forced to end by flow control above?\n    if (this.state.currentPointer.isNull) {\n      return;\n    }\n\n    if (isLogicOrFlowControl) {\n      shouldAddToStream = false;\n    }\n\n    // Choice with condition?\n    // var choicePoint = currentContentObj as ChoicePoint;\n    let choicePoint = asOrNull(currentContentObj, ChoicePoint);\n    if (choicePoint) {\n      let choice = this.ProcessChoice(choicePoint);\n      if (choice) {\n        this.state.generatedChoices.push(choice);\n      }\n\n      currentContentObj = null;\n      shouldAddToStream = false;\n    }\n\n    // If the container has no content, then it will be\n    // the \"content\" itself, but we skip over it.\n    if (currentContentObj instanceof Container) {\n      shouldAddToStream = false;\n    }\n\n    // Content to add to evaluation stack or the output stream\n    if (shouldAddToStream) {\n      // If we're pushing a variable pointer onto the evaluation stack, ensure that it's specific\n      // to our current (possibly temporary) context index. And make a copy of the pointer\n      // so that we're not editing the original runtime object.\n      // var varPointer = currentContentObj as VariablePointerValue;\n      let varPointer = asOrNull(currentContentObj, VariablePointerValue);\n      if (varPointer && varPointer.contextIndex == -1) {\n        // Create new object so we're not overwriting the story's own data\n        let contextIdx = this.state.callStack.ContextForVariableNamed(\n          varPointer.variableName\n        );\n        currentContentObj = new VariablePointerValue(\n          varPointer.variableName,\n          contextIdx\n        );\n      }\n\n      // Expression evaluation content\n      if (this.state.inExpressionEvaluation) {\n        this.state.PushEvaluationStack(currentContentObj);\n      }\n      // Output stream content (i.e. not expression evaluation)\n      else {\n        this.state.PushToOutputStream(currentContentObj);\n      }\n    }\n\n    // Increment the content pointer, following diverts if necessary\n    this.NextContent();\n\n    // Starting a thread should be done after the increment to the content pointer,\n    // so that when returning from the thread, it returns to the content after this instruction.\n    // var controlCmd = currentContentObj as ;\n    let controlCmd = asOrNull(currentContentObj, ControlCommand);\n    if (\n      controlCmd &&\n      controlCmd.commandType == ControlCommand.CommandType.StartThread\n    ) {\n      this.state.callStack.PushThread();\n    }\n  }\n\n  public VisitContainer(container: Container, atStart: boolean) {\n    if (!container.countingAtStartOnly || atStart) {\n      if (container.visitsShouldBeCounted)\n        this.state.IncrementVisitCountForContainer(container);\n\n      if (container.turnIndexShouldBeCounted)\n        this.state.RecordTurnIndexVisitToContainer(container);\n    }\n  }\n\n  private _prevContainers: Container[] = [];\n  public VisitChangedContainersDueToDivert() {\n    let previousPointer = this.state.previousPointer.copy();\n    let pointer = this.state.currentPointer.copy();\n\n    if (pointer.isNull || pointer.index == -1) return;\n\n    this._prevContainers.length = 0;\n    if (!previousPointer.isNull) {\n      // Container prevAncestor = previousPointer.Resolve() as Container ?? previousPointer.container as Container;\n      let resolvedPreviousAncestor = previousPointer.Resolve();\n      let prevAncestor =\n        asOrNull(resolvedPreviousAncestor, Container) ||\n        asOrNull(previousPointer.container, Container);\n      while (prevAncestor) {\n        this._prevContainers.push(prevAncestor);\n        // prevAncestor = prevAncestor.parent as Container;\n        prevAncestor = asOrNull(prevAncestor.parent, Container);\n      }\n    }\n\n    let currentChildOfContainer = pointer.Resolve();\n\n    if (currentChildOfContainer == null) return;\n\n    // Container currentContainerAncestor = currentChildOfContainer.parent as Container;\n    let currentContainerAncestor = asOrNull(\n      currentChildOfContainer.parent,\n      Container\n    );\n    let allChildrenEnteredAtStart = true;\n    while (\n      currentContainerAncestor &&\n      (this._prevContainers.indexOf(currentContainerAncestor) < 0 ||\n        currentContainerAncestor.countingAtStartOnly)\n    ) {\n      // Check whether this ancestor container is being entered at the start,\n      // by checking whether the child object is the first.\n      let enteringAtStart =\n        currentContainerAncestor.content.length > 0 &&\n        currentChildOfContainer == currentContainerAncestor.content[0] &&\n        allChildrenEnteredAtStart;\n\n      if (!enteringAtStart) allChildrenEnteredAtStart = false;\n\n      // Mark a visit to this container\n      this.VisitContainer(currentContainerAncestor, enteringAtStart);\n\n      currentChildOfContainer = currentContainerAncestor;\n      // currentContainerAncestor = currentContainerAncestor.parent as Container;\n      currentContainerAncestor = asOrNull(\n        currentContainerAncestor.parent,\n        Container\n      );\n    }\n  }\n\n  public PopChoiceStringAndTags(tags: string[]) {\n    let choiceOnlyStrVal = asOrThrows(\n      this.state.PopEvaluationStack(),\n      StringValue\n    );\n\n    while (\n      this.state.evaluationStack.length > 0 &&\n      asOrNull(this.state.PeekEvaluationStack(), Tag) != null\n    ) {\n      let tag = asOrNull(this.state.PopEvaluationStack(), Tag);\n      if (tag) tags.push(tag.text);\n    }\n    return choiceOnlyStrVal.value;\n  }\n\n  public ProcessChoice(choicePoint: ChoicePoint) {\n    let showChoice = true;\n\n    // Don't create choice if choice point doesn't pass conditional\n    if (choicePoint.hasCondition) {\n      let conditionValue = this.state.PopEvaluationStack();\n      if (!this.IsTruthy(conditionValue)) {\n        showChoice = false;\n      }\n    }\n\n    let startText = \"\";\n    let choiceOnlyText = \"\";\n    let tags: string[] = [];\n\n    if (choicePoint.hasChoiceOnlyContent) {\n      choiceOnlyText = this.PopChoiceStringAndTags(tags) || \"\";\n    }\n\n    if (choicePoint.hasStartContent) {\n      startText = this.PopChoiceStringAndTags(tags) || \"\";\n    }\n\n    // Don't create choice if player has already read this content\n    if (choicePoint.onceOnly) {\n      let visitCount = this.state.VisitCountForContainer(\n        choicePoint.choiceTarget\n      );\n      if (visitCount > 0) {\n        showChoice = false;\n      }\n    }\n\n    // We go through the full process of creating the choice above so\n    // that we consume the content for it, since otherwise it'll\n    // be shown on the output stream.\n    if (!showChoice) {\n      return null;\n    }\n\n    let choice = new Choice();\n    choice.targetPath = choicePoint.pathOnChoice;\n    choice.sourcePath = choicePoint.path.toString();\n    choice.isInvisibleDefault = choicePoint.isInvisibleDefault;\n    choice.threadAtGeneration = this.state.callStack.ForkThread();\n    choice.tags = tags.reverse(); //C# is a stack\n    choice.text = (startText + choiceOnlyText).replace(/^[ \\t]+|[ \\t]+$/g, \"\");\n\n    return choice;\n  }\n\n  public IsTruthy(obj: InkObject) {\n    let truthy = false;\n    if (obj instanceof Value) {\n      let val = obj;\n\n      if (val instanceof DivertTargetValue) {\n        let divTarget = val;\n        this.Error(\n          \"Shouldn't use a divert target (to \" +\n            divTarget.targetPath +\n            \") as a conditional value. Did you intend a function call 'likeThis()' or a read count check 'likeThis'? (no arrows)\"\n        );\n        return false;\n      }\n\n      return val.isTruthy;\n    }\n    return truthy;\n  }\n\n  public PerformLogicAndFlowControl(contentObj: InkObject | null) {\n    if (contentObj == null) {\n      return false;\n    }\n\n    // Divert\n    if (contentObj instanceof Divert) {\n      let currentDivert = contentObj;\n\n      if (currentDivert.isConditional) {\n        let conditionValue = this.state.PopEvaluationStack();\n\n        // False conditional? Cancel divert\n        if (!this.IsTruthy(conditionValue)) return true;\n      }\n\n      if (currentDivert.hasVariableTarget) {\n        let varName = currentDivert.variableDivertName;\n\n        let varContents =\n          this.state.variablesState.GetVariableWithName(varName);\n\n        if (varContents == null) {\n          this.Error(\n            \"Tried to divert using a target from a variable that could not be found (\" +\n              varName +\n              \")\"\n          );\n        } else if (!(varContents instanceof DivertTargetValue)) {\n          // var intContent = varContents as IntValue;\n          let intContent = asOrNull(varContents, IntValue);\n\n          let errorMessage =\n            \"Tried to divert to a target from a variable, but the variable (\" +\n            varName +\n            \") didn't contain a divert target, it \";\n          if (intContent instanceof IntValue && intContent.value == 0) {\n            errorMessage += \"was empty/null (the value 0).\";\n          } else {\n            errorMessage += \"contained '\" + varContents + \"'.\";\n          }\n\n          this.Error(errorMessage);\n        }\n\n        let target = asOrThrows(varContents, DivertTargetValue);\n        this.state.divertedPointer = this.PointerAtPath(target.targetPath);\n      } else if (currentDivert.isExternal) {\n        this.CallExternalFunction(\n          currentDivert.targetPathString,\n          currentDivert.externalArgs\n        );\n        return true;\n      } else {\n        this.state.divertedPointer = currentDivert.targetPointer.copy();\n      }\n\n      if (currentDivert.pushesToStack) {\n        this.state.callStack.Push(\n          currentDivert.stackPushType,\n          undefined,\n          this.state.outputStream.length\n        );\n      }\n\n      if (this.state.divertedPointer.isNull && !currentDivert.isExternal) {\n        if (\n          currentDivert &&\n          currentDivert.debugMetadata &&\n          currentDivert.debugMetadata.sourceName != null\n        ) {\n          this.Error(\n            \"Divert target doesn't exist: \" +\n              currentDivert.debugMetadata.sourceName\n          );\n        } else {\n          this.Error(\"Divert resolution failed: \" + currentDivert);\n        }\n      }\n\n      return true;\n    }\n\n    // Start/end an expression evaluation? Or print out the result?\n    else if (contentObj instanceof ControlCommand) {\n      let evalCommand = contentObj;\n\n      switch (evalCommand.commandType) {\n        case ControlCommand.CommandType.EvalStart:\n          this.Assert(\n            this.state.inExpressionEvaluation === false,\n            \"Already in expression evaluation?\"\n          );\n          this.state.inExpressionEvaluation = true;\n          break;\n\n        case ControlCommand.CommandType.EvalEnd:\n          this.Assert(\n            this.state.inExpressionEvaluation === true,\n            \"Not in expression evaluation mode\"\n          );\n          this.state.inExpressionEvaluation = false;\n          break;\n\n        case ControlCommand.CommandType.EvalOutput:\n          // If the expression turned out to be empty, there may not be anything on the stack\n          if (this.state.evaluationStack.length > 0) {\n            let output = this.state.PopEvaluationStack();\n\n            // Functions may evaluate to Void, in which case we skip output\n            if (!(output instanceof Void)) {\n              // TODO: Should we really always blanket convert to string?\n              // It would be okay to have numbers in the output stream the\n              // only problem is when exporting text for viewing, it skips over numbers etc.\n              let text = new StringValue(output.toString());\n\n              this.state.PushToOutputStream(text);\n            }\n          }\n          break;\n\n        case ControlCommand.CommandType.NoOp:\n          break;\n\n        case ControlCommand.CommandType.Duplicate:\n          this.state.PushEvaluationStack(this.state.PeekEvaluationStack());\n          break;\n\n        case ControlCommand.CommandType.PopEvaluatedValue:\n          this.state.PopEvaluationStack();\n          break;\n\n        case ControlCommand.CommandType.PopFunction:\n        case ControlCommand.CommandType.PopTunnel:\n          let popType =\n            evalCommand.commandType == ControlCommand.CommandType.PopFunction\n              ? PushPopType.Function\n              : PushPopType.Tunnel;\n\n          let overrideTunnelReturnTarget: DivertTargetValue | null = null;\n          if (popType == PushPopType.Tunnel) {\n            let popped = this.state.PopEvaluationStack();\n            // overrideTunnelReturnTarget = popped as DivertTargetValue;\n            overrideTunnelReturnTarget = asOrNull(popped, DivertTargetValue);\n            if (overrideTunnelReturnTarget === null) {\n              this.Assert(\n                popped instanceof Void,\n                \"Expected void if ->-> doesn't override target\"\n              );\n            }\n          }\n\n          if (this.state.TryExitFunctionEvaluationFromGame()) {\n            break;\n          } else if (\n            this.state.callStack.currentElement.type != popType ||\n            !this.state.callStack.canPop\n          ) {\n            let names: Map<PushPopType, string> = new Map();\n            names.set(\n              PushPopType.Function,\n              \"function return statement (~ return)\"\n            );\n            names.set(PushPopType.Tunnel, \"tunnel onwards statement (->->)\");\n\n            let expected = names.get(this.state.callStack.currentElement.type);\n            if (!this.state.callStack.canPop) {\n              expected = \"end of flow (-> END or choice)\";\n            }\n\n            let errorMsg =\n              \"Found \" + names.get(popType) + \", when expected \" + expected;\n\n            this.Error(errorMsg);\n          } else {\n            this.state.PopCallStack();\n\n            if (overrideTunnelReturnTarget)\n              this.state.divertedPointer = this.PointerAtPath(\n                overrideTunnelReturnTarget.targetPath\n              );\n          }\n          break;\n\n        case ControlCommand.CommandType.BeginString:\n          this.state.PushToOutputStream(evalCommand);\n\n          this.Assert(\n            this.state.inExpressionEvaluation === true,\n            \"Expected to be in an expression when evaluating a string\"\n          );\n          this.state.inExpressionEvaluation = false;\n          break;\n\n        // Leave it to story.currentText and story.currentTags to sort out the text from the tags\n        // This is mostly because we can't always rely on the existence of EndTag, and we don't want\n        // to try and flatten dynamic tags to strings every time \\n is pushed to output\n        case ControlCommand.CommandType.BeginTag:\n          this.state.PushToOutputStream(evalCommand);\n          break;\n\n        // EndTag has 2 modes:\n        //  - When in string evaluation (for choices)\n        //  - Normal\n        //\n        // The only way you could have an EndTag in the middle of\n        // string evaluation is if we're currently generating text for a\n        // choice, such as:\n        //\n        //   + choice # tag\n        //\n        // In the above case, the ink will be run twice:\n        //  - First, to generate the choice text. String evaluation\n        //    will be on, and the final string will be pushed to the\n        //    evaluation stack, ready to be popped to make a Choice\n        //    object.\n        //  - Second, when ink generates text after choosing the choice.\n        //    On this ocassion, it's not in string evaluation mode.\n        //\n        // On the writing side, we disallow manually putting tags within\n        // strings like this:\n        //\n        //   {\"hello # world\"}\n        //\n        // So we know that the tag must be being generated as part of\n        // choice content. Therefore, when the tag has been generated,\n        // we push it onto the evaluation stack in the exact same way\n        // as the string for the choice content.\n        case ControlCommand.CommandType.EndTag: {\n          if (this.state.inStringEvaluation) {\n            let contentStackForTag: InkObject[] = [];\n            let outputCountConsumed = 0;\n            for (let i = this.state.outputStream.length - 1; i >= 0; --i) {\n              let obj = this.state.outputStream[i];\n              outputCountConsumed++;\n\n              // var command = obj as ControlCommand;\n              let command = asOrNull(obj, ControlCommand);\n              if (command != null) {\n                if (\n                  command.commandType == ControlCommand.CommandType.BeginTag\n                ) {\n                  break;\n                } else {\n                  this.Error(\n                    \"Unexpected ControlCommand while extracting tag from choice\"\n                  );\n                  break;\n                }\n              }\n              if (obj instanceof StringValue) {\n                contentStackForTag.push(obj);\n              }\n            }\n\n            // Consume the content that was produced for this string\n            this.state.PopFromOutputStream(outputCountConsumed);\n            // Build string out of the content we collected\n            let sb = new StringBuilder();\n            for (let strVal of contentStackForTag.reverse()) {\n              sb.Append(strVal.toString());\n            }\n            let choiceTag = new Tag(\n              this.state.CleanOutputWhitespace(sb.toString())\n            );\n            // Pushing to the evaluation stack means it gets picked up\n            // when a Choice is generated from the next Choice Point.\n            this.state.PushEvaluationStack(choiceTag);\n          } else {\n            // Otherwise! Simply push EndTag, so that in the output stream we\n            // have a structure of: [BeginTag, \"the tag content\", EndTag]\n            this.state.PushToOutputStream(evalCommand);\n          }\n          break;\n        }\n\n        case ControlCommand.CommandType.EndString: {\n          let contentStackForString: InkObject[] = [];\n          let contentToRetain: InkObject[] = [];\n\n          let outputCountConsumed = 0;\n          for (let i = this.state.outputStream.length - 1; i >= 0; --i) {\n            let obj = this.state.outputStream[i];\n\n            outputCountConsumed++;\n\n            // var command = obj as ControlCommand;\n            let command = asOrNull(obj, ControlCommand);\n            if (\n              command &&\n              command.commandType == ControlCommand.CommandType.BeginString\n            ) {\n              break;\n            }\n            if (obj instanceof Tag) {\n              contentToRetain.push(obj);\n            }\n            if (obj instanceof StringValue) {\n              contentStackForString.push(obj);\n            }\n          }\n\n          // Consume the content that was produced for this string\n          this.state.PopFromOutputStream(outputCountConsumed);\n\n          // Rescue the tags that we want actually to keep on the output stack\n          // rather than consume as part of the string we're building.\n          // At the time of writing, this only applies to Tag objects generated\n          // by choices, which are pushed to the stack during string generation.\n          for (let rescuedTag of contentToRetain)\n            this.state.PushToOutputStream(rescuedTag);\n\n          // The C# version uses a Stack for contentStackForString, but we're\n          // using a simple array, so we need to reverse it before using it\n          contentStackForString = contentStackForString.reverse();\n\n          // Build string out of the content we collected\n          let sb = new StringBuilder();\n          for (let c of contentStackForString) {\n            sb.Append(c.toString());\n          }\n\n          // Return to expression evaluation (from content mode)\n          this.state.inExpressionEvaluation = true;\n          this.state.PushEvaluationStack(new StringValue(sb.toString()));\n          break;\n        }\n\n        case ControlCommand.CommandType.ChoiceCount:\n          let choiceCount = this.state.generatedChoices.length;\n          this.state.PushEvaluationStack(new IntValue(choiceCount));\n          break;\n\n        case ControlCommand.CommandType.Turns:\n          this.state.PushEvaluationStack(\n            new IntValue(this.state.currentTurnIndex + 1)\n          );\n          break;\n\n        case ControlCommand.CommandType.TurnsSince:\n        case ControlCommand.CommandType.ReadCount:\n          let target = this.state.PopEvaluationStack();\n          if (!(target instanceof DivertTargetValue)) {\n            let extraNote = \"\";\n            if (target instanceof IntValue)\n              extraNote =\n                \". Did you accidentally pass a read count ('knot_name') instead of a target ('-> knot_name')?\";\n            this.Error(\n              \"TURNS_SINCE / READ_COUNT expected a divert target (knot, stitch, label name), but saw \" +\n                target +\n                extraNote\n            );\n            break;\n          }\n\n          // var divertTarget = target as DivertTargetValue;\n          let divertTarget = asOrThrows(target, DivertTargetValue);\n          // var container = ContentAtPath (divertTarget.targetPath).correctObj as Container;\n          let container = asOrNull(\n            this.ContentAtPath(divertTarget.targetPath).correctObj,\n            Container\n          );\n\n          let eitherCount;\n          if (container != null) {\n            if (\n              evalCommand.commandType == ControlCommand.CommandType.TurnsSince\n            )\n              eitherCount = this.state.TurnsSinceForContainer(container);\n            else eitherCount = this.state.VisitCountForContainer(container);\n          } else {\n            if (\n              evalCommand.commandType == ControlCommand.CommandType.TurnsSince\n            )\n              eitherCount = -1;\n            else eitherCount = 0;\n\n            this.Warning(\n              \"Failed to find container for \" +\n                evalCommand.toString() +\n                \" lookup at \" +\n                divertTarget.targetPath.toString()\n            );\n          }\n\n          this.state.PushEvaluationStack(new IntValue(eitherCount));\n          break;\n\n        case ControlCommand.CommandType.Random: {\n          let maxInt = asOrNull(this.state.PopEvaluationStack(), IntValue);\n          let minInt = asOrNull(this.state.PopEvaluationStack(), IntValue);\n\n          if (minInt == null || minInt instanceof IntValue === false)\n            return this.Error(\n              \"Invalid value for minimum parameter of RANDOM(min, max)\"\n            );\n\n          if (maxInt == null || maxInt instanceof IntValue === false)\n            return this.Error(\n              \"Invalid value for maximum parameter of RANDOM(min, max)\"\n            );\n\n          // Originally a primitive type, but here, can be null.\n          // TODO: Replace by default value?\n          if (maxInt.value === null) {\n            return throwNullException(\"maxInt.value\");\n          }\n          if (minInt.value === null) {\n            return throwNullException(\"minInt.value\");\n          }\n\n          // This code is differs a bit from the reference implementation, since\n          // JavaScript has no true integers. Hence integer arithmetics and\n          // interger overflows don't apply here. A loss of precision can\n          // happen with big numbers however.\n          //\n          // The case where 'randomRange' is lower than zero is handled below,\n          // so there's no need to test against Number.MIN_SAFE_INTEGER.\n          let randomRange = maxInt.value - minInt.value + 1;\n          if (!isFinite(randomRange) || randomRange > Number.MAX_SAFE_INTEGER) {\n            randomRange = Number.MAX_SAFE_INTEGER;\n            this.Error(\n              \"RANDOM was called with a range that exceeds the size that ink numbers can use.\"\n            );\n          }\n          if (randomRange <= 0)\n            this.Error(\n              \"RANDOM was called with minimum as \" +\n                minInt.value +\n                \" and maximum as \" +\n                maxInt.value +\n                \". The maximum must be larger\"\n            );\n\n          let resultSeed = this.state.storySeed + this.state.previousRandom;\n          let random = new PRNG(resultSeed);\n\n          let nextRandom = random.next();\n          let chosenValue = (nextRandom % randomRange) + minInt.value;\n          this.state.PushEvaluationStack(new IntValue(chosenValue));\n\n          // Next random number (rather than keeping the Random object around)\n          this.state.previousRandom = nextRandom;\n          break;\n        }\n\n        case ControlCommand.CommandType.SeedRandom:\n          let seed = asOrNull(this.state.PopEvaluationStack(), IntValue);\n          if (seed == null || seed instanceof IntValue === false)\n            return this.Error(\"Invalid value passed to SEED_RANDOM\");\n\n          // Originally a primitive type, but here, can be null.\n          // TODO: Replace by default value?\n          if (seed.value === null) {\n            return throwNullException(\"minInt.value\");\n          }\n\n          this.state.storySeed = seed.value;\n          this.state.previousRandom = 0;\n\n          this.state.PushEvaluationStack(new Void());\n          break;\n\n        case ControlCommand.CommandType.VisitIndex:\n          let count =\n            this.state.VisitCountForContainer(\n              this.state.currentPointer.container\n            ) - 1; // index not count\n          this.state.PushEvaluationStack(new IntValue(count));\n          break;\n\n        case ControlCommand.CommandType.SequenceShuffleIndex:\n          let shuffleIndex = this.NextSequenceShuffleIndex();\n          this.state.PushEvaluationStack(new IntValue(shuffleIndex));\n          break;\n\n        case ControlCommand.CommandType.StartThread:\n          // Handled in main step function\n          break;\n\n        case ControlCommand.CommandType.Done:\n          // We may exist in the context of the initial\n          // act of creating the thread, or in the context of\n          // evaluating the content.\n          if (this.state.callStack.canPopThread) {\n            this.state.callStack.PopThread();\n          }\n\n          // In normal flow - allow safe exit without warning\n          else {\n            this.state.didSafeExit = true;\n\n            // Stop flow in current thread\n            this.state.currentPointer = Pointer.Null;\n          }\n\n          break;\n\n        // Force flow to end completely\n        case ControlCommand.CommandType.End:\n          this.state.ForceEnd();\n          break;\n\n        case ControlCommand.CommandType.ListFromInt:\n          // var intVal = state.PopEvaluationStack () as IntValue;\n          let intVal = asOrNull(this.state.PopEvaluationStack(), IntValue);\n          // var listNameVal = state.PopEvaluationStack () as StringValue;\n          let listNameVal = asOrThrows(\n            this.state.PopEvaluationStack(),\n            StringValue\n          );\n\n          if (intVal === null) {\n            throw new StoryException(\n              \"Passed non-integer when creating a list element from a numerical value.\"\n            );\n          }\n\n          let generatedListValue = null;\n\n          if (this.listDefinitions === null) {\n            return throwNullException(\"this.listDefinitions\");\n          }\n          let foundListDef = this.listDefinitions.TryListGetDefinition(\n            listNameVal.value,\n            null\n          );\n          if (foundListDef.exists) {\n            // Originally a primitive type, but here, can be null.\n            // TODO: Replace by default value?\n            if (intVal.value === null) {\n              return throwNullException(\"minInt.value\");\n            }\n\n            let foundItem = foundListDef.result!.TryGetItemWithValue(\n              intVal.value,\n              InkListItem.Null\n            );\n            if (foundItem.exists) {\n              generatedListValue = new ListValue(\n                foundItem.result!,\n                intVal.value\n              );\n            }\n          } else {\n            throw new StoryException(\n              \"Failed to find LIST called \" + listNameVal.value\n            );\n          }\n\n          if (generatedListValue == null) generatedListValue = new ListValue();\n\n          this.state.PushEvaluationStack(generatedListValue);\n          break;\n\n        case ControlCommand.CommandType.ListRange:\n          let max = asOrNull(this.state.PopEvaluationStack(), Value);\n          let min = asOrNull(this.state.PopEvaluationStack(), Value);\n\n          // var targetList = state.PopEvaluationStack () as ListValue;\n          let targetList = asOrNull(this.state.PopEvaluationStack(), ListValue);\n\n          if (targetList === null || min === null || max === null)\n            throw new StoryException(\n              \"Expected list, minimum and maximum for LIST_RANGE\"\n            );\n\n          if (targetList.value === null) {\n            return throwNullException(\"targetList.value\");\n          }\n          let result = targetList.value.ListWithSubRange(\n            min.valueObject,\n            max.valueObject\n          );\n\n          this.state.PushEvaluationStack(new ListValue(result));\n          break;\n\n        case ControlCommand.CommandType.ListRandom: {\n          let listVal = this.state.PopEvaluationStack() as ListValue;\n          if (listVal === null)\n            throw new StoryException(\"Expected list for LIST_RANDOM\");\n\n          let list = listVal.value;\n\n          let newList: InkList | null = null;\n\n          if (list === null) {\n            throw throwNullException(\"list\");\n          }\n          if (list.Count == 0) {\n            newList = new InkList();\n          } else {\n            // Generate a random index for the element to take\n            let resultSeed = this.state.storySeed + this.state.previousRandom;\n            let random = new PRNG(resultSeed);\n\n            let nextRandom = random.next();\n            let listItemIndex = nextRandom % list.Count;\n\n            // This bit is a little different from the original\n            // C# code, since iterators do not work in the same way.\n            // First, we iterate listItemIndex - 1 times, calling next().\n            // The listItemIndex-th time is made outside of the loop,\n            // in order to retrieve the value.\n            let listEnumerator = list.entries();\n            for (let i = 0; i <= listItemIndex - 1; i++) {\n              listEnumerator.next();\n            }\n            let value = listEnumerator.next().value;\n            let randomItem: KeyValuePair<InkListItem, number> = {\n              Key: InkListItem.fromSerializedKey(value[0]),\n              Value: value[1],\n            };\n\n            // Origin list is simply the origin of the one element\n            if (randomItem.Key.originName === null) {\n              return throwNullException(\"randomItem.Key.originName\");\n            }\n            newList = new InkList(randomItem.Key.originName, this);\n            newList.Add(randomItem.Key, randomItem.Value);\n\n            this.state.previousRandom = nextRandom;\n          }\n\n          this.state.PushEvaluationStack(new ListValue(newList));\n          break;\n        }\n\n        default:\n          this.Error(\"unhandled ControlCommand: \" + evalCommand);\n          break;\n      }\n\n      return true;\n    }\n\n    // Variable assignment\n    else if (contentObj instanceof VariableAssignment) {\n      let varAss = contentObj;\n      let assignedVal = this.state.PopEvaluationStack();\n\n      this.state.variablesState.Assign(varAss, assignedVal);\n\n      return true;\n    }\n\n    // Variable reference\n    else if (contentObj instanceof VariableReference) {\n      let varRef = contentObj;\n      let foundValue = null;\n\n      // Explicit read count value\n      if (varRef.pathForCount != null) {\n        let container = varRef.containerForCount;\n        let count = this.state.VisitCountForContainer(container);\n        foundValue = new IntValue(count);\n      }\n\n      // Normal variable reference\n      else {\n        foundValue = this.state.variablesState.GetVariableWithName(varRef.name);\n\n        if (foundValue == null) {\n          this.Warning(\n            \"Variable not found: '\" +\n              varRef.name +\n              \"'. Using default value of 0 (false). This can happen with temporary variables if the declaration hasn't yet been hit. Globals are always given a default value on load if a value doesn't exist in the save state.\"\n          );\n          foundValue = new IntValue(0);\n        }\n      }\n\n      this.state.PushEvaluationStack(foundValue);\n\n      return true;\n    }\n\n    // Native function call\n    else if (contentObj instanceof NativeFunctionCall) {\n      let func = contentObj;\n      let funcParams = this.state.PopEvaluationStack(func.numberOfParameters);\n      let result = func.Call(funcParams);\n      this.state.PushEvaluationStack(result);\n      return true;\n    }\n\n    // No control content, must be ordinary content\n    return false;\n  }\n\n  public ChoosePathString(\n    path: string,\n    resetCallstack = true,\n    args: any[] = []\n  ) {\n    this.IfAsyncWeCant(\"call ChoosePathString right now\");\n    if (this.onChoosePathString !== null) this.onChoosePathString(path, args);\n\n    if (resetCallstack) {\n      this.ResetCallstack();\n    } else {\n      if (this.state.callStack.currentElement.type == PushPopType.Function) {\n        let funcDetail = \"\";\n        let container =\n          this.state.callStack.currentElement.currentPointer.container;\n        if (container != null) {\n          funcDetail = \"(\" + container.path.toString() + \") \";\n        }\n        throw new Error(\n          \"Story was running a function \" +\n            funcDetail +\n            \"when you called ChoosePathString(\" +\n            path +\n            \") - this is almost certainly not not what you want! Full stack trace: \\n\" +\n            this.state.callStack.callStackTrace\n        );\n      }\n    }\n\n    this.state.PassArgumentsToEvaluationStack(args);\n    this.ChoosePath(new Path(path));\n  }\n\n  public IfAsyncWeCant(activityStr: string) {\n    if (this._asyncContinueActive)\n      throw new Error(\n        \"Can't \" +\n          activityStr +\n          \". Story is in the middle of a ContinueAsync(). Make more ContinueAsync() calls or a single Continue() call beforehand.\"\n      );\n  }\n\n  public ChoosePath(p: Path, incrementingTurnIndex: boolean = true) {\n    this.state.SetChosenPath(p, incrementingTurnIndex);\n\n    // Take a note of newly visited containers for read counts etc\n    this.VisitChangedContainersDueToDivert();\n  }\n\n  public ChooseChoiceIndex(choiceIdx: number) {\n    choiceIdx = choiceIdx;\n    let choices = this.currentChoices;\n    this.Assert(\n      choiceIdx >= 0 && choiceIdx < choices.length,\n      \"choice out of range\"\n    );\n\n    let choiceToChoose = choices[choiceIdx];\n    if (this.onMakeChoice !== null) this.onMakeChoice(choiceToChoose);\n\n    if (choiceToChoose.threadAtGeneration === null) {\n      return throwNullException(\"choiceToChoose.threadAtGeneration\");\n    }\n    if (choiceToChoose.targetPath === null) {\n      return throwNullException(\"choiceToChoose.targetPath\");\n    }\n\n    this.state.callStack.currentThread = choiceToChoose.threadAtGeneration;\n\n    this.ChoosePath(choiceToChoose.targetPath);\n  }\n\n  public HasFunction(functionName: string) {\n    try {\n      return this.KnotContainerWithName(functionName) != null;\n    } catch (e) {\n      return false;\n    }\n  }\n\n  public EvaluateFunction(\n    functionName: string,\n    args: any[] = [],\n    returnTextOutput: boolean = false\n  ): Story.EvaluateFunctionTextOutput | any {\n    // EvaluateFunction behaves slightly differently than the C# version.\n    // In C#, you can pass a (second) parameter `out textOutput` to get the\n    // text outputted by the function. This is not possible in js. Instead,\n    // we maintain the regular signature (functionName, args), plus an\n    // optional third parameter returnTextOutput. If set to true, we will\n    // return both the textOutput and the returned value, as an object.\n\n    if (this.onEvaluateFunction !== null)\n      this.onEvaluateFunction(functionName, args);\n\n    this.IfAsyncWeCant(\"evaluate a function\");\n\n    if (functionName == null) {\n      throw new Error(\"Function is null\");\n    } else if (functionName == \"\" || functionName.trim() == \"\") {\n      throw new Error(\"Function is empty or white space.\");\n    }\n\n    let funcContainer = this.KnotContainerWithName(functionName);\n    if (funcContainer == null) {\n      throw new Error(\"Function doesn't exist: '\" + functionName + \"'\");\n    }\n\n    let outputStreamBefore: InkObject[] = [];\n    outputStreamBefore.push(...this.state.outputStream);\n    this._state.ResetOutput();\n\n    this.state.StartFunctionEvaluationFromGame(funcContainer, args);\n\n    // Evaluate the function, and collect the string output\n    let stringOutput = new StringBuilder();\n    while (this.canContinue) {\n      stringOutput.Append(this.Continue());\n    }\n    let textOutput = stringOutput.toString();\n\n    this._state.ResetOutput(outputStreamBefore);\n\n    let result = this.state.CompleteFunctionEvaluationFromGame();\n    if (this.onCompleteEvaluateFunction != null)\n      this.onCompleteEvaluateFunction(functionName, args, textOutput, result);\n\n    return returnTextOutput ? { returned: result, output: textOutput } : result;\n  }\n\n  public EvaluateExpression(exprContainer: Container) {\n    let startCallStackHeight = this.state.callStack.elements.length;\n\n    this.state.callStack.Push(PushPopType.Tunnel);\n\n    this._temporaryEvaluationContainer = exprContainer;\n\n    this.state.GoToStart();\n\n    let evalStackHeight = this.state.evaluationStack.length;\n\n    this.Continue();\n\n    this._temporaryEvaluationContainer = null;\n\n    // Should have fallen off the end of the Container, which should\n    // have auto-popped, but just in case we didn't for some reason,\n    // manually pop to restore the state (including currentPath).\n    if (this.state.callStack.elements.length > startCallStackHeight) {\n      this.state.PopCallStack();\n    }\n\n    let endStackHeight = this.state.evaluationStack.length;\n    if (endStackHeight > evalStackHeight) {\n      return this.state.PopEvaluationStack();\n    } else {\n      return null;\n    }\n  }\n\n  public allowExternalFunctionFallbacks: boolean = false;\n\n  public CallExternalFunction(\n    funcName: string | null,\n    numberOfArguments: number\n  ) {\n    if (funcName === null) {\n      return throwNullException(\"funcName\");\n    }\n    let funcDef = this._externals.get(funcName);\n    let fallbackFunctionContainer = null;\n\n    let foundExternal = typeof funcDef !== \"undefined\";\n\n    if (\n      foundExternal &&\n      !funcDef!.lookAheadSafe &&\n      this._state.inStringEvaluation\n    ) {\n      this.Error(\n        \"External function \" +\n          funcName +\n          ' could not be called because 1) it wasn\\'t marked as lookaheadSafe when BindExternalFunction was called and 2) the story is in the middle of string generation, either because choice text is being generated, or because you have ink like \"hello {func()}\". You can work around this by generating the result of your function into a temporary variable before the string or choice gets generated: ~ temp x = ' +\n          funcName +\n          \"()\"\n      );\n    }\n\n    if (\n      foundExternal &&\n      !funcDef!.lookAheadSafe &&\n      this._stateSnapshotAtLastNewline !== null\n    ) {\n      this._sawLookaheadUnsafeFunctionAfterNewline = true;\n      return;\n    }\n\n    if (!foundExternal) {\n      if (this.allowExternalFunctionFallbacks) {\n        fallbackFunctionContainer = this.KnotContainerWithName(funcName);\n        this.Assert(\n          fallbackFunctionContainer !== null,\n          \"Trying to call EXTERNAL function '\" +\n            funcName +\n            \"' which has not been bound, and fallback ink function could not be found.\"\n        );\n\n        // Divert direct into fallback function and we're done\n        this.state.callStack.Push(\n          PushPopType.Function,\n          undefined,\n          this.state.outputStream.length\n        );\n        this.state.divertedPointer = Pointer.StartOf(fallbackFunctionContainer);\n        return;\n      } else {\n        this.Assert(\n          false,\n          \"Trying to call EXTERNAL function '\" +\n            funcName +\n            \"' which has not been bound (and ink fallbacks disabled).\"\n        );\n      }\n    }\n\n    // Pop arguments\n    let args: any[] = [];\n    for (let i = 0; i < numberOfArguments; ++i) {\n      // var poppedObj = state.PopEvaluationStack () as Value;\n      let poppedObj = asOrThrows(this.state.PopEvaluationStack(), Value);\n      let valueObj = poppedObj.valueObject;\n      args.push(valueObj);\n    }\n\n    // Reverse arguments from the order they were popped,\n    // so they're the right way round again.\n    args.reverse();\n\n    // Run the function!\n    let funcResult = funcDef!.function(args);\n\n    // Convert return value (if any) to the a type that the ink engine can use\n    let returnObj = null;\n    if (funcResult != null) {\n      returnObj = Value.Create(funcResult);\n      this.Assert(\n        returnObj !== null,\n        \"Could not create ink value from returned object of type \" +\n          typeof funcResult\n      );\n    } else {\n      returnObj = new Void();\n    }\n\n    this.state.PushEvaluationStack(returnObj);\n  }\n\n  public BindExternalFunctionGeneral(\n    funcName: string,\n    func: Story.ExternalFunction,\n    lookaheadSafe: boolean = true\n  ) {\n    this.IfAsyncWeCant(\"bind an external function\");\n    this.Assert(\n      !this._externals.has(funcName),\n      \"Function '\" + funcName + \"' has already been bound.\"\n    );\n    this._externals.set(funcName, {\n      function: func,\n      lookAheadSafe: lookaheadSafe,\n    });\n  }\n\n  public TryCoerce(value: any) {\n    // We're skipping type coercition in this implementation. First of, js\n    // is loosely typed, so it's not that important. Secondly, there is no\n    // clean way (AFAIK) for the user to describe what type of parameters\n    // they expect.\n    return value;\n  }\n\n  public BindExternalFunction(\n    funcName: string,\n    func: Story.ExternalFunction,\n    lookaheadSafe: boolean = false\n  ) {\n    this.Assert(func != null, \"Can't bind a null function\");\n\n    this.BindExternalFunctionGeneral(\n      funcName,\n      (args: any) => {\n        this.Assert(\n          args.length >= func.length,\n          \"External function expected \" + func.length + \" arguments\"\n        );\n\n        let coercedArgs = [];\n        for (let i = 0, l = args.length; i < l; i++) {\n          coercedArgs[i] = this.TryCoerce(args[i]);\n        }\n        return func.apply(null, coercedArgs);\n      },\n      lookaheadSafe\n    );\n  }\n\n  public UnbindExternalFunction(funcName: string) {\n    this.IfAsyncWeCant(\"unbind an external a function\");\n    this.Assert(\n      this._externals.has(funcName),\n      \"Function '\" + funcName + \"' has not been bound.\"\n    );\n    this._externals.delete(funcName);\n  }\n\n  public ValidateExternalBindings(): void;\n  public ValidateExternalBindings(\n    c: Container | null,\n    missingExternals: Set<string>\n  ): void;\n  public ValidateExternalBindings(\n    o: InkObject | null,\n    missingExternals: Set<string>\n  ): void;\n  public ValidateExternalBindings() {\n    let c: Container | null = null;\n    let o: InkObject | null = null;\n    let missingExternals: Set<string> = arguments[1] || new Set();\n\n    if (arguments[0] instanceof Container) {\n      c = arguments[0];\n    }\n\n    if (arguments[0] instanceof InkObject) {\n      o = arguments[0];\n    }\n\n    if (c === null && o === null) {\n      this.ValidateExternalBindings(\n        this._mainContentContainer,\n        missingExternals\n      );\n      this._hasValidatedExternals = true;\n\n      // No problem! Validation complete\n      if (missingExternals.size == 0) {\n        this._hasValidatedExternals = true;\n      } else {\n        let message = \"Error: Missing function binding for external\";\n        message += missingExternals.size > 1 ? \"s\" : \"\";\n        message += \": '\";\n        message += Array.from(missingExternals).join(\"', '\");\n        message += \"' \";\n        message += this.allowExternalFunctionFallbacks\n          ? \", and no fallback ink function found.\"\n          : \" (ink fallbacks disabled)\";\n\n        this.Error(message);\n      }\n    } else if (c != null) {\n      for (let innerContent of c.content) {\n        let container = innerContent as Container;\n        if (container == null || !container.hasValidName)\n          this.ValidateExternalBindings(innerContent, missingExternals);\n      }\n      for (let [, value] of c.namedContent) {\n        this.ValidateExternalBindings(\n          asOrNull(value, InkObject),\n          missingExternals\n        );\n      }\n    } else if (o != null) {\n      let divert = asOrNull(o, Divert);\n      if (divert && divert.isExternal) {\n        let name = divert.targetPathString;\n        if (name === null) {\n          return throwNullException(\"name\");\n        }\n        if (!this._externals.has(name)) {\n          if (this.allowExternalFunctionFallbacks) {\n            let fallbackFound =\n              this.mainContentContainer.namedContent.has(name);\n            if (!fallbackFound) {\n              missingExternals.add(name);\n            }\n          } else {\n            missingExternals.add(name);\n          }\n        }\n      }\n    }\n  }\n\n  public ObserveVariable(\n    variableName: string,\n    observer: Story.VariableObserver\n  ) {\n    this.IfAsyncWeCant(\"observe a new variable\");\n\n    if (this._variableObservers === null) this._variableObservers = new Map();\n\n    if (!this.state.variablesState.GlobalVariableExistsWithName(variableName))\n      throw new Error(\n        \"Cannot observe variable '\" +\n          variableName +\n          \"' because it wasn't declared in the ink story.\"\n      );\n\n    if (this._variableObservers.has(variableName)) {\n      this._variableObservers.get(variableName)!.push(observer);\n    } else {\n      this._variableObservers.set(variableName, [observer]);\n    }\n  }\n\n  public ObserveVariables(\n    variableNames: string[],\n    observers: Story.VariableObserver[]\n  ) {\n    for (let i = 0, l = variableNames.length; i < l; i++) {\n      this.ObserveVariable(variableNames[i], observers[i]);\n    }\n  }\n\n  public RemoveVariableObserver(\n    observer?: Story.VariableObserver,\n    specificVariableName?: string\n  ) {\n    // A couple of things to know about this method:\n    //\n    // 1. Since `RemoveVariableObserver` is exposed to the JavaScript world,\n    //    optionality is marked as `undefined` rather than `null`.\n    //    To keep things simple, null-checks are performed using regular\n    //    equality operators, where undefined == null.\n    //\n    // 2. Since C# delegates are translated to arrays of functions,\n    //    -= becomes a call to splice and null-checks are replaced by\n    //    emptiness-checks.\n    //\n    this.IfAsyncWeCant(\"remove a variable observer\");\n\n    if (this._variableObservers === null) return;\n\n    if (specificVariableName != null) {\n      if (this._variableObservers.has(specificVariableName)) {\n        if (observer != null) {\n          let variableObservers =\n            this._variableObservers.get(specificVariableName);\n          if (variableObservers != null) {\n            variableObservers.splice(variableObservers.indexOf(observer), 1);\n            if (variableObservers.length === 0) {\n              this._variableObservers.delete(specificVariableName);\n            }\n          }\n        } else {\n          this._variableObservers.delete(specificVariableName);\n        }\n      }\n    } else if (observer != null) {\n      let keys = this._variableObservers.keys();\n      for (let varName of keys) {\n        let variableObservers = this._variableObservers.get(varName);\n        if (variableObservers != null) {\n          variableObservers.splice(variableObservers.indexOf(observer), 1);\n          if (variableObservers.length === 0) {\n            this._variableObservers.delete(varName);\n          }\n        }\n      }\n    }\n  }\n\n  public VariableStateDidChangeEvent(\n    variableName: string,\n    newValueObj: InkObject\n  ) {\n    if (this._variableObservers === null) return;\n\n    let observers = this._variableObservers.get(variableName);\n    if (typeof observers !== \"undefined\") {\n      if (!(newValueObj instanceof Value)) {\n        throw new Error(\n          \"Tried to get the value of a variable that isn't a standard type\"\n        );\n      }\n      // var val = newValueObj as Value;\n      let val = asOrThrows(newValueObj, Value);\n\n      for (let observer of observers) {\n        observer(variableName, val.valueObject);\n      }\n    }\n  }\n\n  get globalTags() {\n    return this.TagsAtStartOfFlowContainerWithPathString(\"\");\n  }\n\n  public TagsForContentAtPath(path: string) {\n    return this.TagsAtStartOfFlowContainerWithPathString(path);\n  }\n\n  public TagsAtStartOfFlowContainerWithPathString(pathString: string) {\n    let path = new Path(pathString);\n\n    let flowContainer = this.ContentAtPath(path).container;\n    if (flowContainer === null) {\n      return throwNullException(\"flowContainer\");\n    }\n    while (true) {\n      let firstContent: InkObject = flowContainer.content[0];\n      if (firstContent instanceof Container) flowContainer = firstContent;\n      else break;\n    }\n\n    let inTag = false;\n    let tags: string[] | null = null;\n\n    for (let c of flowContainer.content) {\n      // var tag = c as Runtime.Tag;\n      let command = asOrNull(c, ControlCommand);\n\n      if (command != null) {\n        if (command.commandType == ControlCommand.CommandType.BeginTag) {\n          inTag = true;\n        } else if (command.commandType == ControlCommand.CommandType.EndTag) {\n          inTag = false;\n        }\n      } else if (inTag) {\n        let str = asOrNull(c, StringValue);\n        if (str !== null) {\n          if (tags === null) tags = [];\n          if (str.value !== null) tags.push(str.value);\n        } else {\n          this.Error(\n            \"Tag contained non-text content. Only plain text is allowed when using globalTags or TagsAtContentPath. If you want to evaluate dynamic content, you need to use story.Continue().\"\n          );\n        }\n      } else {\n        break;\n      }\n    }\n\n    return tags;\n  }\n\n  public BuildStringOfHierarchy() {\n    let sb = new StringBuilder();\n\n    this.mainContentContainer.BuildStringOfHierarchy(\n      sb,\n      0,\n      this.state.currentPointer.Resolve()\n    );\n\n    return sb.toString();\n  }\n\n  public BuildStringOfContainer(container: Container) {\n    let sb = new StringBuilder();\n    container.BuildStringOfHierarchy(\n      sb,\n      0,\n      this.state.currentPointer.Resolve()\n    );\n    return sb.toString();\n  }\n\n  public NextContent() {\n    this.state.previousPointer = this.state.currentPointer.copy();\n\n    if (!this.state.divertedPointer.isNull) {\n      this.state.currentPointer = this.state.divertedPointer.copy();\n      this.state.divertedPointer = Pointer.Null;\n\n      this.VisitChangedContainersDueToDivert();\n\n      if (!this.state.currentPointer.isNull) {\n        return;\n      }\n    }\n\n    let successfulPointerIncrement = this.IncrementContentPointer();\n\n    if (!successfulPointerIncrement) {\n      let didPop = false;\n\n      if (this.state.callStack.CanPop(PushPopType.Function)) {\n        this.state.PopCallStack(PushPopType.Function);\n\n        if (this.state.inExpressionEvaluation) {\n          this.state.PushEvaluationStack(new Void());\n        }\n\n        didPop = true;\n      } else if (this.state.callStack.canPopThread) {\n        this.state.callStack.PopThread();\n\n        didPop = true;\n      } else {\n        this.state.TryExitFunctionEvaluationFromGame();\n      }\n\n      if (didPop && !this.state.currentPointer.isNull) {\n        this.NextContent();\n      }\n    }\n  }\n\n  public IncrementContentPointer() {\n    let successfulIncrement = true;\n\n    let pointer = this.state.callStack.currentElement.currentPointer.copy();\n    pointer.index++;\n\n    if (pointer.container === null) {\n      return throwNullException(\"pointer.container\");\n    }\n    while (pointer.index >= pointer.container.content.length) {\n      successfulIncrement = false;\n\n      // Container nextAncestor = pointer.container.parent as Container;\n      let nextAncestor = asOrNull(pointer.container.parent, Container);\n      if (nextAncestor instanceof Container === false) {\n        break;\n      }\n\n      let indexInAncestor = nextAncestor!.content.indexOf(pointer.container);\n      if (indexInAncestor == -1) {\n        break;\n      }\n\n      pointer = new Pointer(nextAncestor, indexInAncestor);\n\n      pointer.index++;\n\n      successfulIncrement = true;\n      if (pointer.container === null) {\n        return throwNullException(\"pointer.container\");\n      }\n    }\n\n    if (!successfulIncrement) pointer = Pointer.Null;\n\n    this.state.callStack.currentElement.currentPointer = pointer.copy();\n\n    return successfulIncrement;\n  }\n\n  public TryFollowDefaultInvisibleChoice() {\n    let allChoices = this._state.currentChoices;\n\n    let invisibleChoices = allChoices.filter((c) => c.isInvisibleDefault);\n\n    if (\n      invisibleChoices.length == 0 ||\n      allChoices.length > invisibleChoices.length\n    )\n      return false;\n\n    let choice = invisibleChoices[0];\n\n    if (choice.targetPath === null) {\n      return throwNullException(\"choice.targetPath\");\n    }\n\n    if (choice.threadAtGeneration === null) {\n      return throwNullException(\"choice.threadAtGeneration\");\n    }\n\n    this.state.callStack.currentThread = choice.threadAtGeneration;\n\n    if (this._stateSnapshotAtLastNewline !== null) {\n      this.state.callStack.currentThread = this.state.callStack.ForkThread();\n    }\n\n    this.ChoosePath(choice.targetPath, false);\n\n    return true;\n  }\n\n  public NextSequenceShuffleIndex() {\n    // var numElementsIntVal = state.PopEvaluationStack () as IntValue;\n    let numElementsIntVal = asOrNull(this.state.PopEvaluationStack(), IntValue);\n    if (!(numElementsIntVal instanceof IntValue)) {\n      this.Error(\"expected number of elements in sequence for shuffle index\");\n      return 0;\n    }\n\n    let seqContainer = this.state.currentPointer.container;\n    if (seqContainer === null) {\n      return throwNullException(\"seqContainer\");\n    }\n\n    // Originally a primitive type, but here, can be null.\n    // TODO: Replace by default value?\n    if (numElementsIntVal.value === null) {\n      return throwNullException(\"numElementsIntVal.value\");\n    }\n    let numElements = numElementsIntVal.value;\n\n    // var seqCountVal = state.PopEvaluationStack () as IntValue;\n    let seqCountVal = asOrThrows(this.state.PopEvaluationStack(), IntValue);\n    let seqCount = seqCountVal.value;\n\n    // Originally a primitive type, but here, can be null.\n    // TODO: Replace by default value?\n    if (seqCount === null) {\n      return throwNullException(\"seqCount\");\n    }\n\n    let loopIndex = seqCount / numElements;\n    let iterationIndex = seqCount % numElements;\n\n    let seqPathStr = seqContainer.path.toString();\n    let sequenceHash = 0;\n    for (let i = 0, l = seqPathStr.length; i < l; i++) {\n      sequenceHash += seqPathStr.charCodeAt(i) || 0;\n    }\n    let randomSeed = sequenceHash + loopIndex + this.state.storySeed;\n    let random = new PRNG(Math.floor(randomSeed));\n\n    let unpickedIndices = [];\n    for (let i = 0; i < numElements; ++i) {\n      unpickedIndices.push(i);\n    }\n\n    for (let i = 0; i <= iterationIndex; ++i) {\n      let chosen = random.next() % unpickedIndices.length;\n      let chosenIndex = unpickedIndices[chosen];\n      unpickedIndices.splice(chosen, 1);\n\n      if (i == iterationIndex) {\n        return chosenIndex;\n      }\n    }\n\n    throw new Error(\"Should never reach here\");\n  }\n\n  public Error(message: string, useEndLineNumber = false): never {\n    let e = new StoryException(message);\n    e.useEndLineNumber = useEndLineNumber;\n    throw e;\n  }\n\n  public Warning(message: string) {\n    this.AddError(message, true);\n  }\n\n  public AddError(\n    message: string,\n    isWarning = false,\n    useEndLineNumber = false\n  ) {\n    let dm = this.currentDebugMetadata;\n\n    let errorTypeStr = isWarning ? \"WARNING\" : \"ERROR\";\n\n    if (dm != null) {\n      let lineNum = useEndLineNumber ? dm.endLineNumber : dm.startLineNumber;\n      message =\n        \"RUNTIME \" +\n        errorTypeStr +\n        \": '\" +\n        dm.fileName +\n        \"' line \" +\n        lineNum +\n        \": \" +\n        message;\n    } else if (!this.state.currentPointer.isNull) {\n      message =\n        \"RUNTIME \" +\n        errorTypeStr +\n        \": (\" +\n        this.state.currentPointer +\n        \"): \" +\n        message;\n    } else {\n      message = \"RUNTIME \" + errorTypeStr + \": \" + message;\n    }\n\n    this.state.AddError(message, isWarning);\n\n    // In a broken state don't need to know about any other errors.\n    if (!isWarning) this.state.ForceEnd();\n  }\n\n  public Assert(condition: boolean, message: string | null = null) {\n    if (condition == false) {\n      if (message == null) {\n        message = \"Story assert\";\n      }\n\n      throw new Error(message + \" \" + this.currentDebugMetadata);\n    }\n  }\n\n  get currentDebugMetadata(): DebugMetadata | null {\n    let dm: DebugMetadata | null;\n\n    let pointer = this.state.currentPointer;\n    if (!pointer.isNull && pointer.Resolve() !== null) {\n      dm = pointer.Resolve()!.debugMetadata;\n      if (dm !== null) {\n        return dm;\n      }\n    }\n\n    for (let i = this.state.callStack.elements.length - 1; i >= 0; --i) {\n      pointer = this.state.callStack.elements[i].currentPointer;\n      if (!pointer.isNull && pointer.Resolve() !== null) {\n        dm = pointer.Resolve()!.debugMetadata;\n        if (dm !== null) {\n          return dm;\n        }\n      }\n    }\n\n    for (let i = this.state.outputStream.length - 1; i >= 0; --i) {\n      let outputObj = this.state.outputStream[i];\n      dm = outputObj.debugMetadata;\n      if (dm !== null) {\n        return dm;\n      }\n    }\n\n    return null;\n  }\n\n  get mainContentContainer() {\n    if (this._temporaryEvaluationContainer) {\n      return this._temporaryEvaluationContainer;\n    } else {\n      return this._mainContentContainer;\n    }\n  }\n\n  /**\n   * `_mainContentContainer` is almost guaranteed to be set in the\n   * constructor, unless the json is malformed.\n   */\n  private _mainContentContainer!: Container;\n  private _listDefinitions: ListDefinitionsOrigin | null = null;\n\n  private _externals: Map<string, Story.ExternalFunctionDef>;\n  private _variableObservers: Map<string, Story.VariableObserver[]> | null =\n    null;\n  private _hasValidatedExternals: boolean = false;\n\n  private _temporaryEvaluationContainer: Container | null = null;\n\n  /**\n   * `state` is almost guaranteed to be set in the constructor, unless\n   * using the compiler-specific constructor which will likely not be used in\n   * the real world.\n   */\n  private _state!: StoryState;\n\n  private _asyncContinueActive: boolean = false;\n  private _stateSnapshotAtLastNewline: StoryState | null = null;\n  private _sawLookaheadUnsafeFunctionAfterNewline: boolean = false;\n\n  private _recursiveContinueCount: number = 0;\n\n  private _asyncSaving: boolean = false;\n\n  private _profiler: any | null = null; // TODO: Profiler\n}\n\nexport namespace Story {\n  export enum OutputStateChange {\n    NoChange = 0,\n    ExtendedBeyondNewline = 1,\n    NewlineRemoved = 2,\n  }\n\n  export interface EvaluateFunctionTextOutput {\n    returned: any;\n    output: string;\n  }\n\n  export interface ExternalFunctionDef {\n    function: ExternalFunction;\n    lookAheadSafe: boolean;\n  }\n\n  export type VariableObserver = (variableName: string, newValue: any) => void;\n  export type ExternalFunction = (...args: any) => any;\n}\n","import { AuthorWarning } from \"./AuthorWarning\";\nimport { ConstantDeclaration } from \"./Declaration/ConstantDeclaration\";\nimport { Container as RuntimeContainer } from \"../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../engine/ControlCommand\";\nimport { ErrorHandler } from \"../../../engine/Error\";\nimport { ErrorType } from \"../ErrorType\";\nimport { Expression } from \"./Expression/Expression\";\nimport { ExternalDeclaration } from \"./Declaration/ExternalDeclaration\";\nimport { FlowBase } from \"./Flow/FlowBase\";\nimport { FlowLevel } from \"./Flow/FlowLevel\";\nimport { IncludedFile } from \"./IncludedFile\";\nimport { ListDefinition } from \"./List/ListDefinition\";\nimport { ListElementDefinition } from \"./List/ListElementDefinition\";\nimport { ParsedObject } from \"./Object\";\nimport { Story as RuntimeStory } from \"../../../engine/Story\";\nimport { SymbolType } from \"./SymbolType\";\nimport { Text } from \"./Text\";\nimport { VariableAssignment as RuntimeVariableAssignment } from \"../../../engine/VariableAssignment\";\nimport { Identifier } from \"./Identifier\";\nimport { asOrNull } from \"../../../engine/TypeAssertion\";\nimport { ClosestFlowBase } from \"./Flow/ClosestFlowBase\";\nimport { FunctionCall } from \"./FunctionCall\";\nimport { Path } from \"./Path\";\nimport { VariableAssignment } from \"./Variable/VariableAssignment\";\n\nexport class Story extends FlowBase {\n  public static readonly IsReservedKeyword = (name?: string): boolean => {\n    switch (name) {\n      case \"true\":\n      case \"false\":\n      case \"not\":\n      case \"return\":\n      case \"else\":\n      case \"VAR\":\n      case \"CONST\":\n      case \"temp\":\n      case \"LIST\":\n      case \"function\":\n        return true;\n    }\n\n    return false;\n  };\n\n  private _errorHandler: ErrorHandler | null = null;\n  private _hadError: boolean = false;\n  private _hadWarning: boolean = false;\n  private _dontFlattenContainers: Set<RuntimeContainer> = new Set();\n  private _listDefs: Map<string, ListDefinition> = new Map();\n\n  get flowLevel(): FlowLevel {\n    return FlowLevel.Story;\n  }\n\n  get hadError(): boolean {\n    return this._hadError;\n  }\n\n  get hadWarning(): boolean {\n    return this._hadWarning;\n  }\n\n  public constants: Map<string, Expression> = new Map();\n  public externals: Map<string, ExternalDeclaration> = new Map();\n\n  // Build setting for exporting:\n  // When true, the visit count for *all* knots, stitches, choices,\n  // and gathers is counted. When false, only those that are direclty\n  // referenced by the ink are recorded. Use this flag to allow game-side\n  // querying of  arbitrary knots/stitches etc.\n  // Storing all counts is more robust and future proof (updates to the story file\n  // that reference previously uncounted visits are possible, but generates a much\n  // larger safe file, with a lot of potentially redundant counts.\n  public countAllVisits: boolean = false;\n\n  constructor(toplevelObjects: ParsedObject[], isInclude: boolean = false) {\n    // Don't do anything much on construction, leave it lightweight until\n    // the ExportRuntime method is called.\n    super(null, toplevelObjects, null, false, isInclude);\n  }\n\n  get typeName(): string {\n    return \"Story\";\n  }\n\n  // Before this function is called, we have IncludedFile objects interspersed\n  // in our content wherever an include statement was.\n  // So that the include statement can be added in a sensible place (e.g. the\n  // top of the file) without side-effects of jumping into a knot that was\n  // defined in that include, we separate knots and stitches from anything\n  // else defined at the top scope of the included file.\n  //\n  // Algorithm: For each IncludedFile we find, split its contents into\n  // knots/stiches and any other content. Insert the normal content wherever\n  // the include statement was, and append the knots/stitches to the very\n  // end of the main story.\n  public PreProcessTopLevelObjects(topLevelContent: ParsedObject[]): void {\n    super.PreProcessTopLevelObjects(topLevelContent);\n\n    const flowsFromOtherFiles = [];\n\n    // Inject included files\n    for (let obj of topLevelContent) {\n      if (obj instanceof IncludedFile) {\n        const file: IncludedFile = obj;\n\n        // Remove the IncludedFile itself\n        const posOfObj = topLevelContent.indexOf(obj);\n        topLevelContent.splice(posOfObj, 1);\n\n        // When an included story fails to load, the include\n        // line itself is still valid, so we have to handle it here\n        if (file.includedStory) {\n          const nonFlowContent: ParsedObject[] = [];\n          const subStory = file.includedStory;\n          // Allow empty file\n          if (subStory.content != null) {\n            for (const subStoryObj of subStory.content) {\n              if (subStoryObj instanceof FlowBase) {\n                flowsFromOtherFiles.push(subStoryObj);\n              } else {\n                nonFlowContent.push(subStoryObj);\n              }\n            }\n\n            // Add newline on the end of the include\n            nonFlowContent.push(new Text(\"\\n\"));\n\n            // Add contents of the file in its place\n            topLevelContent.splice(posOfObj, 0, ...nonFlowContent);\n\n            // Skip past the content of this sub story\n            // (since it will already have recursively included\n            //  any lines from other files)\n          }\n        }\n\n        // Include object has been removed, with possible content inserted,\n        // and position of 'i' will have been determined already.\n        continue;\n      }\n    }\n\n    // Add the flows we collected from the included files to the\n    // end of our list of our content\n    topLevelContent.splice(0, 0, ...flowsFromOtherFiles);\n  }\n\n  public readonly ExportRuntime = (\n    errorHandler: ErrorHandler | null = null\n  ): RuntimeStory | null => {\n    this._errorHandler = errorHandler;\n\n    // Find all constants before main export begins, so that VariableReferences know\n    // whether to generate a runtime variable reference or the literal value\n    this.constants = new Map();\n    for (const constDecl of this.FindAll(ConstantDeclaration)()) {\n      // Check for duplicate definitions\n      const existingDefinition: Expression = this.constants.get(\n        constDecl.constantName!\n      ) as any;\n\n      if (existingDefinition) {\n        if (!existingDefinition.Equals(constDecl.expression)) {\n          const errorMsg = `CONST '${constDecl.constantName}' has been redefined with a different value. Multiple definitions of the same CONST are valid so long as they contain the same value. Initial definition was on ${existingDefinition.debugMetadata}.`;\n          this.Error(errorMsg, constDecl, false);\n        }\n      }\n\n      this.constants.set(constDecl.constantName!, constDecl.expression);\n    }\n\n    // List definitions are treated like constants too - they should be usable\n    // from other variable declarations.\n    this._listDefs = new Map();\n    for (const listDef of this.FindAll<ListDefinition>(ListDefinition)()) {\n      if (listDef.identifier?.name) {\n        this._listDefs.set(listDef.identifier?.name, listDef);\n      }\n    }\n\n    this.externals = new Map();\n\n    // Resolution of weave point names has to come first, before any runtime code generation\n    // since names have to be ready before diverts start getting created.\n    // (It used to be done in the constructor for a weave, but didn't allow us to generate\n    // errors when name resolution failed.)\n    this.ResolveWeavePointNaming();\n\n    // Get default implementation of runtimeObject, which calls ContainerBase's generation method\n    const rootContainer = this.runtimeObject as RuntimeContainer;\n\n    // Export initialisation of global variables\n    // TODO: We *could* add this as a declarative block to the story itself...\n    const variableInitialisation = new RuntimeContainer();\n    variableInitialisation.AddContent(RuntimeControlCommand.EvalStart());\n\n    // Global variables are those that are local to the story and marked as global\n    const runtimeLists = [];\n    for (const [key, value] of this.variableDeclarations) {\n      if (value.isGlobalDeclaration) {\n        if (value.listDefinition) {\n          this._listDefs.set(key, value.listDefinition);\n          variableInitialisation.AddContent(\n            value.listDefinition.runtimeObject!\n          );\n\n          runtimeLists.push(value.listDefinition.runtimeListDefinition);\n        } else {\n          if (!value.expression) {\n            throw new Error();\n          }\n          value.expression.GenerateIntoContainer(variableInitialisation);\n        }\n\n        const runtimeVarAss = new RuntimeVariableAssignment(key, true);\n        runtimeVarAss.isGlobal = true;\n        variableInitialisation.AddContent(runtimeVarAss);\n      }\n    }\n\n    variableInitialisation.AddContent(RuntimeControlCommand.EvalEnd());\n    variableInitialisation.AddContent(RuntimeControlCommand.End());\n\n    if (this.variableDeclarations.size > 0) {\n      variableInitialisation.name = \"global decl\";\n      rootContainer.AddToNamedContentOnly(variableInitialisation);\n    }\n\n    // Signal that it's safe to exit without error, even if there are no choices generated\n    // (this only happens at the end of top level content that isn't in any particular knot)\n    rootContainer.AddContent(RuntimeControlCommand.Done());\n\n    // Replace runtimeObject with Story object instead of the Runtime.Container generated by Parsed.ContainerBase\n    const runtimeStory = new RuntimeStory(rootContainer, runtimeLists);\n\n    this.runtimeObject = runtimeStory;\n\n    if (this.hadError) {\n      return null;\n    }\n\n    // Optimisation step - inline containers that can be\n    this.FlattenContainersIn(rootContainer);\n\n    // Now that the story has been fulled parsed into a hierarchy,\n    // and the derived runtime hierarchy has been built, we can\n    // resolve referenced symbols such as variables and paths.\n    // e.g. for paths \" -> knotName --> stitchName\" into an INKPath (knotName.stitchName)\n    // We don't make any assumptions that the INKPath follows the same\n    // conventions as the script format, so we resolve to actual objects before\n    // translating into an INKPath. (This also allows us to choose whether\n    // we want the paths to be absolute)\n    this.ResolveReferences(this);\n\n    if (this.hadError) {\n      return null;\n    }\n\n    runtimeStory.ResetState();\n\n    return runtimeStory;\n  };\n\n  public readonly ResolveList = (listName: string): ListDefinition | null => {\n    let list: ListDefinition | null | undefined = this._listDefs.get(listName);\n    if (!list) {\n      return null;\n    }\n\n    return list;\n  };\n\n  public readonly ResolveListItem = (\n    listName: string | null,\n    itemName: string,\n    source: ParsedObject | null = null\n  ): ListElementDefinition | null => {\n    let listDef: ListDefinition | null | undefined = null;\n\n    // Search a specific list if we know its name (i.e. the form listName.itemName)\n    if (listName) {\n      if (!(listDef = this._listDefs.get(listName))) {\n        return null;\n      }\n\n      return listDef.ItemNamed(itemName);\n    } else {\n      // Otherwise, try to search all lists\n\n      let foundItem: ListElementDefinition | null = null;\n      let originalFoundList: ListDefinition | null = null;\n\n      for (const [, value] of this._listDefs.entries()) {\n        const itemInThisList = value.ItemNamed(itemName);\n        if (itemInThisList) {\n          if (foundItem) {\n            this.Error(\n              `Ambiguous item name '${itemName}' found in multiple sets, including ${\n                originalFoundList!.identifier\n              } and ${value!.identifier}`,\n              source,\n              false\n            );\n          } else {\n            foundItem = itemInThisList;\n            originalFoundList = value!;\n          }\n        }\n      }\n\n      return foundItem;\n    }\n  };\n\n  public readonly FlattenContainersIn = (container: RuntimeContainer): void => {\n    // Need to create a collection to hold the inner containers\n    // because otherwise we'd end up modifying during iteration\n    const innerContainers = new Set<RuntimeContainer>();\n    if (container.content) {\n      for (const c of container.content) {\n        const innerContainer = asOrNull(c, RuntimeContainer);\n        if (innerContainer) {\n          innerContainers.add(innerContainer);\n        }\n      }\n    }\n\n    // Can't flatten the named inner containers, but we can at least\n    // iterate through their children\n    if (container.namedContent) {\n      for (const [, value] of container.namedContent) {\n        const namedInnerContainer = asOrNull(value, RuntimeContainer);\n        if (namedInnerContainer) {\n          innerContainers.add(namedInnerContainer);\n        }\n      }\n    }\n\n    for (const innerContainer of innerContainers) {\n      this.TryFlattenContainer(innerContainer);\n      this.FlattenContainersIn(innerContainer);\n    }\n  };\n\n  public readonly TryFlattenContainer = (container: RuntimeContainer): void => {\n    if (\n      (container.namedContent && container.namedContent.size > 0) ||\n      container.hasValidName ||\n      this._dontFlattenContainers.has(container)\n    ) {\n      return;\n    }\n\n    // Inline all the content in container into the parent\n    const parentContainer = asOrNull(container.parent, RuntimeContainer);\n    if (parentContainer) {\n      let contentIdx = parentContainer.content.indexOf(container);\n      parentContainer.content.splice(contentIdx, 1);\n\n      const dm = container.ownDebugMetadata;\n\n      if (container.content) {\n        for (const innerContent of container.content) {\n          innerContent.parent = null;\n          if (dm !== null && innerContent.ownDebugMetadata === null) {\n            innerContent.debugMetadata = dm;\n          }\n\n          parentContainer.InsertContent(innerContent, contentIdx);\n          contentIdx += 1;\n        }\n      }\n    }\n  };\n\n  public readonly Error = (\n    message: string,\n    source: ParsedObject | null | undefined,\n    isWarning: boolean | null | undefined\n  ) => {\n    let errorType: ErrorType = isWarning ? ErrorType.Warning : ErrorType.Error;\n\n    let sb = \"\";\n    if (source instanceof AuthorWarning) {\n      sb += \"TODO: \";\n      errorType = ErrorType.Author;\n    } else if (isWarning) {\n      sb += \"WARNING: \";\n    } else {\n      sb += \"ERROR: \";\n    }\n\n    if (\n      source &&\n      source.debugMetadata !== null &&\n      source.debugMetadata.startLineNumber >= 1\n    ) {\n      if (source.debugMetadata.fileName != null) {\n        sb += `'${source.debugMetadata.fileName}' `;\n      }\n\n      sb += `line ${source.debugMetadata.startLineNumber}: `;\n    }\n\n    sb += message;\n\n    message = sb;\n\n    if (this._errorHandler !== null) {\n      this._errorHandler(message, errorType);\n    } else {\n      throw new Error(message);\n    }\n\n    this._hadError = errorType === ErrorType.Error;\n    this._hadWarning = errorType === ErrorType.Warning;\n  };\n\n  public readonly ResetError = (): void => {\n    this._hadError = false;\n    this._hadWarning = false;\n  };\n\n  public readonly IsExternal = (namedFuncTarget: string): boolean =>\n    this.externals.has(namedFuncTarget);\n\n  public readonly AddExternal = (decl: ExternalDeclaration): void => {\n    if (this.externals.has(decl.name!)) {\n      this.Error(\n        `Duplicate EXTERNAL definition of '${decl.name}'`,\n        decl,\n        false\n      );\n    } else if (decl.name) {\n      this.externals.set(decl.name, decl);\n    }\n  };\n\n  public readonly DontFlattenContainer = (\n    container: RuntimeContainer\n  ): void => {\n    this._dontFlattenContainers.add(container);\n  };\n\n  public readonly NameConflictError = (\n    obj: ParsedObject,\n    name: string,\n    existingObj: ParsedObject,\n    typeNameToPrint: string\n  ): void => {\n    obj.Error(\n      `${typeNameToPrint} '${name}': name has already been used for a ${existingObj.typeName.toLowerCase()} on ${\n        existingObj.debugMetadata\n      }`\n    );\n  };\n\n  // Check given symbol type against everything that's of a higher priority in the ordered SymbolType enum (above).\n  // When the given symbol type level is reached, we early-out / return.\n  public readonly CheckForNamingCollisions = (\n    obj: ParsedObject,\n    identifier: Identifier,\n    symbolType: SymbolType,\n    typeNameOverride: string = \"\"\n  ): void => {\n    const typeNameToPrint: string = typeNameOverride || obj.typeName;\n    if (Story.IsReservedKeyword(identifier?.name)) {\n      obj.Error(\n        `'${identifier}' cannot be used for the name of a ${typeNameToPrint.toLowerCase()} because it's a reserved keyword`\n      );\n      return;\n    } else if (FunctionCall.IsBuiltIn(identifier?.name || \"\")) {\n      obj.Error(\n        `'${identifier}' cannot be used for the name of a ${typeNameToPrint.toLowerCase()} because it's a built in function`\n      );\n\n      return;\n    }\n\n    // Top level knots\n    const maybeKnotOrFunction = this.ContentWithNameAtLevel(\n      identifier?.name || \"\",\n      FlowLevel.Knot\n    );\n\n    const knotOrFunction = asOrNull(maybeKnotOrFunction, FlowBase);\n\n    if (\n      knotOrFunction &&\n      (knotOrFunction !== obj || symbolType === SymbolType.Arg)\n    ) {\n      this.NameConflictError(\n        obj,\n        identifier?.name || \"\",\n        knotOrFunction,\n        typeNameToPrint\n      );\n      return;\n    }\n\n    if (symbolType < SymbolType.List) {\n      return;\n    }\n\n    // Lists\n    for (const [key, value] of this._listDefs) {\n      if (\n        identifier?.name === key &&\n        obj !== value &&\n        value.variableAssignment !== obj\n      ) {\n        this.NameConflictError(obj, identifier?.name, value, typeNameToPrint);\n      }\n\n      // We don't check for conflicts between individual elements in\n      // different lists because they are namespaced.\n      if (!(obj instanceof ListElementDefinition)) {\n        for (const item of value.itemDefinitions) {\n          if (identifier?.name === item.name) {\n            this.NameConflictError(\n              obj,\n              identifier?.name || \"\",\n              item,\n              typeNameToPrint\n            );\n          }\n        }\n      }\n    }\n\n    // Don't check for VAR->VAR conflicts because that's handled separately\n    // (necessary since checking looks up in a dictionary)\n    if (symbolType <= SymbolType.Var) {\n      return;\n    }\n\n    // Global variable collision\n    const varDecl: VariableAssignment | null =\n      (identifier?.name && this.variableDeclarations.get(identifier?.name)) ||\n      null;\n    if (\n      varDecl &&\n      varDecl !== obj &&\n      varDecl.isGlobalDeclaration &&\n      varDecl.listDefinition == null\n    ) {\n      this.NameConflictError(\n        obj,\n        identifier?.name || \"\",\n        varDecl,\n        typeNameToPrint\n      );\n    }\n\n    if (symbolType < SymbolType.SubFlowAndWeave) {\n      return;\n    }\n\n    // Stitches, Choices and Gathers\n    const path = new Path(identifier);\n    const targetContent = path.ResolveFromContext(obj);\n    if (targetContent && targetContent !== obj) {\n      this.NameConflictError(\n        obj,\n        identifier?.name || \"\",\n        targetContent,\n        typeNameToPrint\n      );\n      return;\n    }\n\n    if (symbolType < SymbolType.Arg) {\n      return;\n    }\n\n    // Arguments to the current flow\n    if (symbolType !== SymbolType.Arg) {\n      let flow: FlowBase | null = asOrNull(obj, FlowBase);\n      if (!flow) {\n        flow = ClosestFlowBase(obj);\n      }\n\n      if (flow && flow.hasParameters && flow.args) {\n        for (const arg of flow.args) {\n          if (arg.identifier?.name === identifier?.name) {\n            obj.Error(\n              `${typeNameToPrint} '${identifier}': name has already been used for a argument to ${flow.identifier} on ${flow.debugMetadata}`\n            );\n\n            return;\n          }\n        }\n      }\n    }\n  };\n}\n","import { Container as RuntimeContainer } from \"../../../../engine/Container\";\nimport { ControlCommand as RuntimeControlCommand } from \"../../../../engine/ControlCommand\";\nimport { Expression } from \"./Expression\";\nimport { ParsedObject } from \"../Object\";\nimport { Text } from \"../Text\";\nimport { asOrNull } from \"../../../../engine/TypeAssertion\";\n\nexport class StringExpression extends Expression {\n  get isSingleString() {\n    if (this.content.length !== 1) {\n      return false;\n    }\n\n    const c = this.content[0];\n    if (!(c instanceof Text)) {\n      return false;\n    }\n\n    return true;\n  }\n\n  constructor(content: ParsedObject[]) {\n    super();\n\n    this.AddContent(content);\n  }\n\n  get typeName(): string {\n    return \"String\";\n  }\n\n  public readonly GenerateIntoContainer = (\n    container: RuntimeContainer\n  ): void => {\n    container.AddContent(RuntimeControlCommand.BeginString());\n\n    for (const c of this.content) {\n      container.AddContent(c.runtimeObject);\n    }\n\n    container.AddContent(RuntimeControlCommand.EndString());\n  };\n\n  public readonly toString = (): string => {\n    let sb = \"\";\n    for (const c of this.content) {\n      sb += c;\n    }\n\n    return sb;\n  };\n\n  // Equals override necessary in order to check for CONST multiple definition equality\n  public Equals(obj: ParsedObject): boolean {\n    const otherStr = asOrNull(obj, StringExpression);\n    if (otherStr === null) {\n      return false;\n    }\n\n    // Can only compare direct equality on single strings rather than\n    // complex string expressions that contain dynamic logic\n    if (!this.isSingleString || !otherStr.isSingleString) {\n      return false;\n    }\n\n    const thisTxt = this.toString();\n    const otherTxt = otherStr.toString();\n    return thisTxt === otherTxt;\n  }\n}\n","import { ParsedObject } from \"./Object\";\nimport { ControlCommand } from \"../../../engine/ControlCommand\";\nimport { InkObject as RuntimeObject } from \"../../../engine/Object\";\n\nexport class Tag extends ParsedObject {\n  public isStart: boolean;\n  public inChoice: boolean;\n\n  constructor(isStart: boolean, inChoice: boolean = false) {\n    super();\n    this.isStart = isStart;\n    this.inChoice = inChoice;\n  }\n  get typeName(): string {\n    return \"Tag\";\n  }\n  public readonly GenerateRuntimeObject = (): RuntimeObject => {\n    if (this.isStart) {\n      return ControlCommand.BeginTag();\n    } else {\n      return ControlCommand.EndTag();\n    }\n  };\n\n  public readonly toString = () => {\n    if (this.isStart) {\n      return \"#StartTag\";\n    } else {\n      return \"#EndTag\";\n    }\n  };\n}\n\nimport { Tag as RuntimeTag } from \"../../../engine/Tag\";\nimport { Wrap } from \"./Wrap\";\nexport class LegacyTag extends Wrap<RuntimeTag> {\n  constructor(tag: RuntimeTag) {\n    super(tag);\n  }\n  get typeName(): string {\n    return \"Tag\";\n  }\n}\n","import { IFileHandler } from \"../IFileHandler\";\n\n// This class replaces upstream's DefaultFileHandler. It doesn't perform any\n// resolution and warns the user about providing a proper file handler when\n// INCLUDE statements are parsed. Since the JavaScript parser can be executed in\n// different environments, we let the user decide which FileHandler is best for\n// their use-case. See PosixFileHandler and JsonFileHandler.\nexport class DefaultFileHandler implements IFileHandler {\n  constructor(public readonly rootPath?: string) {}\n\n  readonly ResolveInkFilename = (): string => {\n    throw Error(\n      \"Can't resolve filename because no FileHandler was provided when instantiating the parser / compiler.\"\n    );\n  };\n\n  readonly LoadInkFileContents = (): string => {\n    throw Error(\n      \"Can't load ink content because no FileHandler was provided when instantiating the parser / compiler.\"\n    );\n  };\n}\n","import { Argument } from \"./ParsedHierarchy/Argument\";\nimport { AuthorWarning } from \"./ParsedHierarchy/AuthorWarning\";\nimport { BinaryExpression } from \"./ParsedHierarchy/Expression/BinaryExpression\";\nimport { CharacterRange } from \"./CharacterRange\";\nimport { CharacterSet } from \"./CharacterSet\";\nimport { Choice } from \"./ParsedHierarchy/Choice\";\nimport { CommentEliminator } from \"./CommentEliminator\";\nimport { Conditional } from \"./ParsedHierarchy/Conditional/Conditional\";\nimport { ConditionalSingleBranch } from \"./ParsedHierarchy/Conditional/ConditionalSingleBranch\";\nimport { ContentList } from \"./ParsedHierarchy/ContentList\";\nimport { ConstantDeclaration } from \"./ParsedHierarchy/Declaration/ConstantDeclaration\";\nimport { CustomFlags } from \"./CustomFlags\";\nimport { DebugMetadata } from \"../../engine/DebugMetadata\";\nimport { Divert } from \"./ParsedHierarchy/Divert/Divert\";\nimport { DivertTarget } from \"./ParsedHierarchy/Divert/DivertTarget\";\nimport { Expression } from \"./ParsedHierarchy/Expression/Expression\";\nimport { ErrorHandler } from \"../../engine/Error\";\nimport { ExternalDeclaration } from \"./ParsedHierarchy/Declaration/ExternalDeclaration\";\nimport { FlowDecl } from \"./FlowDecl\";\nimport { FunctionCall } from \"./ParsedHierarchy/FunctionCall\";\nimport { Gather } from \"./ParsedHierarchy/Gather/Gather\";\nimport { Glue } from \"./ParsedHierarchy/Glue\";\nimport { Glue as RuntimeGlue } from \"../../engine/Glue\";\nimport { IFileHandler } from \"../IFileHandler\";\nimport { IncDecExpression } from \"./ParsedHierarchy/Expression/IncDecExpression\";\nimport { IncludedFile } from \"./ParsedHierarchy/IncludedFile\";\nimport { InfixOperator } from \"./InfixOperator\";\nimport { Knot } from \"./ParsedHierarchy/Knot\";\nimport { List } from \"./ParsedHierarchy/List/List\";\nimport { ListDefinition } from \"./ParsedHierarchy/List/ListDefinition\";\nimport { ListElementDefinition } from \"./ParsedHierarchy/List/ListElementDefinition\";\nimport { MultipleConditionExpression } from \"./ParsedHierarchy/Expression/MultipleConditionExpression\";\nimport { ParsedObject } from \"./ParsedHierarchy/Object\";\nimport { Path } from \"./ParsedHierarchy/Path\";\nimport { ReturnType } from \"./ParsedHierarchy/ReturnType\";\nimport { Sequence } from \"./ParsedHierarchy/Sequence/Sequence\";\nimport { SequenceType } from \"./ParsedHierarchy/Sequence/SequenceType\";\nimport { StatementLevel } from \"./StatementLevel\";\nimport { Stitch } from \"./ParsedHierarchy/Stitch\";\nimport { Story } from \"./ParsedHierarchy/Story\";\nimport { StringExpression } from \"./ParsedHierarchy/Expression/StringExpression\";\nimport {\n  StringParser,\n  SpecificParseRule,\n  ParseRule,\n  ParseRuleReturn,\n  ParseSuccess,\n} from \"./StringParser/StringParser\";\nimport { StringParserElement } from \"./StringParser/StringParserElement\";\nimport { Tag } from \"./ParsedHierarchy/Tag\";\nimport { Text } from \"./ParsedHierarchy/Text\";\nimport { TunnelOnwards } from \"./ParsedHierarchy/TunnelOnwards\";\nimport { VariableAssignment } from \"./ParsedHierarchy/Variable/VariableAssignment\";\nimport { VariableReference } from \"./ParsedHierarchy/Variable/VariableReference\";\nimport { UnaryExpression } from \"./ParsedHierarchy/Expression/UnaryExpression\";\nimport { asOrNull, filterUndef } from \"../../engine/TypeAssertion\";\nimport { Identifier } from \"./ParsedHierarchy/Identifier\";\nimport { NumberExpression } from \"./ParsedHierarchy/Expression/NumberExpression\";\nimport { ErrorType } from \"./ErrorType\";\nimport { DefaultFileHandler } from \"../FileHandler/DefaultFileHandler\";\n\nexport class InkParser extends StringParser {\n  /**\n   * Begin base InkParser section.\n   */\n\n  get fileHandler(): IFileHandler {\n    if (!this._fileHandler) {\n      throw new Error(\"No FileHandler defined\");\n    }\n    return this._fileHandler;\n  }\n\n  set fileHandler(value: IFileHandler) {\n    this._fileHandler = value;\n  }\n\n  constructor(\n    str: string,\n    filename: string | null = null,\n    externalErrorHandler: ErrorHandler | null = null,\n    rootParser: InkParser | null = null,\n    fileHandler: IFileHandler | null = null\n  ) {\n    super(str);\n\n    this._filename = filename;\n    this.RegisterExpressionOperators();\n    this.GenerateStatementLevelRules();\n\n    this.errorHandler = this.OnStringParserError;\n\n    this._externalErrorHandler = externalErrorHandler;\n\n    if (fileHandler === null) {\n      this._fileHandler = new DefaultFileHandler();\n    } else {\n      this._fileHandler = fileHandler;\n    }\n\n    if (rootParser === null) {\n      this._rootParser = this;\n      this._openFilenames = [];\n\n      if (this._filename !== null) {\n        const fullRootInkPath = this.fileHandler.ResolveInkFilename(\n          this._filename\n        );\n        this._openFilenames.push(fullRootInkPath);\n      }\n    } else {\n      this._rootParser = rootParser;\n    }\n  }\n\n  // Main entry point\n  // NOTE: This method is named Parse() in upstream.\n  public readonly ParseStory = (): Story => {\n    const topLevelContent: ParsedObject[] = this.StatementsAtLevel(\n      StatementLevel.Top\n    );\n\n    // Note we used to return null if there were any errors, but this would mean\n    // that include files would return completely empty rather than attempting to\n    // continue with errors. Returning an empty include files meant that anything\n    // that *did* compile successfully would otherwise be ignored, generating way\n    // more errors than necessary.\n    return new Story(topLevelContent, this._rootParser !== this);\n  };\n\n  public readonly SeparatedList = <T extends ParseRule>(\n    mainRule: SpecificParseRule<T>,\n    separatorRule: ParseRule\n  ): ParseRuleReturn[] | null => {\n    const firstElement: ParseRuleReturn = this.Parse(mainRule);\n    if (firstElement === null) {\n      return null;\n    }\n\n    const allElements = [];\n    allElements.push(firstElement);\n\n    do {\n      const nextElementRuleId: number = this.BeginRule();\n      let sep = separatorRule();\n      if (sep === null) {\n        this.FailRule(nextElementRuleId);\n        break;\n      }\n\n      const nextElement = this.Parse(mainRule);\n      if (nextElement === null) {\n        this.FailRule(nextElementRuleId);\n        break;\n      }\n\n      this.SucceedRule(nextElementRuleId);\n      allElements.push(nextElement);\n    } while (true);\n\n    return allElements;\n  };\n\n  public PreProcessInputString(str: string): string {\n    const commentEliminator = new CommentEliminator(str);\n    return commentEliminator.Process();\n  }\n\n  public readonly CreateDebugMetadata = (\n    stateAtStart: StringParserElement | null,\n    stateAtEnd: StringParserElement\n  ): DebugMetadata => {\n    const md = new DebugMetadata();\n    md.startLineNumber = (stateAtStart?.lineIndex || 0) + 1;\n    md.endLineNumber = stateAtEnd.lineIndex + 1;\n    md.startCharacterNumber = (stateAtStart?.characterInLineIndex || 0) + 1;\n    md.endCharacterNumber = stateAtEnd.characterInLineIndex + 1;\n    md.fileName = this._filename;\n\n    return md;\n  };\n\n  public readonly RuleDidSucceed = (\n    result: ParseRuleReturn,\n    stateAtStart: StringParserElement | null,\n    stateAtEnd: StringParserElement\n  ): void => {\n    // Apply DebugMetadata based on the state at the start of the rule\n    // (i.e. use line number as it was at the start of the rule)\n    const parsedObj = asOrNull(result, ParsedObject);\n    if (parsedObj) {\n      parsedObj.debugMetadata = this.CreateDebugMetadata(\n        stateAtStart,\n        stateAtEnd\n      );\n    }\n\n    // A list of objects that doesn't already have metadata?\n    const parsedListObjs: ParsedObject[] | null = Array.isArray(result)\n      ? (result as ParsedObject[])\n      : null;\n    if (parsedListObjs !== null) {\n      for (const parsedListObj of parsedListObjs) {\n        const singleObj = asOrNull(parsedListObj, ParsedObject);\n        if (!singleObj) continue;\n        if (!parsedListObj.hasOwnDebugMetadata) {\n          parsedListObj.debugMetadata = this.CreateDebugMetadata(\n            stateAtStart,\n            stateAtEnd\n          );\n        }\n      }\n    }\n\n    const id = asOrNull(result, Identifier);\n    if (id != null) {\n      id.debugMetadata = this.CreateDebugMetadata(stateAtStart, stateAtEnd);\n    }\n  };\n\n  get parsingStringExpression(): boolean {\n    return this.GetFlag(Number(CustomFlags.ParsingString));\n  }\n\n  set parsingStringExpression(value: boolean) {\n    this.SetFlag(Number(CustomFlags.ParsingString), value);\n  }\n\n  get tagActive(): boolean {\n    return this.GetFlag(Number(CustomFlags.TagActive));\n  }\n\n  set tagActive(value: boolean) {\n    this.SetFlag(Number(CustomFlags.TagActive), value);\n  }\n\n  public readonly OnStringParserError = (\n    message: string,\n    index: number,\n    lineIndex: number = 0,\n    isWarning: boolean = false\n  ): void => {\n    const warningType: string = isWarning ? \"WARNING:\" : \"ERROR:\";\n    let fullMessage: string = warningType;\n\n    if (this._filename !== null) {\n      fullMessage += ` '${this._filename}'`;\n    }\n\n    fullMessage += ` line ${lineIndex + 1}: ${message}`;\n\n    if (this._externalErrorHandler !== null) {\n      this._externalErrorHandler(\n        fullMessage,\n        isWarning ? ErrorType.Warning : ErrorType.Error\n      );\n    } else {\n      throw new Error(fullMessage);\n    }\n  };\n\n  public readonly AuthorWarning = (): AuthorWarning | null => {\n    this.Whitespace();\n\n    const identifier = this.Parse(\n      this.IdentifierWithMetadata\n    ) as unknown as Identifier | null;\n    if (identifier === null || identifier.name !== \"TODO\") {\n      return null;\n    }\n\n    this.Whitespace();\n    this.ParseString(\":\");\n    this.Whitespace();\n\n    const message = this.ParseUntilCharactersFromString(\"\\n\\r\");\n\n    if (message) {\n      return new AuthorWarning(message);\n    }\n\n    return null;\n  };\n\n  /**\n   * End base InkParser section.\n   */\n\n  /**\n   * Begin CharacterRanges section.\n   */\n\n  public static readonly LatinBasic: CharacterRange = CharacterRange.Define(\n    \"\\u0041\",\n    \"\\u007A\",\n    new CharacterSet().AddRange(\"\\u005B\", \"\\u0060\")\n  );\n\n  public static readonly LatinExtendedA: CharacterRange = CharacterRange.Define(\n    \"\\u0100\",\n    \"\\u017F\"\n    // no excludes here\n  );\n\n  public static readonly LatinExtendedB: CharacterRange = CharacterRange.Define(\n    \"\\u0180\",\n    \"\\u024F\"\n    // no excludes here\n  );\n\n  public static readonly Greek: CharacterRange = CharacterRange.Define(\n    \"\\u0370\",\n    \"\\u03FF\",\n    new CharacterSet()\n      .AddRange(\"\\u0378\", \"\\u0385\")\n      .AddCharacters(\"\\u0374\\u0375\\u0378\\u0387\\u038B\\u038D\\u03A2\")\n  );\n\n  public static readonly Cyrillic: CharacterRange = CharacterRange.Define(\n    \"\\u0400\",\n    \"\\u04FF\",\n    new CharacterSet().AddRange(\"\\u0482\", \"\\u0489\")\n  );\n\n  public static readonly Armenian: CharacterRange = CharacterRange.Define(\n    \"\\u0530\",\n    \"\\u058F\",\n    new CharacterSet()\n      .AddCharacters(\"\\u0530\")\n      .AddRange(\"\\u0557\", \"\\u0560\")\n      .AddRange(\"\\u0588\", \"\\u058E\")\n  );\n\n  public static readonly Hebrew: CharacterRange = CharacterRange.Define(\n    \"\\u0590\",\n    \"\\u05FF\",\n    new CharacterSet()\n  );\n\n  public static readonly Arabic: CharacterRange = CharacterRange.Define(\n    \"\\u0600\",\n    \"\\u06FF\",\n    new CharacterSet()\n  );\n\n  public static readonly Korean: CharacterRange = CharacterRange.Define(\n    \"\\uAC00\",\n    \"\\uD7AF\",\n    new CharacterSet()\n  );\n\n  public static readonly Latin1Supplement: CharacterRange =\n    CharacterRange.Define(\"\\u0080\", \"\\u00FF\", new CharacterSet());\n\n  public static readonly Chinese: CharacterRange = CharacterRange.Define(\n    \"\\u4E00\",\n    \"\\u9FFF\",\n    new CharacterSet()\n  );\n\n  private readonly ExtendIdentifierCharacterRanges = (\n    identifierCharSet: CharacterSet\n  ): void => {\n    const characterRanges = InkParser.ListAllCharacterRanges();\n    for (const charRange of characterRanges) {\n      identifierCharSet.AddCharacters(charRange.ToCharacterSet());\n    }\n  };\n\n  /// <summary>\n  /// Gets an array of <see cref=\"CharacterRange\" /> representing all of the currently supported\n  /// non-ASCII character ranges that can be used in identifier names.\n  /// </summary>\n  /// <returns>\n  /// An array of <see cref=\"CharacterRange\" /> representing all of the currently supported\n  /// non-ASCII character ranges that can be used in identifier names.\n  /// </returns>\n  public static readonly ListAllCharacterRanges = (): CharacterRange[] => [\n    InkParser.LatinBasic,\n    InkParser.LatinExtendedA,\n    InkParser.LatinExtendedB,\n    InkParser.Arabic,\n    InkParser.Armenian,\n    InkParser.Cyrillic,\n    InkParser.Greek,\n    InkParser.Hebrew,\n    InkParser.Korean,\n    InkParser.Latin1Supplement,\n    InkParser.Chinese,\n  ];\n\n  /**\n   * End CharacterRanges section.\n   */\n\n  /**\n   * Begin Choices section.\n   */\n\n  public _parsingChoice: boolean = false;\n\n  public readonly Choice = (): Choice | null => {\n    let onceOnlyChoice: boolean = true;\n    let bullets = this.Interleave<string>(\n      this.OptionalExclude(this.Whitespace),\n      this.String(\"*\")\n    );\n\n    if (!bullets) {\n      bullets = this.Interleave<string>(\n        this.OptionalExclude(this.Whitespace),\n        this.String(\"+\")\n      );\n\n      if (bullets === null) {\n        return null;\n      }\n\n      onceOnlyChoice = false;\n    }\n\n    // Optional name for the choice\n    const optionalName: Identifier = this.Parse(\n      this.BracketedName\n    ) as Identifier;\n\n    this.Whitespace();\n\n    // Allow optional newline right after a choice name\n    if (optionalName != null) this.Newline();\n\n    // Optional condition for whether the choice should be shown to the player\n    const conditionExpr: Expression = this.Parse(\n      this.ChoiceCondition\n    ) as Expression;\n\n    this.Whitespace();\n\n    // Ordinarily we avoid parser state variables like these, since\n    // nesting would require us to store them in a stack. But since you should\n    // never be able to nest choices within choice content, it's fine here.\n    if (this._parsingChoice) {\n      throw new Error(\n        \"Already parsing a choice - shouldn't have nested choices\"\n      );\n    }\n\n    this._parsingChoice = true;\n\n    let startContent: ContentList | null = null;\n    const startTextAndLogic = this.Parse(\n      this.MixedTextAndLogic\n    ) as ParsedObject[];\n    if (startTextAndLogic) {\n      startContent = new ContentList(startTextAndLogic);\n    }\n\n    let optionOnlyContent: ContentList | null = null;\n    let innerContent: ContentList | null = null;\n\n    // Check for a the weave style format:\n    //   * \"Hello[.\"],\" he said.\n    const hasWeaveStyleInlineBrackets: boolean = this.ParseString(\"[\") !== null;\n    if (hasWeaveStyleInlineBrackets) {\n      this.EndTagIfNecessary(startContent);\n\n      const optionOnlyTextAndLogic = this.Parse(\n        this.MixedTextAndLogic\n      ) as ParsedObject[];\n\n      if (optionOnlyTextAndLogic !== null) {\n        optionOnlyContent = new ContentList(optionOnlyTextAndLogic);\n      }\n\n      this.Expect(this.String(\"]\"), \"closing ']' for weave-style option\");\n\n      this.EndTagIfNecessary(optionOnlyContent);\n\n      let innerTextAndLogic = this.Parse(\n        this.MixedTextAndLogic\n      ) as ParsedObject[];\n      if (innerTextAndLogic !== null) {\n        innerContent = new ContentList(innerTextAndLogic);\n      }\n    }\n\n    this.Whitespace();\n\n    this.EndTagIfNecessary(innerContent ?? startContent);\n\n    // Finally, now we know we're at the end of the main choice body, parse\n    // any diverts separately.\n    const diverts: ParsedObject[] = this.Parse(\n      this.MultiDivert\n    ) as ParsedObject[];\n\n    this._parsingChoice = false;\n\n    this.Whitespace();\n\n    // Completely empty choice without even an empty divert?\n    const emptyContent: boolean =\n      !startContent && !innerContent && !optionOnlyContent;\n\n    if (emptyContent && diverts === null) {\n      this.Warning(\n        \"Choice is completely empty. Interpretting as a default fallback choice. Add a divert arrow to remove this warning: * ->\"\n      );\n    }\n\n    if (!startContent && hasWeaveStyleInlineBrackets && !optionOnlyContent) {\n      // * [] some text\n      this.Warning(\n        \"Blank choice - if you intended a default fallback choice, use the `* ->` syntax\"\n      );\n    }\n\n    if (!innerContent) {\n      innerContent = new ContentList();\n    }\n\n    this.EndTagIfNecessary(innerContent);\n\n    // Normal diverts on the end of a choice - simply add to the normal content\n    if (diverts !== null) {\n      for (const divObj of diverts) {\n        // may be TunnelOnwards\n        const div = asOrNull(divObj, Divert);\n\n        // Empty divert serves no purpose other than to say\n        // \"this choice is intentionally left blank\"\n        // (as an invisible default choice)\n        if (div && div.isEmpty) {\n          continue;\n        }\n\n        innerContent.AddContent(divObj);\n      }\n    }\n\n    // Terminate main content with a newline since this is the end of the line\n    // Note that this will be redundant if the diverts above definitely take\n    // the flow away permanently.\n    innerContent.AddContent(new Text(\"\\n\"));\n\n    const choice = new Choice(startContent!, optionOnlyContent!, innerContent);\n    if (optionalName) choice.identifier = optionalName;\n    choice.indentationDepth = bullets.length;\n    choice.hasWeaveStyleInlineBrackets = hasWeaveStyleInlineBrackets;\n    choice.condition = conditionExpr;\n    choice.onceOnly = onceOnlyChoice;\n    choice.isInvisibleDefault = emptyContent;\n    return choice;\n  };\n\n  public readonly ChoiceCondition = (): Expression | null => {\n    const conditions = this.Interleave<Expression>(\n      this.ChoiceSingleCondition,\n      this.ChoiceConditionsSpace\n    );\n\n    if (conditions === null) {\n      return null;\n    } else if (conditions.length === 1) {\n      return conditions[0];\n    }\n\n    return new MultipleConditionExpression(conditions);\n  };\n\n  public readonly ChoiceConditionsSpace = (): typeof ParseSuccess => {\n    // Both optional\n    // Newline includes initial end of line whitespace\n    this.Newline();\n    this.Whitespace();\n\n    return ParseSuccess;\n  };\n\n  public readonly ChoiceSingleCondition = (): Expression | null => {\n    if (this.ParseString(\"{\") === null) {\n      return null;\n    }\n\n    const condExpr = this.Expect(\n      this.Expression,\n      \"choice condition inside { }\"\n    ) as Expression;\n\n    this.DisallowIncrement(condExpr);\n    this.Expect(this.String(\"}\"), \"closing '}' for choice condition\");\n\n    return condExpr;\n  };\n\n  public readonly Gather = (): Gather | null => {\n    const gatherDashCountObj: number = this.Parse(this.GatherDashes) as number;\n    if (gatherDashCountObj === null) {\n      return null;\n    }\n\n    const gatherDashCount: number = Number(gatherDashCountObj);\n\n    // Optional name for the gather\n    const optionalName: Identifier = this.Parse(\n      this.BracketedName\n    ) as Identifier;\n\n    const gather = new Gather(optionalName, gatherDashCount);\n\n    // Optional newline before gather's content begins\n    this.Newline();\n\n    return gather;\n  };\n\n  public readonly GatherDashes = (): number | null => {\n    this.Whitespace();\n\n    let gatherDashCount: number = 0;\n    while (this.ParseDashNotArrow() !== null) {\n      gatherDashCount += 1;\n      this.Whitespace();\n    }\n\n    if (gatherDashCount === 0) {\n      return null;\n    }\n\n    return gatherDashCount as number;\n  };\n\n  public readonly ParseDashNotArrow = () => {\n    const ruleId = this.BeginRule();\n\n    if (\n      this.ParseString(\"->\") === null &&\n      this.ParseSingleCharacter() === \"-\"\n    ) {\n      return this.SucceedRule(ruleId);\n    }\n\n    return this.FailRule(ruleId);\n  };\n\n  public readonly BracketedName = (): Identifier | null => {\n    if (this.ParseString(\"(\") === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const name = this.Parse(this.IdentifierWithMetadata) as Identifier | null;\n    if (name === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    this.Expect(this.String(\")\"), \"closing ')' for bracketed name\");\n\n    return name;\n  };\n\n  /**\n   * End Choices section.\n   */\n\n  /**\n   * Begin Conditional section.\n   */\n\n  public readonly InnerConditionalContent = (\n    initialQueryExpression: Expression\n  ): Conditional | null => {\n    if (initialQueryExpression === undefined) {\n      const initialQueryExpression = this.Parse(this.ConditionExpression);\n      const conditional = this.Parse(() =>\n        this.InnerConditionalContent(initialQueryExpression as Expression)\n      ) as Conditional;\n\n      if (conditional === null) {\n        return null;\n      }\n\n      return conditional;\n    }\n\n    let alternatives: ConditionalSingleBranch[] | null;\n    const canBeInline: boolean = initialQueryExpression !== null;\n    const isInline: boolean = this.Parse(this.Newline) === null;\n\n    if (isInline && !canBeInline) {\n      return null;\n    }\n\n    if (isInline) {\n      // Inline innards\n      alternatives = this.InlineConditionalBranches();\n    } else {\n      // Multiline innards\n      alternatives = this.MultilineConditionalBranches();\n\n      if (alternatives === null) {\n        // Allow single piece of content within multi-line expression, e.g.:\n        // { true:\n        //    Some content that isn't preceded by '-'\n        // }\n        if (initialQueryExpression) {\n          let soleContent: ParsedObject[] = this.StatementsAtLevel(\n            StatementLevel.InnerBlock\n          );\n          if (soleContent !== null) {\n            const soleBranch = new ConditionalSingleBranch(soleContent);\n            alternatives = [soleBranch];\n\n            // Also allow a final \"- else:\" clause\n            const elseBranch = this.Parse(\n              this.SingleMultilineCondition\n            ) as ConditionalSingleBranch;\n            if (elseBranch) {\n              if (!elseBranch.isElse) {\n                this.ErrorWithParsedObject(\n                  \"Expected an '- else:' clause here rather than an extra condition\",\n                  elseBranch\n                );\n\n                elseBranch.isElse = true;\n              }\n\n              alternatives.push(elseBranch);\n            }\n          }\n        }\n\n        // Still null?\n        if (alternatives === null) {\n          return null;\n        }\n      } else if (\n        alternatives.length === 1 &&\n        alternatives[0].isElse &&\n        initialQueryExpression\n      ) {\n        // Empty true branch - didn't get parsed, but should insert one for semantic correctness,\n        // and to make sure that any evaluation stack values get tidied up correctly.\n        const emptyTrueBranch = new ConditionalSingleBranch(null);\n        emptyTrueBranch.isTrueBranch = true;\n        alternatives.unshift(emptyTrueBranch);\n      }\n\n      // Like a switch statement\n      // { initialQueryExpression:\n      //    ... match the expression\n      // }\n      if (initialQueryExpression) {\n        let earlierBranchesHaveOwnExpression: boolean = false;\n        for (let ii = 0; ii < alternatives.length; ++ii) {\n          const branch = alternatives[ii];\n          const isLast: boolean = ii === alternatives.length - 1;\n\n          // Matching equality with initial query expression\n          // We set this flag even for the \"else\" clause so that\n          // it knows to tidy up the evaluation stack at the end\n\n          // Match query\n          if (branch.ownExpression) {\n            branch.matchingEquality = true;\n            earlierBranchesHaveOwnExpression = true;\n          } else if (earlierBranchesHaveOwnExpression && isLast) {\n            // Else (final branch)\n            branch.matchingEquality = true;\n            branch.isElse = true;\n          } else {\n            // Binary condition:\n            // { trueOrFalse:\n            //    - when true\n            //    - when false\n            // }\n            if (!isLast && alternatives.length > 2) {\n              this.ErrorWithParsedObject(\n                \"Only final branch can be an 'else'. Did you miss a ':'?\",\n                branch\n              );\n            } else {\n              if (ii === 0) {\n                branch.isTrueBranch = true;\n              } else {\n                branch.isElse = true;\n              }\n            }\n          }\n        }\n      } else {\n        // No initial query, so just a multi-line conditional. e.g.:\n        // {\n        //   - x > 3:  greater than three\n        //   - x == 3: equal to three\n        //   - x < 3:  less than three\n        // }\n\n        for (let ii = 0; ii < alternatives.length; ++ii) {\n          const alt = alternatives[ii];\n          const isLast: boolean = ii === alternatives.length - 1;\n\n          if (alt.ownExpression === null) {\n            if (isLast) {\n              alt.isElse = true;\n            } else {\n              if (alt.isElse) {\n                // Do we ALSO have a valid \"else\" at the end? Let's report the error there.\n                const finalClause = alternatives[alternatives.length - 1];\n                if (finalClause.isElse) {\n                  this.ErrorWithParsedObject(\n                    \"Multiple 'else' cases. Can have a maximum of one, at the end.\",\n                    finalClause\n                  );\n                } else {\n                  this.ErrorWithParsedObject(\n                    \"'else' case in conditional should always be the final one\",\n                    alt\n                  );\n                }\n              } else {\n                this.ErrorWithParsedObject(\n                  \"Branch doesn't have condition. Are you missing a ':'? \",\n                  alt\n                );\n              }\n            }\n          }\n        }\n\n        if (\n          alternatives.length === 1 &&\n          alternatives[0].ownExpression === null\n        ) {\n          this.ErrorWithParsedObject(\n            \"Condition block with no conditions\",\n            alternatives[0]\n          );\n        }\n      }\n    }\n\n    // TODO: Come up with water-tight error conditions... it's quite a flexible system!\n    // e.g.\n    //   - inline conditionals must have exactly 1 or 2 alternatives\n    //   - multiline expression shouldn't have mixed existence of branch-conditions?\n    if (alternatives === null) {\n      return null;\n    }\n\n    for (const branch of alternatives) {\n      branch.isInline = isInline;\n    }\n\n    const cond = new Conditional(initialQueryExpression, alternatives);\n\n    return cond;\n  };\n\n  public readonly InlineConditionalBranches = ():\n    | ConditionalSingleBranch[]\n    | null => {\n    const listOfLists = this.Interleave<ParsedObject[]>(\n      this.MixedTextAndLogic,\n      this.Exclude(this.String(\"|\")),\n      null,\n      false\n    );\n\n    if (listOfLists === null || listOfLists.length === 0) {\n      return null;\n    }\n\n    const result: ConditionalSingleBranch[] = [];\n\n    if (listOfLists.length > 2) {\n      this.Error(\n        \"Expected one or two alternatives separated by '|' in inline conditional\"\n      );\n    } else {\n      const trueBranch = new ConditionalSingleBranch(listOfLists[0]);\n      trueBranch.isTrueBranch = true;\n      result.push(trueBranch);\n\n      if (listOfLists.length > 1) {\n        const elseBranch = new ConditionalSingleBranch(listOfLists[1]);\n        elseBranch.isElse = true;\n        result.push(elseBranch);\n      }\n    }\n\n    return result;\n  };\n\n  public readonly MultilineConditionalBranches = ():\n    | ConditionalSingleBranch[]\n    | null => {\n    this.MultilineWhitespace();\n\n    const multipleConditions = this.OneOrMore(this.SingleMultilineCondition);\n    if (multipleConditions === null) {\n      return null;\n    }\n\n    this.MultilineWhitespace();\n\n    return multipleConditions as ConditionalSingleBranch[];\n  };\n\n  public readonly SingleMultilineCondition =\n    (): ConditionalSingleBranch | null => {\n      this.Whitespace();\n\n      if (\n        // Make sure we're not accidentally parsing a divert\n        this.ParseString(\"->\") !== null ||\n        this.ParseString(\"-\") === null\n      ) {\n        return null;\n      }\n\n      this.Whitespace();\n\n      let expr: Expression | null = null;\n      const isElse: boolean = this.Parse(this.ElseExpression) !== null;\n\n      if (!isElse) {\n        expr = this.Parse(this.ConditionExpression) as Expression;\n      }\n\n      let content: ParsedObject[] = this.StatementsAtLevel(\n        StatementLevel.InnerBlock\n      );\n      if (expr === null && content === null) {\n        this.Error(\"expected content for the conditional branch following '-'\");\n\n        // Recover\n        content = [new Text(\"\")];\n      }\n\n      // Allow additional multiline whitespace, if the statements were empty (valid)\n      // then their surrounding multiline whitespacce needs to be handled manually.\n      // e.g.\n      // { x:\n      //   - 1:    // intentionally left blank, but newline needs to be parsed\n      //   - 2: etc\n      // }\n      this.MultilineWhitespace();\n\n      const branch = new ConditionalSingleBranch(content);\n      branch.ownExpression = expr;\n      branch.isElse = isElse;\n\n      return branch;\n    };\n\n  public readonly ConditionExpression = (): ParsedObject | null => {\n    const expr = this.Parse(this.Expression) as ParsedObject;\n    if (expr === null) {\n      return null;\n    }\n\n    this.DisallowIncrement(expr);\n\n    this.Whitespace();\n\n    if (this.ParseString(\":\") === null) {\n      return null;\n    }\n\n    return expr;\n  };\n\n  public readonly ElseExpression = (): typeof ParseSuccess | null => {\n    if (this.ParseString(\"else\") === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    if (this.ParseString(\":\") === null) {\n      return null;\n    }\n\n    return ParseSuccess;\n  };\n\n  /**\n   * End Conditional section.\n   */\n\n  /**\n   * Begin Content section.\n   */\n\n  public _nonTextPauseCharacters: CharacterSet | null = null;\n  public _nonTextEndCharacters: CharacterSet | null = null;\n  public _notTextEndCharactersChoice: CharacterSet | null = null;\n  public _notTextEndCharactersString: CharacterSet | null = null;\n\n  public readonly TrimEndWhitespace = (\n    mixedTextAndLogicResults: ParsedObject[],\n    terminateWithSpace: boolean\n  ): void => {\n    // Trim whitespace from end\n    if (mixedTextAndLogicResults.length > 0) {\n      const lastObjIdx = mixedTextAndLogicResults.length - 1;\n      const lastObj = mixedTextAndLogicResults[lastObjIdx];\n      if (lastObj instanceof Text) {\n        const textObj: Text = lastObj;\n        textObj.text = textObj.text.replace(new RegExp(/[ \\t]+$/g), \"\");\n\n        if (terminateWithSpace) {\n          textObj.text += \" \";\n        } else if (textObj.text.length === 0) {\n          // No content left at all? trim the whole object\n          mixedTextAndLogicResults.splice(lastObjIdx, 1);\n\n          // Recurse in case there's more whitespace\n          this.TrimEndWhitespace(mixedTextAndLogicResults, false);\n        }\n      }\n    }\n  };\n\n  public readonly LineOfMixedTextAndLogic = (): ParsedObject[] | null => {\n    // Consume any whitespace at the start of the line\n    // (Except for escaped whitespace)\n    this.Parse(this.Whitespace);\n\n    let result: ParsedObject[] = this.Parse(\n      this.MixedTextAndLogic\n    ) as ParsedObject[];\n\n    if (!result || !result.length) {\n      return null;\n    }\n\n    // Warn about accidentally writing \"return\" without \"~\"\n    const firstText = result[0] as Text;\n    if (firstText && firstText.text && firstText.text.startsWith(\"return\")) {\n      this.Warning(\n        \"Do you need a '~' before 'return'? If not, perhaps use a glue: <> (since it's lowercase) or rewrite somehow?\"\n      );\n    }\n\n    if (result.length === 0) {\n      return null;\n    }\n\n    const lastObj = result[result.length - 1];\n    if (!(lastObj instanceof Divert)) {\n      this.TrimEndWhitespace(result, false);\n    }\n\n    this.EndTagIfNecessary(result);\n\n    // If the line doens't actually contain any normal text content\n    // but is in fact entirely a tag, then let's not append\n    // a newline, since we want the tag (or tags) to be associated\n    // with the line below rather than being completely independent.\n    let lineIsPureTag =\n      result.length > 0 && result[0] instanceof Tag && result[0].isStart;\n\n    if (!lineIsPureTag) {\n      result.push(new Text(\"\\n\"));\n    }\n\n    this.Expect(this.EndOfLine, \"end of line\", this.SkipToNextLine);\n    return result;\n  };\n\n  public readonly MixedTextAndLogic = (): ParsedObject[] | null => {\n    // Check for disallowed \"~\" within this context\n    const disallowedTilde = this.ParseObject(this.Spaced(this.String(\"~\")));\n    if (disallowedTilde !== null) {\n      this.Error(\n        \"You shouldn't use a '~' here - tildas are for logic that's on its own line. To do inline logic, use { curly braces } instead\"\n      );\n    }\n\n    // Either, or both interleaved\n    let results: ParsedObject[] = this.Interleave<ParsedObject>(\n      this.Optional(this.ContentText),\n      this.Optional(this.InlineLogicOrGlueOrStartTag)\n    );\n\n    // Terminating divert?\n    // (When parsing content for the text of a choice, diverts aren't allowed.\n    //  The divert on the end of the body of a choice is handled specially.)\n    if (!this._parsingChoice) {\n      const diverts: ParsedObject[] = this.Parse(\n        this.MultiDivert\n      ) as ParsedObject[];\n      if (diverts !== null) {\n        // May not have had any results at all if there's *only* a divert!\n        if (results === null) {\n          results = [];\n        }\n\n        // End previously active tag if necessary\n        this.EndTagIfNecessary(results);\n\n        this.TrimEndWhitespace(results, true);\n\n        results.push(...diverts);\n      }\n    }\n\n    if (!results) {\n      return null;\n    }\n\n    return results;\n  };\n\n  public readonly ContentText = () => {\n    return this.ContentTextAllowingEscapeChar();\n  };\n\n  public readonly ContentTextAllowingEscapeChar = (): Text | null => {\n    let sb: string | null = null;\n\n    do {\n      let str = this.Parse(this.ContentTextNoEscape);\n      const gotEscapeChar: boolean = this.ParseString(\"\\\\\") !== null;\n\n      if (gotEscapeChar || str !== null) {\n        if (sb === null) {\n          sb = \"\";\n        }\n\n        if (str !== null) {\n          sb += String(str);\n        }\n\n        if (gotEscapeChar) {\n          const c: string = this.ParseSingleCharacter();\n          sb += c;\n        }\n      } else {\n        break;\n      }\n    } while (true);\n\n    if (sb !== null) {\n      return new Text(sb);\n    }\n\n    return null;\n  };\n\n  // Content text is an unusual parse rule compared with most since it's\n  // less about saying \"this is is the small selection of stuff that we parse\"\n  // and more \"we parse ANYTHING except this small selection of stuff\".\n  public readonly ContentTextNoEscape = (): string | null => {\n    // Eat through text, pausing at the following characters, and\n    // attempt to parse the nonTextRule.\n    // \"-\": possible start of divert or start of gather\n    // \"<\": possible start of glue\n    if (this._nonTextPauseCharacters === null) {\n      this._nonTextPauseCharacters = new CharacterSet(\"-<\");\n    }\n\n    // If we hit any of these characters, we stop *immediately* without bothering to even check the nonTextRule\n    // \"{\" for start of logic\n    // \"|\" for mid logic branch\n    if (this._nonTextEndCharacters === null) {\n      this._nonTextEndCharacters = new CharacterSet(\"{}|\\n\\r\\\\#\");\n      this._notTextEndCharactersChoice = new CharacterSet(\n        this._nonTextEndCharacters\n      );\n      this._notTextEndCharactersChoice.AddCharacters(\"[]\");\n      this._notTextEndCharactersString = new CharacterSet(\n        this._nonTextEndCharacters\n      );\n      this._notTextEndCharactersString.AddCharacters('\"');\n    }\n\n    // When the ParseUntil pauses, check these rules in case they evaluate successfully\n    const nonTextRule: ParseRule = () =>\n      this.OneOf([\n        this.ParseDivertArrow,\n        this.ParseThreadArrow,\n        this.EndOfLine,\n        this.Glue,\n      ]);\n\n    let endChars: CharacterSet | null = null;\n    if (this.parsingStringExpression) {\n      endChars = this._notTextEndCharactersString;\n    } else if (this._parsingChoice) {\n      endChars = this._notTextEndCharactersChoice;\n    } else {\n      endChars = this._nonTextEndCharacters;\n    }\n\n    const pureTextContent: string = this.ParseUntil(\n      nonTextRule,\n      this._nonTextPauseCharacters,\n      endChars\n    );\n\n    if (pureTextContent !== null) {\n      return pureTextContent;\n    }\n\n    return null;\n  };\n\n  /**\n   * End Content section.\n   */\n\n  /**\n   * Begin Divert section.\n   */\n\n  public readonly MultiDivert = (): ParsedObject[] | null => {\n    this.Whitespace();\n\n    let diverts: ParsedObject[] = [];\n\n    // Try single thread first\n    const threadDivert = this.Parse(this.StartThread) as ParsedObject;\n    if (threadDivert) {\n      diverts = [threadDivert];\n\n      return diverts;\n    }\n\n    // Normal diverts and tunnels\n    const arrowsAndDiverts = this.Interleave<ParsedObject>(\n      this.ParseDivertArrowOrTunnelOnwards,\n      this.DivertIdentifierWithArguments\n    );\n\n    if (!arrowsAndDiverts) {\n      return null;\n    }\n\n    diverts = [];\n\n    this.EndTagIfNecessary(diverts);\n\n    // Possible patterns:\n    //  ->                   -- explicit gather\n    //  ->->                 -- tunnel onwards\n    //  -> div               -- normal divert\n    //  ->-> div             -- tunnel onwards, followed by override divert\n    //  -> div ->            -- normal tunnel\n    //  -> div ->->          -- tunnel then tunnel continue\n    //  -> div -> div        -- tunnel then divert\n    //  -> div -> div ->     -- tunnel then tunnel\n    //  -> div -> div ->->\n    //  -> div -> div ->-> div    (etc)\n\n    // Look at the arrows and diverts\n    for (let ii = 0; ii < arrowsAndDiverts.length; ++ii) {\n      const isArrow: boolean = ii % 2 === 0;\n\n      // Arrow string\n      if (isArrow) {\n        // Tunnel onwards\n        if ((arrowsAndDiverts[ii] as any) === \"->->\") {\n          const tunnelOnwardsPlacementValid: boolean =\n            ii === 0 ||\n            ii === arrowsAndDiverts.length - 1 ||\n            ii === arrowsAndDiverts.length - 2;\n\n          if (!tunnelOnwardsPlacementValid) {\n            this.Error(\n              \"Tunnel onwards '->->' must only come at the begining or the start of a divert\"\n            );\n          }\n\n          const tunnelOnwards = new TunnelOnwards();\n          if (ii < arrowsAndDiverts.length - 1) {\n            const tunnelOnwardDivert = asOrNull(\n              arrowsAndDiverts[ii + 1],\n              Divert\n            );\n            tunnelOnwards.divertAfter = tunnelOnwardDivert;\n          }\n\n          diverts.push(tunnelOnwards);\n\n          // Not allowed to do anything after a tunnel onwards.\n          // If we had anything left it would be caused in the above Error for\n          // the positioning of a ->->\n          break;\n        }\n      } else {\n        // Divert\n        const divert = arrowsAndDiverts[ii] as Divert;\n        // More to come? (further arrows) Must be tunnelling.\n        if (ii < arrowsAndDiverts.length - 1) {\n          divert.isTunnel = true;\n        }\n\n        diverts.push(divert);\n      }\n    }\n\n    // Single -> (used for default choices)\n    if (diverts.length === 0 && arrowsAndDiverts.length === 1) {\n      const gatherDivert = new Divert(null);\n      gatherDivert.isEmpty = true;\n      diverts.push(gatherDivert);\n\n      if (!this._parsingChoice) {\n        this.Error(\"Empty diverts (->) are only valid on choices\");\n      }\n    }\n\n    return diverts;\n  };\n\n  public readonly StartThread = (): Divert | null => {\n    this.Whitespace();\n\n    if (this.ParseThreadArrow() === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const divert = this.Expect(\n      this.DivertIdentifierWithArguments,\n      \"target for new thread\",\n      () => new Divert(null)\n    ) as Divert;\n\n    divert.isThread = true;\n\n    return divert;\n  };\n\n  public readonly DivertIdentifierWithArguments = (): Divert | null => {\n    this.Whitespace();\n\n    const targetComponents: Identifier[] = this.Parse(\n      this.DotSeparatedDivertPathComponents\n    ) as Identifier[];\n\n    if (!targetComponents) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const optionalArguments = this.Parse(\n      this.ExpressionFunctionCallArguments\n    ) as Expression[];\n\n    this.Whitespace();\n\n    const targetPath = new Path(targetComponents);\n\n    return new Divert(targetPath, optionalArguments);\n  };\n\n  public readonly SingleDivert = (): Divert | null => {\n    const diverts = this.Parse(this.MultiDivert) as ParsedObject[];\n    if (!diverts) {\n      return null;\n    }\n\n    // Ideally we'd report errors if we get the\n    // wrong kind of divert, but unfortunately we\n    // have to hack around the fact that sequences use\n    // a very similar syntax.\n    // i.e. if you have a multi-divert at the start\n    // of a sequence, it initially tries to parse it\n    // as a divert target (part of an expression of\n    // a conditional) and gives errors. So instead\n    // we just have to blindly reject it as a single\n    // divert, and give a slightly less nice error\n    // when you DO use a multi divert as a divert taret.\n\n    if (diverts.length !== 1) {\n      return null;\n    }\n\n    const singleDivert = diverts[0];\n    if (singleDivert instanceof TunnelOnwards) {\n      return null;\n    }\n\n    const divert = diverts[0] as Divert;\n    if (divert.isTunnel) {\n      return null;\n    }\n\n    return divert;\n  };\n\n  public readonly DotSeparatedDivertPathComponents = (): Identifier[] =>\n    this.Interleave<Identifier>(\n      this.Spaced(this.IdentifierWithMetadata),\n      this.Exclude(this.String(\".\"))\n    );\n\n  public readonly ParseDivertArrowOrTunnelOnwards = (): string | null => {\n    let numArrows: number = 0;\n    while (this.ParseString(\"->\") !== null) {\n      numArrows += 1;\n    }\n\n    if (numArrows === 0) {\n      return null;\n    } else if (numArrows === 1) {\n      return \"->\";\n    } else if (numArrows === 2) {\n      return \"->->\";\n    }\n\n    this.Error(\n      \"Unexpected number of arrows in divert. Should only have '->' or '->->'\"\n    );\n\n    return \"->->\";\n  };\n\n  public readonly ParseDivertArrow = () => this.ParseString(\"->\");\n\n  public readonly ParseThreadArrow = () => this.ParseString(\"<-\");\n\n  /**\n   * End Divert section.\n   */\n\n  /**\n   * Begin Expressions section.\n   */\n\n  public _binaryOperators: InfixOperator[] = [];\n  public _maxBinaryOpLength: number = 0;\n\n  public readonly TempDeclarationOrAssignment = (): ParsedObject | null => {\n    this.Whitespace();\n\n    const isNewDeclaration: boolean = this.ParseTempKeyword();\n\n    this.Whitespace();\n\n    let varIdentifier: Identifier | null = null;\n    if (isNewDeclaration) {\n      varIdentifier = this.Expect(\n        this.IdentifierWithMetadata,\n        \"variable name\"\n      ) as Identifier;\n    } else {\n      varIdentifier = this.Parse(this.IdentifierWithMetadata) as Identifier;\n    }\n\n    if (varIdentifier === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    // += -=\n    const isIncrement: boolean = this.ParseString(\"+\") !== null;\n    const isDecrement: boolean = this.ParseString(\"-\") !== null;\n\n    if (isIncrement && isDecrement) {\n      this.Error(\"Unexpected sequence '+-'\");\n    }\n\n    if (this.ParseString(\"=\") === null) {\n      // Definitely in an assignment expression?\n      if (isNewDeclaration) {\n        this.Error(\"Expected '='\");\n      }\n\n      return null;\n    }\n\n    const assignedExpression: Expression = this.Expect(\n      this.Expression,\n      \"value expression to be assigned\"\n    ) as Expression;\n\n    if (isIncrement || isDecrement) {\n      const result = new IncDecExpression(\n        varIdentifier,\n        assignedExpression,\n        isIncrement\n      );\n      return result;\n    }\n\n    const result = new VariableAssignment({\n      variableIdentifier: varIdentifier,\n      assignedExpression,\n      isTemporaryNewDeclaration: isNewDeclaration,\n    });\n\n    return result;\n  };\n\n  public readonly DisallowIncrement = (expr: ParsedObject): void => {\n    if (expr instanceof IncDecExpression) {\n      this.Error(\n        \"Can't use increment/decrement here. It can only be used on a ~ line\"\n      );\n    }\n  };\n\n  public readonly ParseTempKeyword = () => {\n    const ruleId = this.BeginRule();\n\n    if (this.Parse(this.Identifier) === \"temp\") {\n      this.SucceedRule(ruleId);\n      return true;\n    }\n\n    this.FailRule(ruleId);\n    return false;\n  };\n\n  public readonly ReturnStatement = (): ReturnType | null => {\n    this.Whitespace();\n\n    const returnOrDone = this.Parse(this.Identifier);\n    if (returnOrDone !== \"return\") {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const expr = this.Parse(this.Expression) as Expression;\n\n    const returnObj = new ReturnType(expr);\n\n    return returnObj;\n  };\n\n  // Pratt Parser\n  // aka \"Top down operator precedence parser\"\n  // http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/\n  // Algorithm overview:\n  // The two types of precedence are handled in two different ways:\n  //   ((((a . b) . c) . d) . e)\t\t\t#1\n  //   (a . (b . (c . (d . e))))\t\t\t#2\n  // Where #1 is automatically handled by successive loops within the main 'while' in this function,\n  // so long as continuing operators have lower (or equal) precedence (e.g. imagine some series of \"*\"s then \"+\" above.\n  // ...and #2 is handled by recursion of the right hand term in the binary expression parser.\n  // (see link for advice on how to extend for postfix and mixfix operators)\n  public readonly Expression = (\n    minimumPrecedence: number = 0\n  ): Expression | null => {\n    this.Whitespace();\n\n    // First parse a unary expression e.g. \"-a\" or parethensised \"(1 + 2)\"\n    let expr = this.ExpressionUnary();\n    if (expr === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    // Attempt to parse (possibly multiple) continuing infix expressions (e.g. 1 + 2 + 3)\n    while (true) {\n      const ruleId = this.BeginRule();\n\n      // Operator\n      const infixOp = this.ParseInfixOperator();\n      if (infixOp !== null && infixOp.precedence > minimumPrecedence) {\n        // Expect right hand side of operator\n        const expectationMessage = `right side of '${infixOp.type}' expression`;\n        const multiaryExpr = this.Expect(\n          () => this.ExpressionInfixRight(expr, infixOp),\n          expectationMessage\n        );\n\n        if (multiaryExpr === null) {\n          // Fail for operator and right-hand side of multiary expression\n          this.FailRule(ruleId);\n\n          return null;\n        }\n\n        expr = this.SucceedRule(ruleId, multiaryExpr) as Expression;\n\n        continue;\n      }\n\n      this.FailRule(ruleId);\n      break;\n    }\n\n    this.Whitespace();\n\n    return expr;\n  };\n\n  public readonly ExpressionUnary = (): Expression | null => {\n    // Divert target is a special case - it can't have any other operators\n    // applied to it, and we also want to check for it first so that we don't\n    // confuse \"->\" for subtraction.\n    const divertTarget = this.Parse(this.ExpressionDivertTarget) as Expression;\n    if (divertTarget !== null) {\n      return divertTarget;\n    }\n\n    let prefixOp: string = this.OneOf([\n      this.String(\"-\"),\n      this.String(\"!\"),\n    ]) as string;\n\n    // Don't parse like the string rules above, in case its actually\n    // a variable that simply starts with \"not\", e.g. \"notable\".\n    // This rule uses the Identifier rule, which will scan as much text\n    // as possible before returning.\n    if (prefixOp === null) {\n      prefixOp = this.Parse(this.ExpressionNot) as string;\n    }\n\n    this.Whitespace();\n\n    // - Since we allow numbers at the start of variable names, variable names are checked before literals\n    // - Function calls before variable names in case we see parentheses\n    let expr = this.OneOf([\n      this.ExpressionList,\n      this.ExpressionParen,\n      this.ExpressionFunctionCall,\n      this.ExpressionVariableName,\n      this.ExpressionLiteral,\n    ]) as Expression | null;\n\n    // Only recurse immediately if we have one of the (usually optional) unary ops\n    if (expr === null && prefixOp !== null) {\n      expr = this.ExpressionUnary();\n    }\n\n    if (expr === null) {\n      return null;\n    } else if (prefixOp !== null) {\n      expr = UnaryExpression.WithInner(expr, prefixOp) as Expression;\n    }\n\n    this.Whitespace();\n\n    const postfixOp = this.OneOf([this.String(\"++\"), this.String(\"--\")]);\n\n    if (postfixOp !== null) {\n      const isInc: boolean = postfixOp === \"++\";\n\n      if (!(expr instanceof VariableReference)) {\n        this.Error(\n          `can only increment and decrement variables, but saw '${expr}'.`\n        );\n\n        // Drop down and succeed without the increment after reporting error\n      } else {\n        const varRef = expr as VariableReference;\n        expr = new IncDecExpression(varRef.identifier, isInc);\n      }\n    }\n\n    return expr;\n  };\n\n  public readonly ExpressionNot = (): string | null => {\n    const id = this.Identifier();\n    if (id === \"not\") {\n      return id;\n    }\n\n    return null;\n  };\n\n  public readonly ExpressionLiteral = (): Expression =>\n    this.OneOf([\n      this.ExpressionFloat,\n      this.ExpressionInt,\n      this.ExpressionBool,\n      this.ExpressionString,\n    ]) as Expression;\n\n  public readonly ExpressionDivertTarget = (): Expression | null => {\n    this.Whitespace();\n\n    const divert = this.Parse(this.SingleDivert) as Divert;\n    if (!divert || (divert && divert.isThread)) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    return new DivertTarget(divert);\n  };\n\n  public readonly ExpressionInt = (): NumberExpression | null => {\n    const intOrNull: number = this.ParseInt() as number;\n    if (intOrNull === null) {\n      return null;\n    }\n\n    return new NumberExpression(intOrNull, \"int\");\n  };\n\n  public readonly ExpressionFloat = (): NumberExpression | null => {\n    const floatOrNull: number = this.ParseFloat() as number;\n    if (floatOrNull === null) {\n      return null;\n    }\n\n    return new NumberExpression(floatOrNull, \"float\");\n  };\n\n  public readonly ExpressionString = (): StringExpression | null => {\n    const openQuote = this.ParseString('\"');\n    if (openQuote === null) {\n      return null;\n    }\n\n    // Set custom parser state flag so that within the text parser,\n    // it knows to treat the quote character (\") as an end character\n    this.parsingStringExpression = true;\n\n    let textAndLogic: ParsedObject[] = this.Parse(\n      this.MixedTextAndLogic\n    ) as ParsedObject[];\n\n    this.Expect(this.String('\"'), \"close quote for string expression\");\n\n    this.parsingStringExpression = false;\n\n    if (textAndLogic === null) {\n      textAndLogic = [new Text(\"\")];\n    } else if (textAndLogic.find((c) => c instanceof Divert)) {\n      this.Error(\"String expressions cannot contain diverts (->)\");\n    }\n\n    return new StringExpression(textAndLogic);\n  };\n\n  public readonly ExpressionBool = (): NumberExpression | null => {\n    const id = this.Parse(this.Identifier);\n    if (id === \"true\") {\n      return new NumberExpression(true, \"bool\");\n    } else if (id === \"false\") {\n      return new NumberExpression(false, \"bool\");\n    }\n\n    return null;\n  };\n\n  public readonly ExpressionFunctionCall = (): Expression | null => {\n    const iden = this.Parse(this.IdentifierWithMetadata);\n    if (iden === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const args = this.Parse(\n      this.ExpressionFunctionCallArguments\n    ) as Expression[];\n    if (args === null) {\n      return null;\n    }\n\n    return new FunctionCall(iden as Identifier, args);\n  };\n\n  public readonly ExpressionFunctionCallArguments = (): Expression[] | null => {\n    if (this.ParseString(\"(\") === null) {\n      return null;\n    }\n\n    // \"Exclude\" requires the rule to succeed, but causes actual comma string to be excluded from the list of results\n    const commas: ParseRule = this.Exclude(this.String(\",\"));\n    let args = this.Interleave<Expression>(this.Expression, commas);\n    if (args === null) {\n      args = [];\n    }\n\n    this.Whitespace();\n\n    this.Expect(this.String(\")\"), \"closing ')' for function call\");\n\n    return args;\n  };\n\n  public readonly ExpressionVariableName = (): Expression | null => {\n    const path = this.Interleave<Identifier>(\n      this.IdentifierWithMetadata,\n      this.Exclude(this.Spaced(this.String(\".\")))\n    );\n\n    if (path === null || Story.IsReservedKeyword(path[0].name)) {\n      return null;\n    }\n\n    return new VariableReference(path);\n  };\n\n  public readonly ExpressionParen = (): Expression | null => {\n    if (this.ParseString(\"(\") === null) {\n      return null;\n    }\n\n    const innerExpr = this.Parse(this.Expression) as Expression;\n    if (innerExpr === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    this.Expect(this.String(\")\"), \"closing parenthesis ')' for expression\");\n\n    return innerExpr;\n  };\n\n  public readonly ExpressionInfixRight = (\n    left: Expression | null,\n    op: InfixOperator\n  ) => {\n    if (!left) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const right = this.Parse(() =>\n      this.Expression(op.precedence)\n    ) as Expression;\n    if (right) {\n      // We assume that the character we use for the operator's type is the same\n      // as that used internally by e.g. Runtime.Expression.Add, Runtime.Expression.Multiply etc\n      const expr = new BinaryExpression(left, right, op.type);\n      return expr;\n    }\n\n    return null;\n  };\n\n  private readonly ParseInfixOperator = (): InfixOperator | null => {\n    for (const op of this._binaryOperators) {\n      const ruleId: number = this.BeginRule();\n\n      if (this.ParseString(op.type) !== null) {\n        if (op.requireWhitespace) {\n          if (this.Whitespace() === null) {\n            this.FailRule(ruleId);\n\n            continue;\n          }\n        }\n\n        return this.SucceedRule(ruleId, op) as InfixOperator;\n      }\n\n      this.FailRule(ruleId);\n    }\n\n    return null;\n  };\n\n  public readonly ExpressionList = (): List | null => {\n    this.Whitespace();\n\n    if (this.ParseString(\"(\") === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    // When list has:\n    //  - 0 elements (null list) - this is okay, it's an empty list: \"()\"\n    //  - 1 element - it could be confused for a single non-list related\n    //    identifier expression in brackets, but this is a useless thing\n    //    to do, so we reserve that syntax for a list with one item.\n    //  - 2 or more elements - normal!\n    const memberNames: Identifier[] = this.SeparatedList(\n      this.ListMember,\n      this.Spaced(this.String(\",\"))\n    ) as Identifier[];\n\n    this.Whitespace();\n\n    // May have failed to parse the inner list - the parentheses may\n    // be for a normal expression\n    if (this.ParseString(\")\") === null) {\n      return null;\n    }\n    return new List(memberNames);\n  };\n\n  public readonly ListMember = (): Identifier | null => {\n    this.Whitespace();\n\n    let identifier: Identifier = this.Parse(\n      this.IdentifierWithMetadata\n    ) as Identifier;\n    if (identifier === null) {\n      return null;\n    }\n\n    const dot = this.ParseString(\".\");\n    if (dot !== null) {\n      const identifier2: Identifier = this.Expect(\n        this.IdentifierWithMetadata,\n        `element name within the set ${identifier}`\n      ) as Identifier;\n\n      identifier.name += `.${identifier2?.name}`;\n    }\n\n    this.Whitespace();\n\n    return identifier;\n  };\n\n  public readonly RegisterExpressionOperators = () => {\n    // These will be tried in order, so we need \"<=\" before \"<\"\n    // for correctness\n\n    this.RegisterBinaryOperator(\"&&\", 1);\n    this.RegisterBinaryOperator(\"||\", 1);\n    this.RegisterBinaryOperator(\"and\", 1, true);\n    this.RegisterBinaryOperator(\"or\", 1, true);\n    this.RegisterBinaryOperator(\"==\", 2);\n    this.RegisterBinaryOperator(\">=\", 2);\n    this.RegisterBinaryOperator(\"<=\", 2);\n    this.RegisterBinaryOperator(\"<\", 2);\n    this.RegisterBinaryOperator(\">\", 2);\n    this.RegisterBinaryOperator(\"!=\", 2);\n\n    // (apples, oranges) + cabbages has (oranges, cabbages) === true\n    this.RegisterBinaryOperator(\"?\", 3);\n    this.RegisterBinaryOperator(\"has\", 3, true);\n    this.RegisterBinaryOperator(\"!?\", 3);\n    this.RegisterBinaryOperator(\"hasnt\", 3, true);\n    this.RegisterBinaryOperator(\"^\", 3);\n\n    this.RegisterBinaryOperator(\"+\", 4);\n    this.RegisterBinaryOperator(\"-\", 5);\n    this.RegisterBinaryOperator(\"*\", 6);\n    this.RegisterBinaryOperator(\"/\", 7);\n\n    this.RegisterBinaryOperator(\"%\", 8);\n    this.RegisterBinaryOperator(\"mod\", 8, true);\n  };\n\n  public readonly RegisterBinaryOperator = (\n    op: string,\n    precedence: number,\n    requireWhitespace: boolean = false\n  ): void => {\n    const infix = new InfixOperator(op, precedence, requireWhitespace);\n    this._binaryOperators.push(infix);\n    this._maxBinaryOpLength = Math.max(this._maxBinaryOpLength, op.length);\n  };\n\n  /**\n   * End Expressions section.\n   */\n\n  /**\n   * Begin Include section.\n   */\n\n  private _rootParser: InkParser;\n  private _openFilenames: string[] = [];\n\n  public readonly IncludeStatement = () => {\n    this.Whitespace();\n\n    if (this.ParseString(\"INCLUDE\") === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    let filename: string = this.Expect(\n      () => this.ParseUntilCharactersFromString(\"\\n\\r\"),\n      \"filename for include statement\"\n    ) as string;\n\n    filename = filename.replace(new RegExp(/[ \\t]+$/g), \"\");\n\n    // Working directory should already have been set up relative to the root ink file.\n    const fullFilename = this.fileHandler.ResolveInkFilename(\n      filename,\n      this._filename\n    );\n\n    if (this.FilenameIsAlreadyOpen(fullFilename)) {\n      this.Error(\n        `Recursive INCLUDE detected: '${fullFilename}' is already open.`\n      );\n      this.ParseUntilCharactersFromString(\"\\r\\n\");\n      return new IncludedFile(null);\n    } else {\n      this.AddOpenFilename(fullFilename);\n    }\n\n    let includedStory: Story | null = null;\n    let includedString: string = \"\";\n    try {\n      includedString = this._rootParser.fileHandler.LoadInkFileContents(\n        fullFilename,\n        this._filename\n      );\n    } catch (err) {\n      this.Error(`Failed to load: '${filename}'.\\nError:${err}`);\n    }\n\n    if (includedString != null) {\n      const parser: InkParser = new InkParser(\n        includedString,\n        filename,\n        this._externalErrorHandler,\n        this._rootParser,\n        this.fileHandler\n      );\n\n      includedStory = parser.ParseStory();\n    }\n\n    this.RemoveOpenFilename(fullFilename);\n\n    // Return valid IncludedFile object even if there were errors when parsing.\n    // We don't want to attempt to re-parse the include line as something else,\n    // and we want to include the bits that *are* valid, so we don't generate\n    // more errors than necessary.\n    return new IncludedFile(includedStory);\n  };\n\n  public readonly FilenameIsAlreadyOpen = (fullFilename: string): boolean =>\n    this._rootParser._openFilenames.includes(fullFilename);\n\n  public readonly AddOpenFilename = (fullFilename: string): void => {\n    this._rootParser._openFilenames.push(fullFilename);\n  };\n\n  public readonly RemoveOpenFilename = (fullFilename: string) => {\n    this._rootParser._openFilenames.splice(\n      this._rootParser._openFilenames.indexOf(fullFilename),\n      1\n    );\n  };\n\n  /**\n   * End Include section.\n   */\n\n  /**\n   * Begin Knot section.\n   */\n\n  public readonly KnotDefinition = (): Knot | null => {\n    const knotDecl: FlowDecl = this.Parse(this.KnotDeclaration) as FlowDecl;\n    if (knotDecl === null) {\n      return null;\n    }\n\n    this.Expect(\n      this.EndOfLine,\n      \"end of line after knot name definition\",\n      this.SkipToNextLine\n    );\n\n    const innerKnotStatements: ParseRule = (): ParsedObject[] =>\n      this.StatementsAtLevel(StatementLevel.Knot);\n\n    const content = this.Expect(\n      innerKnotStatements,\n      \"at least one line within the knot\",\n      this.KnotStitchNoContentRecoveryRule\n    ) as ParsedObject[];\n\n    return new Knot(knotDecl.name, content, knotDecl.args, knotDecl.isFunction);\n  };\n\n  public readonly KnotDeclaration = (): FlowDecl | null => {\n    this.Whitespace();\n\n    if (this.KnotTitleEquals() === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const identifier: Identifier = this.Parse(\n      this.IdentifierWithMetadata\n    ) as Identifier;\n    let knotName: Identifier;\n\n    const isFunc: boolean = identifier?.name === \"function\";\n    if (isFunc) {\n      this.Expect(this.Whitespace, \"whitespace after the 'function' keyword\");\n\n      knotName = this.Parse(this.IdentifierWithMetadata) as Identifier;\n    } else {\n      knotName = identifier;\n    }\n\n    if (knotName === null) {\n      this.Error(`Expected the name of the ${isFunc ? \"function\" : \"knot\"}`);\n      knotName = new Identifier(\"\"); // prevent later null ref\n    }\n\n    this.Whitespace();\n\n    const parameterNames: Argument[] = this.Parse(\n      this.BracketedKnotDeclArguments\n    ) as Argument[];\n\n    this.Whitespace();\n\n    // Optional equals after name\n    this.Parse(this.KnotTitleEquals);\n\n    return new FlowDecl(knotName, parameterNames, isFunc);\n  };\n\n  public readonly KnotTitleEquals = (): string | null => {\n    // 2+ \"=\" starts a knot\n    const multiEquals = this.ParseCharactersFromString(\"=\");\n    if (multiEquals === null || multiEquals.length <= 1) {\n      return null;\n    }\n\n    return multiEquals;\n  };\n\n  public readonly StitchDefinition = (): ParseRuleReturn => {\n    const decl = this.Parse(this.StitchDeclaration) as FlowDecl;\n    if (decl === null) {\n      return null;\n    }\n\n    this.Expect(\n      this.EndOfLine,\n      \"end of line after stitch name\",\n      this.SkipToNextLine\n    );\n\n    const innerStitchStatements: ParseRule = () =>\n      this.StatementsAtLevel(StatementLevel.Stitch);\n\n    const content = this.Expect(\n      innerStitchStatements,\n      \"at least one line within the stitch\",\n      this.KnotStitchNoContentRecoveryRule\n    ) as ParsedObject[];\n\n    return new Stitch(decl.name, content, decl.args, decl.isFunction);\n  };\n\n  public readonly StitchDeclaration = (): FlowDecl | null => {\n    this.Whitespace();\n\n    // Single \"=\" to define a stitch\n    if (this.ParseString(\"=\") === null) {\n      return null;\n    }\n\n    // If there's more than one \"=\", that's actually a knot definition (or divert), so this rule should fail\n    if (this.ParseString(\"=\") !== null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    // Stitches aren't allowed to be functions, but we parse it anyway and report the error later\n    const isFunc: boolean = this.ParseString(\"function\") !== null;\n    if (isFunc) {\n      this.Whitespace();\n    }\n\n    const stitchName: Identifier = this.Parse(\n      this.IdentifierWithMetadata\n    ) as Identifier;\n    if (stitchName === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const flowArgs: Argument[] = this.Parse(\n      this.BracketedKnotDeclArguments\n    ) as Argument[];\n\n    this.Whitespace();\n\n    return new FlowDecl(stitchName, flowArgs, isFunc);\n  };\n\n  public readonly KnotStitchNoContentRecoveryRule = (): ParseRuleReturn => {\n    // Jump ahead to the next knot or the end of the file\n    this.ParseUntil(this.KnotDeclaration, new CharacterSet(\"=\"), null);\n\n    const recoveredFlowContent: ParsedObject[] = [new Text(\"<ERROR IN FLOW>\")];\n\n    return recoveredFlowContent;\n  };\n\n  public readonly BracketedKnotDeclArguments = (): Argument[] | null => {\n    if (this.ParseString(\"(\") === null) {\n      return null;\n    }\n\n    let flowArguments = this.Interleave<Argument>(\n      this.Spaced(this.FlowDeclArgument),\n      this.Exclude(this.String(\",\"))\n    );\n\n    this.Expect(this.String(\")\"), \"closing ')' for parameter list\");\n\n    // If no parameters, create an empty list so that this method is type safe and\n    // doesn't attempt to return the ParseSuccess object\n    if (flowArguments === null) {\n      flowArguments = [];\n    }\n\n    return flowArguments;\n  };\n\n  public readonly FlowDeclArgument = (): Argument | null => {\n    // Possible forms:\n    //  name\n    //  -> name      (variable divert target argument\n    //  ref name\n    //  ref -> name  (variable divert target by reference)\n    const firstIden = this.Parse(this.IdentifierWithMetadata) as Identifier;\n    this.Whitespace();\n\n    const divertArrow = this.ParseDivertArrow();\n\n    this.Whitespace();\n\n    const secondIden = this.Parse(this.IdentifierWithMetadata) as Identifier;\n\n    if (firstIden == null && secondIden === null) {\n      return null;\n    }\n\n    const flowArg = new Argument();\n    if (divertArrow !== null) {\n      flowArg.isDivertTarget = true;\n    }\n\n    // Passing by reference\n    if (firstIden !== null && firstIden.name === \"ref\") {\n      if (secondIden === null) {\n        this.Error(\"Expected an parameter name after 'ref'\");\n      }\n\n      flowArg.identifier = secondIden;\n      flowArg.isByReference = true;\n    } else {\n      // Simple argument name\n      if (flowArg.isDivertTarget) {\n        flowArg.identifier = secondIden;\n      } else {\n        flowArg.identifier = firstIden;\n      }\n\n      if (flowArg.identifier === null) {\n        this.Error(\"Expected an parameter name\");\n      }\n\n      flowArg.isByReference = false;\n    }\n\n    return flowArg;\n  };\n\n  public readonly ExternalDeclaration = (): ExternalDeclaration | null => {\n    this.Whitespace();\n\n    const external = this.Parse(\n      this.IdentifierWithMetadata\n    ) as Identifier | null;\n    if (external === null || external.name != \"EXTERNAL\") {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const funcIdentifier: Identifier =\n      (this.Expect(\n        this.IdentifierWithMetadata,\n        \"name of external function\"\n      ) as Identifier | null) || new Identifier(\"\");\n\n    this.Whitespace();\n\n    let parameterNames = this.Expect(\n      this.BracketedKnotDeclArguments,\n      `declaration of arguments for EXTERNAL, even if empty, i.e. 'EXTERNAL ${funcIdentifier}()'`\n    ) as Argument[];\n\n    if (parameterNames === null) {\n      parameterNames = [];\n    }\n\n    const argNames = parameterNames\n      .map((arg) => arg.identifier?.name)\n      .filter(filterUndef);\n\n    return new ExternalDeclaration(funcIdentifier, argNames);\n  };\n\n  /**\n   * End Knot section.\n   */\n\n  /**\n   * Start Logic section.\n   */\n\n  private _identifierCharSet: CharacterSet | null = null;\n\n  get identifierCharSet(): CharacterSet {\n    if (this._identifierCharSet === null) {\n      (this._identifierCharSet = new CharacterSet())\n        .AddRange(\"A\", \"Z\")\n        .AddRange(\"a\", \"z\")\n        .AddRange(\"0\", \"9\")\n        .Add(\"_\");\n\n      // Enable non-ASCII characters for story identifiers.\n      this.ExtendIdentifierCharacterRanges(this._identifierCharSet);\n    }\n\n    return this._identifierCharSet;\n  }\n\n  public readonly LogicLine = (): ParsedObject | null => {\n    this.Whitespace();\n\n    if (this.ParseString(\"~\") === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    // Some example lines we need to be able to distinguish between:\n    // ~ temp x = 5  -- var decl + assign\n    // ~ temp x      -- var decl\n    // ~ x = 5       -- var assign\n    // ~ x           -- expr (not var decl or assign)\n    // ~ f()         -- expr\n    // We don't treat variable decl/assign as an expression since we don't want an assignment\n    // to have a return value, or to be used in compound expressions.\n    const afterTilde: ParseRule = () =>\n      this.OneOf([\n        this.ReturnStatement,\n        this.TempDeclarationOrAssignment,\n        this.Expression,\n      ]);\n\n    let result = this.Expect(\n      afterTilde,\n      \"expression after '~'\",\n      this.SkipToNextLine\n    ) as ParsedObject;\n\n    // Prevent further errors, already reported expected expression and have skipped to next line.\n    if (result === null) {\n      return new ContentList();\n    }\n\n    // Parse all expressions, but tell the writer off if they did something useless like:\n    //  ~ 5 + 4\n    // And even:\n    //  ~ false && myFunction()\n    // ...since it's bad practice, and won't do what they expect if\n    // they're expecting C's lazy evaluation.\n    if (\n      result instanceof Expression &&\n      !(result instanceof FunctionCall || result instanceof IncDecExpression)\n    ) {\n      this.Error(\n        \"Logic following a '~' can't be that type of expression. It can only be something like:\\n\\t~ return\\n\\t~ var x = blah\\n\\t~ x++\\n\\t~ myFunction()\"\n      );\n    }\n\n    // Line is pure function call? e.g.\n    //  ~ f()\n    // Add extra pop to make sure we tidy up after ourselves.\n    // We no longer need anything on the evaluation stack.\n    const funCall = asOrNull(result, FunctionCall);\n    if (funCall) {\n      funCall.shouldPopReturnedValue = true;\n    }\n\n    // If the expression contains a function call, then it could produce a text side effect,\n    // in which case it needs a newline on the end. e.g.\n    //  ~ printMyName()\n    //  ~ x = 1 + returnAValueAndAlsoPrintStuff()\n    // If no text gets printed, then the extra newline will have to be culled later.\n    // Multiple newlines on the output will be removed, so there will be no \"leak\" for\n    // long running calculations. It's disappointingly messy though :-/\n    if (result.Find(FunctionCall)() !== null) {\n      result = new ContentList(\n        result as unknown as ParsedObject[],\n        new Text(\"\\n\")\n      );\n    }\n\n    this.Expect(this.EndOfLine, \"end of line\", this.SkipToNextLine);\n\n    return result as ParsedObject;\n  };\n\n  public readonly VariableDeclaration = (): ParsedObject | null => {\n    this.Whitespace();\n\n    const id = this.Parse(this.Identifier);\n    if (id !== \"VAR\") {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const varName = this.Expect(\n      this.IdentifierWithMetadata,\n      \"variable name\"\n    ) as Identifier;\n\n    this.Whitespace();\n\n    this.Expect(\n      this.String(\"=\"),\n      \"the '=' for an assignment of a value, e.g. '= 5' (initial values are mandatory)\"\n    );\n\n    this.Whitespace();\n\n    const definition = this.Expect(this.Expression, \"initial value for \");\n\n    const expr = definition as Expression;\n\n    if (expr) {\n      const check =\n        expr instanceof NumberExpression ||\n        expr instanceof StringExpression ||\n        expr instanceof DivertTarget ||\n        expr instanceof VariableReference ||\n        expr instanceof List;\n\n      if (!check) {\n        this.Error(\n          \"initial value for a variable must be a number, constant, list or divert target\"\n        );\n      }\n\n      if (this.Parse(this.ListElementDefinitionSeparator) !== null) {\n        this.Error(\n          \"Unexpected ','. If you're trying to declare a new list, use the LIST keyword, not VAR\"\n        );\n      } else if (expr instanceof StringExpression) {\n        // Ensure string expressions are simple\n        const strExpr = expr as StringExpression;\n        if (!strExpr.isSingleString) {\n          this.Error(\"Constant strings cannot contain any logic.\");\n        }\n      }\n\n      const result = new VariableAssignment({\n        assignedExpression: expr,\n        isGlobalDeclaration: true,\n        variableIdentifier: varName,\n      });\n\n      return result;\n    }\n\n    return null;\n  };\n\n  public readonly ListDeclaration = (): VariableAssignment | null => {\n    this.Whitespace();\n\n    const id = this.Parse(this.Identifier);\n    if (id != \"LIST\") {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const varName = this.Expect(\n      this.IdentifierWithMetadata,\n      \"list name\"\n    ) as Identifier;\n\n    this.Whitespace();\n\n    this.Expect(\n      this.String(\"=\"),\n      \"the '=' for an assignment of the list definition\"\n    );\n\n    this.Whitespace();\n\n    const definition = this.Expect(\n      this.ListDefinition,\n      \"list item names\"\n    ) as ListDefinition;\n\n    if (definition) {\n      definition.identifier = new Identifier(varName.name);\n      return new VariableAssignment({\n        variableIdentifier: varName,\n        listDef: definition,\n      });\n    }\n\n    return null;\n  };\n\n  public readonly ListDefinition = (): ListDefinition | null => {\n    this.AnyWhitespace();\n\n    const allElements = this.SeparatedList(\n      this.ListElementDefinition,\n      this.ListElementDefinitionSeparator\n    ) as ListElementDefinition[];\n\n    if (allElements === null) {\n      return null;\n    }\n\n    return new ListDefinition(allElements);\n  };\n\n  public readonly ListElementDefinitionSeparator = (): string | null => {\n    this.AnyWhitespace();\n\n    if (this.ParseString(\",\") === null) {\n      return null;\n    }\n\n    this.AnyWhitespace();\n\n    return \",\";\n  };\n\n  public readonly ListElementDefinition = () => {\n    const inInitialList = this.ParseString(\"(\") !== null;\n    let needsToCloseParen = inInitialList;\n\n    this.Whitespace();\n\n    const name = this.Parse(this.IdentifierWithMetadata) as Identifier | null;\n    if (name === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    if (inInitialList) {\n      if (this.ParseString(\")\") != null) {\n        needsToCloseParen = false;\n        this.Whitespace();\n      }\n    }\n\n    let elementValue: number | null = null;\n    if (this.ParseString(\"=\") !== null) {\n      this.Whitespace();\n\n      const elementValueNum = this.Expect(\n        this.ExpressionInt,\n        \"value to be assigned to list item\"\n      ) as NumberExpression;\n\n      if (elementValueNum !== null) {\n        elementValue = elementValueNum.value as number;\n      }\n\n      if (needsToCloseParen) {\n        this.Whitespace();\n\n        if (this.ParseString(\")\") !== null) {\n          needsToCloseParen = false;\n        }\n      }\n    }\n\n    if (needsToCloseParen) {\n      this.Error(\"Expected closing ')'\");\n    }\n\n    return new ListElementDefinition(name, inInitialList, elementValue);\n  };\n\n  public readonly ConstDeclaration = (): ParsedObject | null => {\n    this.Whitespace();\n\n    const id = this.Parse(this.Identifier);\n    if (id !== \"CONST\") {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const varName = this.Expect(\n      this.IdentifierWithMetadata,\n      \"constant name\"\n    ) as Identifier;\n\n    this.Whitespace();\n\n    this.Expect(\n      this.String(\"=\"),\n      \"the '=' for an assignment of a value, e.g. '= 5' (initial values are mandatory)\"\n    );\n\n    this.Whitespace();\n\n    const expr = this.Expect(\n      this.Expression,\n      \"initial value for \"\n    ) as Expression;\n\n    const check =\n      expr instanceof NumberExpression ||\n      expr instanceof DivertTarget ||\n      expr instanceof StringExpression;\n\n    if (!check) {\n      this.Error(\n        \"initial value for a constant must be a number or divert target\"\n      );\n    } else if (expr instanceof StringExpression) {\n      // Ensure string expressions are simple\n      const strExpr = expr as StringExpression;\n      if (!strExpr.isSingleString) {\n        this.Error(\"Constant strings cannot contain any logic.\");\n      }\n    }\n\n    const result = new ConstantDeclaration(varName, expr);\n\n    return result;\n  };\n\n  public readonly InlineLogicOrGlueOrStartTag = (): ParsedObject =>\n    this.OneOf([this.InlineLogic, this.Glue, this.StartTag]) as ParsedObject;\n\n  public readonly Glue = (): Glue | null => {\n    // Don't want to parse whitespace, since it might be important\n    // surrounding the glue.\n    const glueStr = this.ParseString(\"<>\");\n    if (glueStr !== null) {\n      return new Glue(new RuntimeGlue());\n    }\n\n    return null;\n  };\n\n  public readonly InlineLogic = () => {\n    if (this.ParseString(\"{\") === null) {\n      return null;\n    }\n\n    let wasParsingString = this.parsingStringExpression;\n    let wasTagActive = this.tagActive;\n\n    this.Whitespace();\n\n    const logic = this.Expect(\n      this.InnerLogic,\n      \"some kind of logic, conditional or sequence within braces: { ... }\"\n    ) as ParsedObject;\n\n    if (logic === null) {\n      this.parsingStringExpression = wasParsingString;\n      return null;\n    }\n\n    this.DisallowIncrement(logic);\n\n    let contentList = asOrNull(logic, ContentList);\n    if (!contentList) {\n      contentList = new ContentList(logic as unknown as ParsedObject[]);\n    }\n\n    this.Whitespace();\n\n    this.Expect(this.String(\"}\"), \"closing brace '}' for inline logic\");\n\n    // Allow nested strings and logic\n    this.parsingStringExpression = wasParsingString;\n\n    // Difference between:\n    //\n    //     1) A thing # {image}.jpg\n    //     2) A {red #red|blue #blue} sequence.\n    //\n    //  When logic ends in (1) we still want tag to continue.\n    //  When logic ends in (2) we want to auto-end the tag.\n    //  Side note: we simply disallow tags within strings.\n    if (!wasTagActive) this.EndTagIfNecessary(contentList);\n\n    return contentList;\n  };\n\n  public readonly InnerLogic = (): ParsedObject | null => {\n    this.Whitespace();\n\n    // Explicitly try the combinations of inner logic\n    // that could potentially have conflicts first.\n\n    // Explicit sequence annotation?\n    const explicitSeqType: SequenceType = this.ParseObject(\n      this.SequenceTypeAnnotation\n    ) as SequenceType;\n\n    if (explicitSeqType !== null) {\n      const contentLists = this.Expect(\n        this.InnerSequenceObjects,\n        \"sequence elements (for cycle/stoping etc)\"\n      ) as ContentList[];\n\n      if (contentLists === null) {\n        return null;\n      }\n\n      return new Sequence(contentLists, explicitSeqType);\n    }\n\n    // Conditional with expression?\n    const initialQueryExpression = this.Parse(\n      this.ConditionExpression\n    ) as Expression;\n    if (initialQueryExpression) {\n      const conditional = this.Expect(\n        () => this.InnerConditionalContent(initialQueryExpression),\n        \"conditional content following query\"\n      ) as Conditional;\n\n      return conditional;\n    }\n\n    // Now try to evaluate each of the \"full\" rules in turn\n    const rules: ParseRule[] = [\n      // Conditional still necessary, since you can have a multi-line conditional\n      // without an initial query expression:\n      // {\n      //   - true:  this is true\n      //   - false: this is false\n      // }\n      this.InnerConditionalContent as ParseRule,\n      this.InnerSequence,\n      this.InnerExpression,\n    ];\n\n    //let wasTagActiveAtStartOfScope = this.tagActive;\n\n    // Adapted from \"OneOf\" structuring rule except that in\n    // order for the rule to succeed, it has to maximally\n    // cover the entire string within the { }. Used to\n    // differentiate between:\n    //  {myVar}                 -- Expression (try first)\n    //  {my content is jolly}   -- sequence with single element\n    for (const rule of rules) {\n      const ruleId: number = this.BeginRule();\n\n      const result: ParsedObject = this.ParseObject(rule) as ParsedObject;\n      if (result) {\n        // Not yet at end?\n        if (this.Peek(this.Spaced(this.String(\"}\"))) === null) {\n          this.FailRule(ruleId);\n        } else {\n          // Full parse of content within braces\n          return this.SucceedRule(ruleId, result) as ParsedObject;\n        }\n      } else {\n        this.FailRule(ruleId);\n      }\n    }\n\n    return null;\n  };\n\n  public readonly InnerExpression = (): ParsedObject => {\n    const expr = this.Parse(this.Expression) as Expression;\n    if (expr) {\n      expr.outputWhenComplete = true;\n    }\n\n    return expr;\n  };\n\n  public readonly IdentifierWithMetadata = (): Identifier | null => {\n    const id = this.Identifier();\n    if (id === null) {\n      return null;\n    }\n    return new Identifier(id);\n  };\n\n  // Note: we allow identifiers that start with a number,\n  // but not if they *only* comprise numbers\n  public readonly Identifier = (): string | null => {\n    // Parse remaining characters (if any)\n    const name = this.ParseCharactersFromCharSet(this.identifierCharSet);\n    if (name === null) {\n      return null;\n    }\n\n    // Reject if it's just a number\n    let isNumberCharsOnly: boolean = true;\n    for (let c of name) {\n      if (!(c >= \"0\" && c <= \"9\")) {\n        isNumberCharsOnly = false;\n        break;\n      }\n    }\n\n    if (isNumberCharsOnly) {\n      return null;\n    }\n\n    return name;\n  };\n\n  /**\n   * End Logic section.\n   */\n\n  /**\n   * Begin Sequences section.\n   */\n\n  public _sequenceTypeSymbols: CharacterSet = new CharacterSet(\"!&~$\");\n\n  public readonly InnerSequence = (): Sequence | null => {\n    this.Whitespace();\n\n    // Default sequence type\n    let seqType: SequenceType = SequenceType.Stopping;\n\n    // Optional explicit sequence type\n    const parsedSeqType: SequenceType = this.Parse(\n      this.SequenceTypeAnnotation\n    ) as SequenceType;\n\n    if (parsedSeqType !== null) {\n      seqType = parsedSeqType;\n    }\n\n    const contentLists = this.Parse(this.InnerSequenceObjects) as ContentList[];\n    if (contentLists === null || contentLists.length <= 1) {\n      return null;\n    }\n\n    return new Sequence(contentLists, seqType);\n  };\n\n  public readonly SequenceTypeAnnotation = (): ParseRuleReturn => {\n    let annotation = this.Parse(\n      this.SequenceTypeSymbolAnnotation\n    ) as SequenceType;\n\n    if (annotation === null) {\n      annotation = this.Parse(this.SequenceTypeWordAnnotation) as SequenceType;\n    }\n\n    if (annotation === null) {\n      return null;\n    }\n\n    switch (annotation) {\n      case SequenceType.Once:\n      case SequenceType.Cycle:\n      case SequenceType.Stopping:\n      case SequenceType.Shuffle:\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison\n      case SequenceType.Shuffle | SequenceType.Stopping:\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison\n      case SequenceType.Shuffle | SequenceType.Once:\n        break;\n      default:\n        this.Error(`Sequence type combination not supported: ${annotation}`);\n        return SequenceType.Stopping;\n    }\n\n    return annotation;\n  };\n\n  public readonly SequenceTypeSymbolAnnotation = (): ParseRuleReturn => {\n    if (this._sequenceTypeSymbols === null) {\n      this._sequenceTypeSymbols = new CharacterSet(\"!&~$ \");\n    }\n\n    let sequenceType = 0 as SequenceType;\n    const sequenceAnnotations = this.ParseCharactersFromCharSet(\n      this._sequenceTypeSymbols\n    );\n\n    if (sequenceAnnotations === null) {\n      return null;\n    }\n\n    for (const symbolChar of sequenceAnnotations) {\n      switch (symbolChar) {\n        case \"!\":\n          sequenceType |= SequenceType.Once;\n          break;\n        case \"&\":\n          sequenceType |= SequenceType.Cycle;\n          break;\n        case \"~\":\n          sequenceType |= SequenceType.Shuffle;\n          break;\n        case \"$\":\n          sequenceType |= SequenceType.Stopping;\n          break;\n      }\n    }\n\n    if (sequenceType === (0 as SequenceType)) {\n      return null;\n    }\n\n    return sequenceType;\n  };\n\n  public readonly SequenceTypeWordAnnotation = (): ParseRuleReturn => {\n    const sequenceTypes = this.Interleave<SequenceType | null>(\n      this.SequenceTypeSingleWord,\n      this.Exclude(this.Whitespace)\n    );\n\n    if (sequenceTypes === null || sequenceTypes.length === 0) {\n      return null;\n    }\n\n    if (this.ParseString(\":\") === null) {\n      return null;\n    }\n\n    let combinedSequenceType = 0 as SequenceType;\n    for (const seqType of sequenceTypes) {\n      combinedSequenceType |= seqType!;\n    }\n\n    return combinedSequenceType;\n  };\n\n  public readonly SequenceTypeSingleWord = () => {\n    let seqType: SequenceType | null = null;\n\n    const word = this.Parse(this.IdentifierWithMetadata) as Identifier | null;\n\n    if (word !== null) {\n      switch (word.name) {\n        case \"once\":\n          seqType = SequenceType.Once;\n          break;\n        case \"cycle\":\n          seqType = SequenceType.Cycle;\n          break;\n        case \"shuffle\":\n          seqType = SequenceType.Shuffle;\n          break;\n        case \"stopping\":\n          seqType = SequenceType.Stopping;\n          break;\n      }\n    }\n\n    if (seqType === null) {\n      return null;\n    }\n\n    return seqType;\n  };\n\n  public readonly InnerSequenceObjects = (): ContentList[] => {\n    const multiline = this.Parse(this.Newline) !== null;\n\n    let result: ContentList[] | null = null;\n    if (multiline) {\n      result = this.Parse(this.InnerMultilineSequenceObjects) as ContentList[];\n    } else {\n      result = this.Parse(this.InnerInlineSequenceObjects) as ContentList[];\n    }\n\n    return result;\n  };\n\n  public readonly InnerInlineSequenceObjects = (): ContentList[] | null => {\n    const interleavedContentAndPipes = this.Interleave<ParsedObject>(\n      this.Optional(this.MixedTextAndLogic),\n      this.String(\"|\"),\n      null,\n      false\n    );\n\n    if (interleavedContentAndPipes === null) {\n      return null;\n    }\n\n    const result = [];\n\n    // The content and pipes won't necessarily be perfectly interleaved in the sense that\n    // the content can be missing, but in that case it's intended that there's blank content.\n    let justHadContent: boolean = false;\n    for (const contentOrPipe of interleavedContentAndPipes) {\n      // Pipe/separator\n      if ((contentOrPipe as any) === \"|\") {\n        // Expected content, saw pipe - need blank content now\n        if (!justHadContent) {\n          // Add blank content\n          result.push(new ContentList());\n        }\n\n        justHadContent = false;\n      } else {\n        // Real content\n        const content = contentOrPipe as unknown as ParsedObject[];\n        if (content === null) {\n          this.Error(\n            `Expected content, but got ${contentOrPipe as unknown as string} (this is an ink compiler bug!)`\n          );\n        } else {\n          result.push(new ContentList(content));\n        }\n\n        justHadContent = true;\n      }\n    }\n\n    // Ended in a pipe? Need to insert final blank content\n    if (!justHadContent) {\n      result.push(new ContentList());\n    }\n\n    return result;\n  };\n\n  public readonly InnerMultilineSequenceObjects = (): ContentList[] | null => {\n    this.MultilineWhitespace();\n\n    const contentLists = this.OneOrMore(\n      this.SingleMultilineSequenceElement\n    ) as ContentList[];\n    if (contentLists === null) {\n      return null;\n    }\n\n    return contentLists;\n  };\n\n  public readonly SingleMultilineSequenceElement = () => {\n    this.Whitespace();\n\n    // Make sure we're not accidentally parsing a divert\n    if (this.ParseString(\"->\") !== null) {\n      return null;\n    }\n\n    if (this.ParseString(\"-\") === null) {\n      return null;\n    }\n\n    this.Whitespace();\n\n    const content: ParsedObject[] = this.StatementsAtLevel(\n      StatementLevel.InnerBlock\n    );\n\n    if (content === null) {\n      this.MultilineWhitespace();\n    } else {\n      // Add newline at the start of each branch\n      content.unshift(new Text(\"\\n\"));\n    }\n\n    return new ContentList(content);\n  };\n\n  /**\n   * End Sequences section.\n   */\n\n  /**\n   * Begin Statements section.\n   */\n\n  private _statementRulesAtLevel: ParseRule[][] = [];\n  private _statementBreakRulesAtLevel: ParseRule[][] = [];\n\n  public readonly StatementsAtLevel = (\n    level: StatementLevel\n  ): ParsedObject[] => {\n    // Check for error: Should not be allowed gather dashes within an inner block\n    if (level === StatementLevel.InnerBlock) {\n      const badGatherDashCount = this.Parse(this.GatherDashes) as ParsedObject;\n      if (badGatherDashCount !== null) {\n        this.Error(\n          \"You can't use a gather (the dashes) within the { curly braces } context. For multi-line sequences and conditions, you should only use one dash.\"\n        );\n      }\n    }\n\n    return this.Interleave<ParsedObject>(\n      this.Optional(this.MultilineWhitespace),\n      () => this.StatementAtLevel(level),\n      () => this.StatementsBreakForLevel(level)\n    );\n  };\n\n  public readonly StatementAtLevel = (level: StatementLevel): ParsedObject => {\n    const rulesAtLevel: ParseRule[] =\n      this._statementRulesAtLevel[level as number];\n    const statement = this.OneOf(rulesAtLevel) as ReturnType;\n\n    // For some statements, allow them to parse, but create errors, since\n    // writers may think they can use the statement, so it's useful to have\n    // the error message.\n    if (level === StatementLevel.Top) {\n      if (statement instanceof ReturnType) {\n        this.Error(\"should not have return statement outside of a knot\");\n      }\n    }\n\n    return statement;\n  };\n\n  public readonly StatementsBreakForLevel = (\n    level: StatementLevel\n  ): ParseRuleReturn => {\n    this.Whitespace();\n\n    const breakRules: ParseRule[] =\n      this._statementBreakRulesAtLevel[level as number];\n    const breakRuleResult = this.OneOf(breakRules);\n    if (breakRuleResult === null) {\n      return null;\n    }\n\n    return breakRuleResult;\n  };\n\n  public readonly GenerateStatementLevelRules = () => {\n    const levels: StatementLevel[] = Object.values(\n      StatementLevel\n    ) as StatementLevel[];\n\n    this._statementRulesAtLevel = \"f\"\n      .repeat(levels.length)\n      .split(\"f\")\n      .map(() => []);\n\n    this._statementBreakRulesAtLevel = \"f\"\n      .repeat(levels.length)\n      .split(\"f\")\n      .map(() => []);\n\n    for (const level of levels) {\n      const rulesAtLevel: ParseRule[] = [];\n      const breakingRules: ParseRule[] = [];\n\n      // Diverts can go anywhere\n      rulesAtLevel.push(this.Line(this.MultiDivert));\n\n      // Knots can only be parsed at Top/Global scope\n      if (level >= StatementLevel.Top) {\n        rulesAtLevel.push(this.KnotDefinition);\n      }\n\n      rulesAtLevel.push(this.Line(this.Choice));\n\n      rulesAtLevel.push(this.Line(this.AuthorWarning));\n\n      // Gather lines would be confused with multi-line block separators, like\n      // within a multi-line if statement\n      if (level > StatementLevel.InnerBlock) {\n        rulesAtLevel.push(this.Gather);\n      }\n\n      // Stitches (and gathers) can (currently) only go in Knots and top level\n      if (level >= StatementLevel.Knot) {\n        rulesAtLevel.push(this.StitchDefinition);\n      }\n\n      // Global variable declarations can go anywhere\n      rulesAtLevel.push(this.Line(this.ListDeclaration));\n      rulesAtLevel.push(this.Line(this.VariableDeclaration));\n      rulesAtLevel.push(this.Line(this.ConstDeclaration));\n      rulesAtLevel.push(this.Line(this.ExternalDeclaration));\n\n      // Global include can go anywhere\n      rulesAtLevel.push(this.Line(this.IncludeStatement));\n\n      // Normal logic / text can go anywhere\n      rulesAtLevel.push(this.LogicLine);\n      rulesAtLevel.push(this.LineOfMixedTextAndLogic);\n\n      // --------\n      // Breaking rules\n\n      // Break current knot with a new knot\n      if (level <= StatementLevel.Knot) {\n        breakingRules.push(this.KnotDeclaration);\n      }\n\n      // Break current stitch with a new stitch\n      if (level <= StatementLevel.Stitch) {\n        breakingRules.push(this.StitchDeclaration);\n      }\n\n      // Breaking an inner block (like a multi-line condition statement)\n      if (level <= StatementLevel.InnerBlock) {\n        breakingRules.push(this.ParseDashNotArrow);\n        breakingRules.push(this.String(\"}\"));\n      }\n\n      this._statementRulesAtLevel[level as number] = rulesAtLevel;\n      this._statementBreakRulesAtLevel[level as number] = breakingRules;\n    }\n  };\n\n  public readonly SkipToNextLine = (): typeof ParseSuccess => {\n    this.ParseUntilCharactersFromString(\"\\n\\r\");\n    this.ParseNewline();\n\n    return ParseSuccess;\n  };\n\n  // Modifier to turn a rule into one that expects a newline on the end.\n  // e.g. anywhere you can use \"MixedTextAndLogic\" as a rule, you can use\n  // \"Line(MixedTextAndLogic)\" to specify that it expects a newline afterwards.\n  public readonly Line =\n    (inlineRule: ParseRule): ParseRule =>\n    () => {\n      const result = this.ParseObject(inlineRule);\n      if (result === null) {\n        return null;\n      }\n\n      this.Expect(this.EndOfLine, \"end of line\", this.SkipToNextLine);\n\n      return result;\n    };\n\n  /**\n   * End Statements section.\n   */\n\n  /**\n   * Begin Tags section.\n   */\n\n  public readonly StartTag = (): ParsedObject | null => {\n    this.Whitespace();\n\n    if (this.ParseString(\"#\") === null) {\n      return null;\n    }\n\n    if (this.parsingStringExpression) {\n      this.Error(\n        \"Tags aren't allowed inside of strings. Please use \\\\# if you want a hash symbol.\"\n      );\n    }\n\n    let result: ParsedObject | null = null;\n    if (this.tagActive) {\n      let contentList = new ContentList();\n      contentList.AddContent(new Tag(/*isStart:*/ false));\n      contentList.AddContent(new Tag(/*isStart:*/ true));\n      result = contentList;\n    } else {\n      result = new Tag(/*isStart:*/ true);\n    }\n    this.tagActive = true;\n\n    this.Whitespace();\n\n    return result;\n  };\n\n  public EndTagIfNecessary(outputContentList: ParsedObject[] | null): void;\n  public EndTagIfNecessary(outputContentList: ContentList | null): void;\n  public EndTagIfNecessary(\n    outputContentList: ParsedObject[] | ContentList | null\n  ): void {\n    if (this.tagActive) {\n      if (outputContentList != null) {\n        if (outputContentList instanceof ContentList) {\n          outputContentList.AddContent(new Tag(/*isStart:*/ false));\n        } else {\n          outputContentList.push(new Tag(/*isStart:*/ false));\n        }\n      }\n      this.tagActive = false;\n    }\n  }\n\n  /**\n   * End Tags section.\n   */\n\n  /**\n   * Begin Whitespace section.\n   */\n\n  private _inlineWhitespaceChars: CharacterSet = new CharacterSet(\" \\t\");\n\n  // Handles both newline and endOfFile\n  public readonly EndOfLine = () => this.OneOf([this.Newline, this.EndOfFile]);\n\n  // Allow whitespace before the actual newline\n  public readonly Newline = (): typeof ParseSuccess | null => {\n    this.Whitespace();\n\n    const gotNewline: boolean = this.ParseNewline() !== null;\n\n    // Optional \\r, definite \\n to support Windows (\\r\\n) and Mac/Unix (\\n)\n\n    if (!gotNewline) {\n      return null;\n    }\n\n    return ParseSuccess;\n  };\n\n  public readonly EndOfFile = (): typeof ParseSuccess | null => {\n    this.Whitespace();\n\n    if (!this.endOfInput) return null;\n\n    return ParseSuccess;\n  };\n\n  // General purpose space, returns N-count newlines (fails if no newlines)\n  public readonly MultilineWhitespace = (): typeof ParseSuccess | null => {\n    let newlines: ParseRuleReturn[] | null = this.OneOrMore(this.Newline);\n    if (newlines === null) {\n      return null;\n    }\n\n    // Use content field of Token to say how many newlines there were\n    // (in most circumstances it's unimportant)\n    const numNewlines: number = newlines.length;\n    if (numNewlines >= 1) {\n      return ParseSuccess;\n    }\n\n    return null;\n  };\n\n  public readonly Whitespace = (): typeof ParseSuccess | null => {\n    const doneParsed = this.ParseCharactersFromCharSet(\n      this._inlineWhitespaceChars\n    );\n\n    if (doneParsed !== null) {\n      return ParseSuccess;\n    }\n\n    return null;\n  };\n\n  public readonly Spaced =\n    (rule: ParseRule): ParseRule =>\n    () => {\n      this.Whitespace();\n\n      const result = this.ParseObject(rule);\n      if (result === null) {\n        return null;\n      }\n\n      this.Whitespace();\n\n      return result;\n    };\n\n  public readonly AnyWhitespace = (): typeof ParseSuccess | null => {\n    let anyWhitespace: boolean = false;\n\n    while (this.OneOf([this.Whitespace, this.MultilineWhitespace]) !== null) {\n      anyWhitespace = true;\n    }\n\n    return anyWhitespace ? ParseSuccess : null;\n  };\n\n  public readonly MultiSpaced =\n    (rule: ParseRule): ParseRuleReturn =>\n    () => {\n      this.AnyWhitespace();\n\n      const result = this.ParseObject(rule);\n      if (result === null) {\n        return null;\n      }\n\n      this.AnyWhitespace();\n\n      return result;\n    };\n\n  private _filename: string | null = null;\n  private _externalErrorHandler: ErrorHandler | null = null;\n  private _fileHandler: IFileHandler | null = null;\n\n  /**\n   * End Whitespace section.\n   */\n}\n","import { IFileHandler } from \"../IFileHandler\";\n\nexport class JsonFileHandler implements IFileHandler {\n  constructor(public readonly fileHierarchy: Record<string, string>) {}\n\n  readonly ResolveInkFilename = (filename: string): string => {\n    if (Object.keys(this.fileHierarchy).includes(filename)) return filename;\n    throw new Error(\n      `Cannot locate ${filename}. Are you trying a relative import ? This is not yet implemented.`\n    );\n  };\n\n  readonly LoadInkFileContents = (filename: string): string => {\n    if (Object.keys(this.fileHierarchy).includes(filename)) {\n      return this.fileHierarchy[filename];\n    } else {\n      throw new Error(`Cannot open ${filename}.`);\n    }\n  };\n}\n","import { CompilerOptions } from \"./CompilerOptions\";\nimport { DebugSourceRange } from \"./DebugSourceRange\";\nimport { ErrorType } from \"./Parser/ErrorType\";\nimport { InkParser } from \"./Parser/InkParser\";\nimport { Story } from \"../engine/Story\";\nimport { Story as ParsedStory } from \"./Parser/ParsedHierarchy/Story\";\nimport { DebugMetadata } from \"../engine/DebugMetadata\";\nimport { StringValue } from \"../engine/Value\";\nimport { asOrNull } from \"../engine/TypeAssertion\";\nimport { GenerateStoryStats, Stats } from \"./Stats\";\n\nexport { CompilerOptions } from \"./CompilerOptions\";\nexport { InkParser } from \"./Parser/InkParser\";\nexport { StatementLevel } from \"./Parser/StatementLevel\";\nexport { JsonFileHandler } from \"./FileHandler/JsonFileHandler\";\nexport { InkList, Story } from \"../engine/Story\";\n\nexport class Compiler {\n  private _errors: string[] = [];\n  get errors(): string[] {\n    return this._errors;\n  }\n\n  private _warnings: string[] = [];\n  get warnings(): string[] {\n    return this._warnings;\n  }\n\n  private _authorMessages: string[] = [];\n  get authorMessages(): string[] {\n    return this._authorMessages;\n  }\n\n  private _inputString: string;\n  get inputString(): string {\n    return this._inputString;\n  }\n\n  private _options: CompilerOptions;\n  get options(): CompilerOptions {\n    return this._options;\n  }\n\n  private _parsedStory: ParsedStory | null = null;\n  get parsedStory(): ParsedStory {\n    if (!this._parsedStory) {\n      throw new Error();\n    }\n\n    return this._parsedStory;\n  }\n\n  private _runtimeStory: Story | null = null;\n  get runtimeStory(): Story {\n    if (!this._runtimeStory) {\n      throw new Error(\"Compilation failed.\");\n    }\n\n    return this._runtimeStory;\n  }\n\n  private _parser: InkParser | null = null;\n  get parser(): InkParser {\n    if (!this._parser) {\n      throw new Error();\n    }\n\n    return this._parser;\n  }\n\n  private _debugSourceRanges: DebugSourceRange[] = [];\n  get debugSourceRanges(): DebugSourceRange[] {\n    return this._debugSourceRanges;\n  }\n\n  constructor(inkSource: string, options: CompilerOptions | null = null) {\n    this._inputString = inkSource;\n    this._options = options || new CompilerOptions();\n  }\n\n  public readonly Compile = (): Story => {\n    this._parser = new InkParser(\n      this.inputString,\n      this.options.sourceFilename || null,\n      this.OnError,\n      null,\n      this.options.fileHandler\n    );\n\n    this._parsedStory = this.parser.ParseStory();\n\n    if (this.errors.length === 0) {\n      this.parsedStory.countAllVisits = this.options.countAllVisits;\n      this._runtimeStory = this.parsedStory.ExportRuntime(this.OnError);\n    } else {\n      this._runtimeStory = null;\n    }\n\n    return this.runtimeStory;\n  };\n\n  public readonly RetrieveDebugSourceForLatestContent = (): void => {\n    for (const outputObj of this.runtimeStory.state.outputStream) {\n      const textContent = asOrNull(outputObj, StringValue);\n      if (textContent !== null) {\n        const range = new DebugSourceRange(\n          textContent.value?.length || 0,\n          textContent.debugMetadata,\n          textContent.value || \"unknown\"\n        );\n\n        this.debugSourceRanges.push(range);\n      }\n    }\n  };\n\n  public readonly GenerateStats = (): Stats | null => {\n    if (this._parsedStory === null) {\n      return null;\n    }\n    return GenerateStoryStats(this._parsedStory);\n  };\n\n  public readonly DebugMetadataForContentAtOffset = (\n    offset: number\n  ): DebugMetadata | null => {\n    let currOffset = 0;\n\n    let lastValidMetadata: DebugMetadata | null = null;\n    for (const range of this.debugSourceRanges) {\n      if (range.debugMetadata !== null) {\n        lastValidMetadata = range.debugMetadata;\n      }\n\n      if (offset >= currOffset && offset < currOffset + range.length) {\n        return lastValidMetadata;\n      }\n\n      currOffset += range.length;\n    }\n\n    return null;\n  };\n\n  public readonly OnError = (message: string, errorType: ErrorType) => {\n    switch (errorType) {\n      case ErrorType.Author:\n        this._authorMessages.push(message);\n        break;\n\n      case ErrorType.Warning:\n        this._warnings.push(message);\n        break;\n\n      case ErrorType.Error:\n        this._errors.push(message);\n        break;\n    }\n\n    if (this.options.errorHandler !== null) {\n      this.options.errorHandler(message, errorType);\n    }\n  };\n}\n","import { Choice } from \"./Parser/ParsedHierarchy/Choice\";\nimport { Divert } from \"./Parser/ParsedHierarchy/Divert/Divert\";\nimport { Gather } from \"./Parser/ParsedHierarchy/Gather/Gather\";\nimport { Knot } from \"./Parser/ParsedHierarchy/Knot\";\nimport { Stitch } from \"./Parser/ParsedHierarchy/Stitch\";\nimport { Story } from \"./Parser/ParsedHierarchy/Story\";\nimport { Text } from \"./Parser/ParsedHierarchy/Text\";\n\nexport interface Stats {\n  words: number;\n  knots: number;\n  stitches: number;\n  functions: number;\n  choices: number;\n  gathers: number;\n  diverts: number;\n}\n\nexport function GenerateStoryStats(story: Story): Stats {\n  let allText = story.FindAll(Text)();\n  let words = 0;\n  for (const text of allText) {\n    let wordsInThisStr = 0;\n    let wasWhiteSpace = true;\n    for (const c of text.text) {\n      if (c == \" \" || c == \"\\t\" || c == \"\\n\" || c == \"\\r\") {\n        wasWhiteSpace = true;\n      } else if (wasWhiteSpace) {\n        wordsInThisStr++;\n        wasWhiteSpace = false;\n      }\n    }\n\n    words += wordsInThisStr;\n  }\n\n  const knots = story.FindAll(Knot)();\n  const stitches = story.FindAll(Stitch)();\n  const choices = story.FindAll(Choice)();\n  const gathers = story.FindAll(Gather)((g) => g.debugMetadata != null);\n  const diverts = story.FindAll(Divert)();\n\n  return {\n    words,\n    knots: knots.length,\n    functions: knots.filter((k) => k.isFunction).length,\n    stitches: stitches.length,\n    gathers: gathers.length,\n    diverts: diverts.length - 1,\n    choices: choices.length,\n  };\n}\n"],"names":["CompilerOptions","constructor","sourceFilename","arguments","length","undefined","pluginNames","countAllVisits","errorHandler","fileHandler","this","DebugSourceRange","debugMetadata","text","ErrorType","Argument","identifier","isByReference","isDivertTarget","typeName","asOrNull","obj","type","unsafeTypeAssertion","asOrThrows","Error","asINamedContentOrNull","hasValidName","name","nullIfUndefined","isEquatable","Equals","filterUndef","element","ParsedObject","_this","_alreadyHadError","_alreadyHadWarning","_debugMetadata","_runtimeObject","content","parent","GetType","AddContent","subContent","sub","Array","isArray","ss","hasOwnProperty","push","InsertContent","index","splice","Find","queryFunc","tObj","nestedResult","FindAll","foundSoFar","found","Warning","message","source","value","hasOwnDebugMetadata","Boolean","story","ancestor","runtimeObject","GenerateRuntimeObject","runtimePath","path","containerForCounting","ancestry","result","reverse","ResolveReferences","context","isWarning","AuthorWarning","warningMessage","super","Path","_components","_componentsString","_isRelative","componentsString","Component","head","tail","concat","relative","isRelative","componentCount","tailComps","slice","self","lastComponent","lastComponentIdx","containsNamedComponent","i","l","isIndex","GetComponent","PathByAppendingPath","pathToAppend","p","upwardMoves","isParent","join","substring","componentStrings","split","str","test","parseInt","toString","otherPath","PathByAppendingComponent","c","Debug","ValueType","PushPopType","parentId","indexOrName","ToParent","otherComp","Assert","condition","console","warn","trace","AssertType","variable","NullException","throwNullException","InkObject","_path","ownDebugMetadata","DebugLineNumberOfPath","root","rootContentContainer","targetContent","ContentAtPath","dm","startLineNumber","comps","child","container","Container","namedChild","unshift","indexOf","ResolvePath","nearestContainer","contentContainer","ConvertPathToRelative","globalPath","ownPath","minPathLength","Math","min","lastSharedPathCompIndex","ownComp","numUpwardsMoves","newPathComps","up","down","CompactPathString","globalPathStr","relativePathStr","Copy","SetChild","prop","StringBuilder","string","Length","Append","AppendLine","AppendFormat","format","_len","args","_key","replace","match","num","Clear","InkListItem","originName","itemName","nameParts","Null","isNull","fullName","otherItem","copy","serialized","JSON","stringify","fromSerializedKey","key","parse","isLikeInkListItem","inkListItem","item","InkList","Map","origins","_originNames","otherList","otherOriginNames","originNames","singleOriginListName","originStory","SetInitialOriginName","listDefinitions","def","TryListGetDefinition","exists","singleElement","Add","Key","Value","FromString","myListItem","listValue","_a","FindSingleItemListWithName","AddItem","itemOrItemName","storyObject","origin","intVal","TryGetValueForItem","foundListDef","ContainsItemWithName","newItem","orderedItems","itemVal","ValueForItem","ContainsItemNamed","ContainsKey","has","serializedKey","set","Remove","delete","Count","size","originOfMaxItem","maxOriginName","maxItem","every","initialOriginName","SetInitialOriginNames","initialOriginNames","max","minItem","inverse","list","items","all","Union","union","Intersect","intersection","HasIntersection","Without","listToRemove","Contains","what","GreaterThan","GreaterThanOrEquals","LessThan","LessThanOrEquals","MaxAsList","MinAsList","ListWithSubRange","minBound","maxBound","ordered","minValue","maxValue","Number","MAX_SAFE_INTEGER","isInteger","subList","otherInkList","sort","x","y","localeCompare","singleItem","sb","valueOf","NaN","StoryException","useEndLineNumber","tryGetValueFromMap","map","val","get","AbstractValue","Create","preferredNumberType","Int","IntValue","Float","isNaN","FloatValue","BoolValue","StringValue","String","DivertTargetValue","ListValue","valueObject","BadCastException","targetType","valueType","isTruthy","Bool","Cast","newType","_isNewline","_isInlineWhitespace","isNewline","isInlineWhitespace","isNonWhitespace","parsedInt","defaultValue","tryParseInt","parsedFloat","parseFloat","tryParseFloat","DivertTarget","targetPath","VariablePointerValue","variableName","contextIndex","_contextIndex","VariablePointer","List","listOrSingleItem","singleValue","RetainListOriginsForAssignment","oldValue","newValue","oldList","newList","SearchResult","approximate","correctObj","searchResult","_content","namedContent","visitsShouldBeCounted","turnIndexShouldBeCounted","countingAtStartOnly","_pathToFirstLeafContent","namedOnlyContent","namedOnlyContentDict","inkObject","named","existingNamedOnly","AddToNamedContentOnly","countFlags","flags","CountFlags","Visits","Turns","CountStartOnly","flag","pathToFirstLeafContent","internalPathToFirstLeafContent","components","contentObjOrList","contentList","contentObj","TryAddNamedContent","namedContentObj","partialPathStart","partialPathLength","currentContainer","currentObj","comp","foundObj","ContentWithPathComponent","nextContainer","AddContentsOfContainer","otherContainer","component","foundContent","BuildStringOfHierarchy","indentation","pointedObj","appendIndentation","onlyNamed","ControlCommand","commandType","_commandType","CommandType","NotSet","EvalStart","EvalOutput","EvalEnd","Duplicate","PopEvaluatedValue","PopFunction","PopTunnel","BeginString","EndString","NoOp","ChoiceCount","TurnsSince","ReadCount","Random","SeedRandom","VisitIndex","SequenceShuffleIndex","StartThread","Done","End","ListFromInt","ListRange","ListRandom","BeginTag","EndTag","Expression","_prototypeRuntimeConstantExpression","outputWhenComplete","RuntimeContainer","RuntimeControlCommand","GenerateIntoContainer","GenerateConstantIntoContainer","runtimeObj","Void","NativeFunctionCall","CallWithName","functionName","CallExistsWithName","GenerateNativeFunctionsIfNecessary","_nativeFunctions","_name","_isPrototype","_prototype","numberOfParameters","_numberOfParameters","Call","parameters","hasList","CallBinaryListOperation","coercedParams","CoerceValuesToSingleType","coercedType","CallType","parametersOfSingleType","param1","valType","val1","paramCount","_operationFuncs","opForTypeObj","val2","opForType","resultVal","CallListIncrementOperation","v1","v2","op","asBooleanOrThrows","listIntParams","listVal","resultInkList","listItemKey","listItemValue","listItem","intOp","targetInt","itemOrigin","incrementedItem","TryGetItemWithValue","parametersIn","specialCaseList","parametersOut","inkObjectVal","castedValue","Identity","t","AddIntBinaryOp","Subtract","Multiply","Divide","floor","Mod","AddIntUnaryOp","Negate","Equal","Greater","Less","NotEquals","Not","And","Or","Max","Min","Pow","pow","Floor","Ceiling","AddFloatBinaryOp","AddFloatUnaryOp","ceil","AddStringBinaryOp","Has","includes","Hasnt","AddListBinaryOp","AddListUnaryOp","Invert","All","ListMin","ListMax","ValueOfList","divertTargetsEqual","d1","d2","divertTargetsNotEqual","AddOpToNativeFunc","AddOpFuncForType","nativeFunc","NumberExpression","subtype","isInt","isFloat","isBool","numberExpression","UnaryExpression","nativeNameForOp","inner","innerExpression","WithInner","innerNumber","BinaryExpression","left","right","opName","leftExpression","rightExpression","NativeNameForOp","leftUnary","CharacterSet","arg","Set","add","AddRange","start","end","charCodeAt","fromCharCode","AddCharacters","chars","FromRange","CharacterRange","_start","_end","excludes","_correspondingCharSet","_excludes","ToCharacterSet","ii","Define","ChoicePoint","onceOnly","_pathOnChoice","hasCondition","hasStartContent","hasChoiceOnlyContent","isInvisibleDefault","pathOnChoice","choiceTargetObj","choiceTarget","pathStringOnChoice","Pointer","Resolve","StartOf","Divert","_targetPath","targetObj","targetPointer","_targetPointer","targetPathString","hasVariableTarget","variableDivertName","stackPushType","pushesToStack","isExternal","externalArgs","isConditional","otherDivert","targetStr","Function","SymbolType","isNewDeclaration","isGlobal","runtimeChoice","_runtimeChoice","_condition","runtimeContainer","_innerContentContainer","innerContentContainer","startContent","choiceOnlyContent","innerContent","_outerContainer","_returnToR1","_returnToR2","_r1Label","_r2Label","_divertToStartContentOuter","_divertToStartContentInner","_startContentRuntimeContainer","hasWeaveStyleInlineBrackets","varAssign","RuntimeVariableAssignment","RuntimeDivert","varDivert","choiceOnlyRuntimeContent","innerChoiceOnlyContent","indentationDepth","CheckForNamingCollisions","SubFlowAndWeave","StringParserElement","characterIndex","characterInLineIndex","lineIndex","reportedErrorInScope","uniqueId","customFlags","CopyFrom","fromElement","_uniqueIdCounter","SquashFrom","StringParserState","currentElement","_stack","_numElements","errorReportedAlreadyInScope","stackHeight","Push","prevElement","newElement","Pop","expectedRuleId","Peek","PeekPenultimate","Squash","penultimateEl","lastEl","NoteErrorReported","el","ParseSuccess","Symbol","StringParser","ParseRule","hadError","BeginRule","state","FailRule","CancelRule","SucceedRule","stateAtSucceedRule","stateAtBeginRule","RuleDidSucceed","finalResult","Expect","rule","recoveryRule","ParseObject","butSaw","lineRemainder","LineRemainder","ErrorOnLine","ErrorWithParsedObject","lineNumber","errorType","ParseUntilCharactersFromString","SetFlag","trueOrFalse","GetFlag","ruleId","stackHeightBefore","Parse","OneOf","array","OneOrMore","results","Optional","Exclude","OptionalExclude","ParseString","TryAddResultToList","flatten","resultCollection","Interleave","ruleA","ruleB","untilTerminator","firstA","lastMainResult","outerResult","remainingLength","cli","li","success","tempIdx","_chars","ParseSingleCharacter","maxCount","ParseCharactersFromString","ParseUntilCharactersFromCharSet","charSet","ParseCharactersFromCharSet","maxCountOrShouldIncludeStrChars","shouldIncludeChars","startIndex","count","ParseInt","oldIndex","oldCharacterInLineIndex","negative","parsedString","numbersCharacterSet","MIN_SAFE_INTEGER","ParseFloat","leadingInt","afterDecimalPointStr","ParseNewline","strPreProc","PreProcessInputString","inputString","currentCharacter","endOfInput","remainingString","ParseUntil","stopRule","pauseCharacters","endCharacters","pauseAndEnd","values","ruleResultAtPause","partialParsedString","pauseCharacter","CommentEliminator","_commentOrNewlineStartCharacter","_commentBlockEndCharacter","_newlineCharacters","Process","stringList","CommentsAndNewlines","MainInk","newLines","ParseSingleComment","EndOfLineComment","BlockComment","startLineIndex","commentResult","repeat","Conditional","initialCondition","branches","_reJoinTarget","branch","branchContainer","ownExpression","isElse","pathToReJoin","returnDivert","Text","ConstantDeclaration","constantName","constantIdentifier","expression","_expression","assignedExpression","Var","FlowLevel","Gather","_b","baseTargetLevel","baseLevelIsAmbiguous","Story","_baseTargetLevel","firstComponent","numberOfComponents","dotSeparatedComponents","_dotSeparatedComponents","filter","argOne","argTwo","WeavePoint","ResolveFromContext","baseTargetObject","ResolveBaseTarget","ResolveTailComponents","originalContext","firstComp","ancestorContext","deepSearch","foundBase","GetChildFromContext","rootTarget","foundComponent","compName","minimumExpectedLevel","foundFlow","FlowBase","flowLevel","childName","minimumLevel","forceDeepSearch","ambiguousChildLevel","weaveContext","Weave","WeavePointNamed","flowContext","shouldDeepSearch","Knot","ContentWithNameAtLevel","Object","ReturnType","returnedExpression","ClosestFlowBase","iamFlowbase","Identifier","hasParameters","subFlowsByName","_subFlowsByName","isFunction","topLevelObjects","isIncludedStory","_rootWeave","_startingSubFlowDivert","_startingSubFlowRuntime","_firstChildFlow","variableDeclarations","SplitWeaveAndSubFlowContent","contentObjs","isRootStory","weaveObjs","subFlowObjs","subFlow","finalContent","ResolveVariableWithName","varName","fromNode","ownerFlow","isArgument","isTemporary","AddNewVariableDeclaration","varDecl","varab","prevDeclError","ResolveWeavePointNaming","foundReturn","CheckForDisallowedFunctionFlowControl","Stitch","GenerateArgumentVariableAssignments","contentIdx","childFlow","childFlowRuntime","existingChild","errorMsg","ValidateTermination","WarningInTermination","paramName","assign","level","weavePointResult","DeepSearchForAnyLevelContent","weaveResultSelf","deepResult","allDiverts","divert","isFunctionCall","allChoices","Choice","choice","terminatingObject","terminatingDivert","isTunnel","target","PreProcessTopLevelObjects","_","Arg","jj","symbolType","ContentList","objects","dontFlatten","TrimTrailingWhitespace","RegExp","contentObjRuntime","DontFlattenContainer","moreObjects","containerForCount","pathForCount","pathStringForCount","VariableReference","pathIdentifiers","id","runtimeVarRef","_runtimeVarRef","isConstantReference","isListItemReference","constantValue","constants","RuntimeVariableReference","listItemName","listName","ResolveListItem","parsedPath","targetForCount","targetFlow","FunctionCall","proxyDivert","_proxyDivert","runtimeDivert","isChoiceCount","isTurns","isTurnsSince","isRandom","isSeedRandom","isListRange","isListRandom","isReadCount","_divertTargetToCount","_variableReferenceToCount","shouldPopReturnedValue","foundList","ResolveList","usingProxyDivert","divertTarget","variableDivertTarget","nativeCall","msg","RuntimeInkList","strArgs","attemptingTurnCountOfVariableTarget","targetObject","IsBuiltIn","MultipleConditionExpression","subExpressions","conditionExpressions","isFirst","conditionExpr","_runtimeDivert","runtimeDivertTargetValue","_runtimeDivertTargetValue","otherDivTarget","isDone","isEnd","usageContext","badUsage","foundUsage","usageParent","binaryExprParent","funcCall","ConditionalSingleBranch","parentFunc","isEmpty","isThread","ResolveTargetContent","CheckArgumentValidity","requiresArgCodeGen","targetArguments","argToPass","argExpected","varRef","varPointer","Tunnel","PathAsVariableName","variableTargetName","flowBaseScope","resolveResult","argument","find","a","numArgs","butClause","flowArg","divArgExpr","knotCountPath","CheckExternalArgumentValidity","externalName","external","externals","externalArgCount","argumentNames","ownArgCount","returnString","targetWasFound","isBuiltIn","IsExternal","RuntimePath","GatherPointToResolve","targetRuntimeObj","SequenceDivertToResolve","SequenceType","Sequence","elementContentLists","sequenceType","_sequenceDivertsToResolve","once","Once","cycle","Cycle","stopping","Stopping","shuffle","Shuffle","seqBranchCount","sequenceElements","postShuffleNoOp","lastIdx","skipShuffleDivert","AddDivertToResolve","elementCountToShuffle","postSequenceNoOp","elIndex","sequenceDivert","contentContainerForSequenceBranch","seqBranchCompleteDivert","elementContentList","seqElObject","toResolve","TunnelOnwards","_overrideDivertTarget","_divertAfter","divertAfter","returnRuntimeObj","returnRuntimeContainer","evalStart","evalEnd","cmd","returnDivertObj","_items","_itemNameToValues","ContainsItem","ListDefinition","runtimeListDefinition","allItems","e","itemDefinitions","seriesValue","RuntimeListDefinition","variableAssignment","_elementsByName","ItemNamed","initialValues","itemDef","inInitialList","RuntimeInkListItem","currentValue","explicitValue","VariableAssignment","variableIdentifier","isNewTemporaryDeclaration","isGlobalDeclaration","listDefinition","isDeclaration","_ref","isTemporaryNewDeclaration","listDef","_runtimeAssignment","newDeclScope","Temp","variableReference","resolvedVarAssignment","rootContainer","_rootContainer","namedWeavePoints","_namedWeavePoints","lastParsedSignificantObject","lastObject","lastText","IsGlobalDeclaration","lastWeave","cont","indentIndex","previousWeavePoint","addContentToPreviousWeavePoint","hasSeenChoiceInSection","_unnamedGatherCount","_choiceCount","looseEnds","gatherPointsToResolve","w","weavePoint","existingWeavePoint","existingObj","_c","ConstructWeaveHierarchyFromIndentation","weaveIndentIdx","baseIndentIndex","innerWeaveStartIdx","innerWeaveObj","weaveContentCount","weaveContent","weave","DetermineBaseIndentationFromContent","AddRuntimeForWeavePoint","AddRuntimeForNestedWeave","AddGeneralRuntimeContent","PassLooseEndsToAncestors","AddRuntimeForGather","gather","autoEnter","gatherContainer","looseEndWeavePoint","looseEnd","looseWeavePoint","WeavePointHasLooseEnd","closestInnerWeaveAncestor","closestOuterWeaveAncestor","nested","weaveAncestor","received","ReceiveLooseEnd","receivingWeave","childWeaveLooseEnd","varAss","ContentThatFollowsWeavePoint","returned","parentWeave","laterObj","badTerminationHandler","looseEndFlow","ValidateFlowOfObjectsTerminates","BadNestedTerminationHandler","terminatingObj","conditional","toLowerCase","objFlow","defaultObj","terminated","flowObj","d","innerDivert","CheckForWeavePointNamingCollisions","ancestorFlows","flow","weavePointName","otherContentWithName","isNestedWeave","gatherPoint","_ownExpression","_contentContainer","_conditionalDivert","_innerWeave","isTrueBranch","matchingEquality","isInline","startsWith","duplicatesStackValue","needsEval","GenerateRuntimeForContent","CustomFlags","DebugMetadata","endLineNumber","startCharacterNumber","endCharacterNumber","fileName","sourceName","Merge","newDebugMetadata","ExternalDeclaration","AddExternal","FlowDecl","Wrap","_objToWrap","glue","Glue","IncDecExpression","varIdentifier","isIncOrExpression","isInc","varResolveResult","incrementDecrementWord","IncludedFile","includedStory","InfixOperator","precedence","requireWhitespace","parentStory","stitchName","knotWithStitchName","stitch","itemIdentifierList","runtimeRawList","itemIdentifier","ListElementDefinition","parentList","indentifier","ListItem","StatementLevel","baseToString","tagText","threadAtGeneration","sourcePath","tags","originalThreadIndex","Clone","ListDefinitionsOrigin","lists","_lists","_allUnambiguousListValueCache","listOfLists","definition","JsonSerialisation","JArrayToRuntimeObjList","jArray","skipLast","jTok","JTokenToRuntimeObject","WriteDictionaryRuntimeObjs","writer","dictionary","WriteObjectStart","WritePropertyStart","WriteRuntimeObject","WritePropertyEnd","WriteObjectEnd","WriteListRuntimeObjs","WriteArrayStart","WriteArrayEnd","WriteIntDictionary","dict","WriteIntProperty","WriteRuntimeContainer","divTypeKey","WriteProperty","choicePoint","boolVal","WriteBool","WriteInt","floatVal","WriteFloat","strVal","Write","WriteStringStart","WriteStringInner","WriteStringEnd","WriteInkList","divTargetVal","varPtrVal","controlCmd","_controlCommandNames","readCountPath","tag","Tag","WriteChoice","JObjectToDictionaryRuntimeObjs","jObject","JObjectToIntDictionary","token","floatRepresentation","exec","firstChar","propValue","varPtr","isDivert","divPushType","readCountVarRef","isVarAss","isGlobalVar","isNewDecl","listContent","rawList","namesAsObjs","nameToVal","JObjectToChoice","JArrayToContainer","toJson","me","removes","space","k","v","some","r","withoutName","hasNameProperty","hasTerminator","namedContainer","WriteNull","namedContentItem","namedSubContainer","jObj","JArrayToTags","WriteChoiceTags","WritePropertyNameStart","WritePropertyNameInner","WritePropertyNameEnd","ListDefinitionsToJToken","listDefJson","JTokenToListDefinitions","defsObj","allDefs","nameValueKey","nameValue","TOTAL_VALUES","CallStack","elements","callStack","depth","cs","_threads","callstack","currentElementIndex","currentThread","canPop","_threadCounter","_startOfRoot","storyContext","Reset","toCopy","otherThread","Thread","Element","SetJsonToken","jThreads","jThreadTok","jThreadObj","thread","WriteJson","WriteObject","PushThread","newThread","threadIndex","ForkThread","forkedThread","PopThread","canPopThread","elementIsEvaluateFromGame","FunctionEvaluationFromGame","externalEvaluationStackHeight","outputStreamLengthWithPushed","currentPointer","evaluationStackHeightWhenPushed","functionStartInOutputStream","CanPop","pop","GetTemporaryVariableWithName","varValue","temporaryVariables","SetTemporaryVariable","declareNew","contextElement","ContextForVariableNamed","ThreadWithIndex","filtered","callStackTrace","isCurrent","pointer","inExpressionEvaluation","previousPointer","jThreadCallstack","jElTok","currentContainerPathStr","jElementObj","pushPopType","currentContainerPathStrToken","threadPointerResult","temps","clear","prevContentObjPath","prevPath","PointerAtPath","resolvedPointer","VariablesState","variableChangedEvent","callback","variableChangedEventCallbacks","StartVariableObservation","_batchObservingVariableChanges","_changedVariablesForBatchObs","CompleteVariableObservation","changedVars","_globalVariables","patch","changedVariables","patchedVal","TryGetGlobal","NotifyObservers","_callStack","$","varContents","_defaultGlobalVariables","SetGlobal","listDefsOrigin","_listDefsOrigin","Proxy","ownKeys","keys","getOwnPropertyDescriptor","enumerable","configurable","ApplyPatch","namedVarKey","namedVarValue","globals","jToken","varValKey","varValValue","loadedToken","tokenInkObject","keyValKey","keyValValue","dontSaveDefaultValues","defaultVal","RuntimeObjectsEqual","obj1","obj2","GetVariableWithName","GetRawVariableWithName","ValueAtVariablePointer","TryGetDefaultVariableValue","GlobalVariableExistsWithName","variableValue","Assign","setGlobal","ResolveVariablePointer","existingPointer","SnapshotDefaultGlobals","AddChangedVariable","GetContextIndexOfVariableNamed","doubleRedirectionPointer","ObserveVariableChange","PRNG","seed","next","nextFloat","StatePatch","_globals","_changedVariables","visitCounts","_visitCounts","turnIndices","_turnIndices","TryGetVisitCount","SetVisitCount","SetTurnIndex","TryGetTurnIndex","SimpleJson","TextToDictionary","Reader","ToDictionary","TextToArray","ToArray","__","explicitFloatReviver","endsWith","_rootObject","jsonWithExplicitFloat","Writer","_currentPropertyName","_currentString","_stateStack","_collectionStack","_propertyNameStack","_jsonObject","StartNewObject","newObject","State","Property","currentCollection","currentPropertyName","propertyName","None","StateElement","innerOrContent","WriteFloatProperty","IncrementChildCount","childCount","PropertyName","_addToCurrentObject","error","POSITIVE_INFINITY","NEGATIVE_INFINITY","currEl","Flow","outputStream","currentChoices","jChoiceThreadsObj","LoadFlowChoiceThreads","hasChoiceThreads","jChoiceThreads","foundActiveThread","jSavedChoiceThread","StoryState","ToJson","indented","LoadJson","json","LoadJsonObj","onDidLoadState","VisitCountAtPathString","pathString","visitCountOut","_patch","VisitCountForContainer","containerPathStr","count2","IncrementVisitCountForContainer","currCount","RecordTurnIndexVisitToContainer","currentTurnIndex","TurnsSinceForContainer","index2","callstackDepth","_currentFlow","canContinue","generatedChoices","currentErrors","_currentErrors","currentWarnings","_currentWarnings","variablesState","_variablesState","evaluationStack","_evaluationStack","_currentTurnIndex","currentPathString","previousPathString","hasError","hasWarning","currentText","_outputStreamTextDirty","inTag","outputObj","textContent","controlCommand","_currentText","CleanOutputWhitespace","currentWhitespaceStart","startOfLine","charAt","currentTags","_outputStreamTagsDirty","_currentTags","txt","currentFlowName","currentFlowIsDefaultFlow","kDefaultFlowName","aliveFlowNames","_aliveFlowNamesDirty","_aliveFlowNames","_namedFlows","flowName","kInkSaveStateVersion","kMinCompatibleLoadVersion","divertedPointer","storySeed","previousRandom","didSafeExit","OutputStreamDirty","timeSeed","Date","getTime","GoToStart","mainContentContainer","SwitchFlow_Internal","SwitchToDefaultFlow_Internal","RemoveFlow_Internal","CopyAndStartPatching","forBackgroundSave","namedFlowKey","namedFlowValue","RestoreAfterPatch","ApplyAnyPatch","ApplyCountChanges","newCount","isVisit","inkVersionCurrent","jSaveVersion","flowsObj","flowsObjDict","flowsObjDictEntries","entries","namedFlowObjKey","namedFlowObjValue","currFlowName","currentDivertTargetPath","divertPath","ResetErrors","ResetOutput","objs","PushToOutputStream","listText","TrySplittingHeadTailWhitespace","textObj","PushToOutputStreamIndividual","PopFromOutputStream","single","headFirstNewlineIdx","headLastNewlineIdx","tailLastNewlineIdx","tailFirstNewlineIdx","listTexts","innerStrStart","innerStrEnd","leadingSpaces","innerStrText","numSpaces","trailingSpaces","includeInOutput","TrimNewlinesFromOutputStream","functionTrimIndex","glueTrimIndex","o","trimIndex","RemoveExistingGlue","callStackElements","outputStreamEndsInNewline","outputStreamContainsContent","removeWhitespaceFrom","inStringEvaluation","PushEvaluationStack","n","PopEvaluationStack","numberOfObjects","PeekEvaluationStack","ForceEnd","TrimWhitespaceFromFunctionEnd","functionStartPoint","PopCallStack","popType","SetChosenPath","incrementingTurnIndex","newPointer","StartFunctionEvaluationFromGame","funcContainer","PassArgumentsToEvaluationStack","TryExitFunctionEvaluationFromGame","CompleteFunctionEvaluationFromGame","originalEvaluationStackHeight","returnedObj","poppedObj","returnVal","AddError","Stopwatch","startTime","ElapsedMilliseconds","Start","Stop","nVal","isFinite","choices","_state","IfAsyncWeCant","_listDefinitions","StartProfiling","EndProfiling","inkVersionMinimumCompatible","onError","onDidContinue","onMakeChoice","onEvaluateFunction","onCompleteEvaluateFunction","onChoosePathString","_prevContainers","allowExternalFunctionFallbacks","_variableObservers","_hasValidatedExternals","_temporaryEvaluationContainer","_asyncContinueActive","_stateSnapshotAtLastNewline","_sawLookaheadUnsafeFunctionAfterNewline","_recursiveContinueCount","_asyncSaving","_profiler","_mainContentContainer","jsonString","_externals","rootObject","versionObj","formatFromFile","listDefsObj","rootToken","ResetState","shouldReturn","VariableStateDidChangeEvent","bind","ResetGlobals","ResetCallstack","originalPointer","ChoosePath","ContinueInternal","SwitchFlow","RemoveFlow","SwitchToDefaultFlow","Continue","ContinueAsync","asyncContinueComplete","millisecsLimitAsync","ValidateExternalBindings","PreContinue","isAsyncTimeLimited","durationStopwatch","ContinueSingleStep","changedVariablesToObserve","RestoreStateSnapshot","PostContinue","err","PreStep","Step","PostStep","TryFollowDefaultInvisibleChoice","PreSnapshot","change","CalculateNewlineOutputStateChange","OutputStateChange","ExtendedBeyondNewline","NewlineRemoved","DiscardSnapshot","StateSnapshot","PostSnapshot","prevText","currText","prevTagCount","currTagCount","newlineStillExists","NoChange","ContinueMaximally","KnotContainerWithName","pathLengthToUse","CopyStateForBackgroundThreadSave","stateToSave","BackgroundSaveComplete","shouldAddToStream","containerToEnter","VisitContainer","currentContentObj","isLogicOrFlowControl","PerformLogicAndFlowControl","ProcessChoice","contextIdx","NextContent","atStart","VisitChangedContainersDueToDivert","prevAncestor","currentChildOfContainer","currentContainerAncestor","allChildrenEnteredAtStart","enteringAtStart","PopChoiceStringAndTags","choiceOnlyStrVal","showChoice","conditionValue","IsTruthy","startText","choiceOnlyText","divTarget","currentDivert","intContent","errorMessage","CallExternalFunction","evalCommand","output","overrideTunnelReturnTarget","popped","names","expected","contentStackForTag","outputCountConsumed","command","choiceTag","contentStackForString","contentToRetain","rescuedTag","choiceCount","extraNote","eitherCount","maxInt","minInt","randomRange","resultSeed","nextRandom","chosenValue","shuffleIndex","NextSequenceShuffleIndex","listNameVal","generatedListValue","foundItem","targetList","listItemIndex","listEnumerator","randomItem","assignedVal","foundValue","func","funcParams","ChoosePathString","resetCallstack","funcDetail","activityStr","ChooseChoiceIndex","choiceIdx","choiceToChoose","HasFunction","EvaluateFunction","returnTextOutput","trim","outputStreamBefore","stringOutput","textOutput","EvaluateExpression","exprContainer","startCallStackHeight","evalStackHeight","funcName","numberOfArguments","funcDef","fallbackFunctionContainer","foundExternal","lookAheadSafe","valueObj","funcResult","function","returnObj","BindExternalFunctionGeneral","lookaheadSafe","TryCoerce","BindExternalFunction","coercedArgs","apply","UnbindExternalFunction","missingExternals","from","ObserveVariable","observer","ObserveVariables","variableNames","observers","RemoveVariableObserver","specificVariableName","variableObservers","newValueObj","globalTags","TagsAtStartOfFlowContainerWithPathString","TagsForContentAtPath","flowContainer","firstContent","BuildStringOfContainer","IncrementContentPointer","didPop","successfulIncrement","nextAncestor","indexInAncestor","invisibleChoices","numElementsIntVal","seqContainer","numElements","seqCount","loopIndex","iterationIndex","seqPathStr","sequenceHash","randomSeed","random","unpickedIndices","chosen","chosenIndex","currentDebugMetadata","errorTypeStr","lineNum","_hadError","hadWarning","_hadWarning","toplevelObjects","_errorHandler","_dontFlattenContainers","_listDefs","ExportRuntime","constDecl","existingDefinition","variableInitialisation","runtimeLists","runtimeVarAss","runtimeStory","RuntimeStory","FlattenContainersIn","originalFoundList","itemInThisList","innerContainers","innerContainer","namedInnerContainer","TryFlattenContainer","parentContainer","Author","ResetError","namedFuncTarget","decl","NameConflictError","typeNameToPrint","IsReservedKeyword","knotOrFunction","topLevelContent","flowsFromOtherFiles","file","posOfObj","nonFlowContent","subStory","subStoryObj","StringExpression","isSingleString","otherStr","isStart","inChoice","DefaultFileHandler","rootPath","ResolveInkFilename","LoadInkFileContents","InkParser","_fileHandler","filename","externalErrorHandler","rootParser","ParseStory","StatementsAtLevel","Top","_rootParser","SeparatedList","mainRule","separatorRule","firstElement","allElements","nextElementRuleId","nextElement","CreateDebugMetadata","stateAtStart","stateAtEnd","md","_filename","parsedObj","parsedListObjs","parsedListObj","OnStringParserError","fullMessage","_externalErrorHandler","Whitespace","IdentifierWithMetadata","ExtendIdentifierCharacterRanges","identifierCharSet","characterRanges","ListAllCharacterRanges","charRange","_parsingChoice","onceOnlyChoice","bullets","optionalName","BracketedName","Newline","ChoiceCondition","startTextAndLogic","MixedTextAndLogic","optionOnlyContent","EndTagIfNecessary","optionOnlyTextAndLogic","innerTextAndLogic","diverts","MultiDivert","emptyContent","divObj","div","conditions","ChoiceSingleCondition","ChoiceConditionsSpace","condExpr","DisallowIncrement","gatherDashCountObj","GatherDashes","gatherDashCount","ParseDashNotArrow","InnerConditionalContent","initialQueryExpression","ConditionExpression","alternatives","canBeInline","InlineConditionalBranches","MultilineConditionalBranches","soleContent","InnerBlock","elseBranch","SingleMultilineCondition","emptyTrueBranch","earlierBranchesHaveOwnExpression","isLast","alt","finalClause","trueBranch","MultilineWhitespace","multipleConditions","expr","ElseExpression","_nonTextPauseCharacters","_nonTextEndCharacters","_notTextEndCharactersChoice","_notTextEndCharactersString","TrimEndWhitespace","mixedTextAndLogicResults","terminateWithSpace","lastObjIdx","lastObj","LineOfMixedTextAndLogic","firstText","EndOfLine","SkipToNextLine","Spaced","ContentText","InlineLogicOrGlueOrStartTag","ContentTextAllowingEscapeChar","ContentTextNoEscape","gotEscapeChar","endChars","parsingStringExpression","pureTextContent","nonTextRule","ParseDivertArrow","ParseThreadArrow","threadDivert","arrowsAndDiverts","ParseDivertArrowOrTunnelOnwards","DivertIdentifierWithArguments","tunnelOnwards","tunnelOnwardDivert","gatherDivert","targetComponents","DotSeparatedDivertPathComponents","optionalArguments","ExpressionFunctionCallArguments","SingleDivert","numArrows","_binaryOperators","_maxBinaryOpLength","TempDeclarationOrAssignment","ParseTempKeyword","isIncrement","isDecrement","ReturnStatement","minimumPrecedence","ExpressionUnary","infixOp","ParseInfixOperator","expectationMessage","multiaryExpr","ExpressionInfixRight","ExpressionDivertTarget","prefixOp","ExpressionNot","ExpressionList","ExpressionParen","ExpressionFunctionCall","ExpressionVariableName","ExpressionLiteral","postfixOp","ExpressionFloat","ExpressionInt","ExpressionBool","ExpressionString","intOrNull","floatOrNull","textAndLogic","iden","commas","innerExpr","memberNames","ListMember","identifier2","RegisterExpressionOperators","RegisterBinaryOperator","infix","_openFilenames","IncludeStatement","fullFilename","FilenameIsAlreadyOpen","AddOpenFilename","includedString","RemoveOpenFilename","KnotDefinition","knotDecl","KnotDeclaration","innerKnotStatements","KnotStitchNoContentRecoveryRule","KnotTitleEquals","knotName","isFunc","parameterNames","BracketedKnotDeclArguments","multiEquals","StitchDefinition","StitchDeclaration","innerStitchStatements","flowArgs","flowArguments","FlowDeclArgument","firstIden","divertArrow","secondIden","funcIdentifier","argNames","_identifierCharSet","LogicLine","afterTilde","funCall","VariableDeclaration","ListElementDefinitionSeparator","ListDeclaration","AnyWhitespace","needsToCloseParen","elementValue","elementValueNum","ConstDeclaration","InlineLogic","StartTag","RuntimeGlue","wasParsingString","wasTagActive","tagActive","logic","InnerLogic","explicitSeqType","SequenceTypeAnnotation","contentLists","InnerSequenceObjects","rules","InnerSequence","InnerExpression","isNumberCharsOnly","_sequenceTypeSymbols","seqType","parsedSeqType","annotation","SequenceTypeSymbolAnnotation","SequenceTypeWordAnnotation","sequenceAnnotations","symbolChar","sequenceTypes","SequenceTypeSingleWord","combinedSequenceType","word","InnerMultilineSequenceObjects","InnerInlineSequenceObjects","interleavedContentAndPipes","justHadContent","contentOrPipe","SingleMultilineSequenceElement","_statementRulesAtLevel","_statementBreakRulesAtLevel","StatementAtLevel","StatementsBreakForLevel","rulesAtLevel","statement","breakRules","breakRuleResult","GenerateStatementLevelRules","levels","breakingRules","Line","inlineRule","_inlineWhitespaceChars","EndOfFile","newlines","anyWhitespace","MultiSpaced","fullRootInkPath","ParsingString","TagActive","outputContentList","LatinBasic","LatinExtendedA","LatinExtendedB","Greek","Cyrillic","Armenian","Hebrew","Arabic","Korean","Latin1Supplement","Chinese","JsonFileHandler","fileHierarchy","Compiler","errors","_errors","warnings","_warnings","authorMessages","_authorMessages","_inputString","options","_options","parsedStory","_parsedStory","_runtimeStory","parser","_parser","debugSourceRanges","_debugSourceRanges","inkSource","Compile","OnError","RetrieveDebugSourceForLatestContent","range","GenerateStats","allText","words","wordsInThisStr","wasWhiteSpace","knots","stitches","gathers","g","functions","GenerateStoryStats","DebugMetadataForContentAtOffset","offset","currOffset","lastValidMetadata"],"mappings":"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"}