@tamagui/compiler-core 0.0.0-bootstrap.0 → 3.0.0-beta.637.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.
Files changed (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -1
  3. package/dist/cjs/ast.cjs +95 -0
  4. package/dist/cjs/contracts.cjs +62 -0
  5. package/dist/cjs/diagnostics.cjs +69 -0
  6. package/dist/cjs/evaluate.cjs +351 -0
  7. package/dist/cjs/graph.cjs +279 -0
  8. package/dist/cjs/hash.cjs +49 -0
  9. package/dist/cjs/index.cjs +44 -0
  10. package/dist/cjs/ir.cjs +33 -0
  11. package/dist/cjs/lower.cjs +225 -0
  12. package/dist/cjs/materialize.cjs +200 -0
  13. package/dist/cjs/normalize.cjs +622 -0
  14. package/dist/cjs/output.cjs +149 -0
  15. package/dist/cjs/planCache.cjs +224 -0
  16. package/dist/cjs/session.cjs +119 -0
  17. package/dist/cjs/yuku.cjs +159 -0
  18. package/dist/cjs/zero.cjs +387 -0
  19. package/dist/esm/ast.mjs +65 -0
  20. package/dist/esm/ast.mjs.map +1 -0
  21. package/dist/esm/contracts.mjs +34 -0
  22. package/dist/esm/contracts.mjs.map +1 -0
  23. package/dist/esm/diagnostics.mjs +44 -0
  24. package/dist/esm/diagnostics.mjs.map +1 -0
  25. package/dist/esm/evaluate.mjs +327 -0
  26. package/dist/esm/evaluate.mjs.map +1 -0
  27. package/dist/esm/graph.mjs +256 -0
  28. package/dist/esm/graph.mjs.map +1 -0
  29. package/dist/esm/hash.mjs +26 -0
  30. package/dist/esm/hash.mjs.map +1 -0
  31. package/dist/esm/index.mjs +30 -0
  32. package/dist/esm/ir.mjs +12 -0
  33. package/dist/esm/ir.mjs.map +1 -0
  34. package/dist/esm/lower.mjs +202 -0
  35. package/dist/esm/lower.mjs.map +1 -0
  36. package/dist/esm/materialize.mjs +179 -0
  37. package/dist/esm/materialize.mjs.map +1 -0
  38. package/dist/esm/normalize.mjs +596 -0
  39. package/dist/esm/normalize.mjs.map +1 -0
  40. package/dist/esm/output.mjs +119 -0
  41. package/dist/esm/output.mjs.map +1 -0
  42. package/dist/esm/planCache.mjs +194 -0
  43. package/dist/esm/planCache.mjs.map +1 -0
  44. package/dist/esm/session.mjs +99 -0
  45. package/dist/esm/session.mjs.map +1 -0
  46. package/dist/esm/yuku.mjs +136 -0
  47. package/dist/esm/yuku.mjs.map +1 -0
  48. package/dist/esm/zero.mjs +352 -0
  49. package/dist/esm/zero.mjs.map +1 -0
  50. package/package.json +42 -4
  51. package/src/ast.ts +86 -0
  52. package/src/contracts.ts +148 -0
  53. package/src/diagnostics.ts +96 -0
  54. package/src/evaluate.ts +497 -0
  55. package/src/graph.ts +347 -0
  56. package/src/hash.ts +36 -0
  57. package/src/index.ts +15 -0
  58. package/src/ir.ts +154 -0
  59. package/src/lower.ts +418 -0
  60. package/src/materialize.ts +330 -0
  61. package/src/normalize.ts +846 -0
  62. package/src/output.ts +175 -0
  63. package/src/planCache.ts +327 -0
  64. package/src/session.ts +172 -0
  65. package/src/yuku.ts +189 -0
  66. package/src/zero.ts +598 -0
  67. package/types/ast.d.ts +10 -0
  68. package/types/ast.d.ts.map +1 -0
  69. package/types/contracts.d.ts +97 -0
  70. package/types/contracts.d.ts.map +1 -0
  71. package/types/diagnostics.d.ts +31 -0
  72. package/types/diagnostics.d.ts.map +1 -0
  73. package/types/evaluate.d.ts +36 -0
  74. package/types/evaluate.d.ts.map +1 -0
  75. package/types/graph.d.ts +37 -0
  76. package/types/graph.d.ts.map +1 -0
  77. package/types/hash.d.ts +8 -0
  78. package/types/hash.d.ts.map +1 -0
  79. package/types/index.d.ts +16 -0
  80. package/types/index.d.ts.map +1 -0
  81. package/types/ir.d.ts +118 -0
  82. package/types/ir.d.ts.map +1 -0
  83. package/types/lower.d.ts +99 -0
  84. package/types/lower.d.ts.map +1 -0
  85. package/types/materialize.d.ts +104 -0
  86. package/types/materialize.d.ts.map +1 -0
  87. package/types/normalize.d.ts +8 -0
  88. package/types/normalize.d.ts.map +1 -0
  89. package/types/output.d.ts +32 -0
  90. package/types/output.d.ts.map +1 -0
  91. package/types/planCache.d.ts +113 -0
  92. package/types/planCache.d.ts.map +1 -0
  93. package/types/session.d.ts +44 -0
  94. package/types/session.d.ts.map +1 -0
  95. package/types/yuku.d.ts +4 -0
  96. package/types/yuku.d.ts.map +1 -0
  97. package/types/zero.d.ts +98 -0
  98. package/types/zero.d.ts.map +1 -0
@@ -0,0 +1,119 @@
1
+ import { GenMapping, addSegment, setSourceContent, toEncodedMap } from "@jridgewell/gen-mapping";
2
+ import MagicString from "magic-string";
3
+ import { contentHash } from "./hash.mjs";
4
+
5
+ function compareEdits(left, right) {
6
+ return left.start - right.start || left.end - right.end || left.index - right.index;
7
+ }
8
+ function sourceContentHash(source) {
9
+ return contentHash(source);
10
+ }
11
+ function validateSourceEdits(source, edits) {
12
+ const sorted = edits.map((edit, index) => ({
13
+ ...edit,
14
+ index
15
+ })).sort(compareEdits);
16
+ let previousEnd = 0;
17
+ for (const edit of sorted) {
18
+ if (!Number.isInteger(edit.start) || !Number.isInteger(edit.end) || edit.start < 0 || edit.end < edit.start || edit.end > source.length) {
19
+ throw new Error(`Invalid UTF-16 source edit [${edit.start}, ${edit.end})`);
20
+ }
21
+ if (edit.start < previousEnd) {
22
+ throw new Error(`Overlapping UTF-16 source edit at ${edit.start}`);
23
+ }
24
+ previousEnd = Math.max(previousEnd, edit.end);
25
+ }
26
+ }
27
+ function sourcePositions(source) {
28
+ const positions = new Array(source.length + 1);
29
+ let line = 0;
30
+ let column = 0;
31
+ for (let index = 0; index <= source.length; index++) {
32
+ positions[index] = {
33
+ line,
34
+ column
35
+ };
36
+ if (index === source.length) break;
37
+ if (source.charCodeAt(index) === 10) {
38
+ line++;
39
+ column = 0;
40
+ } else {
41
+ column++;
42
+ }
43
+ }
44
+ return positions;
45
+ }
46
+ function mappedSourceMap(source, id, edits) {
47
+ const map = new GenMapping();
48
+ setSourceContent(map, id, source);
49
+ const positions = sourcePositions(source);
50
+ let generatedLine = 0;
51
+ let generatedColumn = 0;
52
+ let sourceCursor = 0;
53
+ const emit = (content, sourceStart, sourceEnd) => {
54
+ const available = Math.max(1, sourceEnd - sourceStart);
55
+ for (let offset = 0; offset < content.length; offset++) {
56
+ const originalIndex = Math.min(sourceStart + offset, sourceStart + available - 1);
57
+ const original = positions[originalIndex];
58
+ addSegment(map, generatedLine, generatedColumn, id, original.line, original.column);
59
+ if (content.charCodeAt(offset) === 10) {
60
+ generatedLine++;
61
+ generatedColumn = 0;
62
+ } else {
63
+ generatedColumn++;
64
+ }
65
+ }
66
+ };
67
+ for (const edit of edits) {
68
+ emit(source.slice(sourceCursor, edit.start), sourceCursor, edit.start);
69
+ if (edit.origin.id !== id) {
70
+ throw new Error(`Source edit for ${id} must use a local mapping origin`);
71
+ }
72
+ emit(edit.content, edit.origin.start, edit.start === edit.end ? edit.origin.start + 1 : edit.origin.end);
73
+ sourceCursor = edit.end;
74
+ }
75
+ emit(source.slice(sourceCursor), sourceCursor, source.length);
76
+ const encoded = toEncodedMap(map);
77
+ return {
78
+ version: 3,
79
+ file: encoded.file ?? void 0,
80
+ names: encoded.names,
81
+ sources: encoded.sources,
82
+ sourcesContent: encoded.sourcesContent ?? [source],
83
+ mappings: encoded.mappings
84
+ };
85
+ }
86
+ function applyLoweredModule(source, id, plan) {
87
+ if (plan.id !== id) {
88
+ throw new Error(`Lowered module plan ${plan.id} cannot be applied to ${id}`);
89
+ }
90
+ if (plan.sourceHash !== sourceContentHash(source)) {
91
+ throw new Error(`Lowered module plan for ${id} does not match the supplied source`);
92
+ }
93
+ if (plan.edits.length === 0) return {
94
+ changed: false,
95
+ code: source,
96
+ map: null
97
+ };
98
+ validateSourceEdits(source, plan.edits);
99
+ const output = new MagicString(source);
100
+ const sorted = plan.edits.map((edit, index) => ({
101
+ ...edit,
102
+ index
103
+ })).sort(compareEdits);
104
+ for (const edit of sorted) {
105
+ if (edit.start === edit.end) {
106
+ output.appendLeft(edit.start, edit.content);
107
+ } else {
108
+ output.overwrite(edit.start, edit.end, edit.content);
109
+ }
110
+ }
111
+ return {
112
+ changed: true,
113
+ code: output.toString(),
114
+ map: mappedSourceMap(source, id, sorted)
115
+ };
116
+ }
117
+
118
+ export { applyLoweredModule, sourceContentHash, validateSourceEdits };
119
+ //# sourceMappingURL=output.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","names":[],"sources":["esm/output.js"],"sourcesContent":["import {\n GenMapping,\n addSegment,\n setSourceContent,\n toEncodedMap\n} from \"@jridgewell/gen-mapping\";\nimport MagicString from \"magic-string\";\nimport { contentHash } from \"./hash\";\nfunction compareEdits(left, right) {\n return left.start - right.start || left.end - right.end || left.index - right.index;\n}\nfunction sourceContentHash(source) {\n return contentHash(source);\n}\nfunction validateSourceEdits(source, edits) {\n const sorted = edits.map((edit, index) => ({ ...edit, index })).sort(compareEdits);\n let previousEnd = 0;\n for (const edit of sorted) {\n if (!Number.isInteger(edit.start) || !Number.isInteger(edit.end) || edit.start < 0 || edit.end < edit.start || edit.end > source.length) {\n throw new Error(`Invalid UTF-16 source edit [${edit.start}, ${edit.end})`);\n }\n if (edit.start < previousEnd) {\n throw new Error(`Overlapping UTF-16 source edit at ${edit.start}`);\n }\n previousEnd = Math.max(previousEnd, edit.end);\n }\n}\nfunction sourcePositions(source) {\n const positions = new Array(source.length + 1);\n let line = 0;\n let column = 0;\n for (let index = 0; index <= source.length; index++) {\n positions[index] = { line, column };\n if (index === source.length) break;\n if (source.charCodeAt(index) === 10) {\n line++;\n column = 0;\n } else {\n column++;\n }\n }\n return positions;\n}\nfunction mappedSourceMap(source, id, edits) {\n const map = new GenMapping();\n setSourceContent(map, id, source);\n const positions = sourcePositions(source);\n let generatedLine = 0;\n let generatedColumn = 0;\n let sourceCursor = 0;\n const emit = (content, sourceStart, sourceEnd) => {\n const available = Math.max(1, sourceEnd - sourceStart);\n for (let offset = 0; offset < content.length; offset++) {\n const originalIndex = Math.min(sourceStart + offset, sourceStart + available - 1);\n const original = positions[originalIndex];\n addSegment(map, generatedLine, generatedColumn, id, original.line, original.column);\n if (content.charCodeAt(offset) === 10) {\n generatedLine++;\n generatedColumn = 0;\n } else {\n generatedColumn++;\n }\n }\n };\n for (const edit of edits) {\n emit(source.slice(sourceCursor, edit.start), sourceCursor, edit.start);\n if (edit.origin.id !== id) {\n throw new Error(`Source edit for ${id} must use a local mapping origin`);\n }\n emit(\n edit.content,\n edit.origin.start,\n edit.start === edit.end ? edit.origin.start + 1 : edit.origin.end\n );\n sourceCursor = edit.end;\n }\n emit(source.slice(sourceCursor), sourceCursor, source.length);\n const encoded = toEncodedMap(map);\n return {\n version: 3,\n file: encoded.file ?? void 0,\n names: encoded.names,\n sources: encoded.sources,\n sourcesContent: encoded.sourcesContent ?? [source],\n mappings: encoded.mappings\n };\n}\nfunction applyLoweredModule(source, id, plan) {\n if (plan.id !== id) {\n throw new Error(`Lowered module plan ${plan.id} cannot be applied to ${id}`);\n }\n if (plan.sourceHash !== sourceContentHash(source)) {\n throw new Error(`Lowered module plan for ${id} does not match the supplied source`);\n }\n if (plan.edits.length === 0) return { changed: false, code: source, map: null };\n validateSourceEdits(source, plan.edits);\n const output = new MagicString(source);\n const sorted = plan.edits.map((edit, index) => ({ ...edit, index })).sort(compareEdits);\n for (const edit of sorted) {\n if (edit.start === edit.end) {\n output.appendLeft(edit.start, edit.content);\n } else {\n output.overwrite(edit.start, edit.end, edit.content);\n }\n }\n return {\n changed: true,\n code: output.toString(),\n map: mappedSourceMap(source, id, sorted)\n };\n}\nexport {\n applyLoweredModule,\n sourceContentHash,\n validateSourceEdits\n};\n//# sourceMappingURL=output.js.map\n"],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { mkdir, readFile, readdir, rename, stat, unlink, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { contentHash, stableStringify } from "./hash.mjs";
5
+ import { LOWERED_MODULE_PLAN_VERSION } from "./lower.mjs";
6
+ import { moduleContentHash } from "./graph.mjs";
7
+
8
+ const PLAN_CACHE_SCHEMA_VERSION = 1;
9
+ const PLAN_CACHE_MAX_ENTRIES = 2e4;
10
+ function tamaguiCacheRoot(projectRoot) {
11
+ return join(projectRoot, "node_modules", ".cache", "tamagui");
12
+ }
13
+ function defaultPlanCacheRoot(projectRoot, target) {
14
+ return join(tamaguiCacheRoot(projectRoot), "plans", target);
15
+ }
16
+ function moduleClosureNode(input) {
17
+ return {
18
+ contentHash: moduleContentHash(input),
19
+ dependencies: input.imports.filter(({ external }) => !external).map(({ resolvedId }) => resolvedId)
20
+ };
21
+ }
22
+ function moduleClosureDigest(id, lookup, memo) {
23
+ const cached = memo?.get(id);
24
+ if (cached !== void 0) return cached;
25
+ const reached = /* @__PURE__ */ new Map();
26
+ const queue = [id];
27
+ let complete = true;
28
+ while (queue.length) {
29
+ const current = queue.pop();
30
+ if (reached.has(current)) continue;
31
+ const node = lookup(current);
32
+ if (!node) {
33
+ complete = false;
34
+ break;
35
+ }
36
+ reached.set(current, node.contentHash);
37
+ for (const dependency of node.dependencies) queue.push(dependency);
38
+ }
39
+ const digest = complete ? contentHash([...reached].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([current, hash]) => `${current}\0${hash}`).join("\0")) : null;
40
+ memo?.set(id, digest);
41
+ return digest;
42
+ }
43
+ function planCacheKey(identity, id, closureDigest) {
44
+ return contentHash(stableStringify({
45
+ schema: 1,
46
+ plan: LOWERED_MODULE_PLAN_VERSION,
47
+ stamp: identity.stamp,
48
+ target: identity.target,
49
+ structuralPassHash: identity.structuralPassHash,
50
+ id,
51
+ closureDigest
52
+ }));
53
+ }
54
+ var JsonFileCache = class {
55
+ constructor(root, schemaVersion, maxEntries = PLAN_CACHE_MAX_ENTRIES) {
56
+ this.root = root;
57
+ this.schemaVersion = schemaVersion;
58
+ this.maxEntries = maxEntries;
59
+ }
60
+ root;
61
+ schemaVersion;
62
+ maxEntries;
63
+ #hits = 0;
64
+ #misses = 0;
65
+ #writes = 0;
66
+ #writesSincePrune = 0;
67
+ #prunedThisProcess = false;
68
+ #created = /* @__PURE__ */ new Set();
69
+ get stats() {
70
+ return {
71
+ hits: this.#hits,
72
+ misses: this.#misses,
73
+ writes: this.#writes
74
+ };
75
+ }
76
+ resetStats() {
77
+ this.#hits = 0;
78
+ this.#misses = 0;
79
+ this.#writes = 0;
80
+ }
81
+ #path(key) {
82
+ return join(this.root, `v${this.schemaVersion}`, key.slice(0, 2), `${key}.json`);
83
+ }
84
+ /**
85
+ * Null on anything short of an entry `validate` fully accepts. A miss
86
+ * recompiles; nothing here repairs or partially trusts an entry, and a later
87
+ * successful compile overwrites the bad file.
88
+ */
89
+ async read(key, validate) {
90
+ let parsed;
91
+ try {
92
+ parsed = JSON.parse(await readFile(this.#path(key), "utf8"));
93
+ } catch {
94
+ this.#misses++;
95
+ return null;
96
+ }
97
+ const entry = validate(parsed);
98
+ if (entry === null) {
99
+ this.#misses++;
100
+ return null;
101
+ }
102
+ this.#hits++;
103
+ return entry;
104
+ }
105
+ async write(key, value) {
106
+ const path = this.#path(key);
107
+ const directory = dirname(path);
108
+ if (!this.#created.has(directory)) {
109
+ await mkdir(directory, { recursive: true });
110
+ this.#created.add(directory);
111
+ }
112
+ const temporaryPath = `${path}.${process.pid}-${randomBytes(6).toString("hex")}.tmp`;
113
+ await writeFile(temporaryPath, `${stableStringify(value)}
114
+ `, "utf8");
115
+ await rename(temporaryPath, path);
116
+ this.#writes++;
117
+ this.#writesSincePrune++;
118
+ const batch = Math.max(1, Math.floor(this.maxEntries / 4));
119
+ if (!this.#prunedThisProcess || this.#writesSincePrune >= batch) {
120
+ this.#prunedThisProcess = true;
121
+ this.#writesSincePrune = 0;
122
+ await this.#prune();
123
+ }
124
+ }
125
+ /**
126
+ * Drops the oldest entries once the store exceeds its cap, oldest by the later
127
+ * of read and write time so an entry a build keeps hitting is not treated as
128
+ * dead on filesystems that maintain access times.
129
+ */
130
+ async #prune() {
131
+ const versionRoot = join(this.root, `v${this.schemaVersion}`);
132
+ let shards;
133
+ try {
134
+ shards = await readdir(versionRoot);
135
+ } catch {
136
+ return;
137
+ }
138
+ const paths = [];
139
+ for (const shard of shards) {
140
+ const directory = join(versionRoot, shard);
141
+ let files;
142
+ try {
143
+ files = await readdir(directory);
144
+ } catch {
145
+ continue;
146
+ }
147
+ for (const file of files) {
148
+ if (file.endsWith(".json")) paths.push(join(directory, file));
149
+ }
150
+ }
151
+ if (paths.length <= this.maxEntries) return;
152
+ const entries = [];
153
+ for (const path of paths) {
154
+ try {
155
+ const stats = await stat(path);
156
+ entries.push({
157
+ path,
158
+ usedAt: Math.max(stats.atimeMs, stats.mtimeMs)
159
+ });
160
+ } catch {}
161
+ }
162
+ entries.sort((left, right) => left.usedAt - right.usedAt);
163
+ for (const entry of entries.slice(0, Math.max(0, entries.length - this.maxEntries))) {
164
+ await unlink(entry.path).catch(() => {});
165
+ }
166
+ }
167
+ };
168
+ var ModulePlanCache = class {
169
+ constructor(root) {
170
+ this.root = root;
171
+ this.#files = new JsonFileCache(root, 1);
172
+ }
173
+ root;
174
+ #files;
175
+ get stats() {
176
+ return this.#files.stats;
177
+ }
178
+ resetStats() {
179
+ this.#files.resetStats();
180
+ }
181
+ read(key, id, closureDigest) {
182
+ return this.#files.read(key, (value) => {
183
+ const entry = value;
184
+ const plan = entry?.plan;
185
+ return entry?.schemaVersion === 1 && entry.moduleId === id && entry.closureDigest === closureDigest && plan && plan.version === LOWERED_MODULE_PLAN_VERSION && plan.id === id && typeof plan.sourceHash === "string" && typeof plan.css === "string" && Array.isArray(plan.edits) && Array.isArray(plan.diagnostics) && Array.isArray(plan.dependencies) && !!plan.stats ? entry : null;
186
+ });
187
+ }
188
+ write(key, entry) {
189
+ return this.#files.write(key, entry);
190
+ }
191
+ };
192
+
193
+ export { JsonFileCache, ModulePlanCache, PLAN_CACHE_MAX_ENTRIES, PLAN_CACHE_SCHEMA_VERSION, defaultPlanCacheRoot, moduleClosureDigest, moduleClosureNode, planCacheKey, tamaguiCacheRoot };
194
+ //# sourceMappingURL=planCache.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planCache.js","names":["#hits","#misses","#writes","#path","#created","#writesSincePrune","#prunedThisProcess","#prune","#files"],"sources":["esm/planCache.js"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport {\n mkdir,\n readdir,\n readFile,\n rename,\n stat,\n unlink,\n writeFile\n} from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { contentHash, stableStringify } from \"./hash\";\nimport { LOWERED_MODULE_PLAN_VERSION } from \"./lower\";\nimport { moduleContentHash } from \"./graph\";\nconst PLAN_CACHE_SCHEMA_VERSION = 1;\nconst PLAN_CACHE_MAX_ENTRIES = 2e4;\nfunction tamaguiCacheRoot(projectRoot) {\n return join(projectRoot, \"node_modules\", \".cache\", \"tamagui\");\n}\nfunction defaultPlanCacheRoot(projectRoot, target) {\n return join(tamaguiCacheRoot(projectRoot), \"plans\", target);\n}\nfunction moduleClosureNode(input) {\n return {\n contentHash: moduleContentHash(input),\n dependencies: input.imports.filter(({ external }) => !external).map(({ resolvedId }) => resolvedId)\n };\n}\nfunction moduleClosureDigest(id, lookup, memo) {\n const cached = memo?.get(id);\n if (cached !== void 0) return cached;\n const reached = /* @__PURE__ */ new Map();\n const queue = [id];\n let complete = true;\n while (queue.length) {\n const current = queue.pop();\n if (reached.has(current)) continue;\n const node = lookup(current);\n if (!node) {\n complete = false;\n break;\n }\n reached.set(current, node.contentHash);\n for (const dependency of node.dependencies) queue.push(dependency);\n }\n const digest = complete ? contentHash(\n [...reached].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([current, hash]) => `${current}\\0${hash}`).join(\"\\0\")\n ) : null;\n memo?.set(id, digest);\n return digest;\n}\nfunction planCacheKey(identity, id, closureDigest) {\n return contentHash(\n stableStringify({\n schema: PLAN_CACHE_SCHEMA_VERSION,\n plan: LOWERED_MODULE_PLAN_VERSION,\n stamp: identity.stamp,\n target: identity.target,\n structuralPassHash: identity.structuralPassHash,\n id,\n closureDigest\n })\n );\n}\nclass JsonFileCache {\n constructor(root, schemaVersion, maxEntries = PLAN_CACHE_MAX_ENTRIES) {\n this.root = root;\n this.schemaVersion = schemaVersion;\n this.maxEntries = maxEntries;\n }\n root;\n schemaVersion;\n maxEntries;\n #hits = 0;\n #misses = 0;\n #writes = 0;\n #writesSincePrune = 0;\n #prunedThisProcess = false;\n #created = /* @__PURE__ */ new Set();\n get stats() {\n return { hits: this.#hits, misses: this.#misses, writes: this.#writes };\n }\n resetStats() {\n this.#hits = 0;\n this.#misses = 0;\n this.#writes = 0;\n }\n #path(key) {\n return join(this.root, `v${this.schemaVersion}`, key.slice(0, 2), `${key}.json`);\n }\n /**\n * Null on anything short of an entry `validate` fully accepts. A miss\n * recompiles; nothing here repairs or partially trusts an entry, and a later\n * successful compile overwrites the bad file.\n */\n async read(key, validate) {\n let parsed;\n try {\n parsed = JSON.parse(await readFile(this.#path(key), \"utf8\"));\n } catch {\n this.#misses++;\n return null;\n }\n const entry = validate(parsed);\n if (entry === null) {\n this.#misses++;\n return null;\n }\n this.#hits++;\n return entry;\n }\n async write(key, value) {\n const path = this.#path(key);\n const directory = dirname(path);\n if (!this.#created.has(directory)) {\n await mkdir(directory, { recursive: true });\n this.#created.add(directory);\n }\n const temporaryPath = `${path}.${process.pid}-${randomBytes(6).toString(\"hex\")}.tmp`;\n await writeFile(temporaryPath, `${stableStringify(value)}\n`, \"utf8\");\n await rename(temporaryPath, path);\n this.#writes++;\n this.#writesSincePrune++;\n const batch = Math.max(1, Math.floor(this.maxEntries / 4));\n if (!this.#prunedThisProcess || this.#writesSincePrune >= batch) {\n this.#prunedThisProcess = true;\n this.#writesSincePrune = 0;\n await this.#prune();\n }\n }\n /**\n * Drops the oldest entries once the store exceeds its cap, oldest by the later\n * of read and write time so an entry a build keeps hitting is not treated as\n * dead on filesystems that maintain access times.\n */\n async #prune() {\n const versionRoot = join(this.root, `v${this.schemaVersion}`);\n let shards;\n try {\n shards = await readdir(versionRoot);\n } catch {\n return;\n }\n const paths = [];\n for (const shard of shards) {\n const directory = join(versionRoot, shard);\n let files;\n try {\n files = await readdir(directory);\n } catch {\n continue;\n }\n for (const file of files) {\n if (file.endsWith(\".json\")) paths.push(join(directory, file));\n }\n }\n if (paths.length <= this.maxEntries) return;\n const entries = [];\n for (const path of paths) {\n try {\n const stats = await stat(path);\n entries.push({ path, usedAt: Math.max(stats.atimeMs, stats.mtimeMs) });\n } catch {\n }\n }\n entries.sort((left, right) => left.usedAt - right.usedAt);\n for (const entry of entries.slice(0, Math.max(0, entries.length - this.maxEntries))) {\n await unlink(entry.path).catch(() => {\n });\n }\n }\n}\nclass ModulePlanCache {\n constructor(root) {\n this.root = root;\n this.#files = new JsonFileCache(root, PLAN_CACHE_SCHEMA_VERSION);\n }\n root;\n #files;\n get stats() {\n return this.#files.stats;\n }\n resetStats() {\n this.#files.resetStats();\n }\n read(key, id, closureDigest) {\n return this.#files.read(key, (value) => {\n const entry = value;\n const plan = entry?.plan;\n return entry?.schemaVersion === PLAN_CACHE_SCHEMA_VERSION && entry.moduleId === id && entry.closureDigest === closureDigest && plan && plan.version === LOWERED_MODULE_PLAN_VERSION && plan.id === id && typeof plan.sourceHash === \"string\" && typeof plan.css === \"string\" && Array.isArray(plan.edits) && Array.isArray(plan.diagnostics) && Array.isArray(plan.dependencies) && !!plan.stats ? entry : null;\n });\n }\n write(key, entry) {\n return this.#files.write(key, entry);\n }\n}\nexport {\n JsonFileCache,\n ModulePlanCache,\n PLAN_CACHE_MAX_ENTRIES,\n PLAN_CACHE_SCHEMA_VERSION,\n defaultPlanCacheRoot,\n moduleClosureDigest,\n moduleClosureNode,\n planCacheKey,\n tamaguiCacheRoot\n};\n//# sourceMappingURL=planCache.js.map\n"],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { ProjectGraph } from "./graph.mjs";
2
+ import { lowerModule } from "./lower.mjs";
3
+ import { materializeModule } from "./materialize.mjs";
4
+ import { applyLoweredModule } from "./output.mjs";
5
+ import { PLAN_CACHE_SCHEMA_VERSION, moduleClosureDigest, planCacheKey } from "./planCache.mjs";
6
+ import { yukuFactory } from "./yuku.mjs";
7
+
8
+ function compareIds(left, right) {
9
+ return left < right ? -1 : left > right ? 1 : 0;
10
+ }
11
+ var CompilerSession = class {
12
+ #graph = new ProjectGraph(yukuFactory, { modules: [] });
13
+ #queue = Promise.resolve();
14
+ compile(input) {
15
+ const operation = this.#queue.then(() => this.#compile(input));
16
+ this.#queue = operation.catch(() => void 0);
17
+ return operation;
18
+ }
19
+ update(module) {
20
+ return this.#enqueue(() => this.#graph.updateModule(module).invalidatedIds);
21
+ }
22
+ has(id) {
23
+ return this.#graph.contentHash(id) !== null;
24
+ }
25
+ dependentsOf(id) {
26
+ return this.#graph.dependentsOf(id);
27
+ }
28
+ remove(id) {
29
+ return this.#enqueue(() => this.#graph.removeModule(id));
30
+ }
31
+ parseCount(id) {
32
+ return this.#graph.parseCount(id);
33
+ }
34
+ #enqueue(operation) {
35
+ const queued = this.#queue.then(operation);
36
+ this.#queue = queued.catch(() => void 0);
37
+ return queued;
38
+ }
39
+ async #compile({ module, adapter, structuralPass }) {
40
+ const invalidated = /* @__PURE__ */ new Set();
41
+ await this.#install(module, adapter, /* @__PURE__ */ new Set(), invalidated);
42
+ const graph = this.#graph;
43
+ const cache = adapter.planCache?.stamp ? adapter.planCache : null;
44
+ const closureDigest = cache ? moduleClosureDigest(module.id, (id) => {
45
+ const hash = graph.contentHash(id);
46
+ return hash ? {
47
+ contentHash: hash,
48
+ dependencies: graph.dependenciesOf(id)
49
+ } : null;
50
+ }) : null;
51
+ const entry = cache && closureDigest ? {
52
+ store: cache.store,
53
+ digest: closureDigest,
54
+ key: planCacheKey({
55
+ stamp: cache.stamp,
56
+ target: adapter.target,
57
+ structuralPassHash: structuralPass?.versionHash ?? `${adapter.target}-noop-v1`
58
+ }, module.id, closureDigest)
59
+ } : null;
60
+ const cached = entry ? await entry.store.read(entry.key, module.id, entry.digest) : null;
61
+ const plan = cached?.plan ?? lowerModule({
62
+ module: materializeModule(graph, module.id),
63
+ source: module.source,
64
+ target: adapter.target,
65
+ host: adapter.host,
66
+ options: { projectGeneration: adapter.projectGeneration },
67
+ structuralPass
68
+ });
69
+ if (entry && !cached) {
70
+ await entry.store.write(entry.key, {
71
+ schemaVersion: PLAN_CACHE_SCHEMA_VERSION,
72
+ moduleId: module.id,
73
+ closureDigest: entry.digest,
74
+ plan
75
+ });
76
+ }
77
+ return {
78
+ plan,
79
+ output: applyLoweredModule(module.source, module.id, plan),
80
+ invalidatedIds: [...invalidated].sort(compareIds)
81
+ };
82
+ }
83
+ async #install(module, adapter, visited, invalidated) {
84
+ if (visited.has(module.id)) return;
85
+ visited.add(module.id);
86
+ for (const dependency of module.imports) {
87
+ if (dependency.external || this.has(dependency.resolvedId)) continue;
88
+ const loaded = await adapter.load(dependency.resolvedId);
89
+ if (loaded) {
90
+ await this.#install(loaded, adapter, visited, invalidated);
91
+ }
92
+ }
93
+ const update = this.#graph.updateModule(module);
94
+ for (const id of update.invalidatedIds) invalidated.add(id);
95
+ }
96
+ };
97
+
98
+ export { CompilerSession };
99
+ //# sourceMappingURL=session.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","names":["#queue","#compile","#enqueue","#graph","#install"],"sources":["esm/session.js"],"sourcesContent":["import { ProjectGraph } from \"./graph\";\nimport { lowerModule } from \"./lower\";\nimport { materializeModule } from \"./materialize\";\nimport { applyLoweredModule } from \"./output\";\nimport { PLAN_CACHE_SCHEMA_VERSION, moduleClosureDigest, planCacheKey } from \"./planCache\";\nimport { yukuFactory } from \"./yuku\";\nfunction compareIds(left, right) {\n return left < right ? -1 : left > right ? 1 : 0;\n}\nclass CompilerSession {\n #graph = new ProjectGraph(yukuFactory, { modules: [] });\n #queue = Promise.resolve();\n compile(input) {\n const operation = this.#queue.then(() => this.#compile(input));\n this.#queue = operation.catch(() => void 0);\n return operation;\n }\n update(module) {\n return this.#enqueue(() => this.#graph.updateModule(module).invalidatedIds);\n }\n has(id) {\n return this.#graph.contentHash(id) !== null;\n }\n dependentsOf(id) {\n return this.#graph.dependentsOf(id);\n }\n remove(id) {\n return this.#enqueue(() => this.#graph.removeModule(id));\n }\n parseCount(id) {\n return this.#graph.parseCount(id);\n }\n #enqueue(operation) {\n const queued = this.#queue.then(operation);\n this.#queue = queued.catch(() => void 0);\n return queued;\n }\n async #compile({\n module,\n adapter,\n structuralPass\n }) {\n const invalidated = /* @__PURE__ */ new Set();\n await this.#install(module, adapter, /* @__PURE__ */ new Set(), invalidated);\n const graph = this.#graph;\n const cache = adapter.planCache?.stamp ? adapter.planCache : null;\n const closureDigest = cache ? moduleClosureDigest(module.id, (id) => {\n const hash = graph.contentHash(id);\n return hash ? { contentHash: hash, dependencies: graph.dependenciesOf(id) } : null;\n }) : null;\n const entry = cache && closureDigest ? {\n store: cache.store,\n digest: closureDigest,\n key: planCacheKey(\n {\n stamp: cache.stamp,\n target: adapter.target,\n structuralPassHash: structuralPass?.versionHash ?? `${adapter.target}-noop-v1`\n },\n module.id,\n closureDigest\n )\n } : null;\n const cached = entry ? await entry.store.read(entry.key, module.id, entry.digest) : null;\n const plan = cached?.plan ?? lowerModule({\n module: materializeModule(graph, module.id),\n source: module.source,\n target: adapter.target,\n host: adapter.host,\n options: { projectGeneration: adapter.projectGeneration },\n structuralPass\n });\n if (entry && !cached) {\n await entry.store.write(entry.key, {\n schemaVersion: PLAN_CACHE_SCHEMA_VERSION,\n moduleId: module.id,\n closureDigest: entry.digest,\n plan\n });\n }\n return {\n plan,\n output: applyLoweredModule(module.source, module.id, plan),\n invalidatedIds: [...invalidated].sort(compareIds)\n };\n }\n async #install(module, adapter, visited, invalidated) {\n if (visited.has(module.id)) return;\n visited.add(module.id);\n for (const dependency of module.imports) {\n if (dependency.external || this.has(dependency.resolvedId)) continue;\n const loaded = await adapter.load(dependency.resolvedId);\n if (loaded) {\n await this.#install(loaded, adapter, visited, invalidated);\n }\n }\n const update = this.#graph.updateModule(module);\n for (const id of update.invalidatedIds) invalidated.add(id);\n }\n}\nexport {\n CompilerSession\n};\n//# sourceMappingURL=session.js.map\n"],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ import { Analyzer } from "yuku-analyzer";
2
+ import { resolveFromHost, resolvedModuleId } from "./contracts.mjs";
3
+ import { childNode, walkAst } from "./ast.mjs";
4
+ import { asAstNode, declarationForName, definitionFromDeclaration } from "./normalize.mjs";
5
+
6
+ var YukuCandidate = class {
7
+ constructor(project) {
8
+ this.project = project;
9
+ this.#analyzer = new Analyzer({ resolve: (specifier, importer) => resolveFromHost(this.project.resolutions, specifier, importer) });
10
+ for (const [id, source] of project.files) this.addFile(id, source);
11
+ }
12
+ project;
13
+ name = "yuku";
14
+ #analyzer;
15
+ #parseCounts = /* @__PURE__ */ new Map();
16
+ addFile(id, source) {
17
+ this.#analyzer.addFile(id, source, {
18
+ preserveParens: true,
19
+ sourceType: "module"
20
+ });
21
+ this.#parseCounts.set(id, (this.#parseCounts.get(id) ?? 0) + 1);
22
+ }
23
+ removeFile(id) {
24
+ return this.#analyzer.removeFile(id);
25
+ }
26
+ link() {
27
+ this.#analyzer.link();
28
+ }
29
+ #module(id) {
30
+ const module = this.#analyzer.module(id);
31
+ if (!module) throw new Error(`yuku: unknown module ${id}`);
32
+ return module;
33
+ }
34
+ #canonicalSymbol(id, localName) {
35
+ const symbol = this.#module(id).resolve(localName);
36
+ return symbol ? this.#analyzer.definitionOf(symbol)?.symbol ?? null : null;
37
+ }
38
+ definitionOf(id, localName) {
39
+ const symbol = this.#canonicalSymbol(id, localName);
40
+ if (!symbol) return null;
41
+ const declaration = symbol.declarations[0];
42
+ if (!declaration) return null;
43
+ const program = asAstNode(symbol.module.ast, `${symbol.module.path} program`);
44
+ const normalizedDeclaration = declarationForName(program, symbol.name) ?? asAstNode(declaration, `${symbol.name} declaration`);
45
+ return definitionFromDeclaration(symbol.module.path, symbol.name, program, normalizedDeclaration);
46
+ }
47
+ referencesOf(definition) {
48
+ const symbol = this.#canonicalSymbol(definition.id, definition.name);
49
+ if (!symbol) return [];
50
+ return this.#analyzer.referencesOf(symbol).map(({ module, reference }) => ({
51
+ id: resolvedModuleId(module.path),
52
+ name: reference.name,
53
+ start: reference.node.start,
54
+ end: reference.node.end
55
+ }));
56
+ }
57
+ dependenciesOf(id) {
58
+ return this.#module(id).dependencies.map((module) => module.path).sort();
59
+ }
60
+ dependentsOf(id) {
61
+ return this.#module(id).dependents.map((module) => module.path).sort();
62
+ }
63
+ affectedBy(id) {
64
+ const affected = /* @__PURE__ */ new Set([id]);
65
+ const queue = [id];
66
+ while (queue.length) {
67
+ const current = queue.shift();
68
+ for (const dependent of this.dependentsOf(current)) {
69
+ if (!affected.has(dependent)) {
70
+ affected.add(dependent);
71
+ queue.push(dependent);
72
+ }
73
+ }
74
+ }
75
+ return [...affected].sort();
76
+ }
77
+ programOf(id) {
78
+ return asAstNode(this.#module(id).ast, `${id} program`);
79
+ }
80
+ sourceOf(id) {
81
+ return this.#module(id).source;
82
+ }
83
+ parseCount(id) {
84
+ return this.#parseCounts.get(id) ?? 0;
85
+ }
86
+ diagnostics() {
87
+ const parseDiagnostics = [...this.#analyzer.modules.values()].flatMap((module) => module.diagnostics.map((diagnostic) => ({
88
+ kind: "parse",
89
+ id: resolvedModuleId(module.path),
90
+ message: diagnostic.message
91
+ })));
92
+ return [...parseDiagnostics, ...this.#analyzer.diagnostics.map((diagnostic) => ({
93
+ kind: "link",
94
+ id: resolvedModuleId(diagnostic.module),
95
+ message: diagnostic.message
96
+ }))];
97
+ }
98
+ };
99
+ const yukuFactory = {
100
+ name: "yuku",
101
+ create: (project) => new YukuCandidate(project),
102
+ scanImports(id, source) {
103
+ const candidate = new YukuCandidate({
104
+ files: /* @__PURE__ */ new Map([[id, source]]),
105
+ resolutions: /* @__PURE__ */ new Map()
106
+ });
107
+ const found = [];
108
+ walkAst(candidate.programOf(id), (node) => {
109
+ if (node.type !== "ImportDeclaration" && node.type !== "ExportNamedDeclaration" && node.type !== "ExportAllDeclaration" && node.type !== "ImportExpression") {
110
+ return;
111
+ }
112
+ const sourceNode = childNode(node, "source");
113
+ if (sourceNode && typeof sourceNode.value === "string") {
114
+ found.push({
115
+ start: node.start,
116
+ specifier: sourceNode.value
117
+ });
118
+ }
119
+ });
120
+ return [...new Set(found.sort((left, right) => left.start - right.start).map(({ specifier }) => specifier))];
121
+ }
122
+ };
123
+ function parseModuleAst(source, id = "/tamagui/compiler-module.tsx") {
124
+ const candidate = yukuFactory.create({
125
+ files: /* @__PURE__ */ new Map([[id, source]]),
126
+ resolutions: /* @__PURE__ */ new Map()
127
+ });
128
+ const diagnostics = candidate.diagnostics().filter((diagnostic) => diagnostic.kind === "parse");
129
+ if (diagnostics.length) {
130
+ throw new Error(`Unable to parse ${id}: ${diagnostics.map(({ message }) => message).join("; ")}`);
131
+ }
132
+ return candidate.programOf(id);
133
+ }
134
+
135
+ export { parseModuleAst, yukuFactory };
136
+ //# sourceMappingURL=yuku.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yuku.js","names":["#analyzer","#parseCounts","#module","#canonicalSymbol"],"sources":["esm/yuku.js"],"sourcesContent":["import { Analyzer } from \"yuku-analyzer\";\nimport { resolveFromHost, resolvedModuleId } from \"./contracts\";\nimport { childNode, walkAst } from \"./ast\";\nimport { asAstNode, declarationForName, definitionFromDeclaration } from \"./normalize\";\nclass YukuCandidate {\n constructor(project) {\n this.project = project;\n this.#analyzer = new Analyzer({\n resolve: (specifier, importer) => resolveFromHost(this.project.resolutions, specifier, importer)\n });\n for (const [id, source] of project.files) this.addFile(id, source);\n }\n project;\n name = \"yuku\";\n #analyzer;\n #parseCounts = /* @__PURE__ */ new Map();\n addFile(id, source) {\n this.#analyzer.addFile(id, source, { preserveParens: true, sourceType: \"module\" });\n this.#parseCounts.set(id, (this.#parseCounts.get(id) ?? 0) + 1);\n }\n removeFile(id) {\n return this.#analyzer.removeFile(id);\n }\n link() {\n this.#analyzer.link();\n }\n #module(id) {\n const module = this.#analyzer.module(id);\n if (!module) throw new Error(`yuku: unknown module ${id}`);\n return module;\n }\n #canonicalSymbol(id, localName) {\n const symbol = this.#module(id).resolve(localName);\n return symbol ? this.#analyzer.definitionOf(symbol)?.symbol ?? null : null;\n }\n definitionOf(id, localName) {\n const symbol = this.#canonicalSymbol(id, localName);\n if (!symbol) return null;\n const declaration = symbol.declarations[0];\n if (!declaration) return null;\n const program = asAstNode(symbol.module.ast, `${symbol.module.path} program`);\n const normalizedDeclaration = declarationForName(program, symbol.name) ?? asAstNode(declaration, `${symbol.name} declaration`);\n return definitionFromDeclaration(\n symbol.module.path,\n symbol.name,\n program,\n normalizedDeclaration\n );\n }\n referencesOf(definition) {\n const symbol = this.#canonicalSymbol(definition.id, definition.name);\n if (!symbol) return [];\n return this.#analyzer.referencesOf(symbol).map(({ module, reference }) => ({\n id: resolvedModuleId(module.path),\n name: reference.name,\n start: reference.node.start,\n end: reference.node.end\n }));\n }\n dependenciesOf(id) {\n return this.#module(id).dependencies.map((module) => module.path).sort();\n }\n dependentsOf(id) {\n return this.#module(id).dependents.map((module) => module.path).sort();\n }\n affectedBy(id) {\n const affected = /* @__PURE__ */ new Set([id]);\n const queue = [id];\n while (queue.length) {\n const current = queue.shift();\n for (const dependent of this.dependentsOf(current)) {\n if (!affected.has(dependent)) {\n affected.add(dependent);\n queue.push(dependent);\n }\n }\n }\n return [...affected].sort();\n }\n programOf(id) {\n return asAstNode(this.#module(id).ast, `${id} program`);\n }\n sourceOf(id) {\n return this.#module(id).source;\n }\n parseCount(id) {\n return this.#parseCounts.get(id) ?? 0;\n }\n diagnostics() {\n const parseDiagnostics = [...this.#analyzer.modules.values()].flatMap(\n (module) => module.diagnostics.map((diagnostic) => ({\n kind: \"parse\",\n id: resolvedModuleId(module.path),\n message: diagnostic.message\n }))\n );\n return [\n ...parseDiagnostics,\n ...this.#analyzer.diagnostics.map((diagnostic) => ({\n kind: \"link\",\n id: resolvedModuleId(diagnostic.module),\n message: diagnostic.message\n }))\n ];\n }\n}\nconst yukuFactory = {\n name: \"yuku\",\n create: (project) => new YukuCandidate(project),\n scanImports(id, source) {\n const candidate = new YukuCandidate({\n files: /* @__PURE__ */ new Map([[id, source]]),\n resolutions: /* @__PURE__ */ new Map()\n });\n const found = [];\n walkAst(candidate.programOf(id), (node) => {\n if (node.type !== \"ImportDeclaration\" && node.type !== \"ExportNamedDeclaration\" && node.type !== \"ExportAllDeclaration\" && node.type !== \"ImportExpression\") {\n return;\n }\n const sourceNode = childNode(node, \"source\");\n if (sourceNode && typeof sourceNode.value === \"string\") {\n found.push({ start: node.start, specifier: sourceNode.value });\n }\n });\n return [\n ...new Set(\n found.sort((left, right) => left.start - right.start).map(({ specifier }) => specifier)\n )\n ];\n }\n};\nfunction parseModuleAst(source, id = \"/tamagui/compiler-module.tsx\") {\n const candidate = yukuFactory.create({\n files: /* @__PURE__ */ new Map([[id, source]]),\n resolutions: /* @__PURE__ */ new Map()\n });\n const diagnostics = candidate.diagnostics().filter((diagnostic) => diagnostic.kind === \"parse\");\n if (diagnostics.length) {\n throw new Error(\n `Unable to parse ${id}: ${diagnostics.map(({ message }) => message).join(\"; \")}`\n );\n }\n return candidate.programOf(id);\n}\nexport {\n parseModuleAst,\n yukuFactory\n};\n//# sourceMappingURL=yuku.js.map\n"],"mappings":";;;;;;AAIA,IAAM,gBAAN,MAAoB;CAClB,YAAY,SAAS;EACnB,KAAK,UAAU;EACf,KAAKA,YAAY,IAAI,SAAS,EAC5B,UAAU,WAAW,aAAa,gBAAgB,KAAK,QAAQ,aAAa,WAAW,QAAQ,EACjG,CAAC;EACD,KAAK,MAAM,CAAC,IAAI,WAAW,QAAQ,OAAO,KAAK,QAAQ,IAAI,MAAM;CACnE;CACA;CACA,OAAO;CACP;CACA,+BAA+B,IAAI,IAAI;CACvC,QAAQ,IAAI,QAAQ;EAClB,KAAKA,UAAU,QAAQ,IAAI,QAAQ;GAAE,gBAAgB;GAAM,YAAY;EAAS,CAAC;EACjF,KAAKC,aAAa,IAAI,KAAK,KAAKA,aAAa,IAAI,EAAE,KAAK,KAAK,CAAC;CAChE;CACA,WAAW,IAAI;EACb,OAAO,KAAKD,UAAU,WAAW,EAAE;CACrC;CACA,OAAO;EACL,KAAKA,UAAU,KAAK;CACtB;CACA,QAAQ,IAAI;EACV,MAAM,SAAS,KAAKA,UAAU,OAAO,EAAE;EACvC,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,wBAAwB,IAAI;EACzD,OAAO;CACT;CACA,iBAAiB,IAAI,WAAW;EAC9B,MAAM,SAAS,KAAKE,QAAQ,EAAE,EAAE,QAAQ,SAAS;EACjD,OAAO,SAAS,KAAKF,UAAU,aAAa,MAAM,GAAG,UAAU,OAAO;CACxE;CACA,aAAa,IAAI,WAAW;EAC1B,MAAM,SAAS,KAAKG,iBAAiB,IAAI,SAAS;EAClD,IAAI,CAAC,QAAQ,OAAO;EACpB,MAAM,cAAc,OAAO,aAAa;EACxC,IAAI,CAAC,aAAa,OAAO;EACzB,MAAM,UAAU,UAAU,OAAO,OAAO,KAAK,GAAG,OAAO,OAAO,KAAK,SAAS;EAC5E,MAAM,wBAAwB,mBAAmB,SAAS,OAAO,IAAI,KAAK,UAAU,aAAa,GAAG,OAAO,KAAK,aAAa;EAC7H,OAAO,0BACL,OAAO,OAAO,MACd,OAAO,MACP,SACA,qBACF;CACF;CACA,aAAa,YAAY;EACvB,MAAM,SAAS,KAAKA,iBAAiB,WAAW,IAAI,WAAW,IAAI;EACnE,IAAI,CAAC,QAAQ,OAAO,CAAC;EACrB,OAAO,KAAKH,UAAU,aAAa,MAAM,EAAE,KAAK,EAAE,QAAQ,iBAAiB;GACzE,IAAI,iBAAiB,OAAO,IAAI;GAChC,MAAM,UAAU;GAChB,OAAO,UAAU,KAAK;GACtB,KAAK,UAAU,KAAK;EACtB,EAAE;CACJ;CACA,eAAe,IAAI;EACjB,OAAO,KAAKE,QAAQ,EAAE,EAAE,aAAa,KAAK,WAAW,OAAO,IAAI,EAAE,KAAK;CACzE;CACA,aAAa,IAAI;EACf,OAAO,KAAKA,QAAQ,EAAE,EAAE,WAAW,KAAK,WAAW,OAAO,IAAI,EAAE,KAAK;CACvE;CACA,WAAW,IAAI;EACb,MAAM,2BAA2B,IAAI,IAAI,CAAC,EAAE,CAAC;EAC7C,MAAM,QAAQ,CAAC,EAAE;EACjB,OAAO,MAAM,QAAQ;GACnB,MAAM,UAAU,MAAM,MAAM;GAC5B,KAAK,MAAM,aAAa,KAAK,aAAa,OAAO,GAAG;IAClD,IAAI,CAAC,SAAS,IAAI,SAAS,GAAG;KAC5B,SAAS,IAAI,SAAS;KACtB,MAAM,KAAK,SAAS;IACtB;GACF;EACF;EACA,OAAO,CAAC,GAAG,QAAQ,EAAE,KAAK;CAC5B;CACA,UAAU,IAAI;EACZ,OAAO,UAAU,KAAKA,QAAQ,EAAE,EAAE,KAAK,GAAG,GAAG,SAAS;CACxD;CACA,SAAS,IAAI;EACX,OAAO,KAAKA,QAAQ,EAAE,EAAE;CAC1B;CACA,WAAW,IAAI;EACb,OAAO,KAAKD,aAAa,IAAI,EAAE,KAAK;CACtC;CACA,cAAc;EACZ,MAAM,mBAAmB,CAAC,GAAG,KAAKD,UAAU,QAAQ,OAAO,CAAC,EAAE,SAC3D,WAAW,OAAO,YAAY,KAAK,gBAAgB;GAClD,MAAM;GACN,IAAI,iBAAiB,OAAO,IAAI;GAChC,SAAS,WAAW;EACtB,EAAE,CACJ;EACA,OAAO,CACL,GAAG,kBACH,GAAG,KAAKA,UAAU,YAAY,KAAK,gBAAgB;GACjD,MAAM;GACN,IAAI,iBAAiB,WAAW,MAAM;GACtC,SAAS,WAAW;EACtB,EAAE,CACJ;CACF;AACF;AACA,MAAM,cAAc;CAClB,MAAM;CACN,SAAS,YAAY,IAAI,cAAc,OAAO;CAC9C,YAAY,IAAI,QAAQ;EACtB,MAAM,YAAY,IAAI,cAAc;GAClC,uBAAuB,IAAI,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;GAC7C,6BAA6B,IAAI,IAAI;EACvC,CAAC;EACD,MAAM,QAAQ,CAAC;EACf,QAAQ,UAAU,UAAU,EAAE,IAAI,SAAS;GACzC,IAAI,KAAK,SAAS,uBAAuB,KAAK,SAAS,4BAA4B,KAAK,SAAS,0BAA0B,KAAK,SAAS,oBAAoB;IAC3J;GACF;GACA,MAAM,aAAa,UAAU,MAAM,QAAQ;GAC3C,IAAI,cAAc,OAAO,WAAW,UAAU,UAAU;IACtD,MAAM,KAAK;KAAE,OAAO,KAAK;KAAO,WAAW,WAAW;IAAM,CAAC;GAC/D;EACF,CAAC;EACD,OAAO,CACL,GAAG,IAAI,IACL,MAAM,MAAM,MAAM,UAAU,KAAK,QAAQ,MAAM,KAAK,EAAE,KAAK,EAAE,gBAAgB,SAAS,CACxF,CACF;CACF;AACF;AACA,SAAS,eAAe,QAAQ,KAAK,gCAAgC;CACnE,MAAM,YAAY,YAAY,OAAO;EACnC,uBAAuB,IAAI,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;EAC7C,6BAA6B,IAAI,IAAI;CACvC,CAAC;CACD,MAAM,cAAc,UAAU,YAAY,EAAE,QAAQ,eAAe,WAAW,SAAS,OAAO;CAC9F,IAAI,YAAY,QAAQ;EACtB,MAAM,IAAI,MACR,mBAAmB,GAAG,IAAI,YAAY,KAAK,EAAE,cAAc,OAAO,EAAE,KAAK,IAAI,GAC/E;CACF;CACA,OAAO,UAAU,UAAU,EAAE;AAC/B"}