@graview/core 0.1.14 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/README.md +27 -8
  2. package/dist/app.d.ts +8 -8
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/arrangement.d.ts +2 -2
  5. package/dist/arrangement.d.ts.map +1 -1
  6. package/dist/arrangement.js +5 -5
  7. package/dist/arranging.js +3 -3
  8. package/dist/capabilities.js +1 -1
  9. package/dist/capabilities.js.map +1 -1
  10. package/dist/city.d.ts +5 -5
  11. package/dist/city.js +3 -3
  12. package/dist/cli/check/beginnings.js +2 -2
  13. package/dist/cli/check/brand.d.ts.map +1 -1
  14. package/dist/cli/check/brand.js +15 -9
  15. package/dist/cli/check/brand.js.map +1 -1
  16. package/dist/cli/check/city.js +1 -1
  17. package/dist/cli/check/context.js +1 -1
  18. package/dist/cli/check/hidden-reads.js +1 -1
  19. package/dist/cli/check/hidden-reads.js.map +1 -1
  20. package/dist/cli/check/relations.js +2 -2
  21. package/dist/cli/check/relations.js.map +1 -1
  22. package/dist/cli/check/settings.js +8 -8
  23. package/dist/cli/check/settings.js.map +1 -1
  24. package/dist/cli/check/views.d.ts +1 -1
  25. package/dist/cli/check/views.js +1 -1
  26. package/dist/cli/create.d.ts +1 -1
  27. package/dist/cli/create.js +5 -5
  28. package/dist/cli/describe.d.ts +1 -1
  29. package/dist/cli/describe.js +2 -2
  30. package/dist/cli/describe.js.map +1 -1
  31. package/dist/cli/index.d.ts +1 -1
  32. package/dist/columns.d.ts +1 -1
  33. package/dist/columns.js +1 -1
  34. package/dist/compiled.d.ts +19 -0
  35. package/dist/compiled.d.ts.map +1 -0
  36. package/dist/compiled.js +60 -0
  37. package/dist/compiled.js.map +1 -0
  38. package/dist/conformance/fixtures.d.ts.map +1 -1
  39. package/dist/conformance/fixtures.js +22 -0
  40. package/dist/conformance/fixtures.js.map +1 -1
  41. package/dist/describe.d.ts +1 -1
  42. package/dist/describe.d.ts.map +1 -1
  43. package/dist/document/blocks.d.ts.map +1 -1
  44. package/dist/document/blocks.js +2 -1
  45. package/dist/document/blocks.js.map +1 -1
  46. package/dist/document/brand-check.d.ts +10 -0
  47. package/dist/document/brand-check.d.ts.map +1 -0
  48. package/dist/document/brand-check.js +33 -0
  49. package/dist/document/brand-check.js.map +1 -0
  50. package/dist/document/brand.d.ts +10 -0
  51. package/dist/document/brand.d.ts.map +1 -0
  52. package/dist/document/brand.js +49 -0
  53. package/dist/document/brand.js.map +1 -0
  54. package/dist/document/compile-checked.d.ts.map +1 -1
  55. package/dist/document/compile-checked.js +6 -2
  56. package/dist/document/compile-checked.js.map +1 -1
  57. package/dist/document/compile.d.ts +10 -29
  58. package/dist/document/compile.d.ts.map +1 -1
  59. package/dist/document/compile.js +74 -393
  60. package/dist/document/compile.js.map +1 -1
  61. package/dist/document/compiled.d.ts +130 -0
  62. package/dist/document/compiled.d.ts.map +1 -0
  63. package/dist/document/compiled.js +467 -0
  64. package/dist/document/compiled.js.map +1 -0
  65. package/dist/document/describe-place.d.ts +16 -0
  66. package/dist/document/describe-place.d.ts.map +1 -1
  67. package/dist/document/describe-place.js +14 -1
  68. package/dist/document/describe-place.js.map +1 -1
  69. package/dist/document/diff.d.ts.map +1 -1
  70. package/dist/document/diff.js +45 -6
  71. package/dist/document/diff.js.map +1 -1
  72. package/dist/document/edit.d.ts +7 -2
  73. package/dist/document/edit.d.ts.map +1 -1
  74. package/dist/document/edit.js +174 -46
  75. package/dist/document/edit.js.map +1 -1
  76. package/dist/document/expr/analyze.d.ts +2 -2
  77. package/dist/document/expr/analyze.js +2 -2
  78. package/dist/document/expr/print.js +1 -1
  79. package/dist/document/index.d.ts +5 -2
  80. package/dist/document/index.d.ts.map +1 -1
  81. package/dist/document/index.js +3 -1
  82. package/dist/document/index.js.map +1 -1
  83. package/dist/document/quote.d.ts +5 -0
  84. package/dist/document/quote.d.ts.map +1 -0
  85. package/dist/document/quote.js +17 -0
  86. package/dist/document/quote.js.map +1 -0
  87. package/dist/document/remembered.d.ts +6 -0
  88. package/dist/document/remembered.d.ts.map +1 -0
  89. package/dist/document/remembered.js +16 -0
  90. package/dist/document/remembered.js.map +1 -0
  91. package/dist/document/rules.d.ts +2 -2
  92. package/dist/document/rules.d.ts.map +1 -1
  93. package/dist/document/rules.js +4 -3
  94. package/dist/document/rules.js.map +1 -1
  95. package/dist/document/schema.d.ts +45 -2
  96. package/dist/document/schema.d.ts.map +1 -1
  97. package/dist/document/schema.js +32 -5
  98. package/dist/document/schema.js.map +1 -1
  99. package/dist/document/template-parse.d.ts +18 -0
  100. package/dist/document/template-parse.d.ts.map +1 -0
  101. package/dist/document/template-parse.js +124 -0
  102. package/dist/document/template-parse.js.map +1 -0
  103. package/dist/document/template.d.ts +1 -17
  104. package/dist/document/template.d.ts.map +1 -1
  105. package/dist/document/template.js +6 -115
  106. package/dist/document/template.js.map +1 -1
  107. package/dist/document/thumbnail.d.ts +13 -1
  108. package/dist/document/thumbnail.d.ts.map +1 -1
  109. package/dist/document/thumbnail.js +106 -16
  110. package/dist/document/thumbnail.js.map +1 -1
  111. package/dist/document/to-document.d.ts +1 -4
  112. package/dist/document/to-document.d.ts.map +1 -1
  113. package/dist/document/to-document.js +7 -14
  114. package/dist/document/to-document.js.map +1 -1
  115. package/dist/document/views.d.ts.map +1 -1
  116. package/dist/document/views.js +1 -1
  117. package/dist/document/views.js.map +1 -1
  118. package/dist/graph/graph.js +3 -3
  119. package/dist/graph/primitives.d.ts +2 -2
  120. package/dist/graph/primitives.js +2 -2
  121. package/dist/index.d.ts +11 -6
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +9 -6
  124. package/dist/index.js.map +1 -1
  125. package/dist/invariants/engine.js +1 -1
  126. package/dist/invariants/types.d.ts +3 -3
  127. package/dist/invariants/types.d.ts.map +1 -1
  128. package/dist/labels.d.ts +1 -1
  129. package/dist/modules.d.ts +1 -1
  130. package/dist/modules.js +1 -1
  131. package/dist/mutations/define-mutation.d.ts +12 -0
  132. package/dist/mutations/define-mutation.d.ts.map +1 -1
  133. package/dist/mutations/define-mutation.js +37 -9
  134. package/dist/mutations/define-mutation.js.map +1 -1
  135. package/dist/mutations/derive-edits.js +4 -4
  136. package/dist/mutations/derive-edits.js.map +1 -1
  137. package/dist/mutations/node-ref.js +1 -1
  138. package/dist/mutations/types.d.ts +1 -1
  139. package/dist/mutations/words.js +3 -3
  140. package/dist/ops/types.d.ts +1 -1
  141. package/dist/ops/withheld.d.ts +3 -3
  142. package/dist/permissions/policy.d.ts +1 -1
  143. package/dist/permissions/policy.js +3 -3
  144. package/dist/permissions/types.d.ts +2 -2
  145. package/dist/places.d.ts +14 -1
  146. package/dist/places.d.ts.map +1 -1
  147. package/dist/places.js +27 -4
  148. package/dist/places.js.map +1 -1
  149. package/dist/refusal.d.ts +11 -6
  150. package/dist/refusal.d.ts.map +1 -1
  151. package/dist/refusal.js +11 -6
  152. package/dist/refusal.js.map +1 -1
  153. package/dist/refused.d.ts +13 -6
  154. package/dist/refused.d.ts.map +1 -1
  155. package/dist/refused.js +14 -7
  156. package/dist/refused.js.map +1 -1
  157. package/dist/scaffold/domain.js +3 -3
  158. package/dist/scaffold/index.d.ts +1 -1
  159. package/dist/scaffold/index.d.ts.map +1 -1
  160. package/dist/scaffold/names.d.ts +1 -1
  161. package/dist/scaffold/names.js +1 -1
  162. package/dist/scaffold/names.js.map +1 -1
  163. package/dist/scaffold/project.d.ts.map +1 -1
  164. package/dist/scaffold/project.js +2 -1
  165. package/dist/scaffold/project.js.map +1 -1
  166. package/dist/scene-districts.d.ts +1 -1
  167. package/dist/schema/define-node.d.ts +4 -4
  168. package/dist/schema/define-node.d.ts.map +1 -1
  169. package/dist/schema/define-node.js +8 -8
  170. package/dist/schema/define-node.js.map +1 -1
  171. package/dist/schema/figures.d.ts +1 -1
  172. package/dist/schema/figures.js +7 -7
  173. package/dist/schema/figures.js.map +1 -1
  174. package/dist/schema/json-schema.d.ts.map +1 -1
  175. package/dist/schema/json-schema.js +4 -1
  176. package/dist/schema/json-schema.js.map +1 -1
  177. package/dist/schema/types.d.ts +1 -1
  178. package/dist/search.d.ts +13 -1
  179. package/dist/search.d.ts.map +1 -1
  180. package/dist/search.js +33 -14
  181. package/dist/search.js.map +1 -1
  182. package/dist/seen.d.ts +2 -2
  183. package/dist/seen.js +12 -12
  184. package/dist/seen.js.map +1 -1
  185. package/dist/settings.d.ts +1 -1
  186. package/dist/settings.js +3 -3
  187. package/dist/settings.js.map +1 -1
  188. package/dist/store.d.ts +2 -2
  189. package/dist/store.d.ts.map +1 -1
  190. package/dist/store.js +8 -8
  191. package/dist/store.js.map +1 -1
  192. package/dist/sync/google-calendar.js +1 -1
  193. package/dist/sync/types.d.ts +2 -2
  194. package/dist/testing.d.ts +1 -1
  195. package/dist/testing.d.ts.map +1 -1
  196. package/dist/testing.js +2 -2
  197. package/dist/testing.js.map +1 -1
  198. package/dist/theme/accent.d.ts +37 -0
  199. package/dist/theme/accent.d.ts.map +1 -0
  200. package/dist/theme/accent.js +138 -0
  201. package/dist/theme/accent.js.map +1 -0
  202. package/dist/theme/contrast.d.ts +7 -7
  203. package/dist/theme/contrast.d.ts.map +1 -1
  204. package/dist/theme/contrast.js +14 -14
  205. package/dist/theme/contrast.js.map +1 -1
  206. package/dist/theme/derive.d.ts +4 -4
  207. package/dist/theme/derive.d.ts.map +1 -1
  208. package/dist/theme/derive.js +19 -19
  209. package/dist/theme/derive.js.map +1 -1
  210. package/dist/theme/fonts.d.ts +19 -0
  211. package/dist/theme/fonts.d.ts.map +1 -0
  212. package/dist/theme/fonts.js +73 -0
  213. package/dist/theme/fonts.js.map +1 -0
  214. package/dist/theme/kit.d.ts +9 -9
  215. package/dist/theme/kit.d.ts.map +1 -1
  216. package/dist/theme/kit.js +15 -15
  217. package/dist/theme/kit.js.map +1 -1
  218. package/dist/theme/layers.d.ts +2 -2
  219. package/dist/theme/layers.d.ts.map +1 -1
  220. package/dist/theme/layers.js +2 -2
  221. package/dist/theme/layers.js.map +1 -1
  222. package/dist/theme/look.d.ts +3 -3
  223. package/dist/theme/look.d.ts.map +1 -1
  224. package/dist/theme/look.js +1 -1
  225. package/dist/theme/marks.d.ts +28 -0
  226. package/dist/theme/marks.d.ts.map +1 -0
  227. package/dist/theme/marks.js +237 -0
  228. package/dist/theme/marks.js.map +1 -0
  229. package/dist/theme/palettes.d.ts +2 -2
  230. package/dist/theme/palettes.js +2 -2
  231. package/dist/theme/types.d.ts +28 -6
  232. package/dist/theme/types.d.ts.map +1 -1
  233. package/dist/theme/types.js.map +1 -1
  234. package/dist/validate-graph.js +2 -2
  235. package/dist/version.d.ts +1 -1
  236. package/dist/version.js +1 -1
  237. package/dist/watched.js +8 -8
  238. package/package.json +5 -1
@@ -0,0 +1,124 @@
1
+ import { parseExpr } from "./expr/parse.js";
2
+ import { FORMATTERS } from "./template.js";
3
+ /*
4
+ * A TEMPLATE, READ: "{status} · {quote|money}" into its parts, each brace's
5
+ * expression parsed and its formatter named. Apart from rendering
6
+ * (template.ts), so a page handed a compiled app — its templates already
7
+ * parsed on the server (FR-123) — carries no parser.
8
+ */
9
+ /** Where the formatter begins: the last bar that is not inside quotes or brackets — `count(a | b)` joins two sets (FR-101) — and not half of `||`. */
10
+ export function filterBar(inner) {
11
+ let quote;
12
+ let bar = -1;
13
+ let depth = 0;
14
+ for (let i = 0; i < inner.length; i++) {
15
+ const c = inner[i];
16
+ if (quote) {
17
+ if (c === "\\")
18
+ i++;
19
+ else if (c === quote)
20
+ quote = undefined;
21
+ continue;
22
+ }
23
+ if (c === "'" || c === '"')
24
+ quote = c;
25
+ else if (c === "(" || c === "[")
26
+ depth++;
27
+ else if (c === ")" || c === "]")
28
+ depth--;
29
+ else if (c === "|" && depth === 0) {
30
+ if (inner[i + 1] === "|")
31
+ i++;
32
+ else
33
+ bar = i;
34
+ }
35
+ }
36
+ return bar;
37
+ }
38
+ /** One quoted word, then a comma or the end. */
39
+ const QUOTED = /\s*(?:'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")\s*(,|$)/y;
40
+ /** A formatter and what it is told: `money`, `plural: 'person', 'people'`. */
41
+ function readFormatter(text) {
42
+ const colon = text.indexOf(":");
43
+ const name = (colon >= 0 ? text.slice(0, colon) : text).trim();
44
+ if (!FORMATTERS.includes(name))
45
+ throw new TemplateError(`"${name}" is not a formatter; use one of ${FORMATTERS.join(", ")}`);
46
+ const args = [];
47
+ if (colon >= 0) {
48
+ const rest = text.slice(colon + 1);
49
+ let at = 0;
50
+ while (at < rest.length) {
51
+ QUOTED.lastIndex = at;
52
+ const m = QUOTED.exec(rest);
53
+ if (!m)
54
+ throw new TemplateError(`"${name}" is told quoted words, like ${name}: 'offer'`);
55
+ args.push((m[1] ?? m[2] ?? "").replace(/\\(.)/g, "$1"));
56
+ at = QUOTED.lastIndex;
57
+ if (m[3] === "")
58
+ break;
59
+ }
60
+ }
61
+ if (name === "plural" && (args.length < 1 || args.length > 2)) {
62
+ throw new TemplateError("plural is told its noun, like {count | plural: 'offer'}, and its plural where English does not make it: plural: 'person', 'people'");
63
+ }
64
+ if (name !== "plural" && args.length > 0)
65
+ throw new TemplateError(`"${name}" takes nothing after it`);
66
+ return { format: name, args };
67
+ }
68
+ export class TemplateError extends Error {
69
+ sentence;
70
+ constructor(sentence) {
71
+ super(sentence);
72
+ this.sentence = sentence;
73
+ }
74
+ }
75
+ /**
76
+ * The braces of a template, in order: each `{…}` as written, with where its
77
+ * formatter begins inside it — so a rewrite can change an expression and
78
+ * keep what was said after the bar, spaces and quoted words included.
79
+ */
80
+ export function templateBraces(template) {
81
+ const out = [];
82
+ let i = 0;
83
+ while (i < template.length) {
84
+ const open = template.indexOf("{", i);
85
+ if (open < 0)
86
+ break;
87
+ const close = template.indexOf("}", open);
88
+ if (close < 0)
89
+ break;
90
+ const inner = template.slice(open + 1, close);
91
+ out.push({ inner, bar: filterBar(inner) });
92
+ i = close + 1;
93
+ }
94
+ return out;
95
+ }
96
+ export function parseTemplate(template) {
97
+ const parts = [];
98
+ let i = 0;
99
+ while (i < template.length) {
100
+ const open = template.indexOf("{", i);
101
+ if (open < 0) {
102
+ parts.push({ text: template.slice(i) });
103
+ break;
104
+ }
105
+ if (open > i)
106
+ parts.push({ text: template.slice(i, open) });
107
+ const close = template.indexOf("}", open);
108
+ if (close < 0)
109
+ throw new TemplateError(`a "{" at character ${open + 1} is never closed`);
110
+ const inner = template.slice(open + 1, close);
111
+ const bar = filterBar(inner);
112
+ const source = (bar >= 0 ? inner.slice(0, bar) : inner).trim();
113
+ const formatter = bar >= 0 ? readFormatter(inner.slice(bar + 1)) : undefined;
114
+ parts.push({
115
+ expr: parseExpr(source),
116
+ source,
117
+ ...(formatter ? { format: formatter.format } : {}),
118
+ ...(formatter && formatter.args.length > 0 ? { formatArgs: formatter.args } : {}),
119
+ });
120
+ i = close + 1;
121
+ }
122
+ return parts;
123
+ }
124
+ //# sourceMappingURL=template-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-parse.js","sourceRoot":"","sources":["../../src/document/template-parse.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { AnyGraphNode, GraphReader } from "../index.js";
2
2
  import { type KindShape, type Value } from "./expr/evaluate.js";
3
- import { type Expr } from "./expr/parse.js";
3
+ import type { Expr } from "./expr/parse.js";
4
4
  export declare const FORMATTERS: readonly ["money", "percent", "date", "relative", "upper", "lower", "count", "words", "and", "plural"];
5
5
  export type Formatter = (typeof FORMATTERS)[number];
6
6
  export interface TemplatePart {
@@ -11,22 +11,6 @@ export interface TemplatePart {
11
11
  /** What the formatter is told: `plural`'s noun, and its plural where English does not make it. */
12
12
  readonly formatArgs?: readonly string[];
13
13
  }
14
- /** Where the formatter begins: the last bar that is not inside quotes or brackets — `count(a | b)` joins two sets (FR-101) — and not half of `||`. */
15
- export declare function filterBar(inner: string): number;
16
- export declare class TemplateError extends Error {
17
- readonly sentence: string;
18
- constructor(sentence: string);
19
- }
20
- /**
21
- * The braces of a template, in order: each `{…}` as written, with where its
22
- * formatter begins inside it — so a rewrite can change an expression and
23
- * keep what was said after the bar, spaces and quoted words included.
24
- */
25
- export declare function templateBraces(template: string): readonly {
26
- readonly inner: string;
27
- readonly bar: number;
28
- }[];
29
- export declare function parseTemplate(template: string): readonly TemplatePart[];
30
14
  /** A graph with nothing in it: what an expression walks when it is handed none. */
31
15
  export declare const EMPTY_GRAPH: GraphReader;
32
16
  /** A value as words, through a formatter: the one place templates and view specs say a value. */
@@ -1 +1 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/document/template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAwC,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACtG,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAkBvD,eAAO,MAAM,UAAU,wGAAyG,CAAC;AACjI,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,kGAAkG;IAClG,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,sJAAsJ;AACtJ,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAoB/C;AA8BD,qBAAa,aAAc,SAAQ,KAAK;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM;gBAAhB,QAAQ,EAAE,MAAM;CAGtC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAa5G;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAyBvE;AAED,mFAAmF;AACnF,eAAO,MAAM,WAAW,EAAE,WAUzB,CAAC;AAEF,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,SAAS,MAAM,EAAO,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAE3I;AAED;;;;;GAKG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,KAAU,GAAG,MAAM,CASpE;AAiED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,CAqBzF"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/document/template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAwC,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACtG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAkB5C,eAAO,MAAM,UAAU,wGAAyG,CAAC;AACjI,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,kGAAkG;IAClG,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAUD,mFAAmF;AACnF,eAAO,MAAM,WAAW,EAAE,WAUzB,CAAC;AAEF,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,SAAS,MAAM,EAAO,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAE3I;AAED;;;;;GAKG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,KAAU,GAAG,MAAM,CASpE;AAiED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,CAqBzF"}
@@ -1,5 +1,4 @@
1
1
  import { evaluateExpr, ExprEvalError, NodeSet } from "./expr/evaluate.js";
2
- import { parseExpr } from "./expr/parse.js";
3
2
  /*
4
3
  * TEMPLATES: "{name}", "{status} · {quote|money}", "{fills.name}".
5
4
  *
@@ -16,121 +15,13 @@ import { parseExpr } from "./expr/parse.js";
16
15
  * "Answers {count(out('answers')) | words} of the {count(all('note')) | words} {count(all('note')) | plural: 'thing'} we heard"
17
16
  */
18
17
  export const FORMATTERS = ["money", "percent", "date", "relative", "upper", "lower", "count", "words", "and", "plural"];
19
- /** Where the formatter begins: the last bar that is not inside quotes or brackets — `count(a | b)` joins two sets (FR-101) — and not half of `||`. */
20
- export function filterBar(inner) {
21
- let quote;
22
- let bar = -1;
23
- let depth = 0;
24
- for (let i = 0; i < inner.length; i++) {
25
- const c = inner[i];
26
- if (quote) {
27
- if (c === "\\")
28
- i++;
29
- else if (c === quote)
30
- quote = undefined;
31
- continue;
32
- }
33
- if (c === "'" || c === '"')
34
- quote = c;
35
- else if (c === "(" || c === "[")
36
- depth++;
37
- else if (c === ")" || c === "]")
38
- depth--;
39
- else if (c === "|" && depth === 0) {
40
- if (inner[i + 1] === "|")
41
- i++;
42
- else
43
- bar = i;
44
- }
45
- }
46
- return bar;
47
- }
48
- /** One quoted word, then a comma or the end. */
49
- const QUOTED = /\s*(?:'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")\s*(,|$)/y;
50
- /** A formatter and what it is told: `money`, `plural: 'person', 'people'`. */
51
- function readFormatter(text) {
52
- const colon = text.indexOf(":");
53
- const name = (colon >= 0 ? text.slice(0, colon) : text).trim();
54
- if (!FORMATTERS.includes(name))
55
- throw new TemplateError(`"${name}" is not a formatter; use one of ${FORMATTERS.join(", ")}`);
56
- const args = [];
57
- if (colon >= 0) {
58
- const rest = text.slice(colon + 1);
59
- let at = 0;
60
- while (at < rest.length) {
61
- QUOTED.lastIndex = at;
62
- const m = QUOTED.exec(rest);
63
- if (!m)
64
- throw new TemplateError(`"${name}" is told quoted words, like ${name}: 'offer'`);
65
- args.push((m[1] ?? m[2] ?? "").replace(/\\(.)/g, "$1"));
66
- at = QUOTED.lastIndex;
67
- if (m[3] === "")
68
- break;
69
- }
70
- }
71
- if (name === "plural" && (args.length < 1 || args.length > 2)) {
72
- throw new TemplateError("plural is told its noun, like {count | plural: 'offer'}, and its plural where English does not make it: plural: 'person', 'people'");
73
- }
74
- if (name !== "plural" && args.length > 0)
75
- throw new TemplateError(`"${name}" takes nothing after it`);
76
- return { format: name, args };
77
- }
78
- export class TemplateError extends Error {
79
- sentence;
80
- constructor(sentence) {
81
- super(sentence);
82
- this.sentence = sentence;
83
- }
84
- }
85
- /**
86
- * The braces of a template, in order: each `{…}` as written, with where its
87
- * formatter begins inside it — so a rewrite can change an expression and
88
- * keep what was said after the bar, spaces and quoted words included.
18
+ /*
19
+ * Reading a template is a module of its own (template-parse.ts), imported
20
+ * from there and not through here: a page handed a compiled app (FR-123)
21
+ * renders templates already parsed, and a bundler places every module this
22
+ * one reaches in the chunk that imports it — the reader and the expression
23
+ * parser with it.
89
24
  */
90
- export function templateBraces(template) {
91
- const out = [];
92
- let i = 0;
93
- while (i < template.length) {
94
- const open = template.indexOf("{", i);
95
- if (open < 0)
96
- break;
97
- const close = template.indexOf("}", open);
98
- if (close < 0)
99
- break;
100
- const inner = template.slice(open + 1, close);
101
- out.push({ inner, bar: filterBar(inner) });
102
- i = close + 1;
103
- }
104
- return out;
105
- }
106
- export function parseTemplate(template) {
107
- const parts = [];
108
- let i = 0;
109
- while (i < template.length) {
110
- const open = template.indexOf("{", i);
111
- if (open < 0) {
112
- parts.push({ text: template.slice(i) });
113
- break;
114
- }
115
- if (open > i)
116
- parts.push({ text: template.slice(i, open) });
117
- const close = template.indexOf("}", open);
118
- if (close < 0)
119
- throw new TemplateError(`a "{" at character ${open + 1} is never closed`);
120
- const inner = template.slice(open + 1, close);
121
- const bar = filterBar(inner);
122
- const source = (bar >= 0 ? inner.slice(0, bar) : inner).trim();
123
- const formatter = bar >= 0 ? readFormatter(inner.slice(bar + 1)) : undefined;
124
- parts.push({
125
- expr: parseExpr(source),
126
- source,
127
- ...(formatter ? { format: formatter.format } : {}),
128
- ...(formatter && formatter.args.length > 0 ? { formatArgs: formatter.args } : {}),
129
- });
130
- i = close + 1;
131
- }
132
- return parts;
133
- }
134
25
  /** A graph with nothing in it: what an expression walks when it is handed none. */
135
26
  export const EMPTY_GRAPH = {
136
27
  getNode: () => undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/document/template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAA8B,MAAM,oBAAoB,CAAC;AACtG,OAAO,EAAE,SAAS,EAAa,MAAM,iBAAiB,CAAC;AAEvD;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAU,CAAC;AAYjI,sJAAsJ;AACtJ,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,IAAI,KAAyB,CAAC;IAC9B,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;IACb,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACpB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;iBACf,IAAI,CAAC,KAAK,KAAK;gBAAE,KAAK,GAAG,SAAS,CAAC;YACxC,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,GAAG,CAAC,CAAC;aACjC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;aACpC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;aACpC,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG;gBAAE,CAAC,EAAE,CAAC;;gBACzB,GAAG,GAAG,CAAC,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gDAAgD;AAChD,MAAM,MAAM,GAAG,yDAAyD,CAAC;AAEzE,8EAA8E;AAC9E,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/D,IAAI,CAAE,UAAgC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,IAAI,IAAI,oCAAoC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpJ,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACnC,IAAI,EAAE,GAAG,CAAC,CAAC;QACX,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,CAAC,CAAC;gBAAE,MAAM,IAAI,aAAa,CAAC,IAAI,IAAI,gCAAgC,IAAI,WAAW,CAAC,CAAC;YACzF,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;YACxD,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;YACtB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;gBAAE,MAAM;QACzB,CAAC;IACH,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,aAAa,CAAC,oIAAoI,CAAC,CAAC;IAChK,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,IAAI,IAAI,0BAA0B,CAAC,CAAC;IACtG,OAAO,EAAE,MAAM,EAAE,IAAiB,EAAE,IAAI,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IACjB;IAArB,YAAqB,QAAgB;QACnC,KAAK,CAAC,QAAQ,CAAC,CAAC;QADG,aAAQ,GAAR,QAAQ,CAAQ;IAErC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,GAAG,GAAqC,EAAE,CAAC;IACjD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACtC,IAAI,IAAI,GAAG,CAAC;YAAE,MAAM;QACpB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,GAAG,CAAC;YAAE,MAAM;QACrB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9C,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3C,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACtC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxC,MAAM;QACR,CAAC;QACD,IAAI,IAAI,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,GAAG,CAAC;YAAE,MAAM,IAAI,aAAa,CAAC,sBAAsB,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACzF,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC;YACvB,MAAM;YACN,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClF,CAAC,CAAC;QACH,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;IACxB,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE;IAClB,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE;IAClB,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE;IACrB,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE;IACrB,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE;IACb,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;IACZ,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE;IACnB,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK;CACjB,CAAC;AAEF,iGAAiG;AACjG,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,MAA6B,EAAE,KAAa,EAAE,OAA0B,EAAE,EAAE,KAAa;IACjI,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AACjD,CAAC;AAaD,kGAAkG;AAClG,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,QAAe,EAAE;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,IAAI,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5J,CAAC;IAAC,MAAM,CAAC;QACP,iGAAiG;QACjG,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC5M,MAAM,IAAI,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEpG,kFAAkF;AAClF,SAAS,OAAO,CAAC,CAAS;IACxB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5G,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC,CAAC,CAAE,CAAC;IAC5B,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;AACtF,CAAC;AAED,oCAAoC;AACpC,SAAS,MAAM,CAAC,KAAwB;IACtC,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AAClH,CAAC;AAED,kEAAkE;AAClE,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/D,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,IAAI,IAAI,CAAC;IACrD,OAAO,GAAG,IAAI,GAAG,CAAC;AACpB,CAAC;AAED,oFAAoF;AACpF,MAAM,MAAM,GAAG,CAAC,CAAe,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;AAElG,SAAS,IAAI,CAAC,KAAY,EAAE,MAA6B,EAAE,KAAa,EAAE,OAA0B,EAAE,EAAE,KAAa;IACnH,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7I,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC;QACxD,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC/B,IAAI,KAAK,YAAY,OAAO;QAAE,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/K,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAU,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7E,OAAO,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAqB,CAAC,CAAC;IACpE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpE,KAAK,OAAO;YACV,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/E,KAAK,SAAS;YACZ,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnF,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpC,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACzF,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;gBAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;YAC7E,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;QACzI,CAAC;QACD;YACE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAcD,oHAAoH;AACpH,MAAM,UAAU,cAAc,CAAC,KAA8B,EAAE,GAAkB;IAC/E,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjE,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAK,EAAE;gBACrC,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,WAAW;gBAC/B,OAAO,EAAE,GAAG,CAAC,IAAI;gBACjB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,KAAK;gBACL,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG;gBACzB,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,aAAa;gBAAE,OAAO,GAAG,CAAC;YAC/C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/document/template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAA8B,MAAM,oBAAoB,CAAC;AAGtG;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAU,CAAC;AAYjI;;;;;;GAMG;AAEH,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;IACxB,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE;IAClB,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE;IAClB,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE;IACrB,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE;IACrB,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE;IACb,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;IACZ,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE;IACnB,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK;CACjB,CAAC;AAEF,iGAAiG;AACjG,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,MAA6B,EAAE,KAAa,EAAE,OAA0B,EAAE,EAAE,KAAa;IACjI,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AACjD,CAAC;AAaD,kGAAkG;AAClG,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,QAAe,EAAE;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,IAAI,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5J,CAAC;IAAC,MAAM,CAAC;QACP,iGAAiG;QACjG,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC5M,MAAM,IAAI,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEpG,kFAAkF;AAClF,SAAS,OAAO,CAAC,CAAS;IACxB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5G,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC,CAAC,CAAE,CAAC;IAC5B,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;AACtF,CAAC;AAED,oCAAoC;AACpC,SAAS,MAAM,CAAC,KAAwB;IACtC,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AAClH,CAAC;AAED,kEAAkE;AAClE,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/D,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,IAAI,IAAI,CAAC;IACrD,OAAO,GAAG,IAAI,GAAG,CAAC;AACpB,CAAC;AAED,oFAAoF;AACpF,MAAM,MAAM,GAAG,CAAC,CAAe,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;AAElG,SAAS,IAAI,CAAC,KAAY,EAAE,MAA6B,EAAE,KAAa,EAAE,OAA0B,EAAE,EAAE,KAAa;IACnH,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7I,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC;QACxD,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC/B,IAAI,KAAK,YAAY,OAAO;QAAE,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/K,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAU,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7E,OAAO,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAqB,CAAC,CAAC;IACpE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpE,KAAK,OAAO;YACV,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/E,KAAK,SAAS;YACZ,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnF,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpC,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACzF,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;gBAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;YAC7E,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;QACzI,CAAC;QACD;YACE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAcD,oHAAoH;AACpH,MAAM,UAAU,cAAc,CAAC,KAA8B,EAAE,GAAkB;IAC/E,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjE,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAK,EAAE;gBACrC,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,WAAW;gBAC/B,OAAO,EAAE,GAAG,CAAC,IAAI;gBACjB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,KAAK;gBACL,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG;gBACzB,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,aAAa;gBAAE,OAAO,GAAG,CAAC;YAC/C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
@@ -12,7 +12,10 @@ export interface SceneThumbnailOptions {
12
12
  * sized as the live Scene sizes it (FR-103): its plot's side from its
13
13
  * count, and its village, one building per member up to what the plot
14
14
  * holds, where the Scene's plots stand them. One without members draws a
15
- * single block. Counts move a plot's size, never its corner.
15
+ * single block. Counts move a plot's size, never its corner. Fitted to
16
+ * the content with no counts at all, each district stands three blocks
17
+ * placed and raised by its kind's name (FR-120), so a live app with no
18
+ * snapshot still reads as a place, and as itself.
16
19
  */
17
20
  readonly counts?: Readonly<Record<string, number>>;
18
21
  /** Fill the picture with the scheme's ground. Default true; false leaves it transparent for a host's own surface. */
@@ -40,6 +43,15 @@ export interface SceneThumbnailOptions {
40
43
  * else one block per member up to five, taller for more, else one block.
41
44
  */
42
45
  readonly minBuilding?: number;
46
+ /**
47
+ * `"icon"` draws the app as a tab's icon (FR-130): 32 × 32, each
48
+ * district on its whole block in its hue with one block standing on it,
49
+ * no strokes, readable at 16 px, under 1.5 KB, and named by the app's
50
+ * name alone — a standalone SVG a host serves as a favicon. `width`,
51
+ * `height`, `fit` and `minBuilding` do not apply; counts raise a
52
+ * district's block as they raise its one block on a tile.
53
+ */
54
+ readonly size?: "icon";
43
55
  }
44
56
  /** What the thumbnail can be drawn from: a declaration document (an object or its JSON), or an app already compiled or declared. */
45
57
  export type ThumbnailSource = GraviewDocument | GraviewApp | string;
@@ -1 +1 @@
1
- {"version":3,"file":"thumbnail.d.ts","sourceRoot":"","sources":["../../src/document/thumbnail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAwBnD,MAAM,WAAW,qBAAqB;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,qHAAqH;IACrH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,oIAAoI;AACpI,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,UAAU,GAAG,MAAM,CAAC;AAsNpE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,GAAE,qBAA0B,GAAG,MAAM,CAmFnG"}
1
+ {"version":3,"file":"thumbnail.d.ts","sourceRoot":"","sources":["../../src/document/thumbnail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAwBnD,MAAM,WAAW,qBAAqB;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,qHAAqH;IACrH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,oIAAoI;AACpI,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,UAAU,GAAG,MAAM,CAAC;AAoTpE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,GAAE,qBAA0B,GAAG,MAAM,CAoFnG"}
@@ -1,6 +1,6 @@
1
1
  import { heightOf, MAX_SIDE, toIso, villageCap, villageOf } from "../city.js";
2
2
  import { sceneDistricts } from "../scene-districts.js";
3
- import { coloursIn, hsl } from "../theme/contrast.js";
3
+ import { colorsIn, hsl } from "../theme/contrast.js";
4
4
  import { isoShade } from "../theme/look.js";
5
5
  import { SCHEMES } from "../theme/palettes.js";
6
6
  import { compileDocumentWithoutCheck } from "./compile.js";
@@ -27,7 +27,7 @@ function appOf(source) {
27
27
  const compiled = compileDocumentWithoutCheck(source);
28
28
  return compiled.ok ? compiled.app : null;
29
29
  }
30
- /** One block on the ground: three faces from its foot's centre in lattice cells, and every point it reaches (for the view box). */
30
+ /** One block on the ground: three faces from its foot's center in lattice cells, and every point it reaches (for the view box). */
31
31
  function block(col, row, footprint, height, hue, scheme) {
32
32
  const shade = isoShade(scheme);
33
33
  const half = footprint / 2;
@@ -45,7 +45,7 @@ function block(col, row, footprint, height, hue, scheme) {
45
45
  const right = at(col + half, row - half, rise);
46
46
  const front = at(col + half, row + half, rise);
47
47
  const left = at(col - half, row + half, rise);
48
- const edge = coloursIn(shade.roofEdge)[0];
48
+ const edge = colorsIn(shade.roofEdge)[0];
49
49
  /*
50
50
  * Each face a path from one corner, the rest relative: a wall is two
51
51
  * corners of the roof and the drop to the ground, a roof the diamond.
@@ -72,11 +72,11 @@ function block(col, row, footprint, height, hue, scheme) {
72
72
  */
73
73
  const VILLAGE_MIN_PX = 4;
74
74
  const MOST_BUILDINGS = 300;
75
- /** One block for the district itself, at its plot's centre, taller for more members: the district seen from furthest away. */
75
+ /** One block for the district itself, at its plot's center, taller for more members: the district seen from furthest away. */
76
76
  function landmark(plot, district, scheme) {
77
- const centre = { col: plot.col + plot.side / 2, row: plot.row + plot.side / 2 };
77
+ const center = { col: plot.col + plot.side / 2, row: plot.row + plot.side / 2 };
78
78
  const height = 1.25 + Math.min(1.25, Math.log2(1 + district.count) * 0.2);
79
- return { depth: centre.col + centre.row, ...block(centre.col, centre.row, plot.side * 0.56, height, district.hue, scheme) };
79
+ return { depth: center.col + center.row, ...block(center.col, center.row, plot.side * 0.56, height, district.hue, scheme) };
80
80
  }
81
81
  /** What stands on one district: its village when it has members and room to show them, else one block for the district itself. */
82
82
  function standing(district, scheme, village) {
@@ -135,11 +135,38 @@ const FEW_CELLS = [
135
135
  [2, 2],
136
136
  ],
137
137
  ];
138
+ /*
139
+ * A PLACE WITH NO COUNTS (FR-120). A host listing live apps has no counts
140
+ * for a tile, and one block in the middle of every district made every app
141
+ * the same row of blocks. Told nothing, a district stands three, on cells
142
+ * of the same sub-lattice chosen by its kind's name, raised by it as the
143
+ * counted blocks are by their ordinals: the same map, a different village
144
+ * on each district. No two of the three share a column on the screen or a
145
+ * wall on the ground, so none stands hidden behind or fused to another.
146
+ */
147
+ const UNSAID = 3;
148
+ const UNSAID_CELLS = (() => {
149
+ const cells = [];
150
+ for (let r = 0; r < 3; r++)
151
+ for (let c = 0; c < 3; c++)
152
+ cells.push([c, r]);
153
+ const choices = [];
154
+ for (let a = 0; a < cells.length; a++)
155
+ for (let b = a + 1; b < cells.length; b++)
156
+ for (let d = b + 1; d < cells.length; d++) {
157
+ const three = [cells[a], cells[b], cells[d]];
158
+ const apart = three.every(([c, r], i) => three.slice(i + 1).every(([c2, r2]) => Math.abs(c - c2) + Math.abs(r - r2) >= 2));
159
+ if (apart && new Set(three.map(([c, r]) => c - r)).size === UNSAID)
160
+ choices.push(three);
161
+ }
162
+ return choices;
163
+ })();
138
164
  /** The district on its whole block: the same corner, the largest side. */
139
165
  const wholeBlock = (plot) => ({ col: plot.col, row: plot.row, side: MAX_SIDE });
140
- function standingFitted(district, scheme, rung) {
166
+ function standingFitted(district, scheme, rung, said) {
141
167
  const plot = wholeBlock(district.plot);
142
168
  const { hue, count, kind } = district;
169
+ const unsaid = !said && count === 0;
143
170
  if (rung === "village" && count > FEW) {
144
171
  const { buildings } = villageOf(plot, Array.from({ length: Math.min(count, villageCap(plot.side)) }, (_, i) => `${kind}#${i}`));
145
172
  return { stands: buildings.map((b) => ({ depth: b.col + b.row, ...block(b.col, b.row, b.footprint, b.height, hue, scheme) })), narrowest: buildings[0]?.footprint ?? Infinity };
@@ -152,15 +179,16 @@ function standingFitted(district, scheme, rung) {
152
179
  const footprint = pitch * 0.8;
153
180
  // Past five, the five grow taller with the count, as the one block does.
154
181
  const taller = count > FEW ? Math.min(0.8, Math.log2(count / FEW) * 0.25) : 0;
155
- const stands = FEW_CELLS[Math.max(1, Math.min(FEW, count)) - 1].map(([c, r], i) => {
182
+ const cells = unsaid ? UNSAID_CELLS[Math.floor(heightOf(`${kind}#place`) * UNSAID_CELLS.length)] : FEW_CELLS[Math.max(1, Math.min(FEW, count)) - 1];
183
+ const stands = cells.map(([c, r], i) => {
156
184
  const col = plot.col + (c + 0.5) * pitch;
157
185
  const row = plot.row + (r + 0.5) * pitch;
158
- const height = count === 0 ? 0.6 : 0.7 + heightOf(`${kind}#${i}`) * 0.6 + taller;
186
+ const height = unsaid ? 0.7 + heightOf(`${kind}#${i}`) * 0.6 : count === 0 ? 0.6 : 0.7 + heightOf(`${kind}#${i}`) * 0.6 + taller;
159
187
  return { depth: col + row, ...block(col, row, footprint, height, hue, scheme) };
160
188
  });
161
189
  return { stands, narrowest: footprint };
162
190
  }
163
- /** The view box: the drawing's own bounds with `pad` of air, widened on its shorter side to the picture's proportion so the city is centred, never stretched. */
191
+ /** The view box: the drawing's own bounds with `pad` of air, widened on its shorter side to the picture's proportion so the city is centered, never stretched. */
164
192
  function frame(all, pad, width, height) {
165
193
  const box = bounds(all);
166
194
  let minX = box.minX - pad;
@@ -191,6 +219,66 @@ function bounds(all) {
191
219
  maxY: Math.max(...all.map((p) => p.y)),
192
220
  };
193
221
  }
222
+ /*
223
+ * AN ICON (FR-130). A tab is 16 pixels, and every app's was the same cube
224
+ * in its accent. At that size a village is a smudge and a street is
225
+ * nothing, so the icon keeps what still reads: each district on its whole
226
+ * block, from the corner the Scene gives it, in its hue — the plot solid,
227
+ * in its curb's color, since the Scene's 12% wash is invisible at 16 px —
228
+ * and one block on it, taller for more. Its coordinates are the
229
+ * icon's own pixels, to a tenth, so the whole picture is a kilobyte.
230
+ */
231
+ const ICON = 32;
232
+ function sceneIcon(app, name, districts, scheme, options) {
233
+ const shade = isoShade(scheme);
234
+ const tokens = (app?.brand?.schemes ?? SCHEMES)[scheme] ?? SCHEMES[scheme];
235
+ const ground = colorsIn(tokens.ground)[0] ?? colorsIn(SCHEMES[scheme].ground)[0];
236
+ /* In lattice units first: each district's diamond and the block at its center, as the landmark stands it. */
237
+ const drawn = districts.map((district) => {
238
+ const plot = wholeBlock(district.plot);
239
+ const at = (c, r, lift = 0) => {
240
+ const p = toIso(c, r, CELL);
241
+ return { x: p.x, y: p.y - lift };
242
+ };
243
+ const ground4 = [at(plot.col, plot.row), at(plot.col + plot.side, plot.row), at(plot.col + plot.side, plot.row + plot.side), at(plot.col, plot.row + plot.side)];
244
+ const center = { col: plot.col + plot.side / 2, row: plot.row + plot.side / 2 };
245
+ const half = (plot.side * 0.56) / 2;
246
+ const rise = plot.side * 0.56 * CELL * 0.5 * (1.25 + Math.min(1.25, Math.log2(1 + district.count) * 0.2));
247
+ const foot = [at(center.col - half, center.row - half), at(center.col + half, center.row - half), at(center.col + half, center.row + half), at(center.col - half, center.row + half)];
248
+ const roof = foot.map((p) => ({ x: p.x, y: p.y - rise }));
249
+ const [back, right, front, left] = roof;
250
+ const [, rightFoot, frontFoot, leftFoot] = foot;
251
+ return {
252
+ district,
253
+ plot: ground4,
254
+ left: [left, front, frontFoot, leftFoot],
255
+ right: [front, right, rightFoot, frontFoot],
256
+ roof: [back, right, front, left],
257
+ depth: center.col + center.row,
258
+ };
259
+ });
260
+ const view = frame(drawn.flatMap((d) => [...d.plot, ...d.roof]), CELL * 0.25, ICON, ICON);
261
+ const scale = ICON / (view.maxX - view.minX);
262
+ const path = (fill, list) => `<path fill="${fill}" d="M${list.map((p) => `${fmt((p.x - view.minX) * scale)} ${fmt((p.y - view.minY) * scale)}`).join(" ")}z"/>`;
263
+ const groups = [...drawn]
264
+ .sort((a, b) => a.depth - b.depth)
265
+ .map((d) => {
266
+ const hue = d.district.hue;
267
+ const curb = shade.plotEdge;
268
+ return (`<g data-kind="${escapeSvg(d.district.kind)}">` +
269
+ path(face(hue, curb), d.plot) +
270
+ path(face(hue, shade.left), d.left) +
271
+ path(face(hue, shade.right), d.right) +
272
+ path(face(hue, shade.roof), d.roof) +
273
+ `</g>`);
274
+ });
275
+ const background = options.background === false ? "" : `<rect width="${ICON}" height="${ICON}" fill="${hex(ground)}"/>`;
276
+ return (`<svg xmlns="http://www.w3.org/2000/svg" width="${ICON}" height="${ICON}" viewBox="0 0 ${ICON} ${ICON}" role="img" data-scheme="${scheme}">` +
277
+ `<title>${escapeSvg(options.title ?? name)}</title>` +
278
+ background +
279
+ groups.join("") +
280
+ `</svg>`);
281
+ }
194
282
  /**
195
283
  * The Scene of an app from altitude, as a standalone SVG string: each
196
284
  * kind's plot on the declaration's own map in its hue, with a block or its
@@ -206,10 +294,13 @@ export function sceneThumbnail(source, options = {}) {
206
294
  const height = Math.max(8, Math.round(options.height ?? 132));
207
295
  const app = appOf(source);
208
296
  const districts = app ? sceneDistricts(app, options.counts ? { counts: options.counts } : {}) : [];
297
+ const name = app?.name ?? (typeof source === "object" && source !== null && typeof source.name === "string" ? source.name : "An app");
298
+ if (options.size === "icon")
299
+ return sceneIcon(app, name, districts, scheme, options);
209
300
  const shade = isoShade(scheme);
210
301
  const tokens = (app?.brand?.schemes ?? SCHEMES)[scheme] ?? SCHEMES[scheme];
211
- const ground = coloursIn(tokens.ground)[0] ?? coloursIn(SCHEMES[scheme].ground)[0];
212
- const roofEdge = coloursIn(shade.roofEdge)[0];
302
+ const ground = colorsIn(tokens.ground)[0] ?? colorsIn(SCHEMES[scheme].ground)[0];
303
+ const roofEdge = colorsIn(shade.roofEdge)[0];
213
304
  const fitted = options.fit === "content";
214
305
  const given = options.minBuilding;
215
306
  const minBuilding = typeof given === "number" && Number.isFinite(given) && given >= 0 ? given : fitted ? FITTED_MIN_PX : VILLAGE_MIN_PX;
@@ -222,9 +313,9 @@ export function sceneThumbnail(source, options = {}) {
222
313
  const corners = [toIso(plot.col, plot.row, CELL), toIso(plot.col + plot.side, plot.row, CELL), toIso(plot.col + plot.side, plot.row + plot.side, CELL), toIso(plot.col, plot.row + plot.side, CELL)];
223
314
  all.push(...corners);
224
315
  const fill = hsl(hue, shade.plot.saturation / 100, shade.plot.lightness / 100);
225
- const kerb = hsl(hue, shade.plotEdge.saturation / 100, shade.plotEdge.lightness / 100);
316
+ const curb = hsl(hue, shade.plotEdge.saturation / 100, shade.plotEdge.lightness / 100);
226
317
  tiles.push(`<g data-kind="${escapeSvg(district.kind)}"><title>${escapeSvg(district.count > 0 ? `${district.label}: ${district.count}` : district.label)}</title>` +
227
- `<polygon fill="${hex(fill)}" stroke="${hex(kerb)}" points="${points(corners)}"/></g>`);
318
+ `<polygon fill="${hex(fill)}" stroke="${hex(curb)}" points="${points(corners)}"/></g>`);
228
319
  }
229
320
  let stands = [];
230
321
  let view;
@@ -237,7 +328,7 @@ export function sceneThumbnail(source, options = {}) {
237
328
  const pad = CELL * 0.4;
238
329
  const rungs = ["village", "few", "one"];
239
330
  for (const rung of rungs) {
240
- const drawn = districts.map((district) => standingFitted(district, scheme, rung));
331
+ const drawn = districts.map((district) => standingFitted(district, scheme, rung, options.counts !== undefined));
241
332
  stands = drawn.flatMap((d) => d.stands);
242
333
  view = frame([...all, ...stands.flatMap((s) => s.reach)], pad, width, height);
243
334
  const scale = width / (view.maxX - view.minX);
@@ -261,7 +352,6 @@ export function sceneThumbnail(source, options = {}) {
261
352
  stands.sort((a, b) => a.depth - b.depth);
262
353
  const { minX, maxX, minY, maxY } = view ?? frame(all, CELL * 0.6, width, height);
263
354
  const viewBox = `${fmt(minX)} ${fmt(minY)} ${fmt(maxX - minX)} ${fmt(maxY - minY)}`;
264
- const name = app?.name ?? (typeof source === "object" && source !== null && typeof source.name === "string" ? source.name : "An app");
265
355
  const title = options.title ??
266
356
  (app
267
357
  ? districts.length === 0