@notionx/create-notionx-app 1.0.0

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 (239) hide show
  1. package/README.md +139 -0
  2. package/dist/answers.js +332 -0
  3. package/dist/answers.js.map +1 -0
  4. package/dist/cli-notionx.js +388 -0
  5. package/dist/cli-notionx.js.map +1 -0
  6. package/dist/cli-notionx.test.js +277 -0
  7. package/dist/cli-notionx.test.js.map +1 -0
  8. package/dist/diff.js +40 -0
  9. package/dist/diff.js.map +1 -0
  10. package/dist/diff.test.js +90 -0
  11. package/dist/diff.test.js.map +1 -0
  12. package/dist/index.js +99 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/locale-add/apply.js +39 -0
  15. package/dist/locale-add/apply.js.map +1 -0
  16. package/dist/locale-add/format.js +38 -0
  17. package/dist/locale-add/format.js.map +1 -0
  18. package/dist/locale-add/list.js +44 -0
  19. package/dist/locale-add/list.js.map +1 -0
  20. package/dist/locale-add/list.test.js +45 -0
  21. package/dist/locale-add/list.test.js.map +1 -0
  22. package/dist/locale-add/plan.js +128 -0
  23. package/dist/locale-add/plan.js.map +1 -0
  24. package/dist/locale-add/validate.js +46 -0
  25. package/dist/locale-add/validate.js.map +1 -0
  26. package/dist/metadata.js +41 -0
  27. package/dist/metadata.js.map +1 -0
  28. package/dist/notion-translation-sources/apply.js +61 -0
  29. package/dist/notion-translation-sources/apply.js.map +1 -0
  30. package/dist/notion-translation-sources/index.js +3 -0
  31. package/dist/notion-translation-sources/index.js.map +1 -0
  32. package/dist/notion-translation-sources/plan.js +33 -0
  33. package/dist/notion-translation-sources/plan.js.map +1 -0
  34. package/dist/notionx-source.js +142 -0
  35. package/dist/notionx-source.js.map +1 -0
  36. package/dist/notionx-source.test.js +144 -0
  37. package/dist/notionx-source.test.js.map +1 -0
  38. package/dist/password.js +18 -0
  39. package/dist/password.js.map +1 -0
  40. package/dist/presets.js +83 -0
  41. package/dist/presets.js.map +1 -0
  42. package/dist/presets.test.js +50 -0
  43. package/dist/presets.test.js.map +1 -0
  44. package/dist/prompt.js +218 -0
  45. package/dist/prompt.js.map +1 -0
  46. package/dist/provision/cloudflare.js +236 -0
  47. package/dist/provision/cloudflare.js.map +1 -0
  48. package/dist/provision/dependencies.js +219 -0
  49. package/dist/provision/dependencies.js.map +1 -0
  50. package/dist/provision/index.js +681 -0
  51. package/dist/provision/index.js.map +1 -0
  52. package/dist/provision/index.test.js +54 -0
  53. package/dist/provision/index.test.js.map +1 -0
  54. package/dist/provision/inspect.js +109 -0
  55. package/dist/provision/inspect.js.map +1 -0
  56. package/dist/provision/inspect.test.js +75 -0
  57. package/dist/provision/inspect.test.js.map +1 -0
  58. package/dist/provision/notion.js +1981 -0
  59. package/dist/provision/notion.js.map +1 -0
  60. package/dist/provision/notion.test.js +542 -0
  61. package/dist/provision/notion.test.js.map +1 -0
  62. package/dist/provision/ntn-credentials.js +198 -0
  63. package/dist/provision/ntn-credentials.js.map +1 -0
  64. package/dist/provision/options.js +15 -0
  65. package/dist/provision/options.js.map +1 -0
  66. package/dist/provision/password-hash.js +78 -0
  67. package/dist/provision/password-hash.js.map +1 -0
  68. package/dist/provision/prompts.js +115 -0
  69. package/dist/provision/prompts.js.map +1 -0
  70. package/dist/provision/repair.js +48 -0
  71. package/dist/provision/repair.js.map +1 -0
  72. package/dist/provision/repair.test.js +141 -0
  73. package/dist/provision/repair.test.js.map +1 -0
  74. package/dist/provision/shell.js +84 -0
  75. package/dist/provision/shell.js.map +1 -0
  76. package/dist/provision/wire.js +78 -0
  77. package/dist/provision/wire.js.map +1 -0
  78. package/dist/registry/doctor.js +181 -0
  79. package/dist/registry/doctor.js.map +1 -0
  80. package/dist/registry/doctor.test.js +180 -0
  81. package/dist/registry/doctor.test.js.map +1 -0
  82. package/dist/registry/install.js +217 -0
  83. package/dist/registry/install.js.map +1 -0
  84. package/dist/registry/install.test.js +168 -0
  85. package/dist/registry/install.test.js.map +1 -0
  86. package/dist/registry/load-registry.js +24 -0
  87. package/dist/registry/load-registry.js.map +1 -0
  88. package/dist/registry/load-registry.test.js +59 -0
  89. package/dist/registry/load-registry.test.js.map +1 -0
  90. package/dist/registry/migration-planner.js +204 -0
  91. package/dist/registry/migration-planner.js.map +1 -0
  92. package/dist/registry/migration-planner.test.js +340 -0
  93. package/dist/registry/migration-planner.test.js.map +1 -0
  94. package/dist/registry/migrations-store.js +125 -0
  95. package/dist/registry/migrations-store.js.map +1 -0
  96. package/dist/registry/migrations-store.test.js +163 -0
  97. package/dist/registry/migrations-store.test.js.map +1 -0
  98. package/dist/registry/migrations-types.js +25 -0
  99. package/dist/registry/migrations-types.js.map +1 -0
  100. package/dist/registry/project-meta.js +84 -0
  101. package/dist/registry/project-meta.js.map +1 -0
  102. package/dist/registry/registry-items.js +354 -0
  103. package/dist/registry/registry-items.js.map +1 -0
  104. package/dist/registry/registry-items.test.js +99 -0
  105. package/dist/registry/registry-items.test.js.map +1 -0
  106. package/dist/registry/registry-store.js +232 -0
  107. package/dist/registry/registry-store.js.map +1 -0
  108. package/dist/registry/registry-store.test.js +136 -0
  109. package/dist/registry/registry-store.test.js.map +1 -0
  110. package/dist/registry/registry-types.js +18 -0
  111. package/dist/registry/registry-types.js.map +1 -0
  112. package/dist/registry/registry-types.test.js +146 -0
  113. package/dist/registry/registry-types.test.js.map +1 -0
  114. package/dist/registry/render-content-source-files.js +158 -0
  115. package/dist/registry/render-content-source-files.js.map +1 -0
  116. package/dist/registry/render-multi-source.js +296 -0
  117. package/dist/registry/render-multi-source.js.map +1 -0
  118. package/dist/registry/render-multi-source.test.js +110 -0
  119. package/dist/registry/render-multi-source.test.js.map +1 -0
  120. package/dist/registry/text-utils.js +42 -0
  121. package/dist/registry/text-utils.js.map +1 -0
  122. package/dist/registry/uninstall.js +250 -0
  123. package/dist/registry/uninstall.js.map +1 -0
  124. package/dist/registry/uninstall.test.js +264 -0
  125. package/dist/registry/uninstall.test.js.map +1 -0
  126. package/dist/registry/update.js +280 -0
  127. package/dist/registry/update.js.map +1 -0
  128. package/dist/registry/update.test.js +229 -0
  129. package/dist/registry/update.test.js.map +1 -0
  130. package/dist/render.js +549 -0
  131. package/dist/render.js.map +1 -0
  132. package/dist/render.test.js +414 -0
  133. package/dist/render.test.js.map +1 -0
  134. package/dist/templates/.dev.vars.example.tmpl +32 -0
  135. package/dist/templates/.gitignore.tmpl +58 -0
  136. package/dist/templates/README.md.tmpl +417 -0
  137. package/dist/templates/app/[slug]/page.tsx.tmpl +55 -0
  138. package/dist/templates/app/admin/account/page.tsx.tmpl +18 -0
  139. package/dist/templates/app/admin/content-models/page.tsx.tmpl +6 -0
  140. package/dist/templates/app/admin/layout.tsx.tmpl +90 -0
  141. package/dist/templates/app/admin/loading.tsx.tmpl +6 -0
  142. package/dist/templates/app/admin/page.tsx.tmpl +17 -0
  143. package/dist/templates/app/api/auth/google/callback/route.ts.tmpl +3 -0
  144. package/dist/templates/app/api/auth/google/route.ts.tmpl +3 -0
  145. package/dist/templates/app/api/auth/verify-email/route.ts.tmpl +3 -0
  146. package/dist/templates/app/api/auth/viewer/route.ts.tmpl +3 -0
  147. package/dist/templates/app/api/health/route.ts.tmpl +3 -0
  148. package/dist/templates/app/api/{{contentSourceId}}/[slug]/route.ts.tmpl +27 -0
  149. package/dist/templates/app/api/{{contentSourceId}}/route.ts.tmpl +18 -0
  150. package/dist/templates/app/globals.css.tmpl +109 -0
  151. package/dist/templates/app/layout.tsx.tmpl +56 -0
  152. package/dist/templates/app/login/page.tsx.tmpl +154 -0
  153. package/dist/templates/app/page.fallback.tsx.tmpl +31 -0
  154. package/dist/templates/app/page.tsx.tmpl +42 -0
  155. package/dist/templates/app/register/page.tsx.tmpl +138 -0
  156. package/dist/templates/app/{{contentSourceListPath}}/[slug]/page.tsx.tmpl +113 -0
  157. package/dist/templates/app/{{contentSourceListPath}}/page.tsx.tmpl +74 -0
  158. package/dist/templates/components/content/post-card.tsx.tmpl +80 -0
  159. package/dist/templates/components/notion-blocks.tsx.tmpl +668 -0
  160. package/dist/templates/components/page-blocks/feature-grid-block.tsx.tmpl +68 -0
  161. package/dist/templates/components/page-blocks/hero-block.tsx.tmpl +73 -0
  162. package/dist/templates/components/page-blocks/latest-posts-block.tsx.tmpl +59 -0
  163. package/dist/templates/components/page-blocks/story-block.tsx.tmpl +70 -0
  164. package/dist/templates/components/page-blocks.fallback.tsx.tmpl +17 -0
  165. package/dist/templates/components/page-blocks.tsx.tmpl +32 -0
  166. package/dist/templates/components/search/search-dialog.tsx.tmpl +171 -0
  167. package/dist/templates/components/site/locale-switcher.tsx.tmpl +65 -0
  168. package/dist/templates/components/site/site-footer.tsx.tmpl +106 -0
  169. package/dist/templates/components/site/site-header.tsx.tmpl +80 -0
  170. package/dist/templates/components/site/site-shell.tsx.tmpl +20 -0
  171. package/dist/templates/components/site/theme-bootstrap.tsx.tmpl +51 -0
  172. package/dist/templates/components/theme-provider.tsx.tmpl +14 -0
  173. package/dist/templates/components/theme-toggle.tsx.tmpl +38 -0
  174. package/dist/templates/components/ui/accordion.tsx.tmpl +56 -0
  175. package/dist/templates/components/ui/alert.tsx.tmpl +59 -0
  176. package/dist/templates/components/ui/aspect-ratio.tsx.tmpl +8 -0
  177. package/dist/templates/components/ui/avatar.tsx.tmpl +44 -0
  178. package/dist/templates/components/ui/badge.tsx.tmpl +33 -0
  179. package/dist/templates/components/ui/button.tsx.tmpl +56 -0
  180. package/dist/templates/components/ui/card.tsx.tmpl +61 -0
  181. package/dist/templates/components/ui/checkbox.tsx.tmpl +28 -0
  182. package/dist/templates/components/ui/dialog.tsx.tmpl +104 -0
  183. package/dist/templates/components/ui/dropdown-menu.tsx.tmpl +183 -0
  184. package/dist/templates/components/ui/input.tsx.tmpl +21 -0
  185. package/dist/templates/components/ui/label.tsx.tmpl +25 -0
  186. package/dist/templates/components/ui/popover.tsx.tmpl +30 -0
  187. package/dist/templates/components/ui/radio-group.tsx.tmpl +44 -0
  188. package/dist/templates/components/ui/select.tsx.tmpl +150 -0
  189. package/dist/templates/components/ui/separator.tsx.tmpl +30 -0
  190. package/dist/templates/components/ui/sheet.tsx.tmpl +125 -0
  191. package/dist/templates/components/ui/skeleton.tsx.tmpl +15 -0
  192. package/dist/templates/components/ui/sonner.tsx.tmpl +30 -0
  193. package/dist/templates/components/ui/switch.tsx.tmpl +29 -0
  194. package/dist/templates/components/ui/table.tsx.tmpl +107 -0
  195. package/dist/templates/components/ui/tabs.tsx.tmpl +55 -0
  196. package/dist/templates/components/ui/textarea.tsx.tmpl +24 -0
  197. package/dist/templates/components/ui/tooltip.tsx.tmpl +30 -0
  198. package/dist/templates/components.json.tmpl +21 -0
  199. package/dist/templates/env.d.ts.tmpl +32 -0
  200. package/dist/templates/lib/admin/actions.ts.tmpl +43 -0
  201. package/dist/templates/lib/admin/context.tsx.tmpl +209 -0
  202. package/dist/templates/lib/admin/nav.ts.tmpl +23 -0
  203. package/dist/templates/lib/auth.config.fallback.ts.tmpl +10 -0
  204. package/dist/templates/lib/auth.config.ts.tmpl +45 -0
  205. package/dist/templates/lib/blocks/translations.ts.tmpl +44 -0
  206. package/dist/templates/lib/blog/translations.ts.tmpl +52 -0
  207. package/dist/templates/lib/content/models.ts.tmpl +53 -0
  208. package/dist/templates/lib/i18n/config.ts.tmpl +18 -0
  209. package/dist/templates/lib/i18n/index.ts.tmpl +1 -0
  210. package/dist/templates/lib/locale-contract/built-in.ts.tmpl +19 -0
  211. package/dist/templates/lib/locale-contract/index.ts.tmpl +3 -0
  212. package/dist/templates/lib/locale-contract/paths.ts.tmpl +29 -0
  213. package/dist/templates/lib/pages/model.ts.tmpl +16 -0
  214. package/dist/templates/lib/pages/source.ts.tmpl +566 -0
  215. package/dist/templates/lib/pages/translations.ts.tmpl +34 -0
  216. package/dist/templates/lib/search/config.fallback.ts.tmpl +11 -0
  217. package/dist/templates/lib/search/config.ts.tmpl +25 -0
  218. package/dist/templates/lib/site/config.ts.tmpl +120 -0
  219. package/dist/templates/lib/site/request-env.ts.tmpl +71 -0
  220. package/dist/templates/lib/site/settings.fallback.ts.tmpl +21 -0
  221. package/dist/templates/lib/site/settings.ts.tmpl +320 -0
  222. package/dist/templates/lib/site/translations.ts.tmpl +30 -0
  223. package/dist/templates/lib/utils.ts.tmpl +9 -0
  224. package/dist/templates/migrations/0001_init.sql.tmpl +57 -0
  225. package/dist/templates/migrations/0002_admin_seed.sql.tmpl +30 -0
  226. package/dist/templates/migrations/0003_search_index.sql.tmpl +29 -0
  227. package/dist/templates/next.config.ts.tmpl +18 -0
  228. package/dist/templates/package.json.tmpl +40 -0
  229. package/dist/templates/shims/cloudflare-workers-empty.mjs +4 -0
  230. package/dist/templates/shims/next-headers-empty.mjs +4 -0
  231. package/dist/templates/tests/smoke.test.ts.tmpl +83 -0
  232. package/dist/templates/tsconfig.json.tmpl +31 -0
  233. package/dist/templates/vite.config.ts.tmpl +53 -0
  234. package/dist/templates/vitest.config.ts.tmpl +13 -0
  235. package/dist/templates/worker/index.ts.tmpl +52 -0
  236. package/dist/templates/wrangler.jsonc.tmpl +44 -0
  237. package/dist/ui-presets.js +60 -0
  238. package/dist/ui-presets.js.map +1 -0
  239. package/package.json +60 -0
package/dist/render.js ADDED
@@ -0,0 +1,549 @@
1
+ // packages/create-notionx-app/src/render.ts
2
+ //
3
+ // File renderer for `create-notionx-app`. Walks the `src/templates/`
4
+ // directory, copies static files verbatim, and renders `.tmpl` files
5
+ // with simple `{{token}}` interpolation. The token map is derived
6
+ // from the prompt answers.
7
+ import { promises as fs } from "node:fs";
8
+ import path from "node:path";
9
+ import { siteComponentNames, siteDependencyEntries } from "./presets.js";
10
+ import { hashPasswordForScaffold } from "./provision/password-hash.js";
11
+ import { buildInitialRegistryManifest, writeRegistryManifest, } from "./registry/registry-store.js";
12
+ import { buildMultiSourceTokenMap } from "./registry/render-multi-source.js";
13
+ import { toCamel } from "./registry/text-utils.js";
14
+ import { uiComponents } from "./ui-presets.js";
15
+ /** Local-part of an email, used as the default display name. */
16
+ function localPart(email) {
17
+ const at = email.indexOf("@");
18
+ return at > 0 ? email.slice(0, at) : email;
19
+ }
20
+ async function buildTokenMap(answers, scaffoldVersion) {
21
+ const id = answers.contentSource.id;
22
+ const isBlog = id === "blog";
23
+ // Build the field map block that the generated `defineContentSource`
24
+ // call interpolates. Indent every key/value so the call stays
25
+ // readable inside the `fields: { ... }` object literal.
26
+ const fieldMapLines = answers.contentSource.fields.map((f) => {
27
+ const key = f.key;
28
+ const notionName = JSON.stringify(f.notionName);
29
+ return ` ${key}: ${notionName},`;
30
+ });
31
+ const fieldMapBlock = fieldMapLines.join("\n");
32
+ // Hash the admin password with the same algorithm that
33
+ // `@notionx/core`'s `hashPassword` uses, so the generated
34
+ // `0002_admin_seed.sql` produces a row that `verifyPassword` can
35
+ // check on first login. 100k PBKDF2 iterations takes ~200ms on
36
+ // modern hardware — visible in the spinner, worth the wait.
37
+ const adminPasswordHash = await hashPasswordForScaffold(answers.adminPassword);
38
+ const uiComponentNames = uiComponents();
39
+ return {
40
+ projectName: answers.projectName,
41
+ projectNameLower: answers.projectName.toLowerCase(),
42
+ targetDir: answers.targetDir,
43
+ defaultLocale: answers.defaultLocale,
44
+ supportedLocales: answers.supportedLocales.join(", "),
45
+ supportedLocalesJson: JSON.stringify(answers.supportedLocales),
46
+ notionxSource: answers.notionxSource,
47
+ createNotionxAppVersion: `^${scaffoldVersion}`,
48
+ contentSourceId: id,
49
+ contentSourceTitle: answers.contentSource.title,
50
+ contentSourceKind: '"article"',
51
+ contentSourceListPath: `/${id}`,
52
+ contentSourceDetailPath: `/${id}/[slug]`,
53
+ contentSourceApiPath: `/api/${id}`,
54
+ contentSourceFields: fieldMapBlock,
55
+ contentSourceVarName: `${toCamel(id)}Source`,
56
+ contentSourceConstName: `${toCamel(id)}ContentModel`,
57
+ contentSourceNavLabel: answers.contentSource.title,
58
+ contentSourcePluralName: `${answers.contentSource.title}s`,
59
+ contentSourceListTitle: answers.contentSource.title,
60
+ contentSourceListDescription: isBlog
61
+ ? "Blog posts backed by Notion metadata and page body content."
62
+ : `${answers.contentSource.title} entries backed by Notion.`,
63
+ contentSourceEmptyState: isBlog
64
+ ? "No blog posts published yet."
65
+ : `No ${answers.contentSource.title.toLowerCase()} entries yet.`,
66
+ contentSourceRichBlocks: isBlog ? "true" : "false",
67
+ contentSourceCoverImages: isBlog ? "true" : "false",
68
+ fieldList: answers.contentSource.fields.map((f) => f.key).join(", "),
69
+ adminEmail: answers.adminEmail,
70
+ adminName: localPart(answers.adminEmail),
71
+ adminPasswordHash,
72
+ dependenciesBlock: buildDependenciesBlock(answers.notionxSource),
73
+ uiComponentList: uiComponentNames.map((name) => `\`${name}\``).join(", "),
74
+ uiComponents: uiComponentNames,
75
+ // Multi-source tokens: the scaffold flow always describes exactly
76
+ // one content source (the "first" one), so we synthesise a
77
+ // single-item InstalledItem list and delegate to the multi-source
78
+ // builder. `notionx add` will call `buildMultiSourceTokenMap`
79
+ // directly with the project's full installed list.
80
+ //
81
+ // The `MultiSourceTokenMap` returns `contentSourceSourcesBlock`
82
+ // (the full `defineContentSource` block). The legacy
83
+ // `contentSourceSourcesVarNames` token (used by the
84
+ // `contentSources = [...]` array) is derived from the
85
+ // comma-joined variable names embedded in that block.
86
+ ...(() => {
87
+ const multi = buildMultiSourceTokenMap({
88
+ project: {
89
+ projectName: answers.projectName,
90
+ targetDir: answers.targetDir,
91
+ defaultLocale: answers.defaultLocale,
92
+ supportedLocales: answers.supportedLocales,
93
+ notionxSource: answers.notionxSource,
94
+ adminEmail: answers.adminEmail,
95
+ adminPassword: answers.adminPassword,
96
+ scaffoldVersion,
97
+ },
98
+ installed: [
99
+ {
100
+ id: answers.contentSource.id,
101
+ kind: "content-source",
102
+ version: 1,
103
+ source: { kind: "official", name: "@notionx/official" },
104
+ params: {
105
+ contentSourceId: answers.contentSource.id,
106
+ ...(isBlog ? {} : { basePath: `/${answers.contentSource.id}` }),
107
+ },
108
+ installedAt: new Date(0).toISOString(),
109
+ },
110
+ ],
111
+ internalSources: {
112
+ siteSettings: answers.enableSiteSettings,
113
+ blocks: answers.enableBlocks,
114
+ },
115
+ });
116
+ return {
117
+ contentSourceDeclarations: multi.contentSourceDeclarations,
118
+ contentSourceSourcesVarNames: multi.contentSourceSourcesVarNames,
119
+ internalSourceDeclarations: multi.internalSourceDeclarations,
120
+ internalSourceVarNames: multi.internalSourceVarNames,
121
+ };
122
+ })(),
123
+ };
124
+ }
125
+ /**
126
+ * Build the `dependencies` block that goes into the generated
127
+ * `package.json`. The block is a JSON-style object body (4-space
128
+ * indent, no trailing comma) so it can be dropped between `{` and
129
+ * `}` in the template.
130
+ *
131
+ * The base dependency set is the union of every package the
132
+ * rendered components need. It is augmented by the preset's
133
+ * declared extras (e.g. `@radix-ui/react-accordion` for the
134
+ * `site` preset), filtered against the base set so we never emit
135
+ * duplicate keys.
136
+ */
137
+ function buildDependenciesBlock(notionxSource) {
138
+ // The base dependency set — every project needs these regardless
139
+ // of which UI components it vendors. Keep this list stable: it is
140
+ // the floor of every generated project.
141
+ const baseDependencies = [
142
+ ["@notionx/core", notionxSource],
143
+ ["class-variance-authority", "^0.7.1"],
144
+ ["clsx", "^2.1.1"],
145
+ ["lucide-react", "^0.460.0"],
146
+ ["next", "16.2.7"],
147
+ ["next-themes", "^0.4.4"],
148
+ ["react", "^19.2.7"],
149
+ ["react-dom", "^19.2.7"],
150
+ ["tailwind-merge", "^2.5.5"],
151
+ ["tailwindcss-animate", "^1.0.7"],
152
+ ];
153
+ // The base Radix packages the `site` preset's component files
154
+ // need to compile (label, separator, slot are imported by the
155
+ // vendored `button.tsx`, etc.). We seed the dependency block with
156
+ // them so the scaffolder never emits a project that's missing a
157
+ // Radix dep the components reference.
158
+ const baseRadixDependencies = [
159
+ ["@radix-ui/react-label", "^2.1.0"],
160
+ ["@radix-ui/react-separator", "^1.1.0"],
161
+ ["@radix-ui/react-slot", "^1.2.0"],
162
+ ];
163
+ const presetExtras = siteDependencyEntries(new Set([
164
+ // Anything in the base blocks is already covered — drop it
165
+ // from the preset's contribution to avoid emitting the same
166
+ // key twice in the JSON object.
167
+ ...baseDependencies.map(([name]) => name),
168
+ ...baseRadixDependencies.map(([name]) => name),
169
+ ]));
170
+ // Merge into a single dedup'd map. Preset extras win on conflict
171
+ // (e.g. a future site preset may pin a newer Radix version than
172
+ // the base set), so they go in last.
173
+ const merged = new Map();
174
+ for (const [name, version] of baseDependencies)
175
+ merged.set(name, version);
176
+ for (const [name, version] of baseRadixDependencies) {
177
+ merged.set(name, version);
178
+ }
179
+ for (const dep of presetExtras)
180
+ merged.set(dep.name, dep.version);
181
+ // Render as a stable, alphabetised JSON object body. We keep
182
+ // the 4-space indent and the no-trailing-comma convention so the
183
+ // output is diff-friendly.
184
+ const lines = [];
185
+ const keys = [...merged.keys()].sort();
186
+ for (const name of keys) {
187
+ const version = merged.get(name);
188
+ lines.push(` "${name}": ${JSON.stringify(version)}`);
189
+ }
190
+ return lines.join(",\n");
191
+ }
192
+ function renderTemplate(input, tokens) {
193
+ return input.replace(/\{\{\s*([a-zA-Z][a-zA-Z0-9_]*)\s*\}\}/g, (full, key) => {
194
+ const value = tokens[key];
195
+ if (typeof value === "string") {
196
+ return value;
197
+ }
198
+ return full;
199
+ });
200
+ }
201
+ function templateUiComponentName(filePath) {
202
+ if (path.basename(path.dirname(filePath)) !== "ui")
203
+ return null;
204
+ const baseName = path.basename(filePath);
205
+ if (!baseName.endsWith(".tsx.tmpl"))
206
+ return null;
207
+ return baseName.slice(0, -".tsx.tmpl".length);
208
+ }
209
+ function shouldSkipTemplate(filePath, tokens) {
210
+ const component = templateUiComponentName(filePath);
211
+ return Boolean(component && !tokens.uiComponents.includes(component));
212
+ }
213
+ async function exists(p) {
214
+ try {
215
+ await fs.stat(p);
216
+ return true;
217
+ }
218
+ catch {
219
+ return false;
220
+ }
221
+ }
222
+ async function ensureDir(p) {
223
+ await fs.mkdir(p, { recursive: true });
224
+ }
225
+ async function readPackageVersion() {
226
+ const packageJsonUrl = new URL("../package.json", import.meta.url);
227
+ const raw = await fs.readFile(packageJsonUrl, "utf8");
228
+ const parsed = JSON.parse(raw);
229
+ return parsed.version ?? "0.0.0";
230
+ }
231
+ /**
232
+ * Default three-layer file ownership for a freshly scaffolded
233
+ * project.
234
+ */
235
+ function buildDefaultManagedFiles(input) {
236
+ const userOwned = [
237
+ "app/page.tsx",
238
+ "components/site/site-header.tsx",
239
+ "components/site/site-footer.tsx",
240
+ "lib/content/models.ts",
241
+ ];
242
+ if (input.contentSourceId === "blog") {
243
+ userOwned.push("app/blog/page.tsx", "app/blog/[slug]/page.tsx");
244
+ }
245
+ const bridgeOwned = ["worker/index.ts"];
246
+ // Feature-module files: bridge-owned for the entry point,
247
+ // user-owned for sub-components. Mirrors the ownership tags
248
+ // declared in `registry-items.ts`.
249
+ if (input.enableSiteSettings) {
250
+ bridgeOwned.push("lib/site/settings.ts");
251
+ }
252
+ if (input.enableBlocks) {
253
+ bridgeOwned.push("components/page-blocks.tsx");
254
+ userOwned.push("components/page-blocks/hero-block.tsx", "components/page-blocks/feature-grid-block.tsx", "components/page-blocks/story-block.tsx", "components/page-blocks/latest-posts-block.tsx");
255
+ }
256
+ if (input.enableAuth) {
257
+ bridgeOwned.push("lib/auth.config.ts", "app/api/auth/google/route.ts", "app/api/auth/google/callback/route.ts", "app/api/auth/verify-email/route.ts", "app/api/auth/viewer/route.ts", "migrations/0001_init.sql");
258
+ userOwned.push("app/login/page.tsx", "app/register/page.tsx");
259
+ }
260
+ if (input.enableAdmin) {
261
+ bridgeOwned.push("app/admin/layout.tsx", "app/admin/page.tsx", "app/admin/loading.tsx", "app/admin/account/page.tsx", "app/admin/content-models/page.tsx", "lib/admin/nav.ts", "lib/admin/actions.ts", "lib/admin/context.tsx", "migrations/0002_admin_seed.sql");
262
+ }
263
+ if (input.enablePages) {
264
+ bridgeOwned.push("lib/pages/model.ts", "lib/pages/source.ts", "app/[slug]/page.tsx");
265
+ }
266
+ if (input.enableSearch) {
267
+ bridgeOwned.push("lib/search/config.ts", "migrations/0003_search_index.sql");
268
+ userOwned.push("components/search/search-dialog.tsx");
269
+ }
270
+ return {
271
+ platform: [
272
+ "package.json",
273
+ "wrangler.jsonc",
274
+ "next.config.ts",
275
+ ".dev.vars.example",
276
+ ],
277
+ bridge: bridgeOwned,
278
+ user: userOwned,
279
+ };
280
+ }
281
+ export async function resolveTemplatesDir() {
282
+ const compiled = path.resolve(import.meta.dirname, "templates");
283
+ const fromSource = path.resolve(import.meta.dirname, "..", "src", "templates");
284
+ return (await exists(compiled)) ? compiled : fromSource;
285
+ }
286
+ async function copyDir(src, dest) {
287
+ await ensureDir(dest);
288
+ const entries = await fs.readdir(src, { withFileTypes: true });
289
+ for (const entry of entries) {
290
+ const from = path.join(src, entry.name);
291
+ const to = path.join(dest, entry.name);
292
+ if (entry.isDirectory()) {
293
+ await copyDir(from, to);
294
+ }
295
+ else if (entry.isFile()) {
296
+ await fs.copyFile(from, to);
297
+ }
298
+ }
299
+ }
300
+ /**
301
+ * Render the project. `templatesDir` is the absolute path to
302
+ * `src/templates/` inside the scaffolder package; `outDir` is the
303
+ * target directory the user picked in the prompt (relative or
304
+ * absolute). Existing directories are not removed — the caller is
305
+ * responsible for picking a clean target.
306
+ */
307
+ export async function render(answers, templatesDir, outDir) {
308
+ const scaffoldVersion = await readPackageVersion();
309
+ const tokens = await buildTokenMap(answers, scaffoldVersion);
310
+ const absoluteOut = path.resolve(process.cwd(), outDir);
311
+ if (await exists(absoluteOut)) {
312
+ const entries = await fs.readdir(absoluteOut);
313
+ if (entries.length > 0) {
314
+ throw new Error(`Target directory ${absoluteOut} is not empty. Pick an empty path.`);
315
+ }
316
+ }
317
+ await ensureDir(absoluteOut);
318
+ // Build the initial v2 registry manifest. This is the single
319
+ // source of truth for the project's state.
320
+ const managedFiles = buildDefaultManagedFiles({
321
+ contentSourceId: answers.contentSource.id,
322
+ enableSiteSettings: answers.enableSiteSettings,
323
+ enableBlocks: answers.enableBlocks,
324
+ enableAuth: answers.enableAuth,
325
+ enableAdmin: answers.enableAdmin,
326
+ enablePages: answers.enablePages,
327
+ enableSearch: answers.enableSearch,
328
+ });
329
+ const manifest = buildInitialRegistryManifest({
330
+ projectName: answers.projectName,
331
+ scaffoldVersion,
332
+ notionxCore: answers.notionxSource,
333
+ defaultLocale: answers.defaultLocale,
334
+ supportedLocales: answers.supportedLocales,
335
+ enableSiteSettings: answers.enableSiteSettings,
336
+ enableBlocks: answers.enableBlocks,
337
+ enableAuth: answers.enableAuth,
338
+ enableAdmin: answers.enableAdmin,
339
+ enablePages: answers.enablePages,
340
+ enableSearch: answers.enableSearch,
341
+ contentSource: {
342
+ id: answers.contentSource.id,
343
+ title: answers.contentSource.title,
344
+ fields: answers.contentSource.fields.map((f) => ({
345
+ key: f.key,
346
+ notionName: f.notionName,
347
+ })),
348
+ },
349
+ managedFiles,
350
+ });
351
+ await writeRegistryManifest(absoluteOut, manifest);
352
+ // Feature flags drive the fallback-template selection: when a
353
+ // flag is false, the Notion-backed version is skipped and the
354
+ // `.fallback.ts.tmpl` variant is rendered in its place (so the
355
+ // output filename is unchanged).
356
+ const featureFlags = {
357
+ siteSettings: answers.enableSiteSettings,
358
+ blocks: answers.enableBlocks,
359
+ auth: answers.enableAuth,
360
+ admin: answers.enableAdmin,
361
+ pages: answers.enablePages,
362
+ search: answers.enableSearch,
363
+ };
364
+ // Walk templates/ — every file is either a `.tmpl` (interpolated and
365
+ // written without the `.tmpl` suffix) or a literal copy.
366
+ const entries = await fs.readdir(templatesDir, { withFileTypes: true });
367
+ for (const entry of entries) {
368
+ const from = path.join(templatesDir, entry.name);
369
+ if (entry.isDirectory()) {
370
+ const dest = path.join(absoluteOut, entry.name);
371
+ await copyDirWithRender(from, dest, tokens, featureFlags);
372
+ }
373
+ else if (entry.isFile()) {
374
+ if (shouldSkipTemplate(from, tokens))
375
+ continue;
376
+ if (shouldSkipFeatureTemplate(from, featureFlags))
377
+ continue;
378
+ await writeFileWithRender(from, absoluteOut, tokens);
379
+ }
380
+ }
381
+ }
382
+ /**
383
+ * Feature-gated template skip rules. When a feature is disabled, the
384
+ * Notion-backed `.tmpl` is skipped so the `.fallback.ts.tmpl` variant
385
+ * (rendered to the same output filename) takes its place. The
386
+ * `page-blocks/` subdirectory is also skipped entirely when blocks
387
+ * are disabled — the fallback `page-blocks.tsx` is a no-op that
388
+ * doesn't need the sub-components.
389
+ */
390
+ function shouldSkipFeatureTemplate(filePath, flags) {
391
+ const normalized = filePath.split(path.sep).join("/");
392
+ if (!flags.siteSettings && normalized.endsWith("lib/site/settings.ts.tmpl")) {
393
+ return true;
394
+ }
395
+ if (!flags.blocks && normalized.endsWith("components/page-blocks.tsx.tmpl")) {
396
+ return true;
397
+ }
398
+ // Skip the entire `components/page-blocks/` subdirectory contents
399
+ // when blocks are disabled. The fallback `page-blocks.tsx` doesn't
400
+ // import any of the sub-components.
401
+ if (!flags.blocks && normalized.includes("/components/page-blocks/")) {
402
+ return true;
403
+ }
404
+ // Auth: skip the Notion-backed auth config and auth API routes
405
+ // when auth is disabled. The fallback `auth.config.ts` is a no-op
406
+ // stub, and the auth route handlers are omitted entirely.
407
+ if (!flags.auth && normalized.endsWith("lib/auth.config.ts.tmpl")) {
408
+ return true;
409
+ }
410
+ if (!flags.auth && normalized.includes("/app/api/auth/")) {
411
+ return true;
412
+ }
413
+ if (!flags.auth && normalized.includes("/app/login/")) {
414
+ return true;
415
+ }
416
+ if (!flags.auth && normalized.includes("/app/register/")) {
417
+ return true;
418
+ }
419
+ // Skip the auth D1 migration (users/sessions/rate-limits tables)
420
+ // when auth is disabled.
421
+ if (!flags.auth && normalized.endsWith("migrations/0001_init.sql.tmpl")) {
422
+ return true;
423
+ }
424
+ // Admin: skip the entire admin tree when admin is disabled.
425
+ if (!flags.admin && normalized.includes("/app/admin/")) {
426
+ return true;
427
+ }
428
+ if (!flags.admin && normalized.includes("/lib/admin/")) {
429
+ return true;
430
+ }
431
+ // Skip the admin seed migration when admin is disabled.
432
+ if (!flags.admin && normalized.endsWith("migrations/0002_admin_seed.sql.tmpl")) {
433
+ return true;
434
+ }
435
+ // Pages: skip the pages lib and dynamic slug routes when pages
436
+ // is disabled. The fallback `app/page.tsx` renders a static home.
437
+ if (!flags.pages && normalized.includes("/lib/pages/")) {
438
+ return true;
439
+ }
440
+ if (!flags.pages && normalized.includes("/app/[slug]/")) {
441
+ return true;
442
+ }
443
+ if (!flags.pages && normalized.endsWith("app/page.tsx.tmpl")) {
444
+ return true;
445
+ }
446
+ // Search: skip the Notion-backed search config and the search
447
+ // index migration when search is disabled. The fallback
448
+ // `lib/search/config.ts` is a no-op stub exporting `undefined`.
449
+ if (!flags.search && normalized.endsWith("lib/search/config.ts.tmpl")) {
450
+ return true;
451
+ }
452
+ if (!flags.search && normalized.includes("/components/search/")) {
453
+ return true;
454
+ }
455
+ if (!flags.search && normalized.endsWith("migrations/0003_search_index.sql.tmpl")) {
456
+ return true;
457
+ }
458
+ return false;
459
+ }
460
+ async function copyDirWithRender(src, dest, tokens, featureFlags) {
461
+ await ensureDir(dest);
462
+ const entries = await fs.readdir(src, { withFileTypes: true });
463
+ for (const entry of entries) {
464
+ const from = path.join(src, entry.name);
465
+ if (entry.isDirectory()) {
466
+ // Directory names may also contain tokens (e.g. the blog page
467
+ // lives at `app/{{contentSourceListPath}}/page.tsx.tmpl` so
468
+ // the directory itself must be rendered to `/blog` at scaffold
469
+ // time). Falling through to a literal name would produce an
470
+ // invalid `{{contentSourceListPath}}` folder in the project.
471
+ const renderedName = renderTemplate(entry.name, tokens);
472
+ await copyDirWithRender(from, path.join(dest, renderedName), tokens, featureFlags);
473
+ }
474
+ else if (entry.isFile()) {
475
+ // Per-preset component filter: the `components/ui/` tree in
476
+ // the templates directory carries the *union* of every preset
477
+ // (so we only have to maintain one copy of each shadcn
478
+ // component). At copy time, drop files that the active preset
479
+ // didn't opt into. Since 0.5.4 only the `site` preset
480
+ // survives, so this filter is equivalent to "copy all shadcn
481
+ // components" — kept here so a future preset addition can
482
+ // slot in without touching the renderer.
483
+ if (isUiDirectory(src) && !shouldCopyUiComponent(entry.name)) {
484
+ continue;
485
+ }
486
+ if (shouldSkipFeatureTemplate(from, featureFlags))
487
+ continue;
488
+ await writeFileWithRender(from, dest, tokens);
489
+ }
490
+ }
491
+ }
492
+ /**
493
+ * True when `dir` is the `components/ui/` directory of the
494
+ * templates tree. Used to gate the per-preset component filter
495
+ * (see `copyDirWithRender`).
496
+ */
497
+ function isUiDirectory(dir) {
498
+ const parts = dir.split(path.sep);
499
+ return (parts.length >= 2 &&
500
+ parts[parts.length - 1] === "ui" &&
501
+ parts[parts.length - 2] === "components");
502
+ }
503
+ /**
504
+ * Decide whether a `components/ui/<file>.tsx.tmpl` should be
505
+ * copied for the given preset. The file list is the union across
506
+ * all presets, and the preset's `components` array declares which
507
+ * ones survive.
508
+ *
509
+ * Files that aren't `.tsx.tmpl` shadcn component copies (e.g. a
510
+ * future `index.ts` helper or a barrel) are always copied — only
511
+ * the named shadcn components participate in the filter.
512
+ */
513
+ function shouldCopyUiComponent(fileName) {
514
+ if (!fileName.endsWith(".tsx.tmpl"))
515
+ return true;
516
+ const base = fileName.slice(0, -".tsx.tmpl".length);
517
+ const allowed = new Set(siteComponentNames());
518
+ return allowed.has(base);
519
+ }
520
+ async function writeFileWithRender(from, toDir, tokens) {
521
+ const baseName = path.basename(from);
522
+ // `.fallback.ts.tmpl` / `.fallback.tsx.tmpl` variants render to
523
+ // the same output filename as their Notion-backed counterpart
524
+ // (i.e. `settings.fallback.ts.tmpl` → `settings.ts`). The
525
+ // `.fallback.` segment is stripped in addition to `.tmpl`.
526
+ const isFallbackTmpl = baseName.includes(".fallback.");
527
+ const isTmpl = baseName.endsWith(".tmpl");
528
+ let outName;
529
+ if (isTmpl) {
530
+ outName = isFallbackTmpl
531
+ ? baseName.replace(/\.fallback\.(ts|tsx)\.tmpl$/, ".$1")
532
+ : baseName.slice(0, -".tmpl".length);
533
+ }
534
+ else {
535
+ outName = baseName;
536
+ }
537
+ const outPath = path.join(toDir, outName);
538
+ if (isTmpl) {
539
+ const raw = await fs.readFile(from, "utf8");
540
+ const rendered = renderTemplate(raw, tokens);
541
+ await ensureDir(path.dirname(outPath));
542
+ await fs.writeFile(outPath, rendered, "utf8");
543
+ }
544
+ else {
545
+ await ensureDir(path.dirname(outPath));
546
+ await fs.copyFile(from, outPath);
547
+ }
548
+ }
549
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,kEAAkE;AAClE,2BAA2B;AAE3B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACL,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAqB,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA+D/C,gEAAgE;AAChE,SAAS,SAAS,CAAC,KAAa;IAC9B,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7C,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAAgB,EAChB,eAAuB;IAEvB,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,EAAE,KAAK,MAAM,CAAC;IAC7B,qEAAqE;IACrE,8DAA8D;IAC9D,wDAAwD;IACxD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3D,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAChD,OAAO,SAAS,GAAG,KAAK,UAAU,GAAG,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE/C,uDAAuD;IACvD,0DAA0D;IAC1D,iEAAiE;IACjE,+DAA+D;IAC/D,4DAA4D;IAC5D,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,CACrD,OAAO,CAAC,aAAa,CACtB,CAAC;IACF,MAAM,gBAAgB,GAAG,YAAY,EAAE,CAAC;IAExC,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,gBAAgB,EAAE,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE;QACnD,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QACrD,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,gBAAgB,CAAC;QAC9D,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,uBAAuB,EAAE,IAAI,eAAe,EAAE;QAC9C,eAAe,EAAE,EAAE;QACnB,kBAAkB,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK;QAC/C,iBAAiB,EAAE,WAAW;QAC9B,qBAAqB,EAAE,IAAI,EAAE,EAAE;QAC/B,uBAAuB,EAAE,IAAI,EAAE,SAAS;QACxC,oBAAoB,EAAE,QAAQ,EAAE,EAAE;QAClC,mBAAmB,EAAE,aAAa;QAClC,oBAAoB,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,QAAQ;QAC5C,sBAAsB,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,cAAc;QACpD,qBAAqB,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK;QAClD,uBAAuB,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,GAAG;QAC1D,sBAAsB,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK;QACnD,4BAA4B,EAAE,MAAM;YAClC,CAAC,CAAC,6DAA6D;YAC/D,CAAC,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,4BAA4B;QAC9D,uBAAuB,EAAE,MAAM;YAC7B,CAAC,CAAC,8BAA8B;YAChC,CAAC,CAAC,MAAM,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,eAAe;QAClE,uBAAuB,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;QAClD,wBAAwB,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;QACnD,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACpE,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC;QACxC,iBAAiB;QACjB,iBAAiB,EAAE,sBAAsB,CAAC,OAAO,CAAC,aAAa,CAAC;QAChE,eAAe,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACjF,YAAY,EAAE,gBAAgB;QAC9B,kEAAkE;QAClE,2DAA2D;QAC3D,kEAAkE;QAClE,8DAA8D;QAC9D,mDAAmD;QACnD,EAAE;QACF,gEAAgE;QAChE,qDAAqD;QACrD,oDAAoD;QACpD,sDAAsD;QACtD,sDAAsD;QACtD,GAAG,CAAC,GAKF,EAAE;YACF,MAAM,KAAK,GAAG,wBAAwB,CAAC;gBACrC,OAAO,EAAE;oBACP,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,aAAa,EAAE,OAAO,CAAC,aAAa;oBACpC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;oBAC1C,aAAa,EAAE,OAAO,CAAC,aAAa;oBACpC,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;oBACpC,eAAe;iBAChB;gBACD,SAAS,EAAE;oBACT;wBACE,EAAE,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE;wBAC5B,IAAI,EAAE,gBAAgB;wBACtB,OAAO,EAAE,CAAC;wBACV,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,mBAAmB,EAAE;wBACvD,MAAM,EAAE;4BACN,eAAe,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE;4BACzC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC;yBAChE;wBACD,WAAW,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;qBACvC;iBACF;gBACD,eAAe,EAAE;oBACf,YAAY,EAAE,OAAO,CAAC,kBAAkB;oBACxC,MAAM,EAAE,OAAO,CAAC,YAAY;iBAC7B;aACF,CAAC,CAAC;YACH,OAAO;gBACL,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;gBAC1D,4BAA4B,EAAE,KAAK,CAAC,4BAA4B;gBAChE,0BAA0B,EAAE,KAAK,CAAC,0BAA0B;gBAC5D,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;aACrD,CAAC;QACJ,CAAC,CAAC,EAAE;KACL,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,sBAAsB,CAAC,aAAqB;IACnD,iEAAiE;IACjE,kEAAkE;IAClE,wCAAwC;IACxC,MAAM,gBAAgB,GAA6C;QACjE,CAAC,eAAe,EAAE,aAAa,CAAC;QAChC,CAAC,0BAA0B,EAAE,QAAQ,CAAC;QACtC,CAAC,MAAM,EAAE,QAAQ,CAAC;QAClB,CAAC,cAAc,EAAE,UAAU,CAAC;QAC5B,CAAC,MAAM,EAAE,QAAQ,CAAC;QAClB,CAAC,aAAa,EAAE,QAAQ,CAAC;QACzB,CAAC,OAAO,EAAE,SAAS,CAAC;QACpB,CAAC,WAAW,EAAE,SAAS,CAAC;QACxB,CAAC,gBAAgB,EAAE,QAAQ,CAAC;QAC5B,CAAC,qBAAqB,EAAE,QAAQ,CAAC;KAClC,CAAC;IAEF,8DAA8D;IAC9D,8DAA8D;IAC9D,kEAAkE;IAClE,gEAAgE;IAChE,sCAAsC;IACtC,MAAM,qBAAqB,GAA6C;QACtE,CAAC,uBAAuB,EAAE,QAAQ,CAAC;QACnC,CAAC,2BAA2B,EAAE,QAAQ,CAAC;QACvC,CAAC,sBAAsB,EAAE,QAAQ,CAAC;KACnC,CAAC;IAEF,MAAM,YAAY,GAAG,qBAAqB,CACxC,IAAI,GAAG,CAAC;QACN,2DAA2D;QAC3D,4DAA4D;QAC5D,gCAAgC;QAChC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC;QACzC,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC;KAC/C,CAAC,CACH,CAAC;IAEF,iEAAiE;IACjE,gEAAgE;IAChE,qCAAqC;IACrC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,gBAAgB;QAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1E,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,qBAAqB,EAAE,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,YAAY;QAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAElE,6DAA6D;IAC7D,iEAAiE;IACjE,2BAA2B;IAC3B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,MAAgB;IACrD,OAAO,KAAK,CAAC,OAAO,CAAC,wCAAwC,EAAE,CAAC,IAAI,EAAE,GAAW,EAAE,EAAE;QACnF,MAAM,KAAK,GAAI,MAA6C,CAAC,GAAG,CAAC,CAAC;QAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,uBAAuB,CAAC,QAAgB;IAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB,EAAE,MAAgB;IAC5D,MAAM,SAAS,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,CAAS;IAC7B,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,CAAS;IAChC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;IACvD,OAAO,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,SAAS,wBAAwB,CAAC,KAQjC;IAKC,MAAM,SAAS,GAAG;QAChB,cAAc;QACd,iCAAiC;QACjC,iCAAiC;QACjC,uBAAuB;KACxB,CAAC;IAEF,IAAI,KAAK,CAAC,eAAe,KAAK,MAAM,EAAE,CAAC;QACrC,SAAS,CAAC,IAAI,CAAC,mBAAmB,EAAE,0BAA0B,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,WAAW,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAExC,0DAA0D;IAC1D,4DAA4D;IAC5D,mCAAmC;IACnC,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC7B,WAAW,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,WAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC/C,SAAS,CAAC,IAAI,CACZ,uCAAuC,EACvC,+CAA+C,EAC/C,wCAAwC,EACxC,+CAA+C,CAChD,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,WAAW,CAAC,IAAI,CACd,oBAAoB,EACpB,8BAA8B,EAC9B,uCAAuC,EACvC,oCAAoC,EACpC,8BAA8B,EAC9B,0BAA0B,CAC3B,CAAC;QACF,SAAS,CAAC,IAAI,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,WAAW,CAAC,IAAI,CACd,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,4BAA4B,EAC5B,mCAAmC,EACnC,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,CACjC,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,WAAW,CAAC,IAAI,CACd,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,CACtB,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,WAAW,CAAC,IAAI,CACd,sBAAsB,EACtB,kCAAkC,CACnC,CAAC;QACF,SAAS,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IACxD,CAAC;IAED,OAAO;QACL,QAAQ,EAAE;YACR,cAAc;YACd,gBAAgB;YAChB,gBAAgB;YAChB,mBAAmB;SACpB;QACD,MAAM,EAAE,WAAW;QACnB,IAAI,EAAE,SAAS;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAC/E,OAAO,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,IAAY;IAC9C,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAgB,EAChB,YAAoB,EACpB,MAAc;IAEd,MAAM,eAAe,GAAG,MAAM,kBAAkB,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAExD,IAAI,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,oBAAoB,WAAW,oCAAoC,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC;IAE7B,6DAA6D;IAC7D,2CAA2C;IAC3C,MAAM,YAAY,GAAG,wBAAwB,CAAC;QAC5C,eAAe,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE;QACzC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,4BAA4B,CAAC;QAC5C,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,eAAe;QACf,WAAW,EAAE,OAAO,CAAC,aAAa;QAClC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,aAAa,EAAE;YACb,EAAE,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE;YAC5B,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK;YAClC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/C,GAAG,EAAE,CAAC,CAAC,GAAG;gBACV,UAAU,EAAE,CAAC,CAAC,UAAU;aACzB,CAAC,CAAC;SACJ;QACD,YAAY;KACb,CAAC,CAAC;IACH,MAAM,qBAAqB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAEnD,8DAA8D;IAC9D,8DAA8D;IAC9D,+DAA+D;IAC/D,iCAAiC;IACjC,MAAM,YAAY,GAAG;QACnB,YAAY,EAAE,OAAO,CAAC,kBAAkB;QACxC,MAAM,EAAE,OAAO,CAAC,YAAY;QAC5B,IAAI,EAAE,OAAO,CAAC,UAAU;QACxB,KAAK,EAAE,OAAO,CAAC,WAAW;QAC1B,KAAK,EAAE,OAAO,CAAC,WAAW;QAC1B,MAAM,EAAE,OAAO,CAAC,YAAY;KAC7B,CAAC;IAEF,qEAAqE;IACrE,yDAAyD;IACzD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QAC5D,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,IAAI,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC;gBAAE,SAAS;YAC/C,IAAI,yBAAyB,CAAC,IAAI,EAAE,YAAY,CAAC;gBAAE,SAAS;YAC5D,MAAM,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAChC,QAAgB,EAChB,KAAmB;IAEnB,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,UAAU,CAAC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,iCAAiC,CAAC,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,kEAAkE;IAClE,mEAAmE;IACnE,oCAAoC;IACpC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,+DAA+D;IAC/D,kEAAkE;IAClE,0DAA0D;IAC1D,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,iEAAiE;IACjE,yBAAyB;IACzB,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,+BAA+B,CAAC,EAAE,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,4DAA4D;IAC5D,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,wDAAwD;IACxD,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC,QAAQ,CAAC,qCAAqC,CAAC,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,+DAA+D;IAC/D,kEAAkE;IAClE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,8DAA8D;IAC9D,wDAAwD;IACxD,gEAAgE;IAChE,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,uCAAuC,CAAC,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAeD,KAAK,UAAU,iBAAiB,CAC9B,GAAW,EACX,IAAY,EACZ,MAAgB,EAChB,YAA0B;IAE1B,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,8DAA8D;YAC9D,4DAA4D;YAC5D,+DAA+D;YAC/D,4DAA4D;YAC5D,6DAA6D;YAC7D,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACxD,MAAM,iBAAiB,CACrB,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAC7B,MAAM,EACN,YAAY,CACb,CAAC;QACJ,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,4DAA4D;YAC5D,8DAA8D;YAC9D,uDAAuD;YACvD,8DAA8D;YAC9D,sDAAsD;YACtD,6DAA6D;YAC7D,0DAA0D;YAC1D,yCAAyC;YACzC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7D,SAAS;YACX,CAAC;YACD,IAAI,yBAAyB,CAAC,IAAI,EAAE,YAAY,CAAC;gBAAE,SAAS;YAC5D,MAAM,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,CACL,KAAK,CAAC,MAAM,IAAI,CAAC;QACjB,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI;QAChC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,YAAY,CACzC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,qBAAqB,CAC5B,QAAgB;IAEhB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,IAAY,EACZ,KAAa,EACb,MAAgB;IAEhB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrC,gEAAgE;IAChE,8DAA8D;IAC9D,0DAA0D;IAC1D,2DAA2D;IAC3D,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,OAAe,CAAC;IACpB,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,GAAG,cAAc;YACtB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,6BAA6B,EAAE,KAAK,CAAC;YACxD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,QAAQ,CAAC;IACrB,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAE1C,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACvC,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACvC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;AACH,CAAC"}