livemark 0.7.2 → 0.9.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 (627) hide show
  1. package/README.md +115 -4
  2. package/package.json +15 -14
  3. package/source/actions/changelog/build.ts +245 -0
  4. package/source/actions/changelog/build.unit.ts +69 -0
  5. package/source/actions/config/define.ts +11 -0
  6. package/source/actions/config/define.unit.ts +33 -0
  7. package/source/actions/config/load.ts +22 -0
  8. package/source/actions/config/load.unit.ts +30 -0
  9. package/source/commands/build.ts +21 -0
  10. package/source/commands/escape.ts +77 -0
  11. package/source/commands/preview.ts +25 -0
  12. package/source/commands/start.ts +26 -0
  13. package/{build/website → source}/components/Article.tsx +44 -44
  14. package/{build/website → source}/components/Callout.tsx +1 -1
  15. package/{build/website → source}/components/Layout.tsx +3 -14
  16. package/{build/website → source}/components/LinkButton.tsx +1 -1
  17. package/{build/website → source}/components/PageToolbar.tsx +21 -8
  18. package/{build/website → source}/components/Section.tsx +1 -1
  19. package/{build/website → source}/components/SectionHeader.tsx +1 -1
  20. package/{build/website/components/MiniSidebar.tsx → source/components/Sidebar.tsx} +21 -5
  21. package/{build/website/components/Sidebar.tsx → source/components/SidebarArticles.tsx} +22 -55
  22. package/source/components/SidebarPosts.tsx +129 -0
  23. package/source/components/SidebarReleases.tsx +85 -0
  24. package/{build/website → source}/content-collections.ts +12 -3
  25. package/{build/website → source}/elements/accordion.tsx +1 -1
  26. package/{build/website → source}/elements/alert-dialog.tsx +1 -1
  27. package/{build/website → source}/elements/alert.tsx +1 -1
  28. package/{build/website → source}/elements/aspect-ratio.tsx +1 -1
  29. package/{build/website → source}/elements/avatar.tsx +1 -1
  30. package/{build/website → source}/elements/badge.tsx +1 -1
  31. package/{build/website → source}/elements/breadcrumb.tsx +1 -1
  32. package/{build/website → source}/elements/button-group.tsx +1 -1
  33. package/{build/website → source}/elements/button.tsx +1 -1
  34. package/{build/website → source}/elements/calendar.tsx +1 -1
  35. package/{build/website → source}/elements/card.tsx +1 -1
  36. package/{build/website → source}/elements/carousel.tsx +1 -1
  37. package/{build/website → source}/elements/chart.tsx +1 -1
  38. package/{build/website → source}/elements/checkbox.tsx +1 -1
  39. package/{build/website → source}/elements/command.tsx +1 -1
  40. package/{build/website → source}/elements/context-menu.tsx +1 -1
  41. package/{build/website → source}/elements/dialog.tsx +1 -1
  42. package/{build/website → source}/elements/drawer.tsx +1 -1
  43. package/{build/website → source}/elements/dropdown-menu.tsx +1 -1
  44. package/{build/website → source}/elements/empty.tsx +1 -1
  45. package/{build/website → source}/elements/field.tsx +1 -1
  46. package/{build/website → source}/elements/hover-card.tsx +1 -1
  47. package/{build/website → source}/elements/input-group.tsx +1 -1
  48. package/{build/website → source}/elements/input-otp.tsx +1 -1
  49. package/{build/website → source}/elements/input.tsx +1 -1
  50. package/{build/website → source}/elements/item.tsx +1 -1
  51. package/{build/website → source}/elements/kbd.tsx +1 -1
  52. package/{build/website → source}/elements/label.tsx +1 -1
  53. package/{build/website → source}/elements/menubar.tsx +1 -1
  54. package/{build/website → source}/elements/native-select.tsx +1 -1
  55. package/{build/website → source}/elements/navigation-menu.tsx +1 -1
  56. package/{build/website → source}/elements/pagination.tsx +1 -1
  57. package/{build/website → source}/elements/popover.tsx +1 -1
  58. package/{build/website → source}/elements/progress.tsx +1 -1
  59. package/{build/website → source}/elements/radio-group.tsx +1 -1
  60. package/{build/website → source}/elements/resizable.tsx +1 -1
  61. package/{build/website → source}/elements/scroll-area.tsx +1 -1
  62. package/{build/website → source}/elements/select.tsx +1 -1
  63. package/{build/website → source}/elements/separator.tsx +1 -1
  64. package/{build/website → source}/elements/sheet.tsx +1 -1
  65. package/{build/website → source}/elements/sidebar.tsx +7 -4
  66. package/{build/website → source}/elements/skeleton.tsx +1 -1
  67. package/{build/website → source}/elements/slider.tsx +1 -1
  68. package/{build/website → source}/elements/spinner.tsx +1 -1
  69. package/{build/website → source}/elements/switch.tsx +1 -1
  70. package/{build/website → source}/elements/table.tsx +1 -1
  71. package/{build/website → source}/elements/tabs.tsx +1 -1
  72. package/{build/website → source}/elements/textarea.tsx +1 -1
  73. package/{build/website → source}/elements/toggle-group.tsx +1 -1
  74. package/{build/website → source}/elements/toggle.tsx +1 -1
  75. package/{build/website → source}/elements/tooltip.tsx +1 -1
  76. package/source/entrypoints/main.ts +12 -0
  77. package/{build/website → source}/env.d.ts +1 -1
  78. package/source/helpers/program.ts +6 -0
  79. package/{build/website → source}/helpers/section.ts +1 -1
  80. package/source/hooks/media.ts +29 -0
  81. package/source/index.ts +1 -0
  82. package/{build/website → source}/models/article.ts +5 -0
  83. package/source/models/config.ts +51 -0
  84. package/source/models/link.ts +11 -0
  85. package/source/models/patch.ts +9 -0
  86. package/source/models/section.ts +45 -0
  87. package/source/models/theme.ts +74 -0
  88. package/source/program.ts +18 -0
  89. package/source/settings.ts +6 -0
  90. package/{build/website → source}/vite.config.ts +14 -9
  91. package/{build → target}/actions/changelog/build.d.ts +1 -0
  92. package/target/actions/changelog/build.js +187 -0
  93. package/target/actions/changelog/build.unit.js +66 -0
  94. package/target/actions/config/define.js +8 -0
  95. package/target/actions/config/define.unit.js +29 -0
  96. package/target/actions/config/load.js +25 -0
  97. package/target/actions/config/load.unit.js +23 -0
  98. package/target/client.d.ts +1 -0
  99. package/target/client.js +6 -0
  100. package/target/commands/build.js +14 -0
  101. package/target/commands/escape.js +56 -0
  102. package/target/commands/preview.js +18 -0
  103. package/target/commands/start.js +19 -0
  104. package/target/components/Abbr.d.ts +5 -0
  105. package/target/components/Abbr.js +9 -0
  106. package/target/components/AnsiCode.d.ts +4 -0
  107. package/target/components/AnsiCode.js +6 -0
  108. package/target/components/Article.d.ts +5 -0
  109. package/target/components/Article.js +104 -0
  110. package/target/components/BackToTop.d.ts +3 -0
  111. package/target/components/BackToTop.js +19 -0
  112. package/target/components/Banner.d.ts +2 -0
  113. package/target/components/Banner.js +12 -0
  114. package/target/components/BlogIndex.d.ts +4 -0
  115. package/target/components/BlogIndex.js +62 -0
  116. package/target/components/Breadcrumbs.d.ts +1 -0
  117. package/target/components/Breadcrumbs.js +13 -0
  118. package/target/components/Callout.d.ts +8 -0
  119. package/target/components/Callout.js +43 -0
  120. package/target/components/Card.d.ts +7 -0
  121. package/target/components/Card.js +17 -0
  122. package/target/components/Cards.d.ts +4 -0
  123. package/target/components/Cards.js +6 -0
  124. package/target/components/ChangelogIndex.d.ts +4 -0
  125. package/target/components/ChangelogIndex.js +57 -0
  126. package/target/components/CodeBlock.d.ts +1 -0
  127. package/target/components/CodeBlock.js +47 -0
  128. package/target/components/CodeTabs.d.ts +6 -0
  129. package/target/components/CodeTabs.js +49 -0
  130. package/target/components/Column.d.ts +4 -0
  131. package/target/components/Column.js +6 -0
  132. package/target/components/Columns.d.ts +5 -0
  133. package/target/components/Columns.js +10 -0
  134. package/target/components/Content.d.ts +3 -0
  135. package/target/components/Content.js +5 -0
  136. package/target/components/ContentTab.d.ts +5 -0
  137. package/target/components/ContentTab.js +6 -0
  138. package/target/components/ContentTabs.d.ts +5 -0
  139. package/target/components/ContentTabs.js +47 -0
  140. package/target/components/DefaultCatchBoundary.d.ts +2 -0
  141. package/target/components/DefaultCatchBoundary.js +20 -0
  142. package/target/components/DefinitionList.d.ts +7 -0
  143. package/target/components/DefinitionList.js +14 -0
  144. package/target/components/Details.d.ts +5 -0
  145. package/target/components/Details.js +13 -0
  146. package/target/components/FileTree.d.ts +4 -0
  147. package/target/components/FileTree.js +17 -0
  148. package/target/components/Footer.d.ts +2 -0
  149. package/target/components/Footer.js +9 -0
  150. package/target/components/FootnoteRef.d.ts +3 -0
  151. package/target/components/FootnoteRef.js +31 -0
  152. package/target/components/Heading.d.ts +8 -0
  153. package/target/components/Heading.js +18 -0
  154. package/target/components/InlineBadge.d.ts +5 -0
  155. package/target/components/InlineBadge.js +7 -0
  156. package/target/components/InlineIcon.d.ts +5 -0
  157. package/target/components/InlineIcon.js +10 -0
  158. package/target/components/InlineToc.d.ts +4 -0
  159. package/target/components/InlineToc.js +14 -0
  160. package/target/components/Layout.d.ts +4 -0
  161. package/target/components/Layout.js +65 -0
  162. package/target/components/LinkButton.d.ts +7 -0
  163. package/target/components/LinkButton.js +11 -0
  164. package/target/components/Mermaid.d.ts +4 -0
  165. package/target/components/Mermaid.js +8 -0
  166. package/target/components/MermaidRenderer.d.ts +4 -0
  167. package/target/components/MermaidRenderer.js +32 -0
  168. package/target/components/NotFound.d.ts +3 -0
  169. package/target/components/NotFound.js +10 -0
  170. package/target/components/PackageTabs.d.ts +9 -0
  171. package/target/components/PackageTabs.js +28 -0
  172. package/target/components/PageToolbar.d.ts +7 -0
  173. package/target/components/PageToolbar.js +34 -0
  174. package/target/components/PrevNext.d.ts +4 -0
  175. package/target/components/PrevNext.js +34 -0
  176. package/target/components/Search.d.ts +2 -0
  177. package/target/components/Search.js +16 -0
  178. package/target/components/SearchDialog.d.ts +5 -0
  179. package/target/components/SearchDialog.js +139 -0
  180. package/target/components/Section.d.ts +5 -0
  181. package/target/components/Section.js +8 -0
  182. package/target/components/SectionHeader.d.ts +7 -0
  183. package/target/components/SectionHeader.js +7 -0
  184. package/target/components/Sidebar.d.ts +4 -0
  185. package/target/components/Sidebar.js +33 -0
  186. package/target/components/SidebarArticles.d.ts +2 -0
  187. package/target/components/SidebarArticles.js +45 -0
  188. package/target/components/SidebarLinks.d.ts +4 -0
  189. package/target/components/SidebarLinks.js +26 -0
  190. package/target/components/SidebarPosts.d.ts +2 -0
  191. package/target/components/SidebarPosts.js +53 -0
  192. package/target/components/SidebarReleases.d.ts +2 -0
  193. package/target/components/SidebarReleases.js +35 -0
  194. package/target/components/SidebarSections.d.ts +4 -0
  195. package/target/components/SidebarSections.js +36 -0
  196. package/target/components/SiteTitle.d.ts +2 -0
  197. package/target/components/SiteTitle.js +12 -0
  198. package/target/components/SortableTable.d.ts +5 -0
  199. package/target/components/SortableTable.js +63 -0
  200. package/target/components/SoundCloud.d.ts +4 -0
  201. package/target/components/SoundCloud.js +7 -0
  202. package/target/components/TagIndex.d.ts +5 -0
  203. package/target/components/TagIndex.js +64 -0
  204. package/target/components/Theme.d.ts +1 -0
  205. package/target/components/Theme.js +21 -0
  206. package/target/components/Toc.d.ts +12 -0
  207. package/target/components/Toc.js +128 -0
  208. package/target/components/YouTube.d.ts +4 -0
  209. package/target/components/YouTube.js +6 -0
  210. package/target/components/ZoomImage.d.ts +4 -0
  211. package/target/components/ZoomImage.js +26 -0
  212. package/target/content/article.d.ts +43 -0
  213. package/target/content/article.js +54 -0
  214. package/target/content/tag.d.ts +2 -0
  215. package/target/content/tag.js +30 -0
  216. package/target/content-collections.d.ts +2 -0
  217. package/target/content-collections.js +200 -0
  218. package/target/elements/accordion.d.ts +6 -0
  219. package/target/elements/accordion.js +19 -0
  220. package/target/elements/alert-dialog.d.ts +18 -0
  221. package/target/elements/alert-dialog.js +44 -0
  222. package/target/elements/alert.d.ts +9 -0
  223. package/target/elements/alert.js +28 -0
  224. package/target/elements/aspect-ratio.d.ts +4 -0
  225. package/target/elements/aspect-ratio.js +9 -0
  226. package/target/elements/avatar.d.ts +11 -0
  227. package/target/elements/avatar.js +23 -0
  228. package/target/elements/badge.d.ts +7 -0
  229. package/target/elements/badge.js +34 -0
  230. package/target/elements/breadcrumb.d.ts +9 -0
  231. package/target/elements/breadcrumb.js +39 -0
  232. package/target/elements/button-group.d.ts +10 -0
  233. package/target/elements/button-group.js +37 -0
  234. package/target/elements/button.d.ts +8 -0
  235. package/target/elements/button.js +35 -0
  236. package/target/elements/calendar.d.ts +10 -0
  237. package/target/elements/calendar.js +76 -0
  238. package/target/elements/card.d.ts +11 -0
  239. package/target/elements/card.js +25 -0
  240. package/target/elements/carousel.d.ts +28 -0
  241. package/target/elements/carousel.js +95 -0
  242. package/target/elements/chart.d.ts +44 -0
  243. package/target/elements/chart.js +140 -0
  244. package/target/elements/checkbox.d.ts +3 -0
  245. package/target/elements/checkbox.js +9 -0
  246. package/target/elements/collapsible.d.ts +5 -0
  247. package/target/elements/collapsible.js +13 -0
  248. package/target/elements/command.d.ts +23 -0
  249. package/target/elements/command.js +42 -0
  250. package/target/elements/context-menu.d.ts +29 -0
  251. package/target/elements/context-menu.js +54 -0
  252. package/target/elements/dialog.d.ts +16 -0
  253. package/target/elements/dialog.js +41 -0
  254. package/target/elements/direction.d.ts +1 -0
  255. package/target/elements/direction.js +2 -0
  256. package/target/elements/drawer.d.ts +12 -0
  257. package/target/elements/drawer.js +38 -0
  258. package/target/elements/dropdown-menu.d.ts +24 -0
  259. package/target/elements/dropdown-menu.js +54 -0
  260. package/target/elements/empty.d.ts +11 -0
  261. package/target/elements/empty.js +34 -0
  262. package/target/elements/field.d.ts +24 -0
  263. package/target/elements/field.js +69 -0
  264. package/target/elements/hover-card.d.ts +5 -0
  265. package/target/elements/hover-card.js +14 -0
  266. package/target/elements/input-group.d.ts +18 -0
  267. package/target/elements/input-group.js +60 -0
  268. package/target/elements/input-otp.d.ts +11 -0
  269. package/target/elements/input-otp.js +21 -0
  270. package/target/elements/input.d.ts +2 -0
  271. package/target/elements/input.js +8 -0
  272. package/target/elements/item.d.ts +21 -0
  273. package/target/elements/item.js +79 -0
  274. package/target/elements/kbd.d.ts +3 -0
  275. package/target/elements/kbd.js +10 -0
  276. package/target/elements/label.d.ts +2 -0
  277. package/target/elements/label.js +8 -0
  278. package/target/elements/menubar.d.ts +29 -0
  279. package/target/elements/menubar.js +58 -0
  280. package/target/elements/native-select.d.ts +8 -0
  281. package/target/elements/native-select.js +16 -0
  282. package/target/elements/navigation-menu.d.ts +11 -0
  283. package/target/elements/navigation-menu.js +34 -0
  284. package/target/elements/pagination.d.ts +17 -0
  285. package/target/elements/pagination.js +33 -0
  286. package/target/elements/popover.d.ts +9 -0
  287. package/target/elements/popover.js +23 -0
  288. package/target/elements/progress.d.ts +7 -0
  289. package/target/elements/progress.js +21 -0
  290. package/target/elements/radio-group.d.ts +5 -0
  291. package/target/elements/radio-group.js +12 -0
  292. package/target/elements/resizable.d.ts +7 -0
  293. package/target/elements/resizable.js +14 -0
  294. package/target/elements/scroll-area.d.ts +4 -0
  295. package/target/elements/scroll-area.js +13 -0
  296. package/target/elements/select.d.ts +15 -0
  297. package/target/elements/select.js +39 -0
  298. package/target/elements/separator.d.ts +3 -0
  299. package/target/elements/separator.js +8 -0
  300. package/target/elements/sheet.d.ts +13 -0
  301. package/target/elements/sheet.js +41 -0
  302. package/target/elements/sidebar.d.ts +63 -0
  303. package/target/elements/sidebar.js +272 -0
  304. package/target/elements/skeleton.d.ts +2 -0
  305. package/target/elements/skeleton.js +7 -0
  306. package/target/elements/slider.d.ts +3 -0
  307. package/target/elements/slider.js +15 -0
  308. package/target/elements/sonner.d.ts +3 -0
  309. package/target/elements/sonner.js +23 -0
  310. package/target/elements/spinner.d.ts +2 -0
  311. package/target/elements/spinner.js +8 -0
  312. package/target/elements/switch.d.ts +5 -0
  313. package/target/elements/switch.js +8 -0
  314. package/target/elements/table.d.ts +9 -0
  315. package/target/elements/table.js +28 -0
  316. package/target/elements/tabs.d.ts +10 -0
  317. package/target/elements/tabs.js +29 -0
  318. package/target/elements/textarea.d.ts +2 -0
  319. package/target/elements/textarea.js +7 -0
  320. package/target/elements/toggle-group.d.ts +10 -0
  321. package/target/elements/toggle-group.js +24 -0
  322. package/target/elements/toggle.d.ts +8 -0
  323. package/target/elements/toggle.js +26 -0
  324. package/target/elements/tooltip.d.ts +6 -0
  325. package/target/elements/tooltip.js +18 -0
  326. package/target/entrypoints/main.js +12 -0
  327. package/target/helpers/article-icon.d.ts +3 -0
  328. package/target/helpers/article-icon.js +34 -0
  329. package/target/helpers/article.d.ts +24 -0
  330. package/target/helpers/article.js +73 -0
  331. package/target/helpers/changelog-source.d.ts +7 -0
  332. package/target/helpers/changelog-source.js +16 -0
  333. package/target/helpers/changelog-source.unit.d.ts +1 -0
  334. package/target/helpers/changelog-source.unit.js +33 -0
  335. package/target/helpers/dynamic-icon-resolver.d.ts +5 -0
  336. package/target/helpers/dynamic-icon-resolver.js +17 -0
  337. package/target/helpers/dynamic-icon.d.ts +5 -0
  338. package/target/helpers/dynamic-icon.js +8 -0
  339. package/target/helpers/favicon.d.ts +2 -0
  340. package/target/helpers/favicon.js +11 -0
  341. package/target/helpers/model.d.ts +3 -0
  342. package/target/helpers/model.js +4 -0
  343. package/target/helpers/program.js +5 -0
  344. package/target/helpers/resolve-asset-path.d.ts +2 -0
  345. package/target/helpers/resolve-asset-path.js +9 -0
  346. package/target/helpers/resolve-includes.d.ts +2 -0
  347. package/target/helpers/resolve-includes.js +113 -0
  348. package/target/helpers/resolve-includes.unit.d.ts +1 -0
  349. package/target/helpers/resolve-includes.unit.js +76 -0
  350. package/target/helpers/search-text.d.ts +2 -0
  351. package/target/helpers/search-text.js +16 -0
  352. package/target/helpers/section.d.ts +13 -0
  353. package/target/helpers/section.js +39 -0
  354. package/target/helpers/section.unit.d.ts +1 -0
  355. package/target/helpers/section.unit.js +62 -0
  356. package/target/helpers/theme.d.ts +5 -0
  357. package/target/helpers/theme.js +23 -0
  358. package/target/helpers/toc-context.d.ts +5 -0
  359. package/target/helpers/toc-context.js +8 -0
  360. package/target/helpers/toc.d.ts +3 -0
  361. package/target/helpers/toc.js +41 -0
  362. package/target/helpers/toc.unit.d.ts +1 -0
  363. package/target/helpers/toc.unit.js +65 -0
  364. package/target/hooks/in-view.d.ts +4 -0
  365. package/target/hooks/in-view.js +23 -0
  366. package/target/hooks/media.d.ts +6 -0
  367. package/target/hooks/media.js +25 -0
  368. package/target/index.js +2 -0
  369. package/target/models/article.d.ts +58 -0
  370. package/target/models/article.js +21 -0
  371. package/{build → target}/models/config.d.ts +10 -0
  372. package/target/models/config.js +34 -0
  373. package/target/models/link.js +9 -0
  374. package/{build → target}/models/patch.d.ts +5 -0
  375. package/target/models/patch.js +7 -0
  376. package/target/models/section.js +26 -0
  377. package/target/models/theme.js +73 -0
  378. package/target/models/toc.d.ts +5 -0
  379. package/target/models/toc.js +2 -0
  380. package/target/plugins/rehype-inline-code.d.ts +19 -0
  381. package/target/plugins/rehype-inline-code.js +55 -0
  382. package/target/plugins/rehype-task-list-a11y.d.ts +10 -0
  383. package/target/plugins/rehype-task-list-a11y.js +29 -0
  384. package/target/plugins/remark-abbr.d.ts +6 -0
  385. package/target/plugins/remark-abbr.js +39 -0
  386. package/target/plugins/remark-abbr.unit.d.ts +1 -0
  387. package/target/plugins/remark-abbr.unit.js +79 -0
  388. package/target/plugins/remark-ansi.d.ts +8 -0
  389. package/target/plugins/remark-ansi.js +239 -0
  390. package/target/plugins/remark-ansi.unit.d.ts +1 -0
  391. package/target/plugins/remark-ansi.unit.js +134 -0
  392. package/target/plugins/remark-badge.d.ts +6 -0
  393. package/target/plugins/remark-badge.js +43 -0
  394. package/target/plugins/remark-badge.unit.d.ts +1 -0
  395. package/target/plugins/remark-badge.unit.js +76 -0
  396. package/target/plugins/remark-button.d.ts +6 -0
  397. package/target/plugins/remark-button.js +52 -0
  398. package/target/plugins/remark-button.unit.d.ts +1 -0
  399. package/target/plugins/remark-button.unit.js +105 -0
  400. package/target/plugins/remark-callout.d.ts +4 -0
  401. package/target/plugins/remark-callout.js +39 -0
  402. package/target/plugins/remark-card.d.ts +4 -0
  403. package/target/plugins/remark-card.js +66 -0
  404. package/target/plugins/remark-code-tabs.d.ts +4 -0
  405. package/target/plugins/remark-code-tabs.js +72 -0
  406. package/target/plugins/remark-columns.d.ts +4 -0
  407. package/target/plugins/remark-columns.js +54 -0
  408. package/target/plugins/remark-custom-heading-id.d.ts +14 -0
  409. package/target/plugins/remark-custom-heading-id.js +54 -0
  410. package/target/plugins/remark-custom-heading-id.unit.d.ts +1 -0
  411. package/target/plugins/remark-custom-heading-id.unit.js +91 -0
  412. package/target/plugins/remark-deflist.d.ts +4 -0
  413. package/target/plugins/remark-deflist.js +31 -0
  414. package/target/plugins/remark-details.d.ts +4 -0
  415. package/target/plugins/remark-details.js +33 -0
  416. package/target/plugins/remark-filetree.d.ts +12 -0
  417. package/target/plugins/remark-filetree.js +61 -0
  418. package/target/plugins/remark-filetree.unit.d.ts +1 -0
  419. package/target/plugins/remark-filetree.unit.js +87 -0
  420. package/target/plugins/remark-github-callout.d.ts +4 -0
  421. package/target/plugins/remark-github-callout.js +62 -0
  422. package/target/plugins/remark-icon.d.ts +4 -0
  423. package/target/plugins/remark-icon.js +36 -0
  424. package/target/plugins/remark-image.d.ts +9 -0
  425. package/target/plugins/remark-image.js +26 -0
  426. package/target/plugins/remark-media.d.ts +6 -0
  427. package/target/plugins/remark-media.js +52 -0
  428. package/target/plugins/remark-media.unit.d.ts +1 -0
  429. package/target/plugins/remark-media.unit.js +54 -0
  430. package/target/plugins/remark-mermaid.d.ts +4 -0
  431. package/target/plugins/remark-mermaid.js +20 -0
  432. package/target/plugins/remark-npm.d.ts +4 -0
  433. package/target/plugins/remark-npm.js +32 -0
  434. package/target/plugins/remark-steps.d.ts +6 -0
  435. package/target/plugins/remark-steps.js +30 -0
  436. package/target/plugins/remark-steps.unit.d.ts +1 -0
  437. package/target/plugins/remark-steps.unit.js +65 -0
  438. package/target/plugins/remark-tab.d.ts +6 -0
  439. package/target/plugins/remark-tab.js +76 -0
  440. package/target/plugins/remark-tab.unit.d.ts +1 -0
  441. package/target/plugins/remark-tab.unit.js +156 -0
  442. package/target/plugins/remark-toc.d.ts +6 -0
  443. package/target/plugins/remark-toc.js +33 -0
  444. package/target/plugins/remark-toc.unit.d.ts +1 -0
  445. package/target/plugins/remark-toc.unit.js +57 -0
  446. package/target/plugins/shiki-icon.d.ts +16 -0
  447. package/target/plugins/shiki-icon.js +66 -0
  448. package/target/plugins/shiki-line-highlight.d.ts +27 -0
  449. package/target/plugins/shiki-line-highlight.js +140 -0
  450. package/target/plugins/vite-livemark.d.ts +13 -0
  451. package/target/plugins/vite-livemark.js +76 -0
  452. package/target/program.js +18 -0
  453. package/target/routeTree.gen.d.ts +57 -0
  454. package/target/routeTree.gen.js +27 -0
  455. package/target/router.d.ts +6 -0
  456. package/target/router.js +26 -0
  457. package/target/routes/$.d.ts +1 -0
  458. package/target/routes/$.js +85 -0
  459. package/target/routes/__root.d.ts +1 -0
  460. package/target/routes/__root.js +69 -0
  461. package/target/server.d.ts +2 -0
  462. package/target/server.js +7 -0
  463. package/target/settings.js +7 -0
  464. package/target/utils/style.d.ts +2 -0
  465. package/target/utils/style.js +6 -0
  466. package/target/vite.config.d.ts +2 -0
  467. package/target/vite.config.js +67 -0
  468. package/build/actions/changelog/build.js +0 -158
  469. package/build/actions/changelog/build.unit.js +0 -66
  470. package/build/actions/config/define.js +0 -8
  471. package/build/actions/config/define.unit.js +0 -29
  472. package/build/actions/config/load.js +0 -25
  473. package/build/actions/config/load.unit.js +0 -23
  474. package/build/commands/build.js +0 -14
  475. package/build/commands/escape.js +0 -56
  476. package/build/commands/preview.js +0 -18
  477. package/build/commands/start.js +0 -19
  478. package/build/docs/markdown/includes/example.d.ts +0 -58
  479. package/build/docs/markdown/includes/example.js +0 -5
  480. package/build/entrypoints/main.js +0 -12
  481. package/build/helpers/program.js +0 -5
  482. package/build/index.js +0 -2
  483. package/build/livemark.config.d.ts +0 -58
  484. package/build/livemark.config.js +0 -25
  485. package/build/models/config.js +0 -34
  486. package/build/models/link.js +0 -9
  487. package/build/models/patch.js +0 -7
  488. package/build/models/section.js +0 -26
  489. package/build/models/theme.js +0 -73
  490. package/build/package.json +0 -138
  491. package/build/program.js +0 -18
  492. package/build/settings.js +0 -7
  493. package/build/vite.config.d.ts +0 -2
  494. package/build/vite.config.js +0 -48
  495. package/build/website/components/BlogSidebar.tsx +0 -162
  496. package/build/website/components/ChangelogSidebar.tsx +0 -120
  497. package/build/website/hooks/media.ts +0 -19
  498. package/build/website/routeTree.gen.ts +0 -86
  499. /package/{build/website → source}/assets/logo.svg +0 -0
  500. /package/{build/website → source}/client.tsx +0 -0
  501. /package/{build/website → source}/components/Abbr.tsx +0 -0
  502. /package/{build/website → source}/components/AnsiCode.tsx +0 -0
  503. /package/{build/website → source}/components/BackToTop.tsx +0 -0
  504. /package/{build/website → source}/components/Banner.tsx +0 -0
  505. /package/{build/website → source}/components/BlogIndex.tsx +0 -0
  506. /package/{build/website → source}/components/Breadcrumbs.tsx +0 -0
  507. /package/{build/website → source}/components/Card.tsx +0 -0
  508. /package/{build/website → source}/components/Cards.tsx +0 -0
  509. /package/{build/website → source}/components/ChangelogIndex.tsx +0 -0
  510. /package/{build/website → source}/components/CodeBlock.tsx +0 -0
  511. /package/{build/website → source}/components/CodeTabs.tsx +0 -0
  512. /package/{build/website → source}/components/Column.tsx +0 -0
  513. /package/{build/website → source}/components/Columns.tsx +0 -0
  514. /package/{build/website → source}/components/Content.tsx +0 -0
  515. /package/{build/website → source}/components/ContentTab.tsx +0 -0
  516. /package/{build/website → source}/components/ContentTabs.tsx +0 -0
  517. /package/{build/website → source}/components/DefaultCatchBoundary.tsx +0 -0
  518. /package/{build/website → source}/components/DefinitionList.tsx +0 -0
  519. /package/{build/website → source}/components/Details.tsx +0 -0
  520. /package/{build/website → source}/components/FileTree.tsx +0 -0
  521. /package/{build/website → source}/components/Footer.tsx +0 -0
  522. /package/{build/website → source}/components/FootnoteRef.tsx +0 -0
  523. /package/{build/website → source}/components/Heading.tsx +0 -0
  524. /package/{build/website → source}/components/InlineBadge.tsx +0 -0
  525. /package/{build/website → source}/components/InlineIcon.tsx +0 -0
  526. /package/{build/website → source}/components/InlineToc.tsx +0 -0
  527. /package/{build/website → source}/components/Mermaid.tsx +0 -0
  528. /package/{build/website → source}/components/MermaidRenderer.tsx +0 -0
  529. /package/{build/website → source}/components/NotFound.tsx +0 -0
  530. /package/{build/website → source}/components/PackageTabs.tsx +0 -0
  531. /package/{build/website → source}/components/PrevNext.tsx +0 -0
  532. /package/{build/website → source}/components/Search.tsx +0 -0
  533. /package/{build/website → source}/components/SearchDialog.tsx +0 -0
  534. /package/{build/website → source}/components/SidebarLinks.tsx +0 -0
  535. /package/{build/website → source}/components/SidebarSections.tsx +0 -0
  536. /package/{build/website → source}/components/SiteTitle.tsx +0 -0
  537. /package/{build/website → source}/components/SortableTable.tsx +0 -0
  538. /package/{build/website → source}/components/SoundCloud.tsx +0 -0
  539. /package/{build/website → source}/components/TagIndex.tsx +0 -0
  540. /package/{build/website → source}/components/Theme.tsx +0 -0
  541. /package/{build/website → source}/components/Toc.tsx +0 -0
  542. /package/{build/website → source}/components/YouTube.tsx +0 -0
  543. /package/{build/website → source}/components/ZoomImage.tsx +0 -0
  544. /package/{build/website → source}/content/article.ts +0 -0
  545. /package/{build/website → source}/content/tag.ts +0 -0
  546. /package/{build/website → source}/elements/collapsible.tsx +0 -0
  547. /package/{build/website → source}/elements/direction.tsx +0 -0
  548. /package/{build/website → source}/elements/sonner.tsx +0 -0
  549. /package/{build/website → source}/helpers/article-icon.ts +0 -0
  550. /package/{build/website → source}/helpers/article.ts +0 -0
  551. /package/{build/website → source}/helpers/changelog-source.ts +0 -0
  552. /package/{build/website → source}/helpers/changelog-source.unit.ts +0 -0
  553. /package/{build/website → source}/helpers/dynamic-icon-resolver.tsx +0 -0
  554. /package/{build/website → source}/helpers/dynamic-icon.tsx +0 -0
  555. /package/{build/website → source}/helpers/favicon.ts +0 -0
  556. /package/{build/website → source}/helpers/model.ts +0 -0
  557. /package/{build/website → source}/helpers/resolve-asset-path.ts +0 -0
  558. /package/{build/website → source}/helpers/resolve-includes.ts +0 -0
  559. /package/{build/website → source}/helpers/resolve-includes.unit.ts +0 -0
  560. /package/{build/website → source}/helpers/search-text.ts +0 -0
  561. /package/{build/website → source}/helpers/section.unit.ts +0 -0
  562. /package/{build/website → source}/helpers/theme.ts +0 -0
  563. /package/{build/website → source}/helpers/toc-context.ts +0 -0
  564. /package/{build/website → source}/helpers/toc.ts +0 -0
  565. /package/{build/website → source}/helpers/toc.unit.ts +0 -0
  566. /package/{build/website → source}/hooks/in-view.ts +0 -0
  567. /package/{build/website → source}/models/toc.ts +0 -0
  568. /package/{build/website → source}/plugins/rehype-inline-code.ts +0 -0
  569. /package/{build/website → source}/plugins/rehype-task-list-a11y.ts +0 -0
  570. /package/{build/website → source}/plugins/remark-abbr.ts +0 -0
  571. /package/{build/website → source}/plugins/remark-abbr.unit.ts +0 -0
  572. /package/{build/website → source}/plugins/remark-ansi.ts +0 -0
  573. /package/{build/website → source}/plugins/remark-ansi.unit.ts +0 -0
  574. /package/{build/website → source}/plugins/remark-badge.ts +0 -0
  575. /package/{build/website → source}/plugins/remark-badge.unit.ts +0 -0
  576. /package/{build/website → source}/plugins/remark-button.ts +0 -0
  577. /package/{build/website → source}/plugins/remark-button.unit.ts +0 -0
  578. /package/{build/website → source}/plugins/remark-callout.ts +0 -0
  579. /package/{build/website → source}/plugins/remark-card.ts +0 -0
  580. /package/{build/website → source}/plugins/remark-code-tabs.ts +0 -0
  581. /package/{build/website → source}/plugins/remark-columns.ts +0 -0
  582. /package/{build/website → source}/plugins/remark-custom-heading-id.ts +0 -0
  583. /package/{build/website → source}/plugins/remark-custom-heading-id.unit.ts +0 -0
  584. /package/{build/website → source}/plugins/remark-deflist.ts +0 -0
  585. /package/{build/website → source}/plugins/remark-details.ts +0 -0
  586. /package/{build/website → source}/plugins/remark-filetree.ts +0 -0
  587. /package/{build/website → source}/plugins/remark-filetree.unit.ts +0 -0
  588. /package/{build/website → source}/plugins/remark-github-callout.ts +0 -0
  589. /package/{build/website → source}/plugins/remark-icon.ts +0 -0
  590. /package/{build/website → source}/plugins/remark-image.ts +0 -0
  591. /package/{build/website → source}/plugins/remark-media.ts +0 -0
  592. /package/{build/website → source}/plugins/remark-media.unit.ts +0 -0
  593. /package/{build/website → source}/plugins/remark-mermaid.ts +0 -0
  594. /package/{build/website → source}/plugins/remark-npm.ts +0 -0
  595. /package/{build/website → source}/plugins/remark-steps.ts +0 -0
  596. /package/{build/website → source}/plugins/remark-steps.unit.ts +0 -0
  597. /package/{build/website → source}/plugins/remark-tab.ts +0 -0
  598. /package/{build/website → source}/plugins/remark-tab.unit.ts +0 -0
  599. /package/{build/website → source}/plugins/remark-toc.ts +0 -0
  600. /package/{build/website → source}/plugins/remark-toc.unit.ts +0 -0
  601. /package/{build/website → source}/plugins/shiki-icon.ts +0 -0
  602. /package/{build/website → source}/plugins/shiki-line-highlight.ts +0 -0
  603. /package/{build/website → source}/plugins/vite-livemark.ts +0 -0
  604. /package/{build/website → source}/router.tsx +0 -0
  605. /package/{build/website → source}/routes/$.tsx +0 -0
  606. /package/{build/website → source}/routes/__root.tsx +0 -0
  607. /package/{build/website → source}/server.ts +0 -0
  608. /package/{build/website → source}/styles/general.css +0 -0
  609. /package/{build/website → source}/styles/markdown.css +0 -0
  610. /package/{build/website/helpers → source/utils}/style.ts +0 -0
  611. /package/{build → target}/actions/changelog/build.unit.d.ts +0 -0
  612. /package/{build → target}/actions/config/define.d.ts +0 -0
  613. /package/{build → target}/actions/config/define.unit.d.ts +0 -0
  614. /package/{build → target}/actions/config/load.d.ts +0 -0
  615. /package/{build → target}/actions/config/load.unit.d.ts +0 -0
  616. /package/{build → target}/commands/build.d.ts +0 -0
  617. /package/{build → target}/commands/escape.d.ts +0 -0
  618. /package/{build → target}/commands/preview.d.ts +0 -0
  619. /package/{build → target}/commands/start.d.ts +0 -0
  620. /package/{build → target}/entrypoints/main.d.ts +0 -0
  621. /package/{build → target}/helpers/program.d.ts +0 -0
  622. /package/{build → target}/index.d.ts +0 -0
  623. /package/{build → target}/models/link.d.ts +0 -0
  624. /package/{build → target}/models/section.d.ts +0 -0
  625. /package/{build → target}/models/theme.d.ts +0 -0
  626. /package/{build → target}/program.d.ts +0 -0
  627. /package/{build → target}/settings.d.ts +0 -0
@@ -1,5 +1,5 @@
1
1
  interface ImportMetaEnv {
2
- readonly CONFIG: import("../models/config.ts").WebsiteConfig
2
+ readonly CONFIG: import("./models/config.ts").WebsiteConfig
3
3
  }
4
4
 
5
5
  declare module "content-collections" {
@@ -0,0 +1,6 @@
1
+ import type { HelpConfiguration } from "commander"
2
+ import pc from "picocolors"
3
+
4
+ export const helpConfiguration: HelpConfiguration = {
5
+ styleTitle: str => pc.bold(str.toUpperCase().replace(":", "")),
6
+ }
@@ -1,4 +1,4 @@
1
- import type { Section } from "../../models/section.ts"
1
+ import type { Section } from "../models/section.ts"
2
2
 
3
3
  const DEFAULT_ICONS: Record<Section["type"], string> = {
4
4
  article: "book-open",
@@ -0,0 +1,29 @@
1
+ import { useSyncExternalStore } from "react"
2
+
3
+ export const MOBILE_BREAKPOINT = 768
4
+
5
+ export function useIsMobile() {
6
+ return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)
7
+ }
8
+
9
+ /** Synchronous, render-cycle-independent check.
10
+ * Use at event-handler call sites where React state may be momentarily stale
11
+ * (e.g. right after a SidebarProvider key remount). */
12
+ export function isMobileNow() {
13
+ if (typeof window === "undefined") return false
14
+ return window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`).matches
15
+ }
16
+
17
+ function subscribe(callback: () => void) {
18
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
19
+ mql.addEventListener("change", callback)
20
+ return () => mql.removeEventListener("change", callback)
21
+ }
22
+
23
+ function getSnapshot() {
24
+ return window.innerWidth < MOBILE_BREAKPOINT
25
+ }
26
+
27
+ function getServerSnapshot() {
28
+ return false
29
+ }
@@ -0,0 +1 @@
1
+ export { defineConfig } from "./actions/config/define.ts"
@@ -19,11 +19,14 @@ export const Article = z.object({
19
19
  author: z.union([nonEmptyString, z.array(nonEmptyString)]).optional(),
20
20
  date: nonEmptyString.optional(),
21
21
  tags: z.array(nonEmptyString).optional(),
22
+ sourceUrl: nonEmptyString.optional(),
23
+ sourceAction: z.enum(["edit", "view"]).default("edit"),
22
24
  })
23
25
 
24
26
  /** Processed article ready for page rendering (result of content-collections transform). */
25
27
  export interface ArticleView {
26
28
  path: string
29
+ title: string
27
30
  content: string
28
31
  file: string
29
32
  mdx: string
@@ -35,6 +38,8 @@ export interface ArticleView {
35
38
  author?: string | string[]
36
39
  date?: string
37
40
  tags?: string[]
41
+ sourceUrl?: string
42
+ sourceAction?: "edit" | "view"
38
43
  }
39
44
 
40
45
  export interface ArticleNode {
@@ -0,0 +1,51 @@
1
+ import { z } from "zod"
2
+ import { Link } from "./link.ts"
3
+ import { Patch } from "./patch.ts"
4
+ import { Section } from "./section.ts"
5
+ import { CodeThemeDark, CodeThemeLight } from "./theme.ts"
6
+
7
+ /**
8
+ * User-provided configuration for Livemark.
9
+ */
10
+ export type UserConfig = z.infer<typeof UserConfig>
11
+ export const UserConfig = z.object({
12
+ site: z.string().optional(),
13
+ favicon: z.string().optional(),
14
+ logo: z.string().optional(),
15
+ title: z.string().default("Livemark"),
16
+ description: z.string().default("Markdown site generator"),
17
+ include: z.union([z.string(), z.array(z.string())]),
18
+ exclude: z.union([z.string(), z.array(z.string())]).optional(),
19
+ codeThemeLight: CodeThemeLight.default("catppuccin-latte"),
20
+ codeThemeDark: CodeThemeDark.default("catppuccin-mocha"),
21
+ links: z.array(Link).optional(),
22
+ sections: z.array(Section).optional(),
23
+ patches: z.array(Patch).optional(),
24
+ })
25
+
26
+ /** Website configuration injected at build time via Vite define */
27
+ export type WebsiteConfig = z.infer<typeof WebsiteConfig>
28
+ export const WebsiteConfig = UserConfig.pick({
29
+ title: true,
30
+ description: true,
31
+ site: true,
32
+ favicon: true,
33
+ logo: true,
34
+ links: true,
35
+ sections: true,
36
+ })
37
+
38
+ /**
39
+ * System-computed configuration derived from the config file location.
40
+ */
41
+ export type SystemConfig = z.infer<typeof SystemConfig>
42
+ export const SystemConfig = z.object({
43
+ root: z.string(),
44
+ configPath: z.string(),
45
+ })
46
+
47
+ /**
48
+ * Fully resolved Livemark configuration.
49
+ */
50
+ export type Config = z.infer<typeof Config>
51
+ export const Config = UserConfig.merge(SystemConfig)
@@ -0,0 +1,11 @@
1
+ import { z } from "zod"
2
+
3
+ /** Header or sidebar link to an external URL. */
4
+ export type Link = z.infer<typeof Link>
5
+ export const Link = z.object({
6
+ url: z.string(),
7
+ title: z.string(),
8
+ icon: z.string().optional(),
9
+ prefix: z.string().optional(),
10
+ position: z.enum(["header", "sidebar"]).default("header"),
11
+ })
@@ -0,0 +1,9 @@
1
+ import { z } from "zod"
2
+ import { Article } from "./article.ts"
3
+
4
+ /** Per-file override for article frontmatter provided via `livemark.config.ts`. */
5
+ export type Patch = z.infer<typeof Patch>
6
+ export const Patch = z.object({
7
+ file: z.string(),
8
+ article: Article.omit({ content: true }).partial().strict(),
9
+ })
@@ -0,0 +1,45 @@
1
+ import { z } from "zod"
2
+
3
+ const BaseSection = z.object({
4
+ icon: z.string().optional(),
5
+ title: z.string(),
6
+ prefix: z.string(),
7
+ position: z.enum(["header", "sidebar"]).default("header"),
8
+ })
9
+
10
+ /** Default section: renders articles. */
11
+ export type ArticleSection = z.infer<typeof ArticleSection>
12
+ export const ArticleSection = BaseSection.extend({
13
+ type: z.literal("article"),
14
+ })
15
+
16
+ /** Blog section: date-sorted posts with tags and index. */
17
+ export type BlogSection = z.infer<typeof BlogSection>
18
+ export const BlogSection = BaseSection.extend({
19
+ type: z.literal("blog"),
20
+ })
21
+
22
+ /** Changelog section: single file or GitHub releases, split per version. */
23
+ export type ChangelogSection = z.infer<typeof ChangelogSection>
24
+ export const ChangelogSection = BaseSection.extend({
25
+ type: z.literal("changelog"),
26
+ source: z.string(),
27
+ version: z.boolean().optional(),
28
+ })
29
+
30
+ /**
31
+ * A site section. Discriminated on `type`.
32
+ * When `type` is omitted, it defaults to "article" so plain
33
+ * `{ title, prefix }` entries keep working.
34
+ */
35
+ export type Section = z.infer<typeof Section>
36
+ export const Section = z.preprocess(
37
+ input => {
38
+ if (input === null || typeof input !== "object" || Array.isArray(input)) {
39
+ return input
40
+ }
41
+ const record = input as Record<string, unknown>
42
+ return "type" in record ? record : { ...record, type: "article" }
43
+ },
44
+ z.discriminatedUnion("type", [ArticleSection, BlogSection, ChangelogSection]),
45
+ )
@@ -0,0 +1,74 @@
1
+ import { z } from "zod"
2
+
3
+ /** Light syntax highlighting theme (Shiki) */
4
+ export const CodeThemeLight = z.enum([
5
+ "ayu-light",
6
+ "catppuccin-latte",
7
+ "everforest-light",
8
+ "github-light",
9
+ "github-light-default",
10
+ "github-light-high-contrast",
11
+ "gruvbox-light-hard",
12
+ "gruvbox-light-medium",
13
+ "gruvbox-light-soft",
14
+ "horizon-bright",
15
+ "kanagawa-lotus",
16
+ "light-plus",
17
+ "material-theme-lighter",
18
+ "min-light",
19
+ "night-owl-light",
20
+ "one-light",
21
+ "rose-pine-dawn",
22
+ "slack-ochin",
23
+ "snazzy-light",
24
+ "solarized-light",
25
+ "vitesse-light",
26
+ ])
27
+
28
+ /** Dark syntax highlighting theme (Shiki) */
29
+ export const CodeThemeDark = z.enum([
30
+ "andromeeda",
31
+ "aurora-x",
32
+ "ayu-dark",
33
+ "ayu-mirage",
34
+ "catppuccin-frappe",
35
+ "catppuccin-macchiato",
36
+ "catppuccin-mocha",
37
+ "dark-plus",
38
+ "dracula",
39
+ "dracula-soft",
40
+ "everforest-dark",
41
+ "github-dark",
42
+ "github-dark-default",
43
+ "github-dark-dimmed",
44
+ "github-dark-high-contrast",
45
+ "gruvbox-dark-hard",
46
+ "gruvbox-dark-medium",
47
+ "gruvbox-dark-soft",
48
+ "horizon",
49
+ "houston",
50
+ "kanagawa-dragon",
51
+ "kanagawa-wave",
52
+ "laserwave",
53
+ "material-theme",
54
+ "material-theme-darker",
55
+ "material-theme-ocean",
56
+ "material-theme-palenight",
57
+ "min-dark",
58
+ "monokai",
59
+ "night-owl",
60
+ "nord",
61
+ "one-dark-pro",
62
+ "plastic",
63
+ "poimandres",
64
+ "red",
65
+ "rose-pine",
66
+ "rose-pine-moon",
67
+ "slack-dark",
68
+ "solarized-dark",
69
+ "synthwave-84",
70
+ "tokyo-night",
71
+ "vesper",
72
+ "vitesse-black",
73
+ "vitesse-dark",
74
+ ])
@@ -0,0 +1,18 @@
1
+ import { Command } from "commander"
2
+ import { build } from "./commands/build.ts"
3
+ import { escape } from "./commands/escape.ts"
4
+ import { preview } from "./commands/preview.ts"
5
+ import { start } from "./commands/start.ts"
6
+ import { helpConfiguration } from "./helpers/program.ts"
7
+ import packageJson from "../package.json" with { type: "json" }
8
+
9
+ export const program = new Command()
10
+ .name("livemark")
11
+ .description("Livemark static site generator")
12
+ .version(packageJson.version, "-v, --version", "display the livemark version")
13
+ .option("-c, --config <path>", "path to config file")
14
+ .configureHelp(helpConfiguration)
15
+ .addCommand(start)
16
+ .addCommand(build)
17
+ .addCommand(preview)
18
+ .addCommand(escape)
@@ -0,0 +1,6 @@
1
+ /** Sub-directories of `website/` that participate in the override mechanism. */
2
+ export const OVERRIDE_SUBDIRS: readonly string[] = [
3
+ "components",
4
+ "elements",
5
+ "styles",
6
+ ]
@@ -13,14 +13,14 @@ import {
13
13
  import react from "@vitejs/plugin-react"
14
14
  import { defineConfig } from "vite"
15
15
  import svgr from "vite-plugin-svgr"
16
- import { loadConfig } from "../actions/config/load.ts"
17
- import { WebsiteConfig } from "../models/config.ts"
18
- import { OVERRIDE_SUBDIRS } from "../settings.ts"
16
+ import { loadConfig } from "./actions/config/load.ts"
17
+ import { WebsiteConfig } from "./models/config.ts"
18
+ import { OVERRIDE_SUBDIRS } from "./settings.ts"
19
19
  import { livemark } from "./plugins/vite-livemark.ts"
20
20
 
21
21
  const config = await loadConfig()
22
- const websiteDir = import.meta.dirname
23
- const websiteRelative = relative(config.root, websiteDir)
22
+ const sourceDir = import.meta.dirname
23
+ const sourceRelative = relative(config.root, sourceDir)
24
24
  const overridesRoot = join(config.root, ".livemark")
25
25
 
26
26
  // Seed `.livemark/.gitignore` on first run so Vite's build/cache artifacts
@@ -33,7 +33,12 @@ if (!existsSync(gitignorePath)) {
33
33
 
34
34
  const routeChildren: VirtualRouteNode[] = [route("/$", "$.tsx")]
35
35
  if (existsSync(join(overridesRoot, "routes"))) {
36
- routeChildren.push(physical("../../.livemark/routes"))
36
+ // physical() resolves its argument relative to this file. Hardcoding a
37
+ // relative literal lands at <pkg>/.livemark/ when livemark is installed
38
+ // under node_modules/. Compute it from the consumer's overridesRoot.
39
+ routeChildren.push(
40
+ physical(relative(sourceDir, join(overridesRoot, "routes"))),
41
+ )
37
42
  }
38
43
 
39
44
  export default defineConfig({
@@ -45,7 +50,7 @@ export default defineConfig({
45
50
  },
46
51
  plugins: [
47
52
  livemark({
48
- defaultsRoot: websiteDir,
53
+ defaultsRoot: sourceDir,
49
54
  overridesRoot,
50
55
  subdirs: [...OVERRIDE_SUBDIRS],
51
56
  configPath: config.configPath,
@@ -53,10 +58,10 @@ export default defineConfig({
53
58
  devtools(),
54
59
  tailwind(),
55
60
  contentCollections({
56
- configPath: join(websiteRelative, "content-collections.ts"),
61
+ configPath: join(sourceRelative, "content-collections.ts"),
57
62
  }),
58
63
  tanstackStart({
59
- srcDirectory: websiteRelative,
64
+ srcDirectory: sourceRelative,
60
65
  pages: [{ path: "/" }],
61
66
  prerender: { enabled: true, crawlLinks: true },
62
67
  sitemap: config.site
@@ -5,6 +5,7 @@ interface ChangelogEntry {
5
5
  title: string;
6
6
  date?: string;
7
7
  body: string;
8
+ sourceUrl?: string;
8
9
  }
9
10
  export declare function cacheIncludeGlob(): string;
10
11
  /** Build the per-version changelog cache files for a changelog section */
@@ -0,0 +1,187 @@
1
+ import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import slugify from "@sindresorhus/slugify";
4
+ import { toString as mdastToString } from "mdast-util-to-string";
5
+ import remarkParse from "remark-parse";
6
+ import remarkStringify from "remark-stringify";
7
+ import { unified } from "unified";
8
+ import { visit } from "unist-util-visit";
9
+ import { isGitHubUrl, parseGitHubRepo } from "../../helpers/changelog-source.js";
10
+ const CACHE_DIR = ".livemark/cache/changelog";
11
+ const META_FILE = ".livemark/cache/changelog.meta.json";
12
+ const parser = unified().use(remarkParse);
13
+ const stringifier = unified().use(remarkStringify, {
14
+ bullet: "-",
15
+ fences: true,
16
+ emphasis: "_",
17
+ });
18
+ export function cacheIncludeGlob() {
19
+ return `${CACHE_DIR}/**/*.md`;
20
+ }
21
+ /** Build the per-version changelog cache files for a changelog section */
22
+ export async function buildChangelog(section, config) {
23
+ const cacheDir = join(config.root, CACHE_DIR);
24
+ const metaPath = join(config.root, META_FILE);
25
+ const entries = isGitHubUrl(section.source)
26
+ ? await buildFromGitHub(section.source, metaPath, cacheDir)
27
+ : await buildFromLocal(section.source, config.root);
28
+ if (entries === undefined)
29
+ return;
30
+ await rm(cacheDir, { recursive: true, force: true });
31
+ await mkdir(cacheDir, { recursive: true });
32
+ for (const entry of entries) {
33
+ const markdown = wrapFrontmatter(entry, section);
34
+ await writeFile(join(cacheDir, `${entry.slug}.md`), markdown, "utf-8");
35
+ }
36
+ }
37
+ async function buildFromLocal(source, root) {
38
+ const filePath = resolve(root, source);
39
+ const body = await readFile(filePath, "utf-8");
40
+ return splitLocalChangelog(body);
41
+ }
42
+ /** Parse CHANGELOG.md into per-version entries using mdast */
43
+ export function splitLocalChangelog(body) {
44
+ const tree = parser.parse(body);
45
+ const entries = [];
46
+ let current;
47
+ for (const child of tree.children) {
48
+ if (child.type === "heading" && child.depth === 2) {
49
+ if (current)
50
+ entries.push(finalizeEntry(current));
51
+ current = { heading: mdastToString(child), children: [] };
52
+ }
53
+ else if (current) {
54
+ current.children.push(child);
55
+ }
56
+ }
57
+ if (current)
58
+ entries.push(finalizeEntry(current));
59
+ return entries;
60
+ }
61
+ function finalizeEntry(input) {
62
+ const versionMatch = input.heading.match(/^\[?([^\]\s]+)\]?/);
63
+ const version = versionMatch?.[1] ?? input.heading;
64
+ const dateMatch = input.heading.match(/\d{4}-\d{2}-\d{2}/);
65
+ const body = renderEntryBody(input.children);
66
+ return {
67
+ slug: slugify(version),
68
+ title: version,
69
+ date: dateMatch?.[0],
70
+ body,
71
+ };
72
+ }
73
+ /** Serialize an entry's mdast children back to markdown */
74
+ function renderEntryBody(children) {
75
+ const root = { type: "root", children };
76
+ return stringifier.stringify(root).trimEnd();
77
+ }
78
+ /** Drop the body's leading h1 (typically the conventional-changelog
79
+ * `# 0.7.2 (2026-04-25)` boilerplate that duplicates the article's title),
80
+ * shift h2–h6 up by one so subsection headings become h1 / h2 / …, and
81
+ * escape stray `<` outside code so MDX doesn't mistake them for JSX. */
82
+ function processBody(body) {
83
+ const tree = parser.parse(body);
84
+ visit(tree, "heading", node => {
85
+ if (node.depth > 1)
86
+ node.depth = (node.depth - 1);
87
+ });
88
+ if (tree.children[0]?.type === "heading" && tree.children[0].depth === 1) {
89
+ tree.children.shift();
90
+ }
91
+ return escapeMdxAngles(stringifier.stringify(tree).trimEnd());
92
+ }
93
+ /** Escape `<` to `\<` outside fenced code blocks and inline backtick spans
94
+ * so commit messages with placeholders like `<subdir>` don't get parsed as
95
+ * JSX by MDX. */
96
+ function escapeMdxAngles(markdown) {
97
+ let inFence = false;
98
+ return markdown
99
+ .split("\n")
100
+ .map(line => {
101
+ if (line.startsWith("```")) {
102
+ inFence = !inFence;
103
+ return line;
104
+ }
105
+ if (inFence)
106
+ return line;
107
+ return line.replace(/`[^`]*`|</g, match => match === "<" ? "\\<" : match);
108
+ })
109
+ .join("\n");
110
+ }
111
+ async function buildFromGitHub(source, metaPath, cacheDir) {
112
+ const parsed = parseGitHubRepo(source);
113
+ if (!parsed) {
114
+ throw new Error(`Could not parse GitHub repo from source: ${source}`);
115
+ }
116
+ const url = `https://api.github.com/repos/${parsed.owner}/${parsed.repo}/releases?per_page=100`;
117
+ const headers = {
118
+ Accept: "application/vnd.github+json",
119
+ "X-GitHub-Api-Version": "2022-11-28",
120
+ };
121
+ const token = process.env.GITHUB_TOKEN;
122
+ if (token)
123
+ headers.Authorization = `Bearer ${token}`;
124
+ const meta = await readMeta(metaPath);
125
+ const hasCache = await exists(cacheDir);
126
+ if (meta && hasCache)
127
+ headers["If-None-Match"] = meta.etag;
128
+ const res = await fetch(url, { headers });
129
+ if (res.status === 304)
130
+ return undefined;
131
+ if (!res.ok) {
132
+ const remaining = res.headers.get("x-ratelimit-remaining");
133
+ const reset = res.headers.get("x-ratelimit-reset");
134
+ const msg = `GitHub API ${res.status} ${res.statusText} (rate-limit remaining: ${remaining ?? "?"}, reset: ${reset ?? "?"})`;
135
+ if (hasCache) {
136
+ console.warn(`${msg} — falling back to cached changelog`);
137
+ return undefined;
138
+ }
139
+ throw new Error(msg);
140
+ }
141
+ const releases = (await res.json());
142
+ const etag = res.headers.get("etag");
143
+ if (etag) {
144
+ await mkdir(dirname(metaPath), { recursive: true });
145
+ await writeFile(metaPath, JSON.stringify({ etag, fetchedAt: new Date().toISOString() }, null, 2), "utf-8");
146
+ }
147
+ return releases.map(release => ({
148
+ slug: slugify(release.tag_name),
149
+ title: release.tag_name,
150
+ date: release.published_at ?? undefined,
151
+ body: (release.body ?? "").trim(),
152
+ sourceUrl: release.html_url ?? undefined,
153
+ }));
154
+ }
155
+ function wrapFrontmatter(entry, section) {
156
+ const lines = [
157
+ "---",
158
+ `title: ${entry.title}`,
159
+ `path: ${section.prefix}${entry.slug}/`,
160
+ ];
161
+ if (entry.date)
162
+ lines.push(`date: ${entry.date}`);
163
+ if (entry.sourceUrl) {
164
+ lines.push(`sourceUrl: ${entry.sourceUrl}`, "sourceAction: view");
165
+ }
166
+ lines.push("---", "", `# ${entry.title}`, "", processBody(entry.body));
167
+ return lines.join("\n");
168
+ }
169
+ async function readMeta(metaPath) {
170
+ try {
171
+ const raw = await readFile(metaPath, "utf-8");
172
+ return JSON.parse(raw);
173
+ }
174
+ catch {
175
+ return undefined;
176
+ }
177
+ }
178
+ async function exists(path) {
179
+ try {
180
+ await access(path);
181
+ return true;
182
+ }
183
+ catch {
184
+ return false;
185
+ }
186
+ }
187
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvYWN0aW9ucy9jaGFuZ2Vsb2cvYnVpbGQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUN6RSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDbEQsT0FBTyxPQUFPLE1BQU0sdUJBQXVCLENBQUE7QUFFM0MsT0FBTyxFQUFFLFFBQVEsSUFBSSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUNoRSxPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUE7QUFDdEMsT0FBTyxlQUFlLE1BQU0sa0JBQWtCLENBQUE7QUFDOUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUNqQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFHeEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQTtBQXVCaEYsTUFBTSxTQUFTLEdBQUcsMkJBQTJCLENBQUE7QUFDN0MsTUFBTSxTQUFTLEdBQUcscUNBQXFDLENBQUE7QUFFdkQsTUFBTSxNQUFNLEdBQUcsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFBO0FBQ3pDLE1BQU0sV0FBVyxHQUFHLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUU7SUFDakQsTUFBTSxFQUFFLEdBQUc7SUFDWCxNQUFNLEVBQUUsSUFBSTtJQUNaLFFBQVEsRUFBRSxHQUFHO0NBQ2QsQ0FBQyxDQUFBO0FBRUYsTUFBTSxVQUFVLGdCQUFnQjtJQUM5QixPQUFPLEdBQUcsU0FBUyxVQUFVLENBQUE7QUFDL0IsQ0FBQztBQUVELDBFQUEwRTtBQUMxRSxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FDbEMsT0FBeUIsRUFDekIsTUFBYztJQUVkLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQzdDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBRTdDLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxNQUFNLGVBQWUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUM7UUFDM0QsQ0FBQyxDQUFDLE1BQU0sY0FBYyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBRXJELElBQUksT0FBTyxLQUFLLFNBQVM7UUFBRSxPQUFNO0lBRWpDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDcEQsTUFBTSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFFMUMsS0FBSyxNQUFNLEtBQUssSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUM1QixNQUFNLFFBQVEsR0FBRyxlQUFlLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQ2hELE1BQU0sU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDeEUsQ0FBQztBQUNILENBQUM7QUFFRCxLQUFLLFVBQVUsY0FBYyxDQUFDLE1BQWMsRUFBRSxJQUFZO0lBQ3hELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDdEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQzlDLE9BQU8sbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDbEMsQ0FBQztBQUVELDhEQUE4RDtBQUM5RCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsSUFBWTtJQUM5QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBUyxDQUFBO0lBQ3ZDLE1BQU0sT0FBTyxHQUFxQixFQUFFLENBQUE7SUFDcEMsSUFBSSxPQUFpRSxDQUFBO0lBRXJFLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2xDLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsRCxJQUFJLE9BQU87Z0JBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQTtZQUNqRCxPQUFPLEdBQUcsRUFBRSxPQUFPLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQTtRQUMzRCxDQUFDO2FBQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNuQixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUM5QixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksT0FBTztRQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7SUFDakQsT0FBTyxPQUFPLENBQUE7QUFDaEIsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLEtBR3RCO0lBQ0MsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtJQUM3RCxNQUFNLE9BQU8sR0FBRyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFBO0lBQ2xELE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUE7SUFDMUQsTUFBTSxJQUFJLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUM1QyxPQUFPO1FBQ0wsSUFBSSxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDdEIsS0FBSyxFQUFFLE9BQU87UUFDZCxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3BCLElBQUk7S0FDTCxDQUFBO0FBQ0gsQ0FBQztBQUVELDJEQUEyRDtBQUMzRCxTQUFTLGVBQWUsQ0FBQyxRQUF1QjtJQUM5QyxNQUFNLElBQUksR0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUE7SUFDN0MsT0FBTyxXQUFXLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFBO0FBQzlDLENBQUM7QUFFRDs7O3dFQUd3RTtBQUN4RSxTQUFTLFdBQVcsQ0FBQyxJQUFZO0lBQy9CLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFTLENBQUE7SUFDdkMsS0FBSyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLEVBQUU7UUFDNUIsSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUM7WUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQXNCLENBQUE7SUFDeEUsQ0FBQyxDQUFDLENBQUE7SUFDRixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6RSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFBO0lBQ3ZCLENBQUM7SUFDRCxPQUFPLGVBQWUsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7QUFDL0QsQ0FBQztBQUVEOztpQkFFaUI7QUFDakIsU0FBUyxlQUFlLENBQUMsUUFBZ0I7SUFDdkMsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFBO0lBQ25CLE9BQU8sUUFBUTtTQUNaLEtBQUssQ0FBQyxJQUFJLENBQUM7U0FDWCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDVixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQixPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUE7WUFDbEIsT0FBTyxJQUFJLENBQUE7UUFDYixDQUFDO1FBQ0QsSUFBSSxPQUFPO1lBQUUsT0FBTyxJQUFJLENBQUE7UUFDeEIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsRUFBRSxDQUN4QyxLQUFLLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FDOUIsQ0FBQTtJQUNILENBQUMsQ0FBQztTQUNELElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtBQUNmLENBQUM7QUFFRCxLQUFLLFVBQVUsZUFBZSxDQUM1QixNQUFjLEVBQ2QsUUFBZ0IsRUFDaEIsUUFBZ0I7SUFFaEIsTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3RDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLE1BQU0sRUFBRSxDQUFDLENBQUE7SUFDdkUsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLGdDQUFnQyxNQUFNLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxJQUFJLHdCQUF3QixDQUFBO0lBQy9GLE1BQU0sT0FBTyxHQUEyQjtRQUN0QyxNQUFNLEVBQUUsNkJBQTZCO1FBQ3JDLHNCQUFzQixFQUFFLFlBQVk7S0FDckMsQ0FBQTtJQUVELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFBO0lBQ3RDLElBQUksS0FBSztRQUFFLE9BQU8sQ0FBQyxhQUFhLEdBQUcsVUFBVSxLQUFLLEVBQUUsQ0FBQTtJQUVwRCxNQUFNLElBQUksR0FBRyxNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUNyQyxNQUFNLFFBQVEsR0FBRyxNQUFNLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUN2QyxJQUFJLElBQUksSUFBSSxRQUFRO1FBQUUsT0FBTyxDQUFDLGVBQWUsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUE7SUFFMUQsTUFBTSxHQUFHLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUV6QyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssR0FBRztRQUFFLE9BQU8sU0FBUyxDQUFBO0lBRXhDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDWixNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFBO1FBQzFELE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUE7UUFDbEQsTUFBTSxHQUFHLEdBQUcsY0FBYyxHQUFHLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxVQUFVLDJCQUEyQixTQUFTLElBQUksR0FBRyxZQUFZLEtBQUssSUFBSSxHQUFHLEdBQUcsQ0FBQTtRQUM1SCxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcscUNBQXFDLENBQUMsQ0FBQTtZQUN6RCxPQUFPLFNBQVMsQ0FBQTtRQUNsQixDQUFDO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUN0QixDQUFDO0lBRUQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBYyxDQUFBO0lBQ2hELE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3BDLElBQUksSUFBSSxFQUFFLENBQUM7UUFDVCxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUNuRCxNQUFNLFNBQVMsQ0FDYixRQUFRLEVBQ1IsSUFBSSxDQUFDLFNBQVMsQ0FDWixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsRUFBc0IsRUFDakUsSUFBSSxFQUNKLENBQUMsQ0FDRixFQUNELE9BQU8sQ0FDUixDQUFBO0lBQ0gsQ0FBQztJQUVELE9BQU8sUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDOUIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQy9CLEtBQUssRUFBRSxPQUFPLENBQUMsUUFBUTtRQUN2QixJQUFJLEVBQUUsT0FBTyxDQUFDLFlBQVksSUFBSSxTQUFTO1FBQ3ZDLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFO1FBQ2pDLFNBQVMsRUFBRSxPQUFPLENBQUMsUUFBUSxJQUFJLFNBQVM7S0FDekMsQ0FBQyxDQUFDLENBQUE7QUFDTCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsS0FBcUIsRUFBRSxPQUF5QjtJQUN2RSxNQUFNLEtBQUssR0FBRztRQUNaLEtBQUs7UUFDTCxVQUFVLEtBQUssQ0FBQyxLQUFLLEVBQUU7UUFDdkIsU0FBUyxPQUFPLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLEdBQUc7S0FDeEMsQ0FBQTtJQUNELElBQUksS0FBSyxDQUFDLElBQUk7UUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUE7SUFDakQsSUFBSSxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDcEIsS0FBSyxDQUFDLElBQUksQ0FBQyxjQUFjLEtBQUssQ0FBQyxTQUFTLEVBQUUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFBO0lBQ25FLENBQUM7SUFDRCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUN0RSxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDekIsQ0FBQztBQUVELEtBQUssVUFBVSxRQUFRLENBQUMsUUFBZ0I7SUFDdEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxRQUFRLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQzdDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQWMsQ0FBQTtJQUNyQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztBQUNILENBQUM7QUFFRCxLQUFLLFVBQVUsTUFBTSxDQUFDLElBQVk7SUFDaEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDbEIsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGFjY2VzcywgbWtkaXIsIHJlYWRGaWxlLCBybSwgd3JpdGVGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIlxuaW1wb3J0IHsgZGlybmFtZSwgam9pbiwgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHNsdWdpZnkgZnJvbSBcIkBzaW5kcmVzb3JodXMvc2x1Z2lmeVwiXG5pbXBvcnQgdHlwZSB7IFJvb3QsIFJvb3RDb250ZW50IH0gZnJvbSBcIm1kYXN0XCJcbmltcG9ydCB7IHRvU3RyaW5nIGFzIG1kYXN0VG9TdHJpbmcgfSBmcm9tIFwibWRhc3QtdXRpbC10by1zdHJpbmdcIlxuaW1wb3J0IHJlbWFya1BhcnNlIGZyb20gXCJyZW1hcmstcGFyc2VcIlxuaW1wb3J0IHJlbWFya1N0cmluZ2lmeSBmcm9tIFwicmVtYXJrLXN0cmluZ2lmeVwiXG5pbXBvcnQgeyB1bmlmaWVkIH0gZnJvbSBcInVuaWZpZWRcIlxuaW1wb3J0IHsgdmlzaXQgfSBmcm9tIFwidW5pc3QtdXRpbC12aXNpdFwiXG5pbXBvcnQgdHlwZSB7IENvbmZpZyB9IGZyb20gXCIuLi8uLi9tb2RlbHMvY29uZmlnLnRzXCJcbmltcG9ydCB0eXBlIHsgQ2hhbmdlbG9nU2VjdGlvbiB9IGZyb20gXCIuLi8uLi9tb2RlbHMvc2VjdGlvbi50c1wiXG5pbXBvcnQgeyBpc0dpdEh1YlVybCwgcGFyc2VHaXRIdWJSZXBvIH0gZnJvbSBcIi4uLy4uL2hlbHBlcnMvY2hhbmdlbG9nLXNvdXJjZS50c1wiXG5cbmludGVyZmFjZSBSZWxlYXNlIHtcbiAgdGFnX25hbWU6IHN0cmluZ1xuICBuYW1lPzogc3RyaW5nIHwgbnVsbFxuICBwdWJsaXNoZWRfYXQ/OiBzdHJpbmcgfCBudWxsXG4gIGJvZHk/OiBzdHJpbmcgfCBudWxsXG4gIGh0bWxfdXJsPzogc3RyaW5nIHwgbnVsbFxufVxuXG5pbnRlcmZhY2UgQ2FjaGVNZXRhIHtcbiAgZXRhZzogc3RyaW5nXG4gIGZldGNoZWRBdDogc3RyaW5nXG59XG5cbmludGVyZmFjZSBDaGFuZ2Vsb2dFbnRyeSB7XG4gIHNsdWc6IHN0cmluZ1xuICB0aXRsZTogc3RyaW5nXG4gIGRhdGU/OiBzdHJpbmdcbiAgYm9keTogc3RyaW5nXG4gIHNvdXJjZVVybD86IHN0cmluZ1xufVxuXG5jb25zdCBDQUNIRV9ESVIgPSBcIi5saXZlbWFyay9jYWNoZS9jaGFuZ2Vsb2dcIlxuY29uc3QgTUVUQV9GSUxFID0gXCIubGl2ZW1hcmsvY2FjaGUvY2hhbmdlbG9nLm1ldGEuanNvblwiXG5cbmNvbnN0IHBhcnNlciA9IHVuaWZpZWQoKS51c2UocmVtYXJrUGFyc2UpXG5jb25zdCBzdHJpbmdpZmllciA9IHVuaWZpZWQoKS51c2UocmVtYXJrU3RyaW5naWZ5LCB7XG4gIGJ1bGxldDogXCItXCIsXG4gIGZlbmNlczogdHJ1ZSxcbiAgZW1waGFzaXM6IFwiX1wiLFxufSlcblxuZXhwb3J0IGZ1bmN0aW9uIGNhY2hlSW5jbHVkZUdsb2IoKSB7XG4gIHJldHVybiBgJHtDQUNIRV9ESVJ9LyoqLyoubWRgXG59XG5cbi8qKiBCdWlsZCB0aGUgcGVyLXZlcnNpb24gY2hhbmdlbG9nIGNhY2hlIGZpbGVzIGZvciBhIGNoYW5nZWxvZyBzZWN0aW9uICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRDaGFuZ2Vsb2coXG4gIHNlY3Rpb246IENoYW5nZWxvZ1NlY3Rpb24sXG4gIGNvbmZpZzogQ29uZmlnLFxuKSB7XG4gIGNvbnN0IGNhY2hlRGlyID0gam9pbihjb25maWcucm9vdCwgQ0FDSEVfRElSKVxuICBjb25zdCBtZXRhUGF0aCA9IGpvaW4oY29uZmlnLnJvb3QsIE1FVEFfRklMRSlcblxuICBjb25zdCBlbnRyaWVzID0gaXNHaXRIdWJVcmwoc2VjdGlvbi5zb3VyY2UpXG4gICAgPyBhd2FpdCBidWlsZEZyb21HaXRIdWIoc2VjdGlvbi5zb3VyY2UsIG1ldGFQYXRoLCBjYWNoZURpcilcbiAgICA6IGF3YWl0IGJ1aWxkRnJvbUxvY2FsKHNlY3Rpb24uc291cmNlLCBjb25maWcucm9vdClcblxuICBpZiAoZW50cmllcyA9PT0gdW5kZWZpbmVkKSByZXR1cm5cblxuICBhd2FpdCBybShjYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pXG4gIGF3YWl0IG1rZGlyKGNhY2hlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGNvbnN0IG1hcmtkb3duID0gd3JhcEZyb250bWF0dGVyKGVudHJ5LCBzZWN0aW9uKVxuICAgIGF3YWl0IHdyaXRlRmlsZShqb2luKGNhY2hlRGlyLCBgJHtlbnRyeS5zbHVnfS5tZGApLCBtYXJrZG93biwgXCJ1dGYtOFwiKVxuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGJ1aWxkRnJvbUxvY2FsKHNvdXJjZTogc3RyaW5nLCByb290OiBzdHJpbmcpIHtcbiAgY29uc3QgZmlsZVBhdGggPSByZXNvbHZlKHJvb3QsIHNvdXJjZSlcbiAgY29uc3QgYm9keSA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCBcInV0Zi04XCIpXG4gIHJldHVybiBzcGxpdExvY2FsQ2hhbmdlbG9nKGJvZHkpXG59XG5cbi8qKiBQYXJzZSBDSEFOR0VMT0cubWQgaW50byBwZXItdmVyc2lvbiBlbnRyaWVzIHVzaW5nIG1kYXN0ICovXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRMb2NhbENoYW5nZWxvZyhib2R5OiBzdHJpbmcpOiBDaGFuZ2Vsb2dFbnRyeVtdIHtcbiAgY29uc3QgdHJlZSA9IHBhcnNlci5wYXJzZShib2R5KSBhcyBSb290XG4gIGNvbnN0IGVudHJpZXM6IENoYW5nZWxvZ0VudHJ5W10gPSBbXVxuICBsZXQgY3VycmVudDogeyBoZWFkaW5nOiBzdHJpbmc7IGNoaWxkcmVuOiBSb290Q29udGVudFtdIH0gfCB1bmRlZmluZWRcblxuICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRyZWUuY2hpbGRyZW4pIHtcbiAgICBpZiAoY2hpbGQudHlwZSA9PT0gXCJoZWFkaW5nXCIgJiYgY2hpbGQuZGVwdGggPT09IDIpIHtcbiAgICAgIGlmIChjdXJyZW50KSBlbnRyaWVzLnB1c2goZmluYWxpemVFbnRyeShjdXJyZW50KSlcbiAgICAgIGN1cnJlbnQgPSB7IGhlYWRpbmc6IG1kYXN0VG9TdHJpbmcoY2hpbGQpLCBjaGlsZHJlbjogW10gfVxuICAgIH0gZWxzZSBpZiAoY3VycmVudCkge1xuICAgICAgY3VycmVudC5jaGlsZHJlbi5wdXNoKGNoaWxkKVxuICAgIH1cbiAgfVxuICBpZiAoY3VycmVudCkgZW50cmllcy5wdXNoKGZpbmFsaXplRW50cnkoY3VycmVudCkpXG4gIHJldHVybiBlbnRyaWVzXG59XG5cbmZ1bmN0aW9uIGZpbmFsaXplRW50cnkoaW5wdXQ6IHtcbiAgaGVhZGluZzogc3RyaW5nXG4gIGNoaWxkcmVuOiBSb290Q29udGVudFtdXG59KTogQ2hhbmdlbG9nRW50cnkge1xuICBjb25zdCB2ZXJzaW9uTWF0Y2ggPSBpbnB1dC5oZWFkaW5nLm1hdGNoKC9eXFxbPyhbXlxcXVxcc10rKVxcXT8vKVxuICBjb25zdCB2ZXJzaW9uID0gdmVyc2lvbk1hdGNoPy5bMV0gPz8gaW5wdXQuaGVhZGluZ1xuICBjb25zdCBkYXRlTWF0Y2ggPSBpbnB1dC5oZWFkaW5nLm1hdGNoKC9cXGR7NH0tXFxkezJ9LVxcZHsyfS8pXG4gIGNvbnN0IGJvZHkgPSByZW5kZXJFbnRyeUJvZHkoaW5wdXQuY2hpbGRyZW4pXG4gIHJldHVybiB7XG4gICAgc2x1Zzogc2x1Z2lmeSh2ZXJzaW9uKSxcbiAgICB0aXRsZTogdmVyc2lvbixcbiAgICBkYXRlOiBkYXRlTWF0Y2g/LlswXSxcbiAgICBib2R5LFxuICB9XG59XG5cbi8qKiBTZXJpYWxpemUgYW4gZW50cnkncyBtZGFzdCBjaGlsZHJlbiBiYWNrIHRvIG1hcmtkb3duICovXG5mdW5jdGlvbiByZW5kZXJFbnRyeUJvZHkoY2hpbGRyZW46IFJvb3RDb250ZW50W10pIHtcbiAgY29uc3Qgcm9vdDogUm9vdCA9IHsgdHlwZTogXCJyb290XCIsIGNoaWxkcmVuIH1cbiAgcmV0dXJuIHN0cmluZ2lmaWVyLnN0cmluZ2lmeShyb290KS50cmltRW5kKClcbn1cblxuLyoqIERyb3AgdGhlIGJvZHkncyBsZWFkaW5nIGgxICh0eXBpY2FsbHkgdGhlIGNvbnZlbnRpb25hbC1jaGFuZ2Vsb2dcbiAqIGAjIDAuNy4yICgyMDI2LTA0LTI1KWAgYm9pbGVycGxhdGUgdGhhdCBkdXBsaWNhdGVzIHRoZSBhcnRpY2xlJ3MgdGl0bGUpLFxuICogc2hpZnQgaDLigJNoNiB1cCBieSBvbmUgc28gc3Vic2VjdGlvbiBoZWFkaW5ncyBiZWNvbWUgaDEgLyBoMiAvIOKApiwgYW5kXG4gKiBlc2NhcGUgc3RyYXkgYDxgIG91dHNpZGUgY29kZSBzbyBNRFggZG9lc24ndCBtaXN0YWtlIHRoZW0gZm9yIEpTWC4gKi9cbmZ1bmN0aW9uIHByb2Nlc3NCb2R5KGJvZHk6IHN0cmluZykge1xuICBjb25zdCB0cmVlID0gcGFyc2VyLnBhcnNlKGJvZHkpIGFzIFJvb3RcbiAgdmlzaXQodHJlZSwgXCJoZWFkaW5nXCIsIG5vZGUgPT4ge1xuICAgIGlmIChub2RlLmRlcHRoID4gMSkgbm9kZS5kZXB0aCA9IChub2RlLmRlcHRoIC0gMSkgYXMgMSB8IDIgfCAzIHwgNCB8IDVcbiAgfSlcbiAgaWYgKHRyZWUuY2hpbGRyZW5bMF0/LnR5cGUgPT09IFwiaGVhZGluZ1wiICYmIHRyZWUuY2hpbGRyZW5bMF0uZGVwdGggPT09IDEpIHtcbiAgICB0cmVlLmNoaWxkcmVuLnNoaWZ0KClcbiAgfVxuICByZXR1cm4gZXNjYXBlTWR4QW5nbGVzKHN0cmluZ2lmaWVyLnN0cmluZ2lmeSh0cmVlKS50cmltRW5kKCkpXG59XG5cbi8qKiBFc2NhcGUgYDxgIHRvIGBcXDxgIG91dHNpZGUgZmVuY2VkIGNvZGUgYmxvY2tzIGFuZCBpbmxpbmUgYmFja3RpY2sgc3BhbnNcbiAqIHNvIGNvbW1pdCBtZXNzYWdlcyB3aXRoIHBsYWNlaG9sZGVycyBsaWtlIGA8c3ViZGlyPmAgZG9uJ3QgZ2V0IHBhcnNlZCBhc1xuICogSlNYIGJ5IE1EWC4gKi9cbmZ1bmN0aW9uIGVzY2FwZU1keEFuZ2xlcyhtYXJrZG93bjogc3RyaW5nKSB7XG4gIGxldCBpbkZlbmNlID0gZmFsc2VcbiAgcmV0dXJuIG1hcmtkb3duXG4gICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgLm1hcChsaW5lID0+IHtcbiAgICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoXCJgYGBcIikpIHtcbiAgICAgICAgaW5GZW5jZSA9ICFpbkZlbmNlXG4gICAgICAgIHJldHVybiBsaW5lXG4gICAgICB9XG4gICAgICBpZiAoaW5GZW5jZSkgcmV0dXJuIGxpbmVcbiAgICAgIHJldHVybiBsaW5lLnJlcGxhY2UoL2BbXmBdKmB8PC9nLCBtYXRjaCA9PlxuICAgICAgICBtYXRjaCA9PT0gXCI8XCIgPyBcIlxcXFw8XCIgOiBtYXRjaCxcbiAgICAgIClcbiAgICB9KVxuICAgIC5qb2luKFwiXFxuXCIpXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGJ1aWxkRnJvbUdpdEh1YihcbiAgc291cmNlOiBzdHJpbmcsXG4gIG1ldGFQYXRoOiBzdHJpbmcsXG4gIGNhY2hlRGlyOiBzdHJpbmcsXG4pOiBQcm9taXNlPENoYW5nZWxvZ0VudHJ5W10gfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgcGFyc2VkID0gcGFyc2VHaXRIdWJSZXBvKHNvdXJjZSlcbiAgaWYgKCFwYXJzZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBwYXJzZSBHaXRIdWIgcmVwbyBmcm9tIHNvdXJjZTogJHtzb3VyY2V9YClcbiAgfVxuXG4gIGNvbnN0IHVybCA9IGBodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zLyR7cGFyc2VkLm93bmVyfS8ke3BhcnNlZC5yZXBvfS9yZWxlYXNlcz9wZXJfcGFnZT0xMDBgXG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL3ZuZC5naXRodWIranNvblwiLFxuICAgIFwiWC1HaXRIdWItQXBpLVZlcnNpb25cIjogXCIyMDIyLTExLTI4XCIsXG4gIH1cblxuICBjb25zdCB0b2tlbiA9IHByb2Nlc3MuZW52LkdJVEhVQl9UT0tFTlxuICBpZiAodG9rZW4pIGhlYWRlcnMuQXV0aG9yaXphdGlvbiA9IGBCZWFyZXIgJHt0b2tlbn1gXG5cbiAgY29uc3QgbWV0YSA9IGF3YWl0IHJlYWRNZXRhKG1ldGFQYXRoKVxuICBjb25zdCBoYXNDYWNoZSA9IGF3YWl0IGV4aXN0cyhjYWNoZURpcilcbiAgaWYgKG1ldGEgJiYgaGFzQ2FjaGUpIGhlYWRlcnNbXCJJZi1Ob25lLU1hdGNoXCJdID0gbWV0YS5ldGFnXG5cbiAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2godXJsLCB7IGhlYWRlcnMgfSlcblxuICBpZiAocmVzLnN0YXR1cyA9PT0gMzA0KSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgaWYgKCFyZXMub2spIHtcbiAgICBjb25zdCByZW1haW5pbmcgPSByZXMuaGVhZGVycy5nZXQoXCJ4LXJhdGVsaW1pdC1yZW1haW5pbmdcIilcbiAgICBjb25zdCByZXNldCA9IHJlcy5oZWFkZXJzLmdldChcIngtcmF0ZWxpbWl0LXJlc2V0XCIpXG4gICAgY29uc3QgbXNnID0gYEdpdEh1YiBBUEkgJHtyZXMuc3RhdHVzfSAke3Jlcy5zdGF0dXNUZXh0fSAocmF0ZS1saW1pdCByZW1haW5pbmc6ICR7cmVtYWluaW5nID8/IFwiP1wifSwgcmVzZXQ6ICR7cmVzZXQgPz8gXCI/XCJ9KWBcbiAgICBpZiAoaGFzQ2FjaGUpIHtcbiAgICAgIGNvbnNvbGUud2FybihgJHttc2d9IOKAlCBmYWxsaW5nIGJhY2sgdG8gY2FjaGVkIGNoYW5nZWxvZ2ApXG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihtc2cpXG4gIH1cblxuICBjb25zdCByZWxlYXNlcyA9IChhd2FpdCByZXMuanNvbigpKSBhcyBSZWxlYXNlW11cbiAgY29uc3QgZXRhZyA9IHJlcy5oZWFkZXJzLmdldChcImV0YWdcIilcbiAgaWYgKGV0YWcpIHtcbiAgICBhd2FpdCBta2RpcihkaXJuYW1lKG1ldGFQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgICBhd2FpdCB3cml0ZUZpbGUoXG4gICAgICBtZXRhUGF0aCxcbiAgICAgIEpTT04uc3RyaW5naWZ5KFxuICAgICAgICB7IGV0YWcsIGZldGNoZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0gc2F0aXNmaWVzIENhY2hlTWV0YSxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgMixcbiAgICAgICksXG4gICAgICBcInV0Zi04XCIsXG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIHJlbGVhc2VzLm1hcChyZWxlYXNlID0+ICh7XG4gICAgc2x1Zzogc2x1Z2lmeShyZWxlYXNlLnRhZ19uYW1lKSxcbiAgICB0aXRsZTogcmVsZWFzZS50YWdfbmFtZSxcbiAgICBkYXRlOiByZWxlYXNlLnB1Ymxpc2hlZF9hdCA/PyB1bmRlZmluZWQsXG4gICAgYm9keTogKHJlbGVhc2UuYm9keSA/PyBcIlwiKS50cmltKCksXG4gICAgc291cmNlVXJsOiByZWxlYXNlLmh0bWxfdXJsID8/IHVuZGVmaW5lZCxcbiAgfSkpXG59XG5cbmZ1bmN0aW9uIHdyYXBGcm9udG1hdHRlcihlbnRyeTogQ2hhbmdlbG9nRW50cnksIHNlY3Rpb246IENoYW5nZWxvZ1NlY3Rpb24pIHtcbiAgY29uc3QgbGluZXMgPSBbXG4gICAgXCItLS1cIixcbiAgICBgdGl0bGU6ICR7ZW50cnkudGl0bGV9YCxcbiAgICBgcGF0aDogJHtzZWN0aW9uLnByZWZpeH0ke2VudHJ5LnNsdWd9L2AsXG4gIF1cbiAgaWYgKGVudHJ5LmRhdGUpIGxpbmVzLnB1c2goYGRhdGU6ICR7ZW50cnkuZGF0ZX1gKVxuICBpZiAoZW50cnkuc291cmNlVXJsKSB7XG4gICAgbGluZXMucHVzaChgc291cmNlVXJsOiAke2VudHJ5LnNvdXJjZVVybH1gLCBcInNvdXJjZUFjdGlvbjogdmlld1wiKVxuICB9XG4gIGxpbmVzLnB1c2goXCItLS1cIiwgXCJcIiwgYCMgJHtlbnRyeS50aXRsZX1gLCBcIlwiLCBwcm9jZXNzQm9keShlbnRyeS5ib2R5KSlcbiAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIilcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZE1ldGEobWV0YVBhdGg6IHN0cmluZyk6IFByb21pc2U8Q2FjaGVNZXRhIHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmF3ID0gYXdhaXQgcmVhZEZpbGUobWV0YVBhdGgsIFwidXRmLThcIilcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyYXcpIGFzIENhY2hlTWV0YVxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZXhpc3RzKHBhdGg6IHN0cmluZykge1xuICB0cnkge1xuICAgIGF3YWl0IGFjY2VzcyhwYXRoKVxuICAgIHJldHVybiB0cnVlXG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG4iXX0=