@mark1russell7/render-biblo 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,6 +33,8 @@ readValue(store, text); // { tag: "some", value: "[ planet ]" }
33
33
 
34
34
  Traits give methods to each class with a set of cells. The fingerprint of a class is a product of primes, thus the match of a trait is one division.
35
35
 
36
+ A class is data: each expression is a [coeval](https://github.com/mark1russell7/coeval) document, thus a class from JSON text registers as it is. An instance scopes its cells with `mapRefs` of the kernel: `self` and `parent` become node IDs, and the parameters of a `fn` stay. `updateClass` compares the expressions with `docEquals`.
37
+
36
38
  ## More
37
39
 
38
40
  - [The site](https://mark1russell7.github.io/render/): the guide, live demos and the viewer.
package/build/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import { Expr } from "@mark1russell7/render-dsl";
2
2
  import { NodeId, NodeOps, NodeStore } from "@mark1russell7/render-node";
3
3
  //#region src/class.d.ts
4
4
  /**
5
- * A cell template of a class. It has an expression, and optionally a type: the name of another class.
6
- * A typed cell holds an instance of that class, thus the class level knows the paths through its children.
5
+ * A cell template of a class. It has an expression (a coeval document), and optionally a type: the name of
6
+ * another class. A typed cell holds an instance of that class, thus the class level knows the paths through its children.
7
7
  */
8
8
  type CellDef = {
9
9
  readonly expr: Expr;
@@ -24,7 +24,8 @@ type CellDef = {
24
24
  * - `extends`: the parent class. Cells and methods both resolve through it.
25
25
  *
26
26
  * The values of `methods` are opaque. Each layer reads the method names that it knows, for example
27
- * `render` for splay and `splash` for the node engine. The class `Top` gives the defaults.
27
+ * `render` for splay and `splash` for the node engine. The class `Top` gives the defaults. An expression method is
28
+ * a coeval document, thus a class is data from end to end.
28
29
  */
29
30
  type ComponentClass = {
30
31
  readonly name: string;
@@ -115,7 +116,10 @@ export declare const biblo: () => Biblo;
115
116
  * (`forkStore`), with the class semantics of the copy (`classNodeOps`).
116
117
  */
117
118
  export declare const forkBiblo: (b: Biblo) => Biblo;
118
- /** This function registers a class, or replaces the class with the same name. The live instances do not change. */
119
+ /**
120
+ * This function registers a class, or replaces the class with the same name. The live instances do not change.
121
+ * The expressions of the class are coeval documents, thus a class from JSON text registers as it is.
122
+ */
119
123
  export declare const registerClass: (b: Biblo, cls: ComponentClass) => void;
120
124
  /** This function registers a trait, or replaces the trait with the same name. The live instances use it at once. */
121
125
  export declare const registerTrait: (b: Biblo, trait: Trait) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/class.ts","../src/instance.ts","../src/traits.ts","../src/registry.ts","../src/nodeops.ts"],"mappings":";;;;;;;KAMY;WACD,MAAM;;WAEN;;;;;;WAMA,WAAW,SAAS,eAAe;;;;;;;;;;;;KAalC;WACD;WACA,OAAO,SAAS,eAAe;WAC/B;WACA,UAAU,SAAS;;;qBAIjB,iBACX,cACA,OAAO,SAAS,eAAe,WAC/B,cACA,UAAU,SAAS,6BAClB;;;;;qBAWU,cACX,MAAM,gBACN;WACW,QAAQ,SAAS,eAAe;WAChC,UAAU,SAAS;MAE7B;;;;KCzDS;;;;;KAMA;WACD,MAAM;WACN,QAAQ;;WAER,mBAAmB;;;;;;KAOlB;WACD,IAAI;WACJ;WACA,OAAO;;;;;;;;;;;;;;;;;KCPN;WACD;;WAEA;WACA,SAAS,SAAS;;;KAIjB;WACD,kBAAkB;WAClB;;;qBAkDE,mBAAoB;;;;;;;;;;KC1DrB;WACD,SAAS,oBAAoB;WAC7B,WAAW,YAAY,YAAY;WACnC,QAAQ,oBAAoB;;;qBA+B1B,aAAY;;;;;;qBAoBZ,YAAa,GAAG,UAAQ;;qBA4BxB,gBAAiB,GAAG,OAAO,KAAK;;qBAOhC,gBAAiB,GAAG,OAAO,OAAO;;qBAOlC,kBAAmB,GAAG,OAAO;;;;;;qBAW7B,cAAe,GAAG,OAAO,cAAc;;qBAiCvC,kBAAmB,GAAG,OAAO,kBAAkB;;qBAiC/C,eAAgB,GAAG,OAAO,sBAAoB,SAAS,eAAe;;qBAWtE,mBAAoB,GAAG,OAAO;;qBAU9B,UAAW,GAAG,OAAO;;qBAGrB,gBAAiB,GAAG,OAAO,sBAAoB;;;;;;;;;qBAkB/C,iBAAkB,GAAG,OAAO,sBAAoB,SAAS;;;;;;;;;;;;qBAsGzD,cACX,GAAG,OACH,OAAO,WACP,mBACA,WAAW,YACX,WAAW,SAAS,eAAe,WAClC;;;;;qBAqBU,YAAa,GAAG,OAAO,SAAS,YAAY;;;;;;qBAiB5C,kBAAmB,GAAG,OAAO,OAAO,WAAW,YAAY;;;;;;;;;;;;;qBAuE3D,cAAe,GAAG,OAAO,OAAO,WAAW,KAAK;;;;;qBAsDhD,UAAW,GAAG,OAAO,OAAO,WAAW,QAAQ,WAAS;;;;;;;;;;;;;qBCvexD,eAAgB,GAAG,OAAO,WAAU,YAAuB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/class.ts","../src/instance.ts","../src/traits.ts","../src/registry.ts","../src/nodeops.ts"],"mappings":";;;;;;;KAMY;WACD,MAAM;;WAEN;;;;;;WAMA,WAAW,SAAS,eAAe;;;;;;;;;;;;;KAclC;WACD;WACA,OAAO,SAAS,eAAe;WAC/B;WACA,UAAU,SAAS;;;qBAIjB,iBACX,cACA,OAAO,SAAS,eAAe,WAC/B,cACA,UAAU,SAAS,6BAClB;;;;;qBAWU,cACX,MAAM,gBACN;WACW,QAAQ,SAAS,eAAe;WAChC,UAAU,SAAS;MAE7B;;;;KC1DS;;;;;KAMA;WACD,MAAM;WACN,QAAQ;;WAER,mBAAmB;;;;;;KAOlB;WACD,IAAI;WACJ;WACA,OAAO;;;;;;;;;;;;;;;;;KCPN;WACD;;WAEA;WACA,SAAS,SAAS;;;KAIjB;WACD,kBAAkB;WAClB;;;qBAkDE,mBAAoB;;;;;;;;;;KCzDrB;WACD,SAAS,oBAAoB;WAC7B,WAAW,YAAY,YAAY;WACnC,QAAQ,oBAAoB;;;qBA+B1B,aAAY;;;;;;qBAoBZ,YAAa,GAAG,UAAQ;;;;;qBA+BxB,gBAAiB,GAAG,OAAO,KAAK;;qBAOhC,gBAAiB,GAAG,OAAO,OAAO;;qBAOlC,kBAAmB,GAAG,OAAO;;;;;;qBAW7B,cAAe,GAAG,OAAO,cAAc;;qBAiCvC,kBAAmB,GAAG,OAAO,kBAAkB;;qBAiC/C,eAAgB,GAAG,OAAO,sBAAoB,SAAS,eAAe;;qBAWtE,mBAAoB,GAAG,OAAO;;qBAU9B,UAAW,GAAG,OAAO;;qBAGrB,gBAAiB,GAAG,OAAO,sBAAoB;;;;;;;;;qBAkB/C,iBAAkB,GAAG,OAAO,sBAAoB,SAAS;;;;;;;;;;;;qBAuGzD,cACX,GAAG,OACH,OAAO,WACP,mBACA,WAAW,YACX,WAAW,SAAS,eAAe,WAClC;;;;;qBAqBU,YAAa,GAAG,OAAO,SAAS,YAAY;;;;;;qBAiB5C,kBAAmB,GAAG,OAAO,OAAO,WAAW,YAAY;;;;;;;;;;;;;qBAuE3D,cAAe,GAAG,OAAO,OAAO,WAAW,KAAK;;;;;qBAsDhD,UAAW,GAAG,OAAO,OAAO,WAAW,QAAQ,WAAS;;;;;;;;;;;;;qBC5exD,eAAgB,GAAG,OAAO,WAAU,YAAuB"}
package/build/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { exprEquals, lit, mapFreeRefs, ref } from "@mark1russell7/render-dsl";
1
+ import { docEquals, mapRefs } from "@mark1russell7/coeval";
2
+ import { isLiteral, lit, renderWorld } from "@mark1russell7/render-dsl";
2
3
  import { addNode, batch, defaultOps, removeNode, setExpr, setSlot } from "@mark1russell7/render-node";
3
4
  //#region src/class.ts
4
5
  /** This function makes a class. */
@@ -146,7 +147,10 @@ const clearCaches = (s) => {
146
147
  s.methodsCache.clear();
147
148
  s.traitsCache.clear();
148
149
  };
149
- /** This function registers a class, or replaces the class with the same name. The live instances do not change. */
150
+ /**
151
+ * This function registers a class, or replaces the class with the same name. The live instances do not change.
152
+ * The expressions of the class are coeval documents, thus a class from JSON text registers as it is.
153
+ */
150
154
  const registerClass = (b, cls) => {
151
155
  const s = bstate(b);
152
156
  s.classes.set(cls.name, cls);
@@ -298,14 +302,28 @@ const newInstanceId = (s, store) => {
298
302
  }
299
303
  };
300
304
  /**
301
- * This function changes the scope names of the free references to node IDs:
302
- * `self` becomes the instance and `parent` becomes the parent instance. The parameters of `fn` forms stay.
305
+ * This function changes the scope names of the free `world` references to node IDs with `mapRefs` of the kernel.
306
+ * `self` becomes the instance, and `parent` becomes the parent instance. The parameters of a `fn` stay.
303
307
  */
304
- const scopeExpr = (expr, selfId, parentId) => mapFreeRefs(expr, (r) => {
305
- const [head, ...rest] = r.path;
306
- if (head === "self") return ref(selfId, ...rest);
307
- if (head === "parent" && parentId !== void 0) return ref(parentId, ...rest);
308
- return r;
308
+ const scopeExpr = (expr, selfId, parentId) => isLiteral(expr) ? expr : mapRefs(renderWorld, expr, (use) => {
309
+ if (use.root !== "world") return void 0;
310
+ const [, head, ...rest] = use.path;
311
+ if (head === "self") return {
312
+ type: "ref",
313
+ value: [
314
+ "world",
315
+ selfId,
316
+ ...rest
317
+ ]
318
+ };
319
+ if (head === "parent" && parentId !== void 0) return {
320
+ type: "ref",
321
+ value: [
322
+ "world",
323
+ parentId,
324
+ ...rest
325
+ ]
326
+ };
309
327
  });
310
328
  /**
311
329
  * This function adds one cell to an instance. A typed cell becomes a child instance. The exception is a class
@@ -430,7 +448,7 @@ const updateBindings = (s, b, store, child, oldBindings, newBindings) => {
430
448
  const slot = root.slots.get(k);
431
449
  const cell = slot === void 0 ? void 0 : store.nodes.get(slot);
432
450
  if (!cell || !oldE || !newE || s.instances.has(cell.id)) continue;
433
- if (exprEquals(cell.expr, scopeExpr(oldE, child.id, child.scope.parent))) setExpr(store, cell.id, scopeExpr(newE, child.id, child.scope.parent));
451
+ if (docEquals(cell.expr, scopeExpr(oldE, child.id, child.scope.parent))) setExpr(store, cell.id, scopeExpr(newE, child.id, child.scope.parent));
434
452
  }
435
453
  if (bound.size > 0) s.bound.set(child.id, bound);
436
454
  else s.bound.delete(child.id);
@@ -466,7 +484,7 @@ const updateClass = (b, store, cls) => {
466
484
  const slot = root.slots.get(name);
467
485
  const target = slot === void 0 ? void 0 : store.nodes.get(slot);
468
486
  const child = slot === void 0 ? void 0 : s.instances.get(slot);
469
- const follows = (def) => target !== void 0 && child === void 0 && exprEquals(target.expr, scopeExpr(def.expr, inst.id, inst.scope.parent));
487
+ const follows = (def) => target !== void 0 && child === void 0 && docEquals(target.expr, scopeExpr(def.expr, inst.id, inst.scope.parent));
470
488
  if (!n) {
471
489
  if (slot !== void 0) removeCell(s, store, inst, name, slot);
472
490
  } else if (!o) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/class.ts","../src/traits.ts","../src/registry.ts","../src/nodeops.ts"],"sourcesContent":["import type { Expr } from \"@mark1russell7/render-dsl\";\n\n/**\n * A cell template of a class. It has an expression, and optionally a type: the name of another class.\n * A typed cell holds an instance of that class, thus the class level knows the paths through its children.\n */\nexport type CellDef = {\n readonly expr: Expr;\n /** The class of the child instance that this cell holds. */\n readonly type?: string | undefined;\n /**\n * The bindings of a typed cell: expressions that replace cells of the child.\n * They are in the scope of the child. For example, `{ value: ref(\"parent\", \"key\") }` binds the cell `value`\n * of the child to the cell `key` of this instance.\n */\n readonly bindings?: Readonly<Record<string, Expr>> | undefined;\n};\n\n/**\n * A class is a template. Instances share it, and nothing copies it.\n *\n * - `cells`: the reactive structure, which is the data that each instance holds.\n * - `methods`: the behavior. The extends chain resolves them, and the most specific method wins.\n * - `extends`: the parent class. Cells and methods both resolve through it.\n *\n * The values of `methods` are opaque. Each layer reads the method names that it knows, for example\n * `render` for splay and `splash` for the node engine. The class `Top` gives the defaults.\n */\nexport type ComponentClass = {\n readonly name: string;\n readonly cells: Readonly<Record<string, CellDef>>;\n readonly extends?: string | undefined;\n readonly methods?: Readonly<Record<string, unknown>> | undefined;\n};\n\n/** This function makes a class. */\nexport const componentClass = (\n name: string,\n cells: Readonly<Record<string, CellDef>>,\n ext?: string,\n methods?: Readonly<Record<string, unknown>>,\n): ComponentClass => ({\n name,\n cells,\n ...(ext !== undefined ? { extends: ext } : {}),\n ...(methods !== undefined ? { methods } : {}),\n});\n\n/**\n * This function gives a copy of a class with more cells and methods. The copy keeps the name.\n * An override with the name of an existing cell or method replaces it.\n */\nexport const extendClass = (\n base: ComponentClass,\n overrides: {\n readonly cells?: Readonly<Record<string, CellDef>>;\n readonly methods?: Readonly<Record<string, unknown>>;\n },\n): ComponentClass => ({\n ...base,\n cells: { ...base.cells, ...overrides.cells },\n methods: { ...base.methods, ...overrides.methods },\n});\n","/**\n * Structural traits with prime fingerprints: a granular polymorphism.\n *\n * Each atomic feature of a class gets a unique prime: a cell (`value`), or a typed cell (`kid:Point`).\n * The fingerprint of a class is the product of the primes of its features. The product does not depend on\n * the order of the features, thus two classes with the same features have the same fingerprint.\n *\n * A trait gives methods to each class that has the features of its list. Then the fingerprint of the trait\n * divides the fingerprint of the class. Among the traits that apply, only the most specific ones count\n * (a trait whose fingerprint divides the fingerprint of another applicable trait is dominated). When two of\n * them give the same method, the method is ambiguous: no trait gives it, and the ambiguity is visible.\n */\n\n/** A trait: methods for each class that has the cells of its list. */\nexport type Trait = {\n readonly name: string;\n /** The features that a class must have: a cell name (`label`), or a typed cell (`kid:Point`). */\n readonly requires: readonly string[];\n readonly methods: Readonly<Record<string, unknown>>;\n};\n\n/** The traits that apply to a class, and the names of the methods that two of them give. */\nexport type TraitResolution = {\n readonly applied: readonly Trait[];\n readonly ambiguous: readonly string[];\n};\n\n/** The table of primes: one unique prime for each atomic feature. */\nexport type PrimeTable = {\n readonly primes: Map<string, bigint>;\n readonly found: bigint[];\n};\n\n/** This function makes an empty table of primes. */\nexport const primeTable = (): PrimeTable => ({ primes: new Map(), found: [] });\n\n/** This function gives the next prime after the last prime of the table (trial division by the found primes). */\nconst nextPrime = (t: PrimeTable): bigint => {\n let candidate = t.found.length === 0 ? 2n : t.found[t.found.length - 1]! + 1n;\n for (;;) {\n let prime = true;\n for (const p of t.found) {\n if (p * p > candidate) break;\n if (candidate % p === 0n) {\n prime = false;\n break;\n }\n }\n if (prime) {\n t.found.push(candidate);\n return candidate;\n }\n candidate++;\n }\n};\n\n/** This function gives the prime of an atomic feature. A new feature gets the next free prime. */\nexport const primeIn = (t: PrimeTable, atom: string): bigint => {\n let p = t.primes.get(atom);\n if (p === undefined) {\n p = nextPrime(t);\n t.primes.set(atom, p);\n }\n return p;\n};\n\n/** This function gives the product of the primes of a set of features (the fingerprint). */\nexport const fingerprintOf = (t: PrimeTable, atoms: Iterable<string>): bigint => {\n let product = 1n;\n for (const atom of new Set(atoms)) product *= primeIn(t, atom);\n return product;\n};\n\n/** This function gives the features of an item of the list of a trait: `kid:Point` is the cell `kid` with the type `Point`. */\nexport const requirementAtoms = (requirement: string): string[] => {\n const colon = requirement.indexOf(\":\");\n return colon < 0 ? [`cell:${requirement}`] : [`cell:${requirement.slice(0, colon)}`, `cell:${requirement}`];\n};\n\n/**\n * This function selects the traits for a fingerprint. It keeps each trait whose fingerprint divides the class\n * fingerprint, removes the dominated ones, and finds the methods that two remaining traits give.\n */\nexport const selectTraits = (\n t: PrimeTable,\n traits: Iterable<Trait>,\n classFingerprint: bigint,\n): TraitResolution => {\n const applicable: { trait: Trait; d: bigint }[] = [];\n for (const trait of traits) {\n const d = fingerprintOf(t, trait.requires.flatMap(requirementAtoms));\n if (classFingerprint % d === 0n) applicable.push({ trait, d });\n }\n const maximal = applicable.filter((a) => !applicable.some((b) => b.d !== a.d && b.d % a.d === 0n));\n const owners = new Map<string, number>();\n for (const { trait } of maximal) for (const name of Object.keys(trait.methods)) owners.set(name, (owners.get(name) ?? 0) + 1);\n const ambiguous = [...owners].filter(([, count]) => count > 1).map(([name]) => name).toSorted();\n return { applied: maximal.map((m) => m.trait), ambiguous };\n};\n","import type { ComponentClass, CellDef } from \"./class.ts\";\nimport type { Instance, InstanceId } from \"./instance.ts\";\nimport type { PrimeTable, Trait, TraitResolution } from \"./traits.ts\";\nimport { fingerprintOf, primeIn, primeTable, selectTraits } from \"./traits.ts\";\nimport type { Expr } from \"@mark1russell7/render-dsl\";\nimport { exprEquals, lit, ref, mapFreeRefs } from \"@mark1russell7/render-dsl\";\nimport type { NodeId, NodeStore } from \"@mark1russell7/render-node\";\nimport { addNode, batch, removeNode, setExpr, setSlot } from \"@mark1russell7/render-node\";\n\n/**\n * The biblo is the class registry and the instance store.\n *\n * Classes are shared templates. Instances are small (an ID and a scope), and the values of their cells\n * are in the node store. A trait gives methods to each class that has the cells of its list.\n * Change a biblo only through its functions, for example `registerClass`, `registerTrait` and `instantiate`.\n */\nexport type Biblo = {\n readonly classes: ReadonlyMap<string, ComponentClass>;\n readonly instances: ReadonlyMap<InstanceId, Instance>;\n readonly traits: ReadonlyMap<string, Trait>;\n};\n\ntype MutableInstance = {\n readonly id: InstanceId;\n classRef: string;\n readonly scope: { readonly self: InstanceId; readonly parent: InstanceId | undefined; readonly children: InstanceId[] };\n};\n\ntype BibloState = {\n readonly classes: Map<string, ComponentClass>;\n readonly instances: Map<InstanceId, MutableInstance>;\n /** For each instance: the names of the cells that a binding gave. A change of the class does not change them. */\n readonly bound: Map<InstanceId, Set<string>>;\n readonly traits: Map<string, Trait>;\n readonly primes: PrimeTable;\n nextId: number;\n readonly cellsCache: Map<string, Readonly<Record<string, CellDef>>>;\n readonly methodsCache: Map<string, Readonly<Record<string, unknown>>>;\n readonly traitsCache: Map<string, TraitResolution>;\n};\n\nconst bstate = (b: Biblo): BibloState => b as unknown as BibloState;\n\nconst hasOwn = (o: object, key: string): boolean => Object.prototype.hasOwnProperty.call(o, key);\n\n/** This function gives an own property of a record, or `undefined`. It does not read `Object.prototype`. */\nconst own = <T>(o: Readonly<Record<string, T>> | undefined, key: string): T | undefined =>\n o !== undefined && hasOwn(o, key) ? o[key] : undefined;\n\n/** This function makes an empty biblo. */\nexport const biblo = (): Biblo => {\n const s: BibloState = {\n classes: new Map(),\n instances: new Map(),\n bound: new Map(),\n traits: new Map(),\n primes: primeTable(),\n nextId: 0,\n cellsCache: new Map(),\n methodsCache: new Map(),\n traitsCache: new Map(),\n };\n return s;\n};\n\n/**\n * This function gives an independent copy of a biblo: the same classes, traits, instances and counters. The\n * classes and the traits are immutable, thus the copy shares them. Pair the copy with a copy of its store\n * (`forkStore`), with the class semantics of the copy (`classNodeOps`).\n */\nexport const forkBiblo = (b: Biblo): Biblo => {\n const s = bstate(b);\n const copy: BibloState = {\n classes: new Map(s.classes),\n instances: new Map([...s.instances].map(([id, inst]): [InstanceId, MutableInstance] => [id, {\n id: inst.id,\n classRef: inst.classRef,\n scope: { self: inst.scope.self, parent: inst.scope.parent, children: [...inst.scope.children] },\n }])),\n bound: new Map([...s.bound].map(([id, names]) => [id, new Set(names)])),\n traits: new Map(s.traits),\n primes: { primes: new Map(s.primes.primes), found: [...s.primes.found] },\n nextId: s.nextId,\n // The cached entries are frozen results, thus the copy can share them\n cellsCache: new Map(s.cellsCache),\n methodsCache: new Map(s.methodsCache),\n traitsCache: new Map(s.traitsCache),\n };\n return copy;\n};\n\nconst clearCaches = (s: BibloState): void => {\n s.cellsCache.clear();\n s.methodsCache.clear();\n s.traitsCache.clear();\n};\n\n/** This function registers a class, or replaces the class with the same name. The live instances do not change. */\nexport const registerClass = (b: Biblo, cls: ComponentClass): void => {\n const s = bstate(b);\n s.classes.set(cls.name, cls);\n clearCaches(s);\n};\n\n/** This function registers a trait, or replaces the trait with the same name. The live instances use it at once. */\nexport const registerTrait = (b: Biblo, trait: Trait): void => {\n const s = bstate(b);\n s.traits.set(trait.name, trait);\n clearCaches(s);\n};\n\n/** This function removes a trait. */\nexport const unregisterTrait = (b: Biblo, name: string): void => {\n const s = bstate(b);\n s.traits.delete(name);\n clearCaches(s);\n};\n\n/**\n * This function renames a class. Its subclasses, the typed cells that use it and its live instances use the\n * new name. A trait whose list has a typed cell of the class (`kid:Point`) also uses the new name. The function\n * does nothing and gives `false` when the class is missing or the new name is in use.\n */\nexport const renameClass = (b: Biblo, from: string, to: string): boolean => {\n const s = bstate(b);\n if (!s.classes.has(from) || to === \"\" || s.classes.has(to)) return false;\n const next = new Map<string, ComponentClass>();\n for (const [name, c] of s.classes) {\n const extendsRenamed = c.extends === from;\n const cellsRenamed = Object.values(c.cells).some((def) => def.type === from);\n next.set(name === from ? to : name, {\n ...c,\n name: name === from ? to : name,\n ...(extendsRenamed ? { extends: to } : {}),\n cells: cellsRenamed\n ? Object.fromEntries(Object.entries(c.cells).map(([k, def]) => [k, def.type === from ? { ...def, type: to } : def]))\n : c.cells,\n });\n }\n // The new map keeps the order of registration, with the renamed class at the place of the old name\n s.classes.clear();\n for (const [name, c] of next) s.classes.set(name, c);\n for (const inst of s.instances.values()) if (inst.classRef === from) inst.classRef = to;\n const renamed = (requirement: string): string => {\n const colon = requirement.indexOf(\":\");\n return colon >= 0 && requirement.slice(colon + 1) === from ? `${requirement.slice(0, colon)}:${to}` : requirement;\n };\n for (const [name, trait] of s.traits) {\n const requires = trait.requires.map(renamed);\n if (requires.some((r, i) => r !== trait.requires[i])) s.traits.set(name, { ...trait, requires });\n }\n clearCaches(s);\n return true;\n};\n\n/** This function registers each class of a list, in order. */\nexport const registerClasses = (b: Biblo, classes: readonly ComponentClass[]): void => {\n for (const cls of classes) registerClass(b, cls);\n};\n\n/**\n * This function gives the extends chain of a class, from the class to the root.\n * A cycle (`A` extends `B` extends `A`) stops at the first class that repeats.\n */\nconst extendsChain = (b: Biblo, className: string): ComponentClass[] => {\n const chain: ComponentClass[] = [];\n const visited = new Set<string>();\n let current: string | undefined = className;\n while (current !== undefined && !visited.has(current)) {\n visited.add(current);\n const cls = b.classes.get(current);\n if (!cls) break;\n chain.push(cls);\n current = cls.extends;\n }\n return chain;\n};\n\n/**\n * This function merges the records of an extends chain: the record of the class wins over the record of its parent.\n * `Object.fromEntries` makes own data properties, thus a cell named `__proto__` is a normal cell.\n */\nconst mergeChain = <T>(chain: readonly ComponentClass[], pick: (cls: ComponentClass) => Readonly<Record<string, T>> | undefined): Readonly<Record<string, T>> => {\n const entries: [string, T][] = [];\n for (let i = chain.length - 1; i >= 0; i--) entries.push(...Object.entries(pick(chain[i]!) ?? {}));\n return Object.freeze(Object.fromEntries(entries));\n};\n\n/** This function gives all cell templates of a class through its extends chain. A subclass cell replaces a parent cell. */\nexport const resolveCells = (b: Biblo, className: string): Readonly<Record<string, CellDef>> => {\n const s = bstate(b);\n let out = s.cellsCache.get(className);\n if (!out) {\n out = mergeChain(extendsChain(b, className), (cls) => cls.cells);\n s.cellsCache.set(className, out);\n }\n return out;\n};\n\n/** This function gives the fingerprint of a class: the product of the primes of its cells and typed cells. */\nexport const classFingerprint = (b: Biblo, className: string): bigint => {\n const atoms: string[] = [];\n for (const [name, def] of Object.entries(resolveCells(b, className))) {\n atoms.push(`cell:${name}`);\n if (def.type !== undefined) atoms.push(`cell:${name}:${def.type}`);\n }\n return fingerprintOf(bstate(b).primes, atoms);\n};\n\n/** This function gives the prime of an atomic feature, for example `cell:value`. */\nexport const primeOf = (b: Biblo, atom: string): bigint => primeIn(bstate(b).primes, atom);\n\n/** This function gives the traits that apply to a class (the most specific ones), and the ambiguous method names. */\nexport const resolveTraits = (b: Biblo, className: string): TraitResolution => {\n const s = bstate(b);\n let out = s.traitsCache.get(className);\n if (!out) {\n out = selectTraits(s.primes, s.traits.values(), classFingerprint(b, className));\n s.traitsCache.set(className, out);\n }\n return out;\n};\n\n/**\n * This function gives all methods of a class. There are three layers, from the lowest to the highest.\n * The first layer is the root of the extends chain, for example `Top`. The second layer is the traits that apply.\n * The third layer is the other classes of the chain, to the class itself.\n *\n * Thus a trait changes the defaults of the root, and a class changes a trait.\n * A method that two traits give is ambiguous: no trait gives it.\n */\nexport const resolveMethods = (b: Biblo, className: string): Readonly<Record<string, unknown>> => {\n const s = bstate(b);\n let out = s.methodsCache.get(className);\n if (!out) {\n const chain = extendsChain(b, className);\n const root = chain.length > 1 ? chain.slice(-1) : [];\n const upper = chain.length > 1 ? chain.slice(0, -1) : chain;\n const { applied, ambiguous } = resolveTraits(b, className);\n const traitEntries = applied\n .flatMap((t) => Object.entries(t.methods))\n .filter(([name]) => !ambiguous.includes(name));\n out = Object.freeze(Object.fromEntries([\n ...Object.entries(mergeChain(root, (cls) => cls.methods)),\n ...traitEntries,\n ...Object.entries(mergeChain(upper, (cls) => cls.methods)),\n ]));\n s.methodsCache.set(className, out);\n }\n return out;\n};\n\n/** This function gives an instance ID that is free in the biblo and in the store. */\nconst newInstanceId = (s: BibloState, store: NodeStore): InstanceId => {\n for (;;) {\n const id = `i_${String(s.nextId++)}`;\n if (!s.instances.has(id) && !store.nodes.has(id)) return id;\n }\n};\n\n/**\n * This function changes the scope names of the free references to node IDs:\n * `self` becomes the instance and `parent` becomes the parent instance. The parameters of `fn` forms stay.\n */\nconst scopeExpr = (expr: Expr, selfId: InstanceId, parentId: InstanceId | undefined): Expr =>\n mapFreeRefs(expr, (r) => {\n const [head, ...rest] = r.path;\n if (head === \"self\") return ref(selfId, ...rest);\n if (head === \"parent\" && parentId !== undefined) return ref(parentId, ...rest);\n return r;\n });\n\n/**\n * This function adds one cell to an instance. A typed cell becomes a child instance. The exception is a class\n * that is already on the chain of typed cells above the cell. Then the cell is plain, thus the instance is finite.\n */\nconst addCell = (\n s: BibloState,\n b: Biblo,\n store: NodeStore,\n inst: MutableInstance,\n name: string,\n def: CellDef,\n bound: Expr | undefined,\n chain: ReadonlySet<string>,\n): void => {\n let target: NodeId;\n if (bound === undefined && def.type !== undefined && !chain.has(def.type)) {\n target = instantiateIn(s, b, store, def.type, inst.id, def.bindings, chain).id;\n } else {\n target = addNode(store, scopeExpr(bound ?? def.expr, inst.id, inst.scope.parent), `${inst.id}.${name}`);\n }\n setSlot(store, inst.id, name, target, { own: true });\n};\n\nconst instantiateIn = (\n s: BibloState,\n b: Biblo,\n store: NodeStore,\n className: string,\n parentId: InstanceId | undefined,\n bindings: Readonly<Record<string, Expr>> | undefined,\n chain: ReadonlySet<string>,\n): MutableInstance => {\n const parent = parentId === undefined ? undefined : s.instances.get(parentId);\n const id = newInstanceId(s, store);\n const inst: MutableInstance = { id, classRef: className, scope: { self: id, parent: parent?.id, children: [] } };\n s.instances.set(id, inst);\n parent?.scope.children.push(id);\n\n addNode(store, lit(undefined), id);\n const inner = new Set([...chain, className]);\n const bound = new Set<string>();\n for (const [name, def] of Object.entries(resolveCells(b, className))) {\n const binding = own(bindings, name);\n if (binding !== undefined) bound.add(name);\n addCell(s, b, store, inst, name, def, binding, inner);\n }\n if (bound.size > 0) s.bound.set(id, bound);\n return inst;\n};\n\n/**\n * This function makes an instance of a class. The class is not copied: the instance gets an ID, a scope,\n * and a root node with one slot for each cell. All nodes are evaluated before the end of the function.\n *\n * - A typed cell becomes a child instance of its class, with the bindings of the cell. The slot of the cell\n * holds the root node of the child, thus `ref(\"self\", \"kid\", \"value\")` reads a cell of the child.\n * A typed cell whose class is already above it on the chain of typed cells is a plain cell.\n * - `bindings` replace cells of this instance. They are in the scope of this instance. A binding for a typed\n * cell makes it a plain cell with the bound expression.\n * - An unknown class gives an instance with no cells.\n */\nexport const instantiate = (\n b: Biblo,\n store: NodeStore,\n className: string,\n parentId?: InstanceId,\n bindings?: Readonly<Record<string, Expr>>,\n): Instance => batch(store, () => instantiateIn(bstate(b), b, store, className, parentId, bindings, new Set()));\n\nconst destroyIn = (s: BibloState, store: NodeStore, id: InstanceId): void => {\n const inst = s.instances.get(id);\n if (!inst) return;\n // A copy, because each destroy removes the child from this array\n for (const childId of inst.scope.children.slice()) destroyIn(s, store, childId);\n removeNode(store, id);\n const parent = inst.scope.parent === undefined ? undefined : s.instances.get(inst.scope.parent);\n if (parent) {\n const idx = parent.scope.children.indexOf(id);\n if (idx >= 0) parent.scope.children.splice(idx, 1);\n }\n s.instances.delete(id);\n s.bound.delete(id);\n};\n\n/**\n * This function moves a child instance to a position in the children of its parent. A position past the end\n * moves it to the end. It does nothing for an instance without a parent.\n */\nexport const moveChild = (b: Biblo, childId: InstanceId, index: number): void => {\n const s = bstate(b);\n const child = s.instances.get(childId);\n const parent = child?.scope.parent === undefined ? undefined : s.instances.get(child.scope.parent);\n if (!parent) return;\n const children = parent.scope.children;\n const from = children.indexOf(childId);\n if (from < 0) return;\n children.splice(from, 1);\n children.splice(Math.max(0, Math.min(index, children.length)), 0, childId);\n};\n\n/**\n * This function destroys an instance, the inverse of `instantiate`. It destroys the children first, then\n * removes the nodes of the instance and detaches it from its parent. The readers of the removed nodes\n * become `none` in one epoch.\n */\nexport const destroyInstance = (b: Biblo, store: NodeStore, instanceId: InstanceId): void => {\n batch(store, () => { destroyIn(bstate(b), store, instanceId); });\n};\n\n/** This function gives the classes on the chain of typed cells above an instance, with the class of the instance. */\nconst typedChain = (s: BibloState, store: NodeStore, inst: MutableInstance): Set<string> => {\n const chain = new Set<string>([inst.classRef]);\n let current: MutableInstance | undefined = inst;\n while (current?.scope.parent !== undefined) {\n const parent = s.instances.get(current.scope.parent);\n const childId: InstanceId = current.id;\n const holds = parent !== undefined && [...(store.nodes.get(parent.id)?.slots.values() ?? [])].includes(childId);\n if (!parent || !holds || chain.has(parent.classRef)) break;\n chain.add(parent.classRef);\n current = parent;\n }\n return chain;\n};\n\n/** This function removes a cell of an instance: an owned cell node goes, and a shared one only loses the slot. */\nconst removeCell = (s: BibloState, store: NodeStore, inst: MutableInstance, name: string, slot: NodeId): void => {\n const child = s.instances.get(slot);\n if (child) destroyIn(s, store, child.id);\n else if (store.nodes.get(slot)?.parent === inst.id) removeNode(store, slot);\n else setSlot(store, inst.id, name, undefined);\n};\n\n/**\n * This function updates the cells of a child instance after a change of the bindings of its typed cell.\n * A child cell that still has the old binding (or the old default of its class) gets the new one.\n */\nconst updateBindings = (\n s: BibloState,\n b: Biblo,\n store: NodeStore,\n child: MutableInstance,\n oldBindings: Readonly<Record<string, Expr>> | undefined,\n newBindings: Readonly<Record<string, Expr>> | undefined,\n): void => {\n const cells = resolveCells(b, child.classRef);\n const root = store.nodes.get(child.id);\n if (!root) return;\n const bound = s.bound.get(child.id) ?? new Set<string>();\n for (const k of new Set([...Object.keys(oldBindings ?? {}), ...Object.keys(newBindings ?? {})])) {\n const oldE = own(oldBindings, k) ?? own(cells, k)?.expr;\n const newE = own(newBindings, k) ?? own(cells, k)?.expr;\n if (own(newBindings, k) !== undefined) bound.add(k);\n else bound.delete(k);\n const slot = root.slots.get(k);\n const cell = slot === undefined ? undefined : store.nodes.get(slot);\n if (!cell || !oldE || !newE || s.instances.has(cell.id)) continue;\n if (exprEquals(cell.expr, scopeExpr(oldE, child.id, child.scope.parent))) {\n setExpr(store, cell.id, scopeExpr(newE, child.id, child.scope.parent));\n }\n }\n if (bound.size > 0) s.bound.set(child.id, bound);\n else s.bound.delete(child.id);\n};\n\n/**\n * This function registers a new version of a class and updates the live instances: the class is a template,\n * and the instances follow it. The update applies to each instance of the class and of its subclasses.\n * When a cell of the resolved class changes, the instance cell changes too, if it still has the old expression.\n *\n * - A cell with an edit of its own keeps it. A cell that a binding gave keeps the binding.\n * - A new cell is added, and a removed cell is removed. A shared cell node only loses its slot.\n * - A typed cell that changes its type gets a new child instance. A change of its bindings reaches the cells of\n * the child that still follow the old bindings. A change between a typed cell and a plain cell replaces the cell.\n *\n * All changes evaluate in one epoch.\n */\nexport const updateClass = (b: Biblo, store: NodeStore, cls: ComponentClass): void => {\n const s = bstate(b);\n const before = new Map<string, Readonly<Record<string, CellDef>>>();\n for (const inst of s.instances.values()) {\n if (!before.has(inst.classRef)) before.set(inst.classRef, resolveCells(b, inst.classRef));\n }\n registerClass(b, cls);\n batch(store, () => {\n for (const inst of Array.from(s.instances.values())) {\n const root = store.nodes.get(inst.id);\n const old = before.get(inst.classRef);\n if (!root || !old || !s.instances.has(inst.id)) continue;\n const next = resolveCells(b, inst.classRef);\n const bound = s.bound.get(inst.id);\n for (const name of new Set([...Object.keys(old), ...Object.keys(next)])) {\n const o = own(old, name);\n const n = own(next, name);\n if (o === n || bound?.has(name) === true) continue;\n const slot = root.slots.get(name);\n const target = slot === undefined ? undefined : store.nodes.get(slot);\n const child = slot === undefined ? undefined : s.instances.get(slot);\n const follows = (def: CellDef): boolean =>\n target !== undefined && child === undefined && exprEquals(target.expr, scopeExpr(def.expr, inst.id, inst.scope.parent));\n if (!n) {\n if (slot !== undefined) removeCell(s, store, inst, name, slot);\n } else if (!o) {\n if (slot === undefined) addCell(s, b, store, inst, name, n, undefined, typedChain(s, store, inst));\n } else if (o.type !== undefined && n.type !== undefined) {\n if (!child) continue;\n if (o.type !== n.type) {\n removeCell(s, store, inst, name, child.id);\n addCell(s, b, store, inst, name, n, undefined, typedChain(s, store, inst));\n } else {\n updateBindings(s, b, store, child, o.bindings, n.bindings);\n }\n } else if (o.type !== undefined || n.type !== undefined) {\n // A change between a typed cell and a plain cell: the cell follows the class only in its old form\n const followsOld = o.type !== undefined ? child !== undefined : follows(o);\n if (slot !== undefined && followsOld) {\n removeCell(s, store, inst, name, slot);\n addCell(s, b, store, inst, name, n, undefined, typedChain(s, store, inst));\n }\n } else if (slot !== undefined && follows(o)) {\n setExpr(store, slot, scopeExpr(n.expr, inst.id, inst.scope.parent));\n }\n }\n }\n });\n};\n\n/**\n * This function gives the instance that owns a node. For an instance root, it is the node itself.\n * For another node, it is the nearest owner up the slot tree. A node outside all instances gives `undefined`.\n */\nexport const ownerOf = (b: Biblo, store: NodeStore, nodeId: NodeId): InstanceId | undefined => {\n let current: NodeId | undefined = nodeId;\n for (let guard = 0; current !== undefined && guard < 10_000; guard++) {\n if (b.instances.has(current)) return current;\n current = store.nodes.get(current)?.parent;\n }\n return undefined;\n};\n","import type { NodeOps, SplashFn, FlowFn, DerefFn, TargetsFn, Node, NodeStore } from \"@mark1russell7/render-node\";\nimport { defaultOps } from \"@mark1russell7/render-node\";\nimport type { Biblo } from \"./registry.ts\";\nimport { ownerOf, resolveMethods } from \"./registry.ts\";\n\n/**\n * This function makes the class-level reactive semantics (the defaults of `Top`).\n *\n * The ops of the result use the `splash`, `flow`, `deref` and `targets` methods of the class that owns each node.\n * The extends chain resolves them, thus the defaults of `Top` apply to all classes, and a class can\n * change them. A node without an owner, or a class without the method, uses `fallback`.\n *\n * The node layer knows nothing of biblo. This factory is how the class layer gives semantics to the\n * node layer without a dependency in the wrong direction. Give the result to `nodeStore`.\n */\nexport const classNodeOps = (b: Biblo, fallback: NodeOps = defaultOps): NodeOps => {\n type Methods = { readonly splash: SplashFn; readonly flow: FlowFn; readonly deref: DerefFn; readonly targets: TargetsFn };\n const methodFor = <K extends keyof Methods>(n: Node, store: NodeStore, name: K): Methods[K] => {\n const owner = ownerOf(b, store, n.id);\n const inst = owner === undefined ? undefined : b.instances.get(owner);\n const method = inst ? resolveMethods(b, inst.classRef)[name] : undefined;\n return typeof method === \"function\" ? (method as Methods[K]) : fallback[name];\n };\n\n return {\n splash: (value, target, store) => methodFor(target, store, \"splash\")(value, target, store),\n flow: (target, store) => methodFor(target, store, \"flow\")(target, store),\n deref: (root, path, store) => methodFor(root, store, \"deref\")(root, path, store),\n targets: (root, path, store) => methodFor(root, store, \"targets\")(root, path, store),\n };\n};\n"],"mappings":";;;;AAoCA,MAAa,kBACX,MACA,OACA,KACA,aACoB;CACpB;CACA;CACA,GAAI,QAAQ,KAAA,IAAY,EAAE,SAAS,IAAI,IAAI,CAAC;CAC5C,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;AAC7C;;;;;AAMA,MAAa,eACX,MACA,eAIoB;CACpB,GAAG;CACH,OAAO;EAAE,GAAG,KAAK;EAAO,GAAG,UAAU;CAAM;CAC3C,SAAS;EAAE,GAAG,KAAK;EAAS,GAAG,UAAU;CAAQ;AACnD;;;;AC5BA,MAAa,oBAAgC;CAAE,wBAAQ,IAAI,IAAI;CAAG,OAAO,CAAC;AAAE;;AAG5E,MAAM,aAAa,MAA0B;CAC3C,IAAI,YAAY,EAAE,MAAM,WAAW,IAAI,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,KAAM;CAC3E,SAAS;EACP,IAAI,QAAQ;EACZ,KAAK,MAAM,KAAK,EAAE,OAAO;GACvB,IAAI,IAAI,IAAI,WAAW;GACvB,IAAI,YAAY,MAAM,IAAI;IACxB,QAAQ;IACR;GACF;EACF;EACA,IAAI,OAAO;GACT,EAAE,MAAM,KAAK,SAAS;GACtB,OAAO;EACT;EACA;CACF;AACF;;AAGA,MAAa,WAAW,GAAe,SAAyB;CAC9D,IAAI,IAAI,EAAE,OAAO,IAAI,IAAI;CACzB,IAAI,MAAM,KAAA,GAAW;EACnB,IAAI,UAAU,CAAC;EACf,EAAE,OAAO,IAAI,MAAM,CAAC;CACtB;CACA,OAAO;AACT;;AAGA,MAAa,iBAAiB,GAAe,UAAoC;CAC/E,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,IAAI,IAAI,KAAK,GAAG,WAAW,QAAQ,GAAG,IAAI;CAC7D,OAAO;AACT;;AAGA,MAAa,oBAAoB,gBAAkC;CACjE,MAAM,QAAQ,YAAY,QAAQ,GAAG;CACrC,OAAO,QAAQ,IAAI,CAAC,QAAQ,aAAa,IAAI,CAAC,QAAQ,YAAY,MAAM,GAAG,KAAK,KAAK,QAAQ,aAAa;AAC5G;;;;;AAMA,MAAa,gBACX,GACA,QACA,qBACoB;CACpB,MAAM,aAA4C,CAAC;CACnD,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,IAAI,cAAc,GAAG,MAAM,SAAS,QAAQ,gBAAgB,CAAC;EACnE,IAAI,mBAAmB,MAAM,IAAI,WAAW,KAAK;GAAE;GAAO;EAAE,CAAC;CAC/D;CACA,MAAM,UAAU,WAAW,QAAQ,MAAM,CAAC,WAAW,MAAM,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;CACjG,MAAM,yBAAS,IAAI,IAAoB;CACvC,KAAK,MAAM,EAAE,WAAW,SAAS,KAAK,MAAM,QAAQ,OAAO,KAAK,MAAM,OAAO,GAAG,OAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC;CAC5H,MAAM,YAAY,CAAC,GAAG,MAAM,CAAC,CAAC,QAAQ,GAAG,WAAW,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC,SAAS;CAC9F,OAAO;EAAE,SAAS,QAAQ,KAAK,MAAM,EAAE,KAAK;EAAG;CAAU;AAC3D;;;ACzDA,MAAM,UAAU,MAAyB;AAEzC,MAAM,UAAU,GAAW,QAAyB,OAAO,UAAU,eAAe,KAAK,GAAG,GAAG;;AAG/F,MAAM,OAAU,GAA4C,QAC1D,MAAM,KAAA,KAAa,OAAO,GAAG,GAAG,IAAI,EAAE,OAAO,KAAA;;AAG/C,MAAa,cAAqB;CAYhC,OAAO;EAVL,yBAAS,IAAI,IAAI;EACjB,2BAAW,IAAI,IAAI;EACnB,uBAAO,IAAI,IAAI;EACf,wBAAQ,IAAI,IAAI;EAChB,QAAQ,WAAW;EACnB,QAAQ;EACR,4BAAY,IAAI,IAAI;EACpB,8BAAc,IAAI,IAAI;EACtB,6BAAa,IAAI,IAAI;CAEhB;AACT;;;;;;AAOA,MAAa,aAAa,MAAoB;CAC5C,MAAM,IAAI,OAAO,CAAC;CAiBlB,OAAO;EAfL,SAAS,IAAI,IAAI,EAAE,OAAO;EAC1B,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,UAAyC,CAAC,IAAI;GAC1F,IAAI,KAAK;GACT,UAAU,KAAK;GACf,OAAO;IAAE,MAAM,KAAK,MAAM;IAAM,QAAQ,KAAK,MAAM;IAAQ,UAAU,CAAC,GAAG,KAAK,MAAM,QAAQ;GAAE;EAChG,CAAC,CAAC,CAAC;EACH,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;EACtE,QAAQ,IAAI,IAAI,EAAE,MAAM;EACxB,QAAQ;GAAE,QAAQ,IAAI,IAAI,EAAE,OAAO,MAAM;GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,KAAK;EAAE;EACvE,QAAQ,EAAE;EAEV,YAAY,IAAI,IAAI,EAAE,UAAU;EAChC,cAAc,IAAI,IAAI,EAAE,YAAY;EACpC,aAAa,IAAI,IAAI,EAAE,WAAW;CAE1B;AACZ;AAEA,MAAM,eAAe,MAAwB;CAC3C,EAAE,WAAW,MAAM;CACnB,EAAE,aAAa,MAAM;CACrB,EAAE,YAAY,MAAM;AACtB;;AAGA,MAAa,iBAAiB,GAAU,QAA8B;CACpE,MAAM,IAAI,OAAO,CAAC;CAClB,EAAE,QAAQ,IAAI,IAAI,MAAM,GAAG;CAC3B,YAAY,CAAC;AACf;;AAGA,MAAa,iBAAiB,GAAU,UAAuB;CAC7D,MAAM,IAAI,OAAO,CAAC;CAClB,EAAE,OAAO,IAAI,MAAM,MAAM,KAAK;CAC9B,YAAY,CAAC;AACf;;AAGA,MAAa,mBAAmB,GAAU,SAAuB;CAC/D,MAAM,IAAI,OAAO,CAAC;CAClB,EAAE,OAAO,OAAO,IAAI;CACpB,YAAY,CAAC;AACf;;;;;;AAOA,MAAa,eAAe,GAAU,MAAc,OAAwB;CAC1E,MAAM,IAAI,OAAO,CAAC;CAClB,IAAI,CAAC,EAAE,QAAQ,IAAI,IAAI,KAAK,OAAO,MAAM,EAAE,QAAQ,IAAI,EAAE,GAAG,OAAO;CACnE,MAAM,uBAAO,IAAI,IAA4B;CAC7C,KAAK,MAAM,CAAC,MAAM,MAAM,EAAE,SAAS;EACjC,MAAM,iBAAiB,EAAE,YAAY;EACrC,MAAM,eAAe,OAAO,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,QAAQ,IAAI,SAAS,IAAI;EAC3E,KAAK,IAAI,SAAS,OAAO,KAAK,MAAM;GAClC,GAAG;GACH,MAAM,SAAS,OAAO,KAAK;GAC3B,GAAI,iBAAiB,EAAE,SAAS,GAAG,IAAI,CAAC;GACxC,OAAO,eACH,OAAO,YAAY,OAAO,QAAQ,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,GAAG,IAAI,SAAS,OAAO;IAAE,GAAG;IAAK,MAAM;GAAG,IAAI,GAAG,CAAC,CAAC,IACjH,EAAE;EACR,CAAC;CACH;CAEA,EAAE,QAAQ,MAAM;CAChB,KAAK,MAAM,CAAC,MAAM,MAAM,MAAM,EAAE,QAAQ,IAAI,MAAM,CAAC;CACnD,KAAK,MAAM,QAAQ,EAAE,UAAU,OAAO,GAAG,IAAI,KAAK,aAAa,MAAM,KAAK,WAAW;CACrF,MAAM,WAAW,gBAAgC;EAC/C,MAAM,QAAQ,YAAY,QAAQ,GAAG;EACrC,OAAO,SAAS,KAAK,YAAY,MAAM,QAAQ,CAAC,MAAM,OAAO,GAAG,YAAY,MAAM,GAAG,KAAK,EAAE,GAAG,OAAO;CACxG;CACA,KAAK,MAAM,CAAC,MAAM,UAAU,EAAE,QAAQ;EACpC,MAAM,WAAW,MAAM,SAAS,IAAI,OAAO;EAC3C,IAAI,SAAS,MAAM,GAAG,MAAM,MAAM,MAAM,SAAS,EAAE,GAAG,EAAE,OAAO,IAAI,MAAM;GAAE,GAAG;GAAO;EAAS,CAAC;CACjG;CACA,YAAY,CAAC;CACb,OAAO;AACT;;AAGA,MAAa,mBAAmB,GAAU,YAA6C;CACrF,KAAK,MAAM,OAAO,SAAS,cAAc,GAAG,GAAG;AACjD;;;;;AAMA,MAAM,gBAAgB,GAAU,cAAwC;CACtE,MAAM,QAA0B,CAAC;CACjC,MAAM,0BAAU,IAAI,IAAY;CAChC,IAAI,UAA8B;CAClC,OAAO,YAAY,KAAA,KAAa,CAAC,QAAQ,IAAI,OAAO,GAAG;EACrD,QAAQ,IAAI,OAAO;EACnB,MAAM,MAAM,EAAE,QAAQ,IAAI,OAAO;EACjC,IAAI,CAAC,KAAK;EACV,MAAM,KAAK,GAAG;EACd,UAAU,IAAI;CAChB;CACA,OAAO;AACT;;;;;AAMA,MAAM,cAAiB,OAAkC,SAAwG;CAC/J,MAAM,UAAyB,CAAC;CAChC,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,QAAQ,KAAK,GAAG,OAAO,QAAQ,KAAK,MAAM,EAAG,KAAK,CAAC,CAAC,CAAC;CACjG,OAAO,OAAO,OAAO,OAAO,YAAY,OAAO,CAAC;AAClD;;AAGA,MAAa,gBAAgB,GAAU,cAAyD;CAC9F,MAAM,IAAI,OAAO,CAAC;CAClB,IAAI,MAAM,EAAE,WAAW,IAAI,SAAS;CACpC,IAAI,CAAC,KAAK;EACR,MAAM,WAAW,aAAa,GAAG,SAAS,IAAI,QAAQ,IAAI,KAAK;EAC/D,EAAE,WAAW,IAAI,WAAW,GAAG;CACjC;CACA,OAAO;AACT;;AAGA,MAAa,oBAAoB,GAAU,cAA8B;CACvE,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,aAAa,GAAG,SAAS,CAAC,GAAG;EACpE,MAAM,KAAK,QAAQ,MAAM;EACzB,IAAI,IAAI,SAAS,KAAA,GAAW,MAAM,KAAK,QAAQ,KAAK,GAAG,IAAI,MAAM;CACnE;CACA,OAAO,cAAc,OAAO,CAAC,CAAC,CAAC,QAAQ,KAAK;AAC9C;;AAGA,MAAa,WAAW,GAAU,SAAyB,QAAQ,OAAO,CAAC,CAAC,CAAC,QAAQ,IAAI;;AAGzF,MAAa,iBAAiB,GAAU,cAAuC;CAC7E,MAAM,IAAI,OAAO,CAAC;CAClB,IAAI,MAAM,EAAE,YAAY,IAAI,SAAS;CACrC,IAAI,CAAC,KAAK;EACR,MAAM,aAAa,EAAE,QAAQ,EAAE,OAAO,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAAC;EAC9E,EAAE,YAAY,IAAI,WAAW,GAAG;CAClC;CACA,OAAO;AACT;;;;;;;;;AAUA,MAAa,kBAAkB,GAAU,cAAyD;CAChG,MAAM,IAAI,OAAO,CAAC;CAClB,IAAI,MAAM,EAAE,aAAa,IAAI,SAAS;CACtC,IAAI,CAAC,KAAK;EACR,MAAM,QAAQ,aAAa,GAAG,SAAS;EACvC,MAAM,OAAO,MAAM,SAAS,IAAI,MAAM,MAAM,EAAE,IAAI,CAAC;EACnD,MAAM,QAAQ,MAAM,SAAS,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;EACtD,MAAM,EAAE,SAAS,cAAc,cAAc,GAAG,SAAS;EACzD,MAAM,eAAe,QAClB,SAAS,MAAM,OAAO,QAAQ,EAAE,OAAO,CAAC,CAAC,CACzC,QAAQ,CAAC,UAAU,CAAC,UAAU,SAAS,IAAI,CAAC;EAC/C,MAAM,OAAO,OAAO,OAAO,YAAY;GACrC,GAAG,OAAO,QAAQ,WAAW,OAAO,QAAQ,IAAI,OAAO,CAAC;GACxD,GAAG;GACH,GAAG,OAAO,QAAQ,WAAW,QAAQ,QAAQ,IAAI,OAAO,CAAC;EAC3D,CAAC,CAAC;EACF,EAAE,aAAa,IAAI,WAAW,GAAG;CACnC;CACA,OAAO;AACT;;AAGA,MAAM,iBAAiB,GAAe,UAAiC;CACrE,SAAS;EACP,MAAM,KAAK,KAAK,OAAO,EAAE,QAAQ;EACjC,IAAI,CAAC,EAAE,UAAU,IAAI,EAAE,KAAK,CAAC,MAAM,MAAM,IAAI,EAAE,GAAG,OAAO;CAC3D;AACF;;;;;AAMA,MAAM,aAAa,MAAY,QAAoB,aACjD,YAAY,OAAO,MAAM;CACvB,MAAM,CAAC,MAAM,GAAG,QAAQ,EAAE;CAC1B,IAAI,SAAS,QAAQ,OAAO,IAAI,QAAQ,GAAG,IAAI;CAC/C,IAAI,SAAS,YAAY,aAAa,KAAA,GAAW,OAAO,IAAI,UAAU,GAAG,IAAI;CAC7E,OAAO;AACT,CAAC;;;;;AAMH,MAAM,WACJ,GACA,GACA,OACA,MACA,MACA,KACA,OACA,UACS;CACT,IAAI;CACJ,IAAI,UAAU,KAAA,KAAa,IAAI,SAAS,KAAA,KAAa,CAAC,MAAM,IAAI,IAAI,IAAI,GACtE,SAAS,cAAc,GAAG,GAAG,OAAO,IAAI,MAAM,KAAK,IAAI,IAAI,UAAU,KAAK,CAAC,CAAC;MAE5E,SAAS,QAAQ,OAAO,UAAU,SAAS,IAAI,MAAM,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG,GAAG,KAAK,GAAG,GAAG,MAAM;CAExG,QAAQ,OAAO,KAAK,IAAI,MAAM,QAAQ,EAAE,KAAK,KAAK,CAAC;AACrD;AAEA,MAAM,iBACJ,GACA,GACA,OACA,WACA,UACA,UACA,UACoB;CACpB,MAAM,SAAS,aAAa,KAAA,IAAY,KAAA,IAAY,EAAE,UAAU,IAAI,QAAQ;CAC5E,MAAM,KAAK,cAAc,GAAG,KAAK;CACjC,MAAM,OAAwB;EAAE;EAAI,UAAU;EAAW,OAAO;GAAE,MAAM;GAAI,QAAQ,QAAQ;GAAI,UAAU,CAAC;EAAE;CAAE;CAC/G,EAAE,UAAU,IAAI,IAAI,IAAI;CACxB,QAAQ,MAAM,SAAS,KAAK,EAAE;CAE9B,QAAQ,OAAO,IAAI,KAAA,CAAS,GAAG,EAAE;CACjC,MAAM,wBAAQ,IAAI,IAAI,CAAC,GAAG,OAAO,SAAS,CAAC;CAC3C,MAAM,wBAAQ,IAAI,IAAY;CAC9B,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,aAAa,GAAG,SAAS,CAAC,GAAG;EACpE,MAAM,UAAU,IAAI,UAAU,IAAI;EAClC,IAAI,YAAY,KAAA,GAAW,MAAM,IAAI,IAAI;EACzC,QAAQ,GAAG,GAAG,OAAO,MAAM,MAAM,KAAK,SAAS,KAAK;CACtD;CACA,IAAI,MAAM,OAAO,GAAG,EAAE,MAAM,IAAI,IAAI,KAAK;CACzC,OAAO;AACT;;;;;;;;;;;;AAaA,MAAa,eACX,GACA,OACA,WACA,UACA,aACa,MAAM,aAAa,cAAc,OAAO,CAAC,GAAG,GAAG,OAAO,WAAW,UAAU,0BAAU,IAAI,IAAI,CAAC,CAAC;AAE9G,MAAM,aAAa,GAAe,OAAkB,OAAyB;CAC3E,MAAM,OAAO,EAAE,UAAU,IAAI,EAAE;CAC/B,IAAI,CAAC,MAAM;CAEX,KAAK,MAAM,WAAW,KAAK,MAAM,SAAS,MAAM,GAAG,UAAU,GAAG,OAAO,OAAO;CAC9E,WAAW,OAAO,EAAE;CACpB,MAAM,SAAS,KAAK,MAAM,WAAW,KAAA,IAAY,KAAA,IAAY,EAAE,UAAU,IAAI,KAAK,MAAM,MAAM;CAC9F,IAAI,QAAQ;EACV,MAAM,MAAM,OAAO,MAAM,SAAS,QAAQ,EAAE;EAC5C,IAAI,OAAO,GAAG,OAAO,MAAM,SAAS,OAAO,KAAK,CAAC;CACnD;CACA,EAAE,UAAU,OAAO,EAAE;CACrB,EAAE,MAAM,OAAO,EAAE;AACnB;;;;;AAMA,MAAa,aAAa,GAAU,SAAqB,UAAwB;CAC/E,MAAM,IAAI,OAAO,CAAC;CAClB,MAAM,QAAQ,EAAE,UAAU,IAAI,OAAO;CACrC,MAAM,SAAS,OAAO,MAAM,WAAW,KAAA,IAAY,KAAA,IAAY,EAAE,UAAU,IAAI,MAAM,MAAM,MAAM;CACjG,IAAI,CAAC,QAAQ;CACb,MAAM,WAAW,OAAO,MAAM;CAC9B,MAAM,OAAO,SAAS,QAAQ,OAAO;CACrC,IAAI,OAAO,GAAG;CACd,SAAS,OAAO,MAAM,CAAC;CACvB,SAAS,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,SAAS,MAAM,CAAC,GAAG,GAAG,OAAO;AAC3E;;;;;;AAOA,MAAa,mBAAmB,GAAU,OAAkB,eAAiC;CAC3F,MAAM,aAAa;EAAE,UAAU,OAAO,CAAC,GAAG,OAAO,UAAU;CAAG,CAAC;AACjE;;AAGA,MAAM,cAAc,GAAe,OAAkB,SAAuC;CAC1F,MAAM,wBAAQ,IAAI,IAAY,CAAC,KAAK,QAAQ,CAAC;CAC7C,IAAI,UAAuC;CAC3C,OAAO,SAAS,MAAM,WAAW,KAAA,GAAW;EAC1C,MAAM,SAAS,EAAE,UAAU,IAAI,QAAQ,MAAM,MAAM;EACnD,MAAM,UAAsB,QAAQ;EACpC,MAAM,QAAQ,WAAW,KAAA,KAAa,CAAC,GAAI,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC,EAAE,MAAM,OAAO,KAAK,CAAC,CAAE,CAAC,CAAC,SAAS,OAAO;EAC9G,IAAI,CAAC,UAAU,CAAC,SAAS,MAAM,IAAI,OAAO,QAAQ,GAAG;EACrD,MAAM,IAAI,OAAO,QAAQ;EACzB,UAAU;CACZ;CACA,OAAO;AACT;;AAGA,MAAM,cAAc,GAAe,OAAkB,MAAuB,MAAc,SAAuB;CAC/G,MAAM,QAAQ,EAAE,UAAU,IAAI,IAAI;CAClC,IAAI,OAAO,UAAU,GAAG,OAAO,MAAM,EAAE;MAClC,IAAI,MAAM,MAAM,IAAI,IAAI,CAAC,EAAE,WAAW,KAAK,IAAI,WAAW,OAAO,IAAI;MACrE,QAAQ,OAAO,KAAK,IAAI,MAAM,KAAA,CAAS;AAC9C;;;;;AAMA,MAAM,kBACJ,GACA,GACA,OACA,OACA,aACA,gBACS;CACT,MAAM,QAAQ,aAAa,GAAG,MAAM,QAAQ;CAC5C,MAAM,OAAO,MAAM,MAAM,IAAI,MAAM,EAAE;CACrC,IAAI,CAAC,MAAM;CACX,MAAM,QAAQ,EAAE,MAAM,IAAI,MAAM,EAAE,qBAAK,IAAI,IAAY;CACvD,KAAK,MAAM,qBAAK,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,eAAe,CAAC,CAAC,GAAG,GAAG,OAAO,KAAK,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG;EAC/F,MAAM,OAAO,IAAI,aAAa,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,EAAE;EACnD,MAAM,OAAO,IAAI,aAAa,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,EAAE;EACnD,IAAI,IAAI,aAAa,CAAC,MAAM,KAAA,GAAW,MAAM,IAAI,CAAC;OAC7C,MAAM,OAAO,CAAC;EACnB,MAAM,OAAO,KAAK,MAAM,IAAI,CAAC;EAC7B,MAAM,OAAO,SAAS,KAAA,IAAY,KAAA,IAAY,MAAM,MAAM,IAAI,IAAI;EAClE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,IAAI,KAAK,EAAE,GAAG;EACzD,IAAI,WAAW,KAAK,MAAM,UAAU,MAAM,MAAM,IAAI,MAAM,MAAM,MAAM,CAAC,GACrE,QAAQ,OAAO,KAAK,IAAI,UAAU,MAAM,MAAM,IAAI,MAAM,MAAM,MAAM,CAAC;CAEzE;CACA,IAAI,MAAM,OAAO,GAAG,EAAE,MAAM,IAAI,MAAM,IAAI,KAAK;MAC1C,EAAE,MAAM,OAAO,MAAM,EAAE;AAC9B;;;;;;;;;;;;;AAcA,MAAa,eAAe,GAAU,OAAkB,QAA8B;CACpF,MAAM,IAAI,OAAO,CAAC;CAClB,MAAM,yBAAS,IAAI,IAA+C;CAClE,KAAK,MAAM,QAAQ,EAAE,UAAU,OAAO,GACpC,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,GAAG,OAAO,IAAI,KAAK,UAAU,aAAa,GAAG,KAAK,QAAQ,CAAC;CAE1F,cAAc,GAAG,GAAG;CACpB,MAAM,aAAa;EACjB,KAAK,MAAM,QAAQ,MAAM,KAAK,EAAE,UAAU,OAAO,CAAC,GAAG;GACnD,MAAM,OAAO,MAAM,MAAM,IAAI,KAAK,EAAE;GACpC,MAAM,MAAM,OAAO,IAAI,KAAK,QAAQ;GACpC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,IAAI,KAAK,EAAE,GAAG;GAChD,MAAM,OAAO,aAAa,GAAG,KAAK,QAAQ;GAC1C,MAAM,QAAQ,EAAE,MAAM,IAAI,KAAK,EAAE;GACjC,KAAK,MAAM,wBAAQ,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,GAAG,GAAG,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,GAAG;IACvE,MAAM,IAAI,IAAI,KAAK,IAAI;IACvB,MAAM,IAAI,IAAI,MAAM,IAAI;IACxB,IAAI,MAAM,KAAK,OAAO,IAAI,IAAI,MAAM,MAAM;IAC1C,MAAM,OAAO,KAAK,MAAM,IAAI,IAAI;IAChC,MAAM,SAAS,SAAS,KAAA,IAAY,KAAA,IAAY,MAAM,MAAM,IAAI,IAAI;IACpE,MAAM,QAAQ,SAAS,KAAA,IAAY,KAAA,IAAY,EAAE,UAAU,IAAI,IAAI;IACnE,MAAM,WAAW,QACf,WAAW,KAAA,KAAa,UAAU,KAAA,KAAa,WAAW,OAAO,MAAM,UAAU,IAAI,MAAM,KAAK,IAAI,KAAK,MAAM,MAAM,CAAC;IACxH,IAAI,CAAC,GACC;SAAA,SAAS,KAAA,GAAW,WAAW,GAAG,OAAO,MAAM,MAAM,IAAI;IAAA,OACxD,IAAI,CAAC,GACN;SAAA,SAAS,KAAA,GAAW,QAAQ,GAAG,GAAG,OAAO,MAAM,MAAM,GAAG,KAAA,GAAW,WAAW,GAAG,OAAO,IAAI,CAAC;IAAA,OAC5F,IAAI,EAAE,SAAS,KAAA,KAAa,EAAE,SAAS,KAAA,GAAW;KACvD,IAAI,CAAC,OAAO;KACZ,IAAI,EAAE,SAAS,EAAE,MAAM;MACrB,WAAW,GAAG,OAAO,MAAM,MAAM,MAAM,EAAE;MACzC,QAAQ,GAAG,GAAG,OAAO,MAAM,MAAM,GAAG,KAAA,GAAW,WAAW,GAAG,OAAO,IAAI,CAAC;KAC3E,OACE,eAAe,GAAG,GAAG,OAAO,OAAO,EAAE,UAAU,EAAE,QAAQ;IAE7D,OAAO,IAAI,EAAE,SAAS,KAAA,KAAa,EAAE,SAAS,KAAA,GAAW;KAEvD,MAAM,aAAa,EAAE,SAAS,KAAA,IAAY,UAAU,KAAA,IAAY,QAAQ,CAAC;KACzE,IAAI,SAAS,KAAA,KAAa,YAAY;MACpC,WAAW,GAAG,OAAO,MAAM,MAAM,IAAI;MACrC,QAAQ,GAAG,GAAG,OAAO,MAAM,MAAM,GAAG,KAAA,GAAW,WAAW,GAAG,OAAO,IAAI,CAAC;KAC3E;IACF,OAAO,IAAI,SAAS,KAAA,KAAa,QAAQ,CAAC,GACxC,QAAQ,OAAO,MAAM,UAAU,EAAE,MAAM,KAAK,IAAI,KAAK,MAAM,MAAM,CAAC;GAEtE;EACF;CACF,CAAC;AACH;;;;;AAMA,MAAa,WAAW,GAAU,OAAkB,WAA2C;CAC7F,IAAI,UAA8B;CAClC,KAAK,IAAI,QAAQ,GAAG,YAAY,KAAA,KAAa,QAAQ,KAAQ,SAAS;EACpE,IAAI,EAAE,UAAU,IAAI,OAAO,GAAG,OAAO;EACrC,UAAU,MAAM,MAAM,IAAI,OAAO,CAAC,EAAE;CACtC;AAEF;;;;;;;;;;;;;AC9eA,MAAa,gBAAgB,GAAU,WAAoB,eAAwB;CAEjF,MAAM,aAAsC,GAAS,OAAkB,SAAwB;EAC7F,MAAM,QAAQ,QAAQ,GAAG,OAAO,EAAE,EAAE;EACpC,MAAM,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,UAAU,IAAI,KAAK;EACpE,MAAM,SAAS,OAAO,eAAe,GAAG,KAAK,QAAQ,CAAC,CAAC,QAAQ,KAAA;EAC/D,OAAO,OAAO,WAAW,aAAc,SAAwB,SAAS;CAC1E;CAEA,OAAO;EACL,SAAS,OAAO,QAAQ,UAAU,UAAU,QAAQ,OAAO,QAAQ,CAAC,CAAC,OAAO,QAAQ,KAAK;EACzF,OAAO,QAAQ,UAAU,UAAU,QAAQ,OAAO,MAAM,CAAC,CAAC,QAAQ,KAAK;EACvE,QAAQ,MAAM,MAAM,UAAU,UAAU,MAAM,OAAO,OAAO,CAAC,CAAC,MAAM,MAAM,KAAK;EAC/E,UAAU,MAAM,MAAM,UAAU,UAAU,MAAM,OAAO,SAAS,CAAC,CAAC,MAAM,MAAM,KAAK;CACrF;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/class.ts","../src/traits.ts","../src/registry.ts","../src/nodeops.ts"],"sourcesContent":["import type { Expr } from \"@mark1russell7/render-dsl\";\n\n/**\n * A cell template of a class. It has an expression (a coeval document), and optionally a type: the name of\n * another class. A typed cell holds an instance of that class, thus the class level knows the paths through its children.\n */\nexport type CellDef = {\n readonly expr: Expr;\n /** The class of the child instance that this cell holds. */\n readonly type?: string | undefined;\n /**\n * The bindings of a typed cell: expressions that replace cells of the child.\n * They are in the scope of the child. For example, `{ value: ref(\"parent\", \"key\") }` binds the cell `value`\n * of the child to the cell `key` of this instance.\n */\n readonly bindings?: Readonly<Record<string, Expr>> | undefined;\n};\n\n/**\n * A class is a template. Instances share it, and nothing copies it.\n *\n * - `cells`: the reactive structure, which is the data that each instance holds.\n * - `methods`: the behavior. The extends chain resolves them, and the most specific method wins.\n * - `extends`: the parent class. Cells and methods both resolve through it.\n *\n * The values of `methods` are opaque. Each layer reads the method names that it knows, for example\n * `render` for splay and `splash` for the node engine. The class `Top` gives the defaults. An expression method is\n * a coeval document, thus a class is data from end to end.\n */\nexport type ComponentClass = {\n readonly name: string;\n readonly cells: Readonly<Record<string, CellDef>>;\n readonly extends?: string | undefined;\n readonly methods?: Readonly<Record<string, unknown>> | undefined;\n};\n\n/** This function makes a class. */\nexport const componentClass = (\n name: string,\n cells: Readonly<Record<string, CellDef>>,\n ext?: string,\n methods?: Readonly<Record<string, unknown>>,\n): ComponentClass => ({\n name,\n cells,\n ...(ext !== undefined ? { extends: ext } : {}),\n ...(methods !== undefined ? { methods } : {}),\n});\n\n/**\n * This function gives a copy of a class with more cells and methods. The copy keeps the name.\n * An override with the name of an existing cell or method replaces it.\n */\nexport const extendClass = (\n base: ComponentClass,\n overrides: {\n readonly cells?: Readonly<Record<string, CellDef>>;\n readonly methods?: Readonly<Record<string, unknown>>;\n },\n): ComponentClass => ({\n ...base,\n cells: { ...base.cells, ...overrides.cells },\n methods: { ...base.methods, ...overrides.methods },\n});\n","/**\n * Structural traits with prime fingerprints: a granular polymorphism.\n *\n * Each atomic feature of a class gets a unique prime: a cell (`value`), or a typed cell (`kid:Point`).\n * The fingerprint of a class is the product of the primes of its features. The product does not depend on\n * the order of the features, thus two classes with the same features have the same fingerprint.\n *\n * A trait gives methods to each class that has the features of its list. Then the fingerprint of the trait\n * divides the fingerprint of the class. Among the traits that apply, only the most specific ones count\n * (a trait whose fingerprint divides the fingerprint of another applicable trait is dominated). When two of\n * them give the same method, the method is ambiguous: no trait gives it, and the ambiguity is visible.\n */\n\n/** A trait: methods for each class that has the cells of its list. */\nexport type Trait = {\n readonly name: string;\n /** The features that a class must have: a cell name (`label`), or a typed cell (`kid:Point`). */\n readonly requires: readonly string[];\n readonly methods: Readonly<Record<string, unknown>>;\n};\n\n/** The traits that apply to a class, and the names of the methods that two of them give. */\nexport type TraitResolution = {\n readonly applied: readonly Trait[];\n readonly ambiguous: readonly string[];\n};\n\n/** The table of primes: one unique prime for each atomic feature. */\nexport type PrimeTable = {\n readonly primes: Map<string, bigint>;\n readonly found: bigint[];\n};\n\n/** This function makes an empty table of primes. */\nexport const primeTable = (): PrimeTable => ({ primes: new Map(), found: [] });\n\n/** This function gives the next prime after the last prime of the table (trial division by the found primes). */\nconst nextPrime = (t: PrimeTable): bigint => {\n let candidate = t.found.length === 0 ? 2n : t.found[t.found.length - 1]! + 1n;\n for (;;) {\n let prime = true;\n for (const p of t.found) {\n if (p * p > candidate) break;\n if (candidate % p === 0n) {\n prime = false;\n break;\n }\n }\n if (prime) {\n t.found.push(candidate);\n return candidate;\n }\n candidate++;\n }\n};\n\n/** This function gives the prime of an atomic feature. A new feature gets the next free prime. */\nexport const primeIn = (t: PrimeTable, atom: string): bigint => {\n let p = t.primes.get(atom);\n if (p === undefined) {\n p = nextPrime(t);\n t.primes.set(atom, p);\n }\n return p;\n};\n\n/** This function gives the product of the primes of a set of features (the fingerprint). */\nexport const fingerprintOf = (t: PrimeTable, atoms: Iterable<string>): bigint => {\n let product = 1n;\n for (const atom of new Set(atoms)) product *= primeIn(t, atom);\n return product;\n};\n\n/** This function gives the features of an item of the list of a trait: `kid:Point` is the cell `kid` with the type `Point`. */\nexport const requirementAtoms = (requirement: string): string[] => {\n const colon = requirement.indexOf(\":\");\n return colon < 0 ? [`cell:${requirement}`] : [`cell:${requirement.slice(0, colon)}`, `cell:${requirement}`];\n};\n\n/**\n * This function selects the traits for a fingerprint. It keeps each trait whose fingerprint divides the class\n * fingerprint, removes the dominated ones, and finds the methods that two remaining traits give.\n */\nexport const selectTraits = (\n t: PrimeTable,\n traits: Iterable<Trait>,\n classFingerprint: bigint,\n): TraitResolution => {\n const applicable: { trait: Trait; d: bigint }[] = [];\n for (const trait of traits) {\n const d = fingerprintOf(t, trait.requires.flatMap(requirementAtoms));\n if (classFingerprint % d === 0n) applicable.push({ trait, d });\n }\n const maximal = applicable.filter((a) => !applicable.some((b) => b.d !== a.d && b.d % a.d === 0n));\n const owners = new Map<string, number>();\n for (const { trait } of maximal) for (const name of Object.keys(trait.methods)) owners.set(name, (owners.get(name) ?? 0) + 1);\n const ambiguous = [...owners].filter(([, count]) => count > 1).map(([name]) => name).toSorted();\n return { applied: maximal.map((m) => m.trait), ambiguous };\n};\n","import type { ComponentClass, CellDef } from \"./class.ts\";\nimport type { Instance, InstanceId } from \"./instance.ts\";\nimport type { PrimeTable, Trait, TraitResolution } from \"./traits.ts\";\nimport { fingerprintOf, primeIn, primeTable, selectTraits } from \"./traits.ts\";\nimport { docEquals, mapRefs } from \"@mark1russell7/coeval\";\nimport type { Expr } from \"@mark1russell7/render-dsl\";\nimport { isLiteral, lit, renderWorld } from \"@mark1russell7/render-dsl\";\nimport type { NodeId, NodeStore } from \"@mark1russell7/render-node\";\nimport { addNode, batch, removeNode, setExpr, setSlot } from \"@mark1russell7/render-node\";\n\n/**\n * The biblo is the class registry and the instance store.\n *\n * Classes are shared templates. Instances are small (an ID and a scope), and the values of their cells\n * are in the node store. A trait gives methods to each class that has the cells of its list.\n * Change a biblo only through its functions, for example `registerClass`, `registerTrait` and `instantiate`.\n */\nexport type Biblo = {\n readonly classes: ReadonlyMap<string, ComponentClass>;\n readonly instances: ReadonlyMap<InstanceId, Instance>;\n readonly traits: ReadonlyMap<string, Trait>;\n};\n\ntype MutableInstance = {\n readonly id: InstanceId;\n classRef: string;\n readonly scope: { readonly self: InstanceId; readonly parent: InstanceId | undefined; readonly children: InstanceId[] };\n};\n\ntype BibloState = {\n readonly classes: Map<string, ComponentClass>;\n readonly instances: Map<InstanceId, MutableInstance>;\n /** For each instance: the names of the cells that a binding gave. A change of the class does not change them. */\n readonly bound: Map<InstanceId, Set<string>>;\n readonly traits: Map<string, Trait>;\n readonly primes: PrimeTable;\n nextId: number;\n readonly cellsCache: Map<string, Readonly<Record<string, CellDef>>>;\n readonly methodsCache: Map<string, Readonly<Record<string, unknown>>>;\n readonly traitsCache: Map<string, TraitResolution>;\n};\n\nconst bstate = (b: Biblo): BibloState => b as unknown as BibloState;\n\nconst hasOwn = (o: object, key: string): boolean => Object.prototype.hasOwnProperty.call(o, key);\n\n/** This function gives an own property of a record, or `undefined`. It does not read `Object.prototype`. */\nconst own = <T>(o: Readonly<Record<string, T>> | undefined, key: string): T | undefined =>\n o !== undefined && hasOwn(o, key) ? o[key] : undefined;\n\n/** This function makes an empty biblo. */\nexport const biblo = (): Biblo => {\n const s: BibloState = {\n classes: new Map(),\n instances: new Map(),\n bound: new Map(),\n traits: new Map(),\n primes: primeTable(),\n nextId: 0,\n cellsCache: new Map(),\n methodsCache: new Map(),\n traitsCache: new Map(),\n };\n return s;\n};\n\n/**\n * This function gives an independent copy of a biblo: the same classes, traits, instances and counters. The\n * classes and the traits are immutable, thus the copy shares them. Pair the copy with a copy of its store\n * (`forkStore`), with the class semantics of the copy (`classNodeOps`).\n */\nexport const forkBiblo = (b: Biblo): Biblo => {\n const s = bstate(b);\n const copy: BibloState = {\n classes: new Map(s.classes),\n instances: new Map([...s.instances].map(([id, inst]): [InstanceId, MutableInstance] => [id, {\n id: inst.id,\n classRef: inst.classRef,\n scope: { self: inst.scope.self, parent: inst.scope.parent, children: [...inst.scope.children] },\n }])),\n bound: new Map([...s.bound].map(([id, names]) => [id, new Set(names)])),\n traits: new Map(s.traits),\n primes: { primes: new Map(s.primes.primes), found: [...s.primes.found] },\n nextId: s.nextId,\n // The cached entries are frozen results, thus the copy can share them\n cellsCache: new Map(s.cellsCache),\n methodsCache: new Map(s.methodsCache),\n traitsCache: new Map(s.traitsCache),\n };\n return copy;\n};\n\nconst clearCaches = (s: BibloState): void => {\n s.cellsCache.clear();\n s.methodsCache.clear();\n s.traitsCache.clear();\n};\n\n/**\n * This function registers a class, or replaces the class with the same name. The live instances do not change.\n * The expressions of the class are coeval documents, thus a class from JSON text registers as it is.\n */\nexport const registerClass = (b: Biblo, cls: ComponentClass): void => {\n const s = bstate(b);\n s.classes.set(cls.name, cls);\n clearCaches(s);\n};\n\n/** This function registers a trait, or replaces the trait with the same name. The live instances use it at once. */\nexport const registerTrait = (b: Biblo, trait: Trait): void => {\n const s = bstate(b);\n s.traits.set(trait.name, trait);\n clearCaches(s);\n};\n\n/** This function removes a trait. */\nexport const unregisterTrait = (b: Biblo, name: string): void => {\n const s = bstate(b);\n s.traits.delete(name);\n clearCaches(s);\n};\n\n/**\n * This function renames a class. Its subclasses, the typed cells that use it and its live instances use the\n * new name. A trait whose list has a typed cell of the class (`kid:Point`) also uses the new name. The function\n * does nothing and gives `false` when the class is missing or the new name is in use.\n */\nexport const renameClass = (b: Biblo, from: string, to: string): boolean => {\n const s = bstate(b);\n if (!s.classes.has(from) || to === \"\" || s.classes.has(to)) return false;\n const next = new Map<string, ComponentClass>();\n for (const [name, c] of s.classes) {\n const extendsRenamed = c.extends === from;\n const cellsRenamed = Object.values(c.cells).some((def) => def.type === from);\n next.set(name === from ? to : name, {\n ...c,\n name: name === from ? to : name,\n ...(extendsRenamed ? { extends: to } : {}),\n cells: cellsRenamed\n ? Object.fromEntries(Object.entries(c.cells).map(([k, def]) => [k, def.type === from ? { ...def, type: to } : def]))\n : c.cells,\n });\n }\n // The new map keeps the order of registration, with the renamed class at the place of the old name\n s.classes.clear();\n for (const [name, c] of next) s.classes.set(name, c);\n for (const inst of s.instances.values()) if (inst.classRef === from) inst.classRef = to;\n const renamed = (requirement: string): string => {\n const colon = requirement.indexOf(\":\");\n return colon >= 0 && requirement.slice(colon + 1) === from ? `${requirement.slice(0, colon)}:${to}` : requirement;\n };\n for (const [name, trait] of s.traits) {\n const requires = trait.requires.map(renamed);\n if (requires.some((r, i) => r !== trait.requires[i])) s.traits.set(name, { ...trait, requires });\n }\n clearCaches(s);\n return true;\n};\n\n/** This function registers each class of a list, in order. */\nexport const registerClasses = (b: Biblo, classes: readonly ComponentClass[]): void => {\n for (const cls of classes) registerClass(b, cls);\n};\n\n/**\n * This function gives the extends chain of a class, from the class to the root.\n * A cycle (`A` extends `B` extends `A`) stops at the first class that repeats.\n */\nconst extendsChain = (b: Biblo, className: string): ComponentClass[] => {\n const chain: ComponentClass[] = [];\n const visited = new Set<string>();\n let current: string | undefined = className;\n while (current !== undefined && !visited.has(current)) {\n visited.add(current);\n const cls = b.classes.get(current);\n if (!cls) break;\n chain.push(cls);\n current = cls.extends;\n }\n return chain;\n};\n\n/**\n * This function merges the records of an extends chain: the record of the class wins over the record of its parent.\n * `Object.fromEntries` makes own data properties, thus a cell named `__proto__` is a normal cell.\n */\nconst mergeChain = <T>(chain: readonly ComponentClass[], pick: (cls: ComponentClass) => Readonly<Record<string, T>> | undefined): Readonly<Record<string, T>> => {\n const entries: [string, T][] = [];\n for (let i = chain.length - 1; i >= 0; i--) entries.push(...Object.entries(pick(chain[i]!) ?? {}));\n return Object.freeze(Object.fromEntries(entries));\n};\n\n/** This function gives all cell templates of a class through its extends chain. A subclass cell replaces a parent cell. */\nexport const resolveCells = (b: Biblo, className: string): Readonly<Record<string, CellDef>> => {\n const s = bstate(b);\n let out = s.cellsCache.get(className);\n if (!out) {\n out = mergeChain(extendsChain(b, className), (cls) => cls.cells);\n s.cellsCache.set(className, out);\n }\n return out;\n};\n\n/** This function gives the fingerprint of a class: the product of the primes of its cells and typed cells. */\nexport const classFingerprint = (b: Biblo, className: string): bigint => {\n const atoms: string[] = [];\n for (const [name, def] of Object.entries(resolveCells(b, className))) {\n atoms.push(`cell:${name}`);\n if (def.type !== undefined) atoms.push(`cell:${name}:${def.type}`);\n }\n return fingerprintOf(bstate(b).primes, atoms);\n};\n\n/** This function gives the prime of an atomic feature, for example `cell:value`. */\nexport const primeOf = (b: Biblo, atom: string): bigint => primeIn(bstate(b).primes, atom);\n\n/** This function gives the traits that apply to a class (the most specific ones), and the ambiguous method names. */\nexport const resolveTraits = (b: Biblo, className: string): TraitResolution => {\n const s = bstate(b);\n let out = s.traitsCache.get(className);\n if (!out) {\n out = selectTraits(s.primes, s.traits.values(), classFingerprint(b, className));\n s.traitsCache.set(className, out);\n }\n return out;\n};\n\n/**\n * This function gives all methods of a class. There are three layers, from the lowest to the highest.\n * The first layer is the root of the extends chain, for example `Top`. The second layer is the traits that apply.\n * The third layer is the other classes of the chain, to the class itself.\n *\n * Thus a trait changes the defaults of the root, and a class changes a trait.\n * A method that two traits give is ambiguous: no trait gives it.\n */\nexport const resolveMethods = (b: Biblo, className: string): Readonly<Record<string, unknown>> => {\n const s = bstate(b);\n let out = s.methodsCache.get(className);\n if (!out) {\n const chain = extendsChain(b, className);\n const root = chain.length > 1 ? chain.slice(-1) : [];\n const upper = chain.length > 1 ? chain.slice(0, -1) : chain;\n const { applied, ambiguous } = resolveTraits(b, className);\n const traitEntries = applied\n .flatMap((t) => Object.entries(t.methods))\n .filter(([name]) => !ambiguous.includes(name));\n out = Object.freeze(Object.fromEntries([\n ...Object.entries(mergeChain(root, (cls) => cls.methods)),\n ...traitEntries,\n ...Object.entries(mergeChain(upper, (cls) => cls.methods)),\n ]));\n s.methodsCache.set(className, out);\n }\n return out;\n};\n\n/** This function gives an instance ID that is free in the biblo and in the store. */\nconst newInstanceId = (s: BibloState, store: NodeStore): InstanceId => {\n for (;;) {\n const id = `i_${String(s.nextId++)}`;\n if (!s.instances.has(id) && !store.nodes.has(id)) return id;\n }\n};\n\n/**\n * This function changes the scope names of the free `world` references to node IDs with `mapRefs` of the kernel.\n * `self` becomes the instance, and `parent` becomes the parent instance. The parameters of a `fn` stay.\n */\nconst scopeExpr = (expr: Expr, selfId: InstanceId, parentId: InstanceId | undefined): Expr =>\n isLiteral(expr) ? expr : (mapRefs(renderWorld, expr, (use) => {\n if (use.root !== \"world\") return undefined;\n const [, head, ...rest] = use.path;\n if (head === \"self\") return { type: \"ref\", value: [\"world\", selfId, ...rest] };\n if (head === \"parent\" && parentId !== undefined) return { type: \"ref\", value: [\"world\", parentId, ...rest] };\n return undefined;\n }) as Expr);\n\n/**\n * This function adds one cell to an instance. A typed cell becomes a child instance. The exception is a class\n * that is already on the chain of typed cells above the cell. Then the cell is plain, thus the instance is finite.\n */\nconst addCell = (\n s: BibloState,\n b: Biblo,\n store: NodeStore,\n inst: MutableInstance,\n name: string,\n def: CellDef,\n bound: Expr | undefined,\n chain: ReadonlySet<string>,\n): void => {\n let target: NodeId;\n if (bound === undefined && def.type !== undefined && !chain.has(def.type)) {\n target = instantiateIn(s, b, store, def.type, inst.id, def.bindings, chain).id;\n } else {\n target = addNode(store, scopeExpr(bound ?? def.expr, inst.id, inst.scope.parent), `${inst.id}.${name}`);\n }\n setSlot(store, inst.id, name, target, { own: true });\n};\n\nconst instantiateIn = (\n s: BibloState,\n b: Biblo,\n store: NodeStore,\n className: string,\n parentId: InstanceId | undefined,\n bindings: Readonly<Record<string, Expr>> | undefined,\n chain: ReadonlySet<string>,\n): MutableInstance => {\n const parent = parentId === undefined ? undefined : s.instances.get(parentId);\n const id = newInstanceId(s, store);\n const inst: MutableInstance = { id, classRef: className, scope: { self: id, parent: parent?.id, children: [] } };\n s.instances.set(id, inst);\n parent?.scope.children.push(id);\n\n addNode(store, lit(undefined), id);\n const inner = new Set([...chain, className]);\n const bound = new Set<string>();\n for (const [name, def] of Object.entries(resolveCells(b, className))) {\n const binding = own(bindings, name);\n if (binding !== undefined) bound.add(name);\n addCell(s, b, store, inst, name, def, binding, inner);\n }\n if (bound.size > 0) s.bound.set(id, bound);\n return inst;\n};\n\n/**\n * This function makes an instance of a class. The class is not copied: the instance gets an ID, a scope,\n * and a root node with one slot for each cell. All nodes are evaluated before the end of the function.\n *\n * - A typed cell becomes a child instance of its class, with the bindings of the cell. The slot of the cell\n * holds the root node of the child, thus `ref(\"self\", \"kid\", \"value\")` reads a cell of the child.\n * A typed cell whose class is already above it on the chain of typed cells is a plain cell.\n * - `bindings` replace cells of this instance. They are in the scope of this instance. A binding for a typed\n * cell makes it a plain cell with the bound expression.\n * - An unknown class gives an instance with no cells.\n */\nexport const instantiate = (\n b: Biblo,\n store: NodeStore,\n className: string,\n parentId?: InstanceId,\n bindings?: Readonly<Record<string, Expr>>,\n): Instance => batch(store, () => instantiateIn(bstate(b), b, store, className, parentId, bindings, new Set()));\n\nconst destroyIn = (s: BibloState, store: NodeStore, id: InstanceId): void => {\n const inst = s.instances.get(id);\n if (!inst) return;\n // A copy, because each destroy removes the child from this array\n for (const childId of inst.scope.children.slice()) destroyIn(s, store, childId);\n removeNode(store, id);\n const parent = inst.scope.parent === undefined ? undefined : s.instances.get(inst.scope.parent);\n if (parent) {\n const idx = parent.scope.children.indexOf(id);\n if (idx >= 0) parent.scope.children.splice(idx, 1);\n }\n s.instances.delete(id);\n s.bound.delete(id);\n};\n\n/**\n * This function moves a child instance to a position in the children of its parent. A position past the end\n * moves it to the end. It does nothing for an instance without a parent.\n */\nexport const moveChild = (b: Biblo, childId: InstanceId, index: number): void => {\n const s = bstate(b);\n const child = s.instances.get(childId);\n const parent = child?.scope.parent === undefined ? undefined : s.instances.get(child.scope.parent);\n if (!parent) return;\n const children = parent.scope.children;\n const from = children.indexOf(childId);\n if (from < 0) return;\n children.splice(from, 1);\n children.splice(Math.max(0, Math.min(index, children.length)), 0, childId);\n};\n\n/**\n * This function destroys an instance, the inverse of `instantiate`. It destroys the children first, then\n * removes the nodes of the instance and detaches it from its parent. The readers of the removed nodes\n * become `none` in one epoch.\n */\nexport const destroyInstance = (b: Biblo, store: NodeStore, instanceId: InstanceId): void => {\n batch(store, () => { destroyIn(bstate(b), store, instanceId); });\n};\n\n/** This function gives the classes on the chain of typed cells above an instance, with the class of the instance. */\nconst typedChain = (s: BibloState, store: NodeStore, inst: MutableInstance): Set<string> => {\n const chain = new Set<string>([inst.classRef]);\n let current: MutableInstance | undefined = inst;\n while (current?.scope.parent !== undefined) {\n const parent = s.instances.get(current.scope.parent);\n const childId: InstanceId = current.id;\n const holds = parent !== undefined && [...(store.nodes.get(parent.id)?.slots.values() ?? [])].includes(childId);\n if (!parent || !holds || chain.has(parent.classRef)) break;\n chain.add(parent.classRef);\n current = parent;\n }\n return chain;\n};\n\n/** This function removes a cell of an instance: an owned cell node goes, and a shared one only loses the slot. */\nconst removeCell = (s: BibloState, store: NodeStore, inst: MutableInstance, name: string, slot: NodeId): void => {\n const child = s.instances.get(slot);\n if (child) destroyIn(s, store, child.id);\n else if (store.nodes.get(slot)?.parent === inst.id) removeNode(store, slot);\n else setSlot(store, inst.id, name, undefined);\n};\n\n/**\n * This function updates the cells of a child instance after a change of the bindings of its typed cell.\n * A child cell that still has the old binding (or the old default of its class) gets the new one.\n */\nconst updateBindings = (\n s: BibloState,\n b: Biblo,\n store: NodeStore,\n child: MutableInstance,\n oldBindings: Readonly<Record<string, Expr>> | undefined,\n newBindings: Readonly<Record<string, Expr>> | undefined,\n): void => {\n const cells = resolveCells(b, child.classRef);\n const root = store.nodes.get(child.id);\n if (!root) return;\n const bound = s.bound.get(child.id) ?? new Set<string>();\n for (const k of new Set([...Object.keys(oldBindings ?? {}), ...Object.keys(newBindings ?? {})])) {\n const oldE = own(oldBindings, k) ?? own(cells, k)?.expr;\n const newE = own(newBindings, k) ?? own(cells, k)?.expr;\n if (own(newBindings, k) !== undefined) bound.add(k);\n else bound.delete(k);\n const slot = root.slots.get(k);\n const cell = slot === undefined ? undefined : store.nodes.get(slot);\n if (!cell || !oldE || !newE || s.instances.has(cell.id)) continue;\n if (docEquals(cell.expr, scopeExpr(oldE, child.id, child.scope.parent))) {\n setExpr(store, cell.id, scopeExpr(newE, child.id, child.scope.parent));\n }\n }\n if (bound.size > 0) s.bound.set(child.id, bound);\n else s.bound.delete(child.id);\n};\n\n/**\n * This function registers a new version of a class and updates the live instances: the class is a template,\n * and the instances follow it. The update applies to each instance of the class and of its subclasses.\n * When a cell of the resolved class changes, the instance cell changes too, if it still has the old expression.\n *\n * - A cell with an edit of its own keeps it. A cell that a binding gave keeps the binding.\n * - A new cell is added, and a removed cell is removed. A shared cell node only loses its slot.\n * - A typed cell that changes its type gets a new child instance. A change of its bindings reaches the cells of\n * the child that still follow the old bindings. A change between a typed cell and a plain cell replaces the cell.\n *\n * All changes evaluate in one epoch.\n */\nexport const updateClass = (b: Biblo, store: NodeStore, cls: ComponentClass): void => {\n const s = bstate(b);\n const before = new Map<string, Readonly<Record<string, CellDef>>>();\n for (const inst of s.instances.values()) {\n if (!before.has(inst.classRef)) before.set(inst.classRef, resolveCells(b, inst.classRef));\n }\n registerClass(b, cls);\n batch(store, () => {\n for (const inst of Array.from(s.instances.values())) {\n const root = store.nodes.get(inst.id);\n const old = before.get(inst.classRef);\n if (!root || !old || !s.instances.has(inst.id)) continue;\n const next = resolveCells(b, inst.classRef);\n const bound = s.bound.get(inst.id);\n for (const name of new Set([...Object.keys(old), ...Object.keys(next)])) {\n const o = own(old, name);\n const n = own(next, name);\n if (o === n || bound?.has(name) === true) continue;\n const slot = root.slots.get(name);\n const target = slot === undefined ? undefined : store.nodes.get(slot);\n const child = slot === undefined ? undefined : s.instances.get(slot);\n const follows = (def: CellDef): boolean =>\n target !== undefined && child === undefined && docEquals(target.expr, scopeExpr(def.expr, inst.id, inst.scope.parent));\n if (!n) {\n if (slot !== undefined) removeCell(s, store, inst, name, slot);\n } else if (!o) {\n if (slot === undefined) addCell(s, b, store, inst, name, n, undefined, typedChain(s, store, inst));\n } else if (o.type !== undefined && n.type !== undefined) {\n if (!child) continue;\n if (o.type !== n.type) {\n removeCell(s, store, inst, name, child.id);\n addCell(s, b, store, inst, name, n, undefined, typedChain(s, store, inst));\n } else {\n updateBindings(s, b, store, child, o.bindings, n.bindings);\n }\n } else if (o.type !== undefined || n.type !== undefined) {\n // A change between a typed cell and a plain cell: the cell follows the class only in its old form\n const followsOld = o.type !== undefined ? child !== undefined : follows(o);\n if (slot !== undefined && followsOld) {\n removeCell(s, store, inst, name, slot);\n addCell(s, b, store, inst, name, n, undefined, typedChain(s, store, inst));\n }\n } else if (slot !== undefined && follows(o)) {\n setExpr(store, slot, scopeExpr(n.expr, inst.id, inst.scope.parent));\n }\n }\n }\n });\n};\n\n/**\n * This function gives the instance that owns a node. For an instance root, it is the node itself.\n * For another node, it is the nearest owner up the slot tree. A node outside all instances gives `undefined`.\n */\nexport const ownerOf = (b: Biblo, store: NodeStore, nodeId: NodeId): InstanceId | undefined => {\n let current: NodeId | undefined = nodeId;\n for (let guard = 0; current !== undefined && guard < 10_000; guard++) {\n if (b.instances.has(current)) return current;\n current = store.nodes.get(current)?.parent;\n }\n return undefined;\n};\n","import type { NodeOps, SplashFn, FlowFn, DerefFn, TargetsFn, Node, NodeStore } from \"@mark1russell7/render-node\";\nimport { defaultOps } from \"@mark1russell7/render-node\";\nimport type { Biblo } from \"./registry.ts\";\nimport { ownerOf, resolveMethods } from \"./registry.ts\";\n\n/**\n * This function makes the class-level reactive semantics (the defaults of `Top`).\n *\n * The ops of the result use the `splash`, `flow`, `deref` and `targets` methods of the class that owns each node.\n * The extends chain resolves them, thus the defaults of `Top` apply to all classes, and a class can\n * change them. A node without an owner, or a class without the method, uses `fallback`.\n *\n * The node layer knows nothing of biblo. This factory is how the class layer gives semantics to the\n * node layer without a dependency in the wrong direction. Give the result to `nodeStore`.\n */\nexport const classNodeOps = (b: Biblo, fallback: NodeOps = defaultOps): NodeOps => {\n type Methods = { readonly splash: SplashFn; readonly flow: FlowFn; readonly deref: DerefFn; readonly targets: TargetsFn };\n const methodFor = <K extends keyof Methods>(n: Node, store: NodeStore, name: K): Methods[K] => {\n const owner = ownerOf(b, store, n.id);\n const inst = owner === undefined ? undefined : b.instances.get(owner);\n const method = inst ? resolveMethods(b, inst.classRef)[name] : undefined;\n return typeof method === \"function\" ? (method as Methods[K]) : fallback[name];\n };\n\n return {\n splash: (value, target, store) => methodFor(target, store, \"splash\")(value, target, store),\n flow: (target, store) => methodFor(target, store, \"flow\")(target, store),\n deref: (root, path, store) => methodFor(root, store, \"deref\")(root, path, store),\n targets: (root, path, store) => methodFor(root, store, \"targets\")(root, path, store),\n };\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@mark1russell7/render-biblo",
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "description": "The class registry and the instance store of render, and the class-level NodeOps.",
6
6
  "keywords": [
7
7
  "classes",
@@ -48,8 +48,9 @@
48
48
  "node": ">=22.12"
49
49
  },
50
50
  "dependencies": {
51
- "@mark1russell7/render-dsl": "0.1.0",
52
- "@mark1russell7/render-node": "0.1.0",
51
+ "@mark1russell7/coeval": "^0.4.3",
52
+ "@mark1russell7/render-dsl": "0.2.1",
53
+ "@mark1russell7/render-node": "0.2.1",
53
54
  "@mark1russell7/render-optional": "0.1.0"
54
55
  },
55
56
  "devDependencies": {
package/src/class.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { Expr } from "@mark1russell7/render-dsl";
2
2
 
3
3
  /**
4
- * A cell template of a class. It has an expression, and optionally a type: the name of another class.
5
- * A typed cell holds an instance of that class, thus the class level knows the paths through its children.
4
+ * A cell template of a class. It has an expression (a coeval document), and optionally a type: the name of
5
+ * another class. A typed cell holds an instance of that class, thus the class level knows the paths through its children.
6
6
  */
7
7
  export type CellDef = {
8
8
  readonly expr: Expr;
@@ -24,7 +24,8 @@ export type CellDef = {
24
24
  * - `extends`: the parent class. Cells and methods both resolve through it.
25
25
  *
26
26
  * The values of `methods` are opaque. Each layer reads the method names that it knows, for example
27
- * `render` for splay and `splash` for the node engine. The class `Top` gives the defaults.
27
+ * `render` for splay and `splash` for the node engine. The class `Top` gives the defaults. An expression method is
28
+ * a coeval document, thus a class is data from end to end.
28
29
  */
29
30
  export type ComponentClass = {
30
31
  readonly name: string;
package/src/registry.ts CHANGED
@@ -2,8 +2,9 @@ import type { ComponentClass, CellDef } from "./class.ts";
2
2
  import type { Instance, InstanceId } from "./instance.ts";
3
3
  import type { PrimeTable, Trait, TraitResolution } from "./traits.ts";
4
4
  import { fingerprintOf, primeIn, primeTable, selectTraits } from "./traits.ts";
5
+ import { docEquals, mapRefs } from "@mark1russell7/coeval";
5
6
  import type { Expr } from "@mark1russell7/render-dsl";
6
- import { exprEquals, lit, ref, mapFreeRefs } from "@mark1russell7/render-dsl";
7
+ import { isLiteral, lit, renderWorld } from "@mark1russell7/render-dsl";
7
8
  import type { NodeId, NodeStore } from "@mark1russell7/render-node";
8
9
  import { addNode, batch, removeNode, setExpr, setSlot } from "@mark1russell7/render-node";
9
10
 
@@ -95,7 +96,10 @@ const clearCaches = (s: BibloState): void => {
95
96
  s.traitsCache.clear();
96
97
  };
97
98
 
98
- /** This function registers a class, or replaces the class with the same name. The live instances do not change. */
99
+ /**
100
+ * This function registers a class, or replaces the class with the same name. The live instances do not change.
101
+ * The expressions of the class are coeval documents, thus a class from JSON text registers as it is.
102
+ */
99
103
  export const registerClass = (b: Biblo, cls: ComponentClass): void => {
100
104
  const s = bstate(b);
101
105
  s.classes.set(cls.name, cls);
@@ -259,16 +263,17 @@ const newInstanceId = (s: BibloState, store: NodeStore): InstanceId => {
259
263
  };
260
264
 
261
265
  /**
262
- * This function changes the scope names of the free references to node IDs:
263
- * `self` becomes the instance and `parent` becomes the parent instance. The parameters of `fn` forms stay.
266
+ * This function changes the scope names of the free `world` references to node IDs with `mapRefs` of the kernel.
267
+ * `self` becomes the instance, and `parent` becomes the parent instance. The parameters of a `fn` stay.
264
268
  */
265
269
  const scopeExpr = (expr: Expr, selfId: InstanceId, parentId: InstanceId | undefined): Expr =>
266
- mapFreeRefs(expr, (r) => {
267
- const [head, ...rest] = r.path;
268
- if (head === "self") return ref(selfId, ...rest);
269
- if (head === "parent" && parentId !== undefined) return ref(parentId, ...rest);
270
- return r;
271
- });
270
+ isLiteral(expr) ? expr : (mapRefs(renderWorld, expr, (use) => {
271
+ if (use.root !== "world") return undefined;
272
+ const [, head, ...rest] = use.path;
273
+ if (head === "self") return { type: "ref", value: ["world", selfId, ...rest] };
274
+ if (head === "parent" && parentId !== undefined) return { type: "ref", value: ["world", parentId, ...rest] };
275
+ return undefined;
276
+ }) as Expr);
272
277
 
273
278
  /**
274
279
  * This function adds one cell to an instance. A typed cell becomes a child instance. The exception is a class
@@ -426,7 +431,7 @@ const updateBindings = (
426
431
  const slot = root.slots.get(k);
427
432
  const cell = slot === undefined ? undefined : store.nodes.get(slot);
428
433
  if (!cell || !oldE || !newE || s.instances.has(cell.id)) continue;
429
- if (exprEquals(cell.expr, scopeExpr(oldE, child.id, child.scope.parent))) {
434
+ if (docEquals(cell.expr, scopeExpr(oldE, child.id, child.scope.parent))) {
430
435
  setExpr(store, cell.id, scopeExpr(newE, child.id, child.scope.parent));
431
436
  }
432
437
  }
@@ -468,7 +473,7 @@ export const updateClass = (b: Biblo, store: NodeStore, cls: ComponentClass): vo
468
473
  const target = slot === undefined ? undefined : store.nodes.get(slot);
469
474
  const child = slot === undefined ? undefined : s.instances.get(slot);
470
475
  const follows = (def: CellDef): boolean =>
471
- target !== undefined && child === undefined && exprEquals(target.expr, scopeExpr(def.expr, inst.id, inst.scope.parent));
476
+ target !== undefined && child === undefined && docEquals(target.expr, scopeExpr(def.expr, inst.id, inst.scope.parent));
472
477
  if (!n) {
473
478
  if (slot !== undefined) removeCell(s, store, inst, name, slot);
474
479
  } else if (!o) {