@livenetworks/ashlar 1.6.0 → 2.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 (560) hide show
  1. package/LICENSE +641 -0
  2. package/README.md +202 -86
  3. package/{js → components}/COMPONENTS.md +1116 -1108
  4. package/{js → components}/index.js +81 -58
  5. package/{js → components}/ln-accordion/README.md +7 -6
  6. package/components/ln-accordion/ln-accordion-dev.scss +8 -0
  7. package/components/ln-accordion/ln-accordion.js +1 -0
  8. package/components/ln-accordion/ln-accordion.schema.json +30 -0
  9. package/components/ln-accordion/ln-accordion.scss +8 -0
  10. package/{js → components}/ln-accordion/src/ln-accordion.js +8 -2
  11. package/{js → components}/ln-ajax/README.md +171 -160
  12. package/components/ln-ajax/ln-ajax-dev.scss +8 -0
  13. package/components/ln-ajax/ln-ajax.js +1 -0
  14. package/components/ln-ajax/ln-ajax.schema.json +30 -0
  15. package/{js → components}/ln-ajax/src/ln-ajax.js +65 -30
  16. package/{js → components}/ln-api-connector/README.md +27 -5
  17. package/components/ln-api-connector/ln-api-connector.js +1 -0
  18. package/components/ln-api-connector/ln-api-connector.schema.json +96 -0
  19. package/components/ln-api-connector/src/connector-core.js +97 -0
  20. package/components/ln-api-connector/src/ln-api-connector.js +447 -0
  21. package/{js → components}/ln-api-queue/README.md +12 -9
  22. package/components/ln-api-queue/ln-api-queue.js +1 -0
  23. package/components/ln-api-queue/ln-api-queue.schema.json +34 -0
  24. package/{js → components}/ln-api-queue/src/ln-api-queue.js +33 -14
  25. package/{js → components}/ln-api-queue/src/queue-storage.js +7 -3
  26. package/{js → components}/ln-autoresize/README.md +129 -127
  27. package/components/ln-autoresize/ln-autoresize-dev.scss +8 -0
  28. package/components/ln-autoresize/ln-autoresize.js +1 -0
  29. package/components/ln-autoresize/ln-autoresize.schema.json +22 -0
  30. package/{js → components}/ln-autoresize/src/ln-autoresize.js +8 -1
  31. package/{js → components}/ln-autosave/README.md +127 -124
  32. package/components/ln-autosave/ln-autosave-dev.scss +13 -0
  33. package/components/ln-autosave/ln-autosave.js +1 -0
  34. package/components/ln-autosave/ln-autosave.schema.json +48 -0
  35. package/components/ln-autosave/src/autosave-model.js +34 -0
  36. package/{js → components}/ln-autosave/src/ln-autosave.js +65 -58
  37. package/components/ln-chart/README.md +145 -0
  38. package/components/ln-chart/ln-chart-dev.scss +20 -0
  39. package/components/ln-chart/ln-chart.js +1 -0
  40. package/components/ln-chart/ln-chart.schema.json +146 -0
  41. package/components/ln-chart/ln-chart.scss +8 -0
  42. package/components/ln-chart/src/chart-model.js +154 -0
  43. package/components/ln-chart/src/ln-chart.js +176 -0
  44. package/{js → components}/ln-circular-progress/README.md +15 -14
  45. package/components/ln-circular-progress/ln-circular-progress-dev.scss +8 -0
  46. package/components/ln-circular-progress/ln-circular-progress.js +1 -0
  47. package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -0
  48. package/{js → components}/ln-circular-progress/src/ln-circular-progress.js +32 -50
  49. package/components/ln-confirm/README.md +216 -0
  50. package/components/ln-confirm/ln-confirm-dev.scss +24 -0
  51. package/components/ln-confirm/ln-confirm.js +1 -0
  52. package/components/ln-confirm/ln-confirm.schema.json +66 -0
  53. package/components/ln-confirm/ln-confirm.scss +24 -0
  54. package/{js → components}/ln-confirm/src/ln-confirm.js +180 -167
  55. package/{js → components}/ln-core/README.md +374 -149
  56. package/components/ln-core/attrs.js +273 -0
  57. package/components/ln-core/compare.js +40 -0
  58. package/components/ln-core/crypto.js +265 -0
  59. package/components/ln-core/date.js +50 -0
  60. package/components/ln-core/dom.js +115 -0
  61. package/components/ln-core/events.js +122 -0
  62. package/components/ln-core/form.js +136 -0
  63. package/{js → components}/ln-core/hash.js +149 -92
  64. package/components/ln-core/helpers.js +33 -0
  65. package/components/ln-core/http.js +48 -0
  66. package/components/ln-core/index.js +11 -0
  67. package/components/ln-core/lifecycle.js +403 -0
  68. package/components/ln-core/ln-core.schema.json +109 -0
  69. package/components/ln-core/locale.js +55 -0
  70. package/components/ln-core/matching.js +78 -0
  71. package/components/ln-core/number.js +125 -0
  72. package/components/ln-core/progress.js +30 -0
  73. package/components/ln-core/template.js +206 -0
  74. package/{js → components}/ln-core/window-cache.js +247 -213
  75. package/{js → components}/ln-couchdb-connector/README.md +7 -5
  76. package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -0
  77. package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -0
  78. package/{js → components}/ln-couchdb-connector/src/ln-couchdb-connector.js +29 -43
  79. package/{js → components}/ln-data-coordinator/README.md +109 -73
  80. package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -0
  81. package/components/ln-data-coordinator/ln-data-coordinator.js +1 -0
  82. package/components/ln-data-coordinator/ln-data-coordinator.schema.json +196 -0
  83. package/components/ln-data-coordinator/src/data-read-policy.js +41 -0
  84. package/{js → components}/ln-data-coordinator/src/ln-data-coordinator.js +411 -154
  85. package/{js → components}/ln-data-coordinator/src/mutation-receipts.js +0 -5
  86. package/{js → components}/ln-data-store/README.md +42 -17
  87. package/components/ln-data-store/ln-data-store-dev.scss +13 -0
  88. package/components/ln-data-store/ln-data-store.js +1 -0
  89. package/components/ln-data-store/ln-data-store.schema.json +84 -0
  90. package/components/ln-data-store/src/data-store-model.js +155 -0
  91. package/{js → components}/ln-data-store/src/ln-data-store.js +407 -105
  92. package/components/ln-data-store/src/window-index.js +119 -0
  93. package/{js → components}/ln-date/README.md +17 -7
  94. package/{js → components}/ln-date/ln-date-dev.scss +14 -14
  95. package/components/ln-date/ln-date.js +1 -0
  96. package/components/ln-date/ln-date.schema.json +92 -0
  97. package/components/ln-date/src/date-model.js +186 -0
  98. package/components/ln-date/src/ln-date.js +486 -0
  99. package/components/ln-debug/README.md +132 -0
  100. package/components/ln-debug/ln-debug.js +1 -0
  101. package/components/ln-debug/ln-debug.schema.json +28 -0
  102. package/components/ln-debug/src/console-sink.js +19 -0
  103. package/components/ln-debug/src/debug-verifier.js +331 -0
  104. package/components/ln-debug/src/gate.js +95 -0
  105. package/components/ln-debug/src/generated-attributes.js +299 -0
  106. package/components/ln-debug/src/ln-debug.js +60 -0
  107. package/{js → components}/ln-dropdown/README.md +150 -140
  108. package/components/ln-dropdown/ln-dropdown-dev.scss +13 -0
  109. package/components/ln-dropdown/ln-dropdown.js +1 -0
  110. package/components/ln-dropdown/ln-dropdown.schema.json +90 -0
  111. package/components/ln-dropdown/ln-dropdown.scss +18 -0
  112. package/{js → components}/ln-dropdown/src/ln-dropdown.js +114 -11
  113. package/{js → components}/ln-editor/README.md +11 -9
  114. package/components/ln-editor/ln-editor-dev.scss +18 -0
  115. package/components/ln-editor/ln-editor.js +1 -0
  116. package/components/ln-editor/ln-editor.schema.json +58 -0
  117. package/components/ln-editor/ln-editor.scss +13 -0
  118. package/{js → components}/ln-editor/src/ln-editor.js +59 -11
  119. package/{js → components}/ln-external-links/README.md +10 -8
  120. package/components/ln-external-links/ln-external-links.js +1 -0
  121. package/components/ln-external-links/ln-external-links.schema.json +18 -0
  122. package/{js → components}/ln-external-links/src/ln-external-links.js +13 -11
  123. package/{js → components}/ln-fill/README.md +6 -8
  124. package/components/ln-fill/ln-fill.js +1 -0
  125. package/components/ln-fill/ln-fill.schema.json +23 -0
  126. package/{js → components}/ln-fill/src/ln-fill.js +7 -1
  127. package/components/ln-filter/README.md +131 -0
  128. package/components/ln-filter/ln-filter-dev.scss +13 -0
  129. package/components/ln-filter/ln-filter.js +1 -0
  130. package/components/ln-filter/ln-filter.schema.json +153 -0
  131. package/components/ln-filter/src/filter-model.js +185 -0
  132. package/components/ln-filter/src/ln-filter.js +435 -0
  133. package/{js → components}/ln-form/README.md +260 -264
  134. package/components/ln-form/ln-form-dev.scss +8 -0
  135. package/components/ln-form/ln-form.js +1 -0
  136. package/components/ln-form/ln-form.schema.json +45 -0
  137. package/{js → components}/ln-form/src/ln-form.js +107 -99
  138. package/{js → components}/ln-http/README.md +11 -6
  139. package/components/ln-http/ln-http.js +1 -0
  140. package/components/ln-http/ln-http.schema.json +6 -0
  141. package/components/ln-http/src/http-core.js +51 -0
  142. package/{js → components}/ln-http/src/ln-http.js +28 -33
  143. package/{js → components}/ln-icon/README.md +16 -9
  144. package/components/ln-icon/ln-icon.schema.json +6 -0
  145. package/components/ln-include/README.md +75 -0
  146. package/components/ln-include/ln-include-dev.scss +13 -0
  147. package/components/ln-include/ln-include.js +1 -0
  148. package/components/ln-include/ln-include.schema.json +23 -0
  149. package/components/ln-include/src/ln-include.js +111 -0
  150. package/components/ln-key/README.md +130 -0
  151. package/components/ln-key/ln-key-dev.scss +18 -0
  152. package/components/ln-key/ln-key.js +1 -0
  153. package/components/ln-key/ln-key.schema.json +56 -0
  154. package/components/ln-key/src/key-model.js +146 -0
  155. package/components/ln-key/src/ln-key.js +201 -0
  156. package/{js → components}/ln-link/README.md +7 -9
  157. package/components/ln-link/ln-link-dev.scss +8 -0
  158. package/components/ln-link/ln-link.js +1 -0
  159. package/components/ln-link/ln-link.schema.json +22 -0
  160. package/{js → components}/ln-link/src/ln-link.js +16 -11
  161. package/components/ln-list/README.md +152 -0
  162. package/components/ln-list/ln-list-dev.scss +8 -0
  163. package/components/ln-list/ln-list.js +1 -0
  164. package/components/ln-list/ln-list.schema.json +166 -0
  165. package/components/ln-list/ln-list.scss +25 -0
  166. package/{js → components}/ln-list/src/ln-list.js +1301 -1216
  167. package/{js → components}/ln-modal/README.md +13 -10
  168. package/components/ln-modal/ln-modal-dev.scss +18 -0
  169. package/components/ln-modal/ln-modal.js +1 -0
  170. package/components/ln-modal/ln-modal.schema.json +54 -0
  171. package/components/ln-modal/ln-modal.scss +51 -0
  172. package/{js → components}/ln-modal/src/ln-modal.js +164 -137
  173. package/{js → components}/ln-nav/README.md +11 -11
  174. package/components/ln-nav/ln-nav.js +1 -0
  175. package/components/ln-nav/ln-nav.schema.json +25 -0
  176. package/{js → components}/ln-nav/src/ln-nav.js +25 -14
  177. package/components/ln-number/README.md +205 -0
  178. package/{js → components}/ln-number/ln-number-dev.scss +13 -13
  179. package/components/ln-number/ln-number.js +1 -0
  180. package/components/ln-number/ln-number.schema.json +63 -0
  181. package/components/ln-number/src/ln-number.js +400 -0
  182. package/components/ln-number/src/number-model.js +31 -0
  183. package/components/ln-obfuscator/README.md +60 -0
  184. package/components/ln-obfuscator/ln-obfuscator.js +1 -0
  185. package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -0
  186. package/components/ln-obfuscator/src/ln-obfuscator.js +159 -0
  187. package/components/ln-obfuscator/src/obfuscator-model.js +250 -0
  188. package/{js → components}/ln-options/README.md +3 -1
  189. package/components/ln-options/ln-options-dev.scss +13 -0
  190. package/components/ln-options/ln-options.js +1 -0
  191. package/components/ln-options/ln-options.schema.json +41 -0
  192. package/{js → components}/ln-options/src/ln-options.js +13 -5
  193. package/components/ln-persist/README.md +151 -0
  194. package/components/ln-persist/ln-persist.js +1 -0
  195. package/components/ln-persist/ln-persist.schema.json +28 -0
  196. package/components/ln-persist/src/ln-persist.js +83 -0
  197. package/components/ln-picklist/README.md +230 -0
  198. package/components/ln-picklist/ln-picklist-dev.scss +22 -0
  199. package/components/ln-picklist/ln-picklist.js +1 -0
  200. package/components/ln-picklist/ln-picklist.schema.json +49 -0
  201. package/components/ln-picklist/src/ln-picklist.js +228 -0
  202. package/{js → components}/ln-popover/README.md +164 -162
  203. package/components/ln-popover/ln-popover-dev.scss +13 -0
  204. package/components/ln-popover/ln-popover.js +1 -0
  205. package/components/ln-popover/ln-popover.schema.json +82 -0
  206. package/components/ln-popover/ln-popover.scss +18 -0
  207. package/{js → components}/ln-popover/src/ln-popover.js +42 -36
  208. package/{js → components}/ln-progress/README.md +410 -413
  209. package/components/ln-progress/ln-progress-dev.scss +8 -0
  210. package/components/ln-progress/ln-progress.js +1 -0
  211. package/components/ln-progress/ln-progress.schema.json +40 -0
  212. package/components/ln-progress/src/ln-progress.js +91 -0
  213. package/components/ln-progress/src/progress-model.js +20 -0
  214. package/{js → components}/ln-router/README.md +443 -432
  215. package/components/ln-router/ln-router-dev.scss +13 -0
  216. package/components/ln-router/ln-router.js +1 -0
  217. package/components/ln-router/ln-router.schema.json +68 -0
  218. package/{js → components}/ln-router/src/ln-router.js +585 -539
  219. package/components/ln-router/src/router-model.js +50 -0
  220. package/components/ln-scroll/README.md +45 -0
  221. package/components/ln-scroll/ln-scroll.js +1 -0
  222. package/components/ln-scroll/ln-scroll.schema.json +85 -0
  223. package/components/ln-scroll/src/ln-scroll.js +150 -0
  224. package/components/ln-search/README.md +188 -0
  225. package/components/ln-search/ln-search-dev.scss +13 -0
  226. package/components/ln-search/ln-search.js +1 -0
  227. package/components/ln-search/ln-search.schema.json +103 -0
  228. package/components/ln-search/src/ln-search.js +330 -0
  229. package/{js → components}/ln-slug/README.md +6 -3
  230. package/components/ln-slug/ln-slug-dev.scss +18 -0
  231. package/components/ln-slug/ln-slug.js +1 -0
  232. package/components/ln-slug/ln-slug.schema.json +23 -0
  233. package/{js → components}/ln-slug/src/ln-slug.js +20 -13
  234. package/components/ln-slug/src/slug-model.js +21 -0
  235. package/{js → components}/ln-sort/README.md +178 -170
  236. package/{js → components}/ln-sort/ln-sort-dev.scss +8 -8
  237. package/components/ln-sort/ln-sort.js +1 -0
  238. package/components/ln-sort/ln-sort.schema.json +104 -0
  239. package/components/ln-sort/src/ln-sort.js +321 -0
  240. package/components/ln-sort/src/sort-model.js +117 -0
  241. package/{js → components}/ln-sortable/README.md +7 -11
  242. package/components/ln-sortable/ln-sortable-dev.scss +13 -0
  243. package/components/ln-sortable/ln-sortable.js +1 -0
  244. package/components/ln-sortable/ln-sortable.schema.json +36 -0
  245. package/{js → components}/ln-sortable/src/ln-sortable.js +8 -13
  246. package/{js → components}/ln-stat/README.md +3 -1
  247. package/components/ln-stat/ln-stat-dev.scss +8 -0
  248. package/components/ln-stat/ln-stat.js +1 -0
  249. package/components/ln-stat/ln-stat.schema.json +32 -0
  250. package/{js → components}/ln-stat/src/ln-stat.js +14 -18
  251. package/components/ln-stat/src/stat-model.js +28 -0
  252. package/{js → components}/ln-table/README.md +37 -24
  253. package/{js → components}/ln-table/ln-table-dev.scss +17 -17
  254. package/components/ln-table/ln-table.js +1 -0
  255. package/components/ln-table/ln-table.schema.json +211 -0
  256. package/components/ln-table/ln-table.scss +15 -0
  257. package/{js → components}/ln-table/src/ln-table.js +1365 -1493
  258. package/components/ln-table/src/table-model.js +98 -0
  259. package/components/ln-table-coordinator/README.md +61 -0
  260. package/components/ln-table-coordinator/ln-table-coordinator.js +1 -0
  261. package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -0
  262. package/components/ln-table-coordinator/src/ln-table-coordinator.js +193 -0
  263. package/{js → components}/ln-tabs/README.md +32 -14
  264. package/components/ln-tabs/ln-tabs-dev.scss +24 -0
  265. package/components/ln-tabs/ln-tabs.js +1 -0
  266. package/components/ln-tabs/ln-tabs.schema.json +75 -0
  267. package/components/ln-tabs/ln-tabs.scss +8 -0
  268. package/components/ln-tabs/src/ln-tabs.js +207 -0
  269. package/components/ln-tabs/src/tabs-model.js +82 -0
  270. package/{js → components}/ln-time/README.md +96 -95
  271. package/components/ln-time/ln-time-dev.scss +13 -0
  272. package/components/ln-time/ln-time.js +1 -0
  273. package/components/ln-time/ln-time.schema.json +38 -0
  274. package/{js → components}/ln-time/src/ln-time.js +206 -223
  275. package/components/ln-time/src/time-model.js +64 -0
  276. package/{js → components}/ln-toast/README.md +23 -5
  277. package/components/ln-toast/ln-toast-dev.scss +8 -0
  278. package/components/ln-toast/ln-toast.js +1 -0
  279. package/components/ln-toast/ln-toast.schema.json +65 -0
  280. package/components/ln-toast/ln-toast.scss +59 -0
  281. package/{js → components}/ln-toast/src/ln-toast.js +233 -232
  282. package/{js → components}/ln-toggle/README.md +198 -196
  283. package/{js → components}/ln-toggle/ln-toggle-dev.scss +13 -13
  284. package/components/ln-toggle/ln-toggle.js +1 -0
  285. package/components/ln-toggle/ln-toggle.schema.json +52 -0
  286. package/components/ln-toggle/ln-toggle.scss +37 -0
  287. package/{js → components}/ln-toggle/src/ln-toggle.js +61 -46
  288. package/{js → components}/ln-tooltip/README.md +6 -6
  289. package/{js → components}/ln-tooltip/ln-tooltip-dev.scss +9 -9
  290. package/components/ln-tooltip/ln-tooltip.js +1 -0
  291. package/components/ln-tooltip/ln-tooltip.schema.json +86 -0
  292. package/components/ln-tooltip/ln-tooltip.scss +9 -0
  293. package/{js → components}/ln-tooltip/src/ln-tooltip.js +14 -3
  294. package/{js → components}/ln-translations/README.md +3 -1
  295. package/components/ln-translations/ln-translations-dev.scss +13 -0
  296. package/components/ln-translations/ln-translations.js +1 -0
  297. package/components/ln-translations/ln-translations.schema.json +120 -0
  298. package/{js → components}/ln-translations/src/ln-translations.js +25 -10
  299. package/components/ln-ui-coordinator/README.md +101 -0
  300. package/components/ln-ui-coordinator/ln-ui-coordinator-dev.scss +8 -0
  301. package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -0
  302. package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +60 -0
  303. package/{js/ln-modal-coordinator/src/ln-modal-coordinator.js → components/ln-ui-coordinator/src/ln-ui-coordinator.js} +403 -345
  304. package/components/ln-upload/README.md +133 -0
  305. package/components/ln-upload/ln-upload-dev.scss +18 -0
  306. package/components/ln-upload/ln-upload.js +1 -0
  307. package/components/ln-upload/ln-upload.schema.json +193 -0
  308. package/components/ln-upload/ln-upload.scss +20 -0
  309. package/components/ln-upload/src/ln-upload.js +652 -0
  310. package/components/ln-upload/src/upload-model.js +78 -0
  311. package/{js → components}/ln-validate/README.md +182 -180
  312. package/{js → components}/ln-validate/ln-validate-dev.scss +15 -15
  313. package/components/ln-validate/ln-validate.js +1 -0
  314. package/components/ln-validate/ln-validate.schema.json +50 -0
  315. package/components/ln-validate/ln-validate.scss +7 -0
  316. package/{js → components}/ln-validate/src/ln-validate.js +23 -45
  317. package/components/ln-validate/src/validate-model.js +64 -0
  318. package/components/ln-websocket-connector/README.md +166 -0
  319. package/components/ln-websocket-connector/ln-websocket-connector.js +1 -0
  320. package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -0
  321. package/components/ln-websocket-connector/src/ln-websocket-connector.js +279 -0
  322. package/ln-ashlar.html-data.json +1796 -0
  323. package/package.json +84 -61
  324. package/{scss → theme}/base/_global.scss +1 -2
  325. package/{scss → theme}/base/_reset.scss +1 -1
  326. package/{scss → theme}/base/_typography.scss +2 -0
  327. package/theme/brand.css +73 -0
  328. package/{scss → theme}/components/_app-shell.scss +8 -0
  329. package/theme/components/_button.scss +24 -0
  330. package/theme/components/_chart.scss +5 -0
  331. package/theme/components/_confirm.scss +6 -0
  332. package/{scss → theme}/components/_date.scss +30 -22
  333. package/{scss → theme}/components/_dropdown.scss +6 -1
  334. package/theme/components/_form.scss +140 -0
  335. package/{scss → theme}/components/_layout.scss +6 -0
  336. package/{scss → theme}/components/_ln-table.scss +1 -6
  337. package/theme/components/_picklist.scss +3 -0
  338. package/{scss → theme}/components/_sort.scss +10 -10
  339. package/theme/components/_status-badge.scss +6 -0
  340. package/{scss → theme}/components/_table.scss +16 -0
  341. package/{scss → theme}/components/_tabs.scss +0 -4
  342. package/theme/components/_toast.scss +48 -0
  343. package/{scss → theme}/components/_toggle.scss +1 -1
  344. package/theme/components/_upload.scss +45 -0
  345. package/{scss → theme}/config/_breakpoints.scss +1 -1
  346. package/theme/config/_contrast.scss +128 -0
  347. package/{scss → theme}/config/_density.scss +191 -205
  348. package/theme/config/_palette.scss +274 -0
  349. package/theme/config/_theme.scss +293 -0
  350. package/{scss → theme}/config/_tokens.scss +285 -441
  351. package/{scss → theme}/config/mixins/_accordion.scss +1 -1
  352. package/{scss → theme}/config/mixins/_alert.scss +1 -0
  353. package/{scss → theme}/config/mixins/_app-shell.scss +4 -2
  354. package/{scss → theme}/config/mixins/_borders.scss +2 -0
  355. package/theme/config/mixins/_btn.scss +175 -0
  356. package/{scss → theme}/config/mixins/_card.scss +55 -46
  357. package/theme/config/mixins/_chart.scss +82 -0
  358. package/{scss → theme}/config/mixins/_collapsible.scss +2 -1
  359. package/{scss → theme}/config/mixins/_colors.scss +8 -14
  360. package/{scss → theme}/config/mixins/_diagnostics.scss +48 -48
  361. package/theme/config/mixins/_dropdown.scss +169 -0
  362. package/{scss → theme}/config/mixins/_editor.scss +0 -7
  363. package/{scss → theme}/config/mixins/_filter.scss +47 -47
  364. package/{scss → theme}/config/mixins/_footer.scss +1 -1
  365. package/{scss → theme}/config/mixins/_form.scss +49 -18
  366. package/{scss → theme}/config/mixins/_index.scss +62 -61
  367. package/{scss → theme}/config/mixins/_layout.scss +6 -2
  368. package/{scss → theme}/config/mixins/_ln-table.scss +31 -10
  369. package/{scss → theme}/config/mixins/_loader.scss +1 -1
  370. package/{scss → theme}/config/mixins/_modal.scss +145 -149
  371. package/{scss → theme}/config/mixins/_motion.scss +13 -0
  372. package/{scss → theme}/config/mixins/_nav.scss +7 -7
  373. package/theme/config/mixins/_picklist.scss +66 -0
  374. package/theme/config/mixins/_popover.scss +96 -0
  375. package/{scss → theme}/config/mixins/_sidebar.scss +7 -4
  376. package/{scss → theme}/config/mixins/_sort.scss +43 -42
  377. package/{scss → theme}/config/mixins/_status-badge.scss +15 -2
  378. package/{scss → theme}/config/mixins/_table.scss +25 -14
  379. package/{scss → theme}/config/mixins/_tabs.scss +1 -1
  380. package/{scss → theme}/config/mixins/_toast.scss +174 -179
  381. package/{scss → theme}/config/mixins/_tooltip.scss +2 -2
  382. package/{scss → theme}/config/mixins/_typography.scss +16 -5
  383. package/{scss → theme}/config/mixins/_upload.scss +8 -6
  384. package/theme/ln-ashlar-core.scss +24 -0
  385. package/theme/ln-ashlar-dev.scss +66 -0
  386. package/theme/ln-ashlar-landing.scss +56 -0
  387. package/{scss/ln-ashlar.scss → theme/ln-ashlar-theme.scss} +63 -69
  388. package/theme/ln-ashlar.scss +8 -0
  389. package/theme/presentation/_bento.scss +151 -0
  390. package/theme/presentation/_cta.scss +111 -0
  391. package/theme/presentation/_effects.scss +216 -0
  392. package/theme/presentation/_features.scss +108 -0
  393. package/theme/presentation/_footer.scss +129 -0
  394. package/theme/presentation/_hero.scss +158 -0
  395. package/theme/presentation/_layout.scss +170 -0
  396. package/theme/presentation/_navbar.scss +140 -0
  397. package/theme/presentation/_pricing.scss +262 -0
  398. package/theme/presentation/_stats.scss +87 -0
  399. package/theme/presentation/_testimonials.scss +124 -0
  400. package/theme/presentation/_tokens.scss +39 -0
  401. package/theme/presentation/_typography.scss +163 -0
  402. package/{scss → theme}/utilities/_animations.scss +38 -0
  403. package/{scss → theme}/utilities/_utilities.scss +6 -0
  404. package/web-types.json +2312 -0
  405. package/js/ln-accordion/ln-accordion.js +0 -1
  406. package/js/ln-ajax/ln-ajax.js +0 -1
  407. package/js/ln-api-connector/ln-api-connector.js +0 -1
  408. package/js/ln-api-connector/src/ln-api-connector.js +0 -368
  409. package/js/ln-api-queue/ln-api-queue.js +0 -1
  410. package/js/ln-autoresize/ln-autoresize.js +0 -1
  411. package/js/ln-autosave/ln-autosave.js +0 -1
  412. package/js/ln-circular-progress/ln-circular-progress.js +0 -1
  413. package/js/ln-confirm/README.md +0 -162
  414. package/js/ln-confirm/_ln-confirm.scss +0 -24
  415. package/js/ln-confirm/ln-confirm.js +0 -1
  416. package/js/ln-core/crypto.js +0 -83
  417. package/js/ln-core/helpers.js +0 -788
  418. package/js/ln-core/index.js +0 -7
  419. package/js/ln-core/persist.js +0 -97
  420. package/js/ln-couchdb-connector/ln-couchdb-connector.js +0 -1
  421. package/js/ln-data-coordinator/ln-data-coordinator.js +0 -1
  422. package/js/ln-data-coordinator/src/data-read-policy.js +0 -18
  423. package/js/ln-data-store/ln-data-store.js +0 -1
  424. package/js/ln-date/ln-date.js +0 -1
  425. package/js/ln-date/src/ln-date.js +0 -603
  426. package/js/ln-debug/README.md +0 -58
  427. package/js/ln-debug/ln-debug.js +0 -1
  428. package/js/ln-debug/src/ln-debug.js +0 -19
  429. package/js/ln-dropdown/ln-dropdown.js +0 -1
  430. package/js/ln-dropdown/ln-dropdown.scss +0 -15
  431. package/js/ln-editor/ln-editor.js +0 -1
  432. package/js/ln-editor/ln-editor.scss +0 -43
  433. package/js/ln-external-links/ln-external-links.js +0 -1
  434. package/js/ln-fill/ln-fill.js +0 -1
  435. package/js/ln-filter/README.md +0 -189
  436. package/js/ln-filter/ln-filter-dev.scss +0 -8
  437. package/js/ln-filter/ln-filter.js +0 -1
  438. package/js/ln-filter/src/ln-filter.js +0 -419
  439. package/js/ln-form/ln-form.js +0 -1
  440. package/js/ln-http/ln-http.js +0 -1
  441. package/js/ln-link/ln-link.js +0 -1
  442. package/js/ln-list/README.md +0 -129
  443. package/js/ln-list/ln-list.js +0 -1
  444. package/js/ln-list/ln-list.scss +0 -28
  445. package/js/ln-modal/ln-modal-dev.scss +0 -13
  446. package/js/ln-modal/ln-modal.js +0 -1
  447. package/js/ln-modal/ln-modal.scss +0 -35
  448. package/js/ln-modal-coordinator/README.md +0 -99
  449. package/js/ln-modal-coordinator/ln-modal-coordinator-dev.scss +0 -8
  450. package/js/ln-modal-coordinator/ln-modal-coordinator.js +0 -1
  451. package/js/ln-nav/ln-nav.js +0 -1
  452. package/js/ln-number/README.md +0 -149
  453. package/js/ln-number/ln-number.js +0 -1
  454. package/js/ln-number/src/ln-number.js +0 -443
  455. package/js/ln-options/ln-options.js +0 -1
  456. package/js/ln-popover/ln-popover.js +0 -1
  457. package/js/ln-progress/ln-progress.js +0 -1
  458. package/js/ln-progress/src/ln-progress.js +0 -98
  459. package/js/ln-router/ln-router.js +0 -1
  460. package/js/ln-search/README.md +0 -158
  461. package/js/ln-search/ln-search-dev.scss +0 -8
  462. package/js/ln-search/ln-search.js +0 -1
  463. package/js/ln-search/src/ln-search.js +0 -117
  464. package/js/ln-slug/ln-slug.js +0 -1
  465. package/js/ln-sort/ln-sort.js +0 -1
  466. package/js/ln-sort/src/ln-sort.js +0 -178
  467. package/js/ln-sortable/ln-sortable.js +0 -1
  468. package/js/ln-stat/ln-stat.js +0 -1
  469. package/js/ln-table/ln-table.js +0 -1
  470. package/js/ln-table/ln-table.scss +0 -11
  471. package/js/ln-table-coordinator/README.md +0 -73
  472. package/js/ln-table-coordinator/ln-table-coordinator.js +0 -1
  473. package/js/ln-table-coordinator/src/ln-table-coordinator.js +0 -160
  474. package/js/ln-tabs/ln-tabs-dev.scss +0 -18
  475. package/js/ln-tabs/ln-tabs.js +0 -1
  476. package/js/ln-tabs/src/ln-tabs.js +0 -188
  477. package/js/ln-time/ln-time.js +0 -1
  478. package/js/ln-toast/ln-toast.js +0 -1
  479. package/js/ln-toggle/ln-toggle.js +0 -1
  480. package/js/ln-tooltip/ln-tooltip.js +0 -1
  481. package/js/ln-tooltip/ln-tooltip.scss +0 -9
  482. package/js/ln-translations/ln-translations.js +0 -1
  483. package/js/ln-upload/README.md +0 -255
  484. package/js/ln-upload/ln-upload.js +0 -1
  485. package/js/ln-upload/ln-upload.scss +0 -20
  486. package/js/ln-upload/src/ln-upload.js +0 -423
  487. package/js/ln-validate/ln-validate.js +0 -1
  488. package/scss/components/_button.scss +0 -20
  489. package/scss/components/_confirm.scss +0 -5
  490. package/scss/components/_form.scss +0 -107
  491. package/scss/components/_status-badge.scss +0 -4
  492. package/scss/components/_toast.scss +0 -68
  493. package/scss/components/_upload.scss +0 -51
  494. package/scss/config/_theme.scss +0 -216
  495. package/scss/config/mixins/_btn.scss +0 -179
  496. package/scss/config/mixins/_confirm.scss +0 -31
  497. package/scss/config/mixins/_dropdown.scss +0 -141
  498. package/scss/config/mixins/_popover.scss +0 -64
  499. package/scss/ln-ashlar-dev.scss +0 -39
  500. /package/{js → components}/ln-core/positioning.js +0 -0
  501. /package/{js → components}/ln-core/reactive.js +0 -0
  502. /package/{js → components}/ln-filter/ln-filter.scss +0 -0
  503. /package/{js → components}/ln-icon/ln-icon.js +0 -0
  504. /package/{js → components}/ln-icon/src/ln-icon.js +0 -0
  505. /package/{js → components}/ln-search/ln-search.scss +0 -0
  506. /package/{js → components}/ln-toast/template.html +0 -0
  507. /package/{scss → theme}/components/_accordion.scss +0 -0
  508. /package/{scss → theme}/components/_ajax.scss +0 -0
  509. /package/{scss → theme}/components/_alert.scss +0 -0
  510. /package/{scss → theme}/components/_avatar.scss +0 -0
  511. /package/{scss → theme}/components/_breadcrumbs.scss +0 -0
  512. /package/{scss → theme}/components/_card.scss +0 -0
  513. /package/{scss → theme}/components/_chip.scss +0 -0
  514. /package/{scss → theme}/components/_circular-progress.scss +0 -0
  515. /package/{scss → theme}/components/_editor.scss +0 -0
  516. /package/{scss → theme}/components/_empty-state.scss +0 -0
  517. /package/{scss → theme}/components/_filter.scss +0 -0
  518. /package/{scss → theme}/components/_link.scss +0 -0
  519. /package/{scss → theme}/components/_loader.scss +0 -0
  520. /package/{scss → theme}/components/_modal.scss +0 -0
  521. /package/{scss → theme}/components/_nav.scss +0 -0
  522. /package/{scss → theme}/components/_page-header.scss +0 -0
  523. /package/{scss → theme}/components/_popover.scss +0 -0
  524. /package/{scss → theme}/components/_progress.scss +0 -0
  525. /package/{scss → theme}/components/_prose.scss +0 -0
  526. /package/{scss → theme}/components/_scrollbar.scss +0 -0
  527. /package/{scss → theme}/components/_sections.scss +0 -0
  528. /package/{scss → theme}/components/_sidebar.scss +0 -0
  529. /package/{scss → theme}/components/_stat-card.scss +0 -0
  530. /package/{scss → theme}/components/_stepper.scss +0 -0
  531. /package/{scss → theme}/components/_timeline.scss +0 -0
  532. /package/{scss → theme}/components/_tooltip.scss +0 -0
  533. /package/{scss → theme}/components/_translations.scss +0 -0
  534. /package/{scss → theme}/config/_icons.scss +0 -0
  535. /package/{scss → theme}/config/_mixins.scss +0 -0
  536. /package/{scss → theme}/config/mixins/_ajax.scss +0 -0
  537. /package/{scss → theme}/config/mixins/_avatar.scss +0 -0
  538. /package/{scss → theme}/config/mixins/_breadcrumbs.scss +0 -0
  539. /package/{scss → theme}/config/mixins/_breakpoints.scss +0 -0
  540. /package/{scss → theme}/config/mixins/_chip.scss +0 -0
  541. /package/{scss → theme}/config/mixins/_circular-progress.scss +0 -0
  542. /package/{scss → theme}/config/mixins/_display.scss +0 -0
  543. /package/{scss → theme}/config/mixins/_empty-state.scss +0 -0
  544. /package/{scss → theme}/config/mixins/_focus.scss +0 -0
  545. /package/{scss → theme}/config/mixins/_interaction.scss +0 -0
  546. /package/{scss → theme}/config/mixins/_kbd.scss +0 -0
  547. /package/{scss → theme}/config/mixins/_link.scss +0 -0
  548. /package/{scss → theme}/config/mixins/_page-header.scss +0 -0
  549. /package/{scss → theme}/config/mixins/_position.scss +0 -0
  550. /package/{scss → theme}/config/mixins/_progress.scss +0 -0
  551. /package/{scss → theme}/config/mixins/_prose.scss +0 -0
  552. /package/{scss → theme}/config/mixins/_shadows.scss +0 -0
  553. /package/{scss → theme}/config/mixins/_sizing.scss +0 -0
  554. /package/{scss → theme}/config/mixins/_spacing.scss +0 -0
  555. /package/{scss → theme}/config/mixins/_stat-card.scss +0 -0
  556. /package/{scss → theme}/config/mixins/_stepper.scss +0 -0
  557. /package/{scss → theme}/config/mixins/_timeline.scss +0 -0
  558. /package/{scss → theme}/config/mixins/_transitions.scss +0 -0
  559. /package/{scss → theme}/config/mixins/_translations.scss +0 -0
  560. /package/{scss → theme}/tabler-icons.txt +0 -0
@@ -0,0 +1 @@
1
+ var LnAshlarComponent=(function(y){"use strict";function L(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function A(t){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return t?window.lnCore._debugIsContained(t):window.lnCore._debugSink!==null;if(t&&t.closest){const e=t.closest("[data-ln-debug]");return!(!e||typeof document<"u"&&e===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const t=console.warn;console.warn=function(...e){if(typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))){let a=null;for(let r=1;r<e.length;r++)if(e[r]&&e[r].nodeType===1){a=e[r];break}if(!A(a))return}t.apply(console,e)}}function Y(t,e){window.lnCore=window.lnCore||{},window.lnCore._debugSink=t,window.lnCore._debugIsContained=e||null}function Z(t,e,n){const a=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",e,t,a),t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:a}))}function p(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){p(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}const M={};function tt(t,e){M[t]=e}function et(t){return M[t]||{ingress:e=>e,egress:e=>e}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=tt,window.lnCore.getDataMapper=et);function nt(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,p(function(){new MutationObserver(function(){Z(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const R={};function at(t,e){if(!t||typeof e!="object")return;const n=t.toLowerCase().split("-")[0];R[n]=e}function lt(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return R[e]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=at,window.lnCore.getLocaleFallback=lt,window.lnCore.ensureLocaleObserver=nt);const S={};function ot(t,e){S[t]||(S[t]=document.querySelector('[data-ln-template="'+t+'"]'));const n=S[t];return n?n.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function W(t,e){if(!t||!e)return t;const n=t.querySelectorAll("[data-ln-field]");for(let o=0;o<n.length;o++){const d=n[o],i=d.getAttribute("data-ln-field");e[i]!=null&&(d.textContent=e[i])}const a=t.querySelectorAll("[data-ln-attr]");for(let o=0;o<a.length;o++){const d=a[o],i=d.getAttribute("data-ln-attr").split(",");for(let s=0;s<i.length;s++){const c=i[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();e[f]!=null&&d.setAttribute(u,e[f])}}const r=t.querySelectorAll("[data-ln-show]");for(let o=0;o<r.length;o++){const d=r[o],i=d.getAttribute("data-ln-show");i in e&&d.classList.toggle("hidden",!e[i])}const l=t.querySelectorAll("[data-ln-class]");for(let o=0;o<l.length;o++){const d=l[o],i=d.getAttribute("data-ln-class").split(",");for(let s=0;s<i.length;s++){const c=i[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();f in e&&d.classList.toggle(u,!!e[f])}}return t}function rt(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",t,e??null),t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0})));const n=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<n.length;a++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[a],e??null),n[a].dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(t){if(!(!t.target.matches||!t.target.matches("[data-ln-fillable]")))if(t.detail)W(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let n=0;n<e.length;n++)e[n].textContent=""}})));function j(t,e){if(!t||!e)return t;const n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const l=n.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(o,d){return e[d]!==void 0?e[d]:""}))}const a=function(l,o){return e[o]!==void 0?e[o]:""},r=Array.from(t.querySelectorAll("*"));t.nodeType===1&&r.push(t);for(let l=0;l<r.length;l++){const o=r[l],d=o.attributes;for(let i=0;i<d.length;i++){const s=d[i];s.value.indexOf("{{")!==-1&&o.setAttribute(s.name,s.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return t}function it(t,e,n,a,r,l){const o={};for(let i=0;i<t.children.length;i++){const s=t.children[i],c=s.getAttribute("data-ln-render-key");c&&(o[c]=s)}const d=document.createDocumentFragment();for(let i=0;i<e.length;i++){const s=e[i],c=String(a(s));let u=o[c];if(u)r(u,s,i);else{const f=ot(n,l);if(!f||(j(f,s),u=f.firstElementChild,!u))continue;u.setAttribute("data-ln-render-key",c),r(u,s,i)}d.appendChild(u)}t.textContent="",t.appendChild(d)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=j,window.lnCore.fill=W,window.lnCore.lnFill=rt,window.lnCore.renderList=it);function B(t,e,n,a,r){if(!t||e===null)return!0;const l=a||"ln-component",o=t.type;if(o==="trigger"||o==="marker"||o==="string"||o==="list"||!o||e===""&&t.fallback!==void 0)return!0;const d=i=>{r?console.warn(i,r):console.warn(i)};if(o==="boolean"){const i=e.trim().toLowerCase();return i!==""&&i!=="true"&&i!=="false"&&i!=="1"&&i!=="0"?(d(`[${l}] Invalid value "${e}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(o==="enum"){const i=t.values||[];return i.includes(e)?!0:(d(`[${l}] Invalid value "${e}" for attribute "${n}". Allowed: ${i.join(", ")}. Fallback: "${t.fallback}".`),!1)}if(o==="integer"){if(!/^-?\d+$/.test(e))return d(`[${l}] Invalid integer "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1;const i=parseInt(e,10);return t.min!==void 0&&i<t.min?(d(`[${l}] Value ${i} for attribute "${n}" is less than min (${t.min}).`),!1):t.max!==void 0&&i>t.max?(d(`[${l}] Value ${i} for attribute "${n}" is greater than max (${t.max}).`),!1):!0}if(o==="float")return isNaN(Number(e))?(d(`[${l}] Invalid float "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1):!0;if(o==="json")try{return JSON.parse(e),!0}catch(i){return d(`[${l}] Invalid JSON for attribute "${n}": ${i.message}. Fallback: ${t.fallback}.`),!1}return!0}function dt(t){const e={};for(const n in t){const a=t[n];a&&a.effect&&(e[n]=a.effect)}return Object.keys(e).length?e:null}function st(t){if(t.onAttrChange&&!t.declared)return null;const e=new Set;if(t.effects)for(const n in t.effects)e.add(n);if(t.onAttrChange&&t.declared)for(const n of t.declared)e.add(n);return e}function _(t,e,n,a){if(t.nodeType!==1)return;const l=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",o=Array.from(t.querySelectorAll(l));t.matches&&t.matches(l)&&o.push(t);for(const d of o)if(!d[n]){window.lnCore._persistSink&&d.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(d,e);try{d[n]=new a(d)}catch(i){console.error("["+n+"] init failed",d,i)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function N(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function F(t){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(t):setTimeout(t,0)):t()}function V(){window.lnCore=window.lnCore||{};const t=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return t.byReactive=t.byReactive||new Map,t.reactiveWildcard=t.reactiveWildcard||[],t}function H(t){const e=V(),n=t.observed||[];for(let a=0;a<n.length;a++){const r=n[a];e.byAttr.has(r)||e.byAttr.set(r,[]),e.byAttr.get(r).push(t)}if(e.byDeclaredAttr=e.byDeclaredAttr||new Map,t.attributes)for(const a in t.attributes){e.byDeclaredAttr.has(a)||e.byDeclaredAttr.set(a,[]);const r=e.byDeclaredAttr.get(a);r.some(l=>l.componentTag===t.componentTag)||r.push({spec:t.attributes[a],componentTag:t.componentTag})}if(t.onAttrChange||t.effects){e.reactive.push(t);const a=st(t);if(a===null)e.reactiveWildcard.push(t);else for(const r of a)e.byReactive.has(r)||e.byReactive.set(r,[]),e.byReactive.get(r).push(t)}t.persist&&e.persist.push(t)}function U(t,e,n,a){for(let r=0;r<t.length;r++){const l=t[r];if(!e[l.attribute])continue;const o=l.effects&&l.effects[n];o?o(e,n,a):l.onAttrChange&&(!l.declared||l.declared.has(n))&&l.onAttrChange(e,n,a)}}function ct(t){const e=t.target,n=t.attributeName;if(t.oldValue===e.getAttribute(n))return;const a=V(),r=a.byAttr.get(n);if(L()&&a.byDeclaredAttr&&a.byDeclaredAttr.has(n)&&A(e)){const l=a.byDeclaredAttr.get(n),o=e.getAttribute(n);for(let d=0;d<l.length;d++)B(l[d].spec,o,n,l[d].componentTag,e)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||r)&&window.lnCore._debugSink("attr",n,e,{oldValue:t.oldValue,newValue:e.getAttribute(n)}),n.indexOf("data-ln-")===0){const l=a.byReactive.get(n);l&&U(l,e,n,t.oldValue),a.reactiveWildcard.length&&U(a.reactiveWildcard,e,n,t.oldValue)}if(r)for(let l=0;l<r.length;l++){const o=r[l];if(o.handler){o.handler(e,n,t.oldValue);continue}o.onAttributeChange&&e[o.attribute]?o.onAttributeChange(e,n):(_(e,o.selector,o.attribute,o.ComponentFn),o.onInit&&o.onInit(e))}}function z(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,p(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++)try{ct(e[n])}catch(a){console.error("[ln-core] mutation handler failed",e[n].target,a)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function G(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function ut(t){const e=G();if(e.length){if(t.target)for(let n=0;n<e.length;n++){const a=e[n];if(a.onSubtreeChange){const r=a.query,l=t.target.nodeType===1?t.target.matches(r)?t.target:t.target.closest(r):t.target.parentElement?t.target.parentElement.closest(r):null;l&&a.onSubtreeChange(l,t)}}for(let n=0;n<t.addedNodes.length;n++){const a=t.addedNodes[n];if(a.nodeType===1)for(let r=0;r<e.length;r++){const l=e[r];_(a,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(a)}}for(let n=0;n<t.removedNodes.length;n++){const a=t.removedNodes[n];if(a.nodeType===1)for(let r=0;r<e.length;r++){const l=e[r],o=l.query,d=Array.from(a.querySelectorAll(o));a.matches&&a.matches(o)&&d.push(a);for(let i=0;i<d.length;i++){const s=d[i];if(!document.contains(s)){const c=s[l.attribute];if(c&&typeof c.destroy=="function")try{c.destroy()}catch(u){console.error("["+l.attribute+"] destroy failed",s,u)}delete s[l.attribute]}}}}}}function ft(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,p(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++){const a=e[n];if(a.type==="childList")try{ut(a)}catch(r){console.error("[ln-core] lifecycle handler failed",a.target,r)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function wt(t,e){H({observed:t,handler:e}),z()}function bt(t,e,n,a,r={}){const l=r.extraAttributes||[],o=r.onAttributeChange||null,d=r.onSubtreeChange||null,i=r.onInit||null,s=r.onAttrChange||null,c=r.effects||null,u=r.attributes||null,f=u?dt(u):c,D=u?new Set(Object.keys(u)):null,qt=r.persist||null;function v(E){const w=E||document.body;if(_(w,t,e,n),u&&L())for(const g in u){const Mt=u[g],O=Array.from(w.querySelectorAll("["+g+"]"));w.matches&&w.matches("["+g+"]")&&O.push(w);for(let T=0;T<O.length;T++){const q=O[T];A(q)&&B(Mt,q.getAttribute(g),g,a,q)}}i&&i(w)}const I=[];if(t.indexOf("[")!==-1){const E=/\[([\w-]+)/g;let w;for(;(w=E.exec(t))!==null;)I.push(w[1])}else I.push(t);H({selector:t,attribute:e,componentTag:a,attributes:u,ComponentFn:n,onInit:i,observed:I.concat(l),onAttributeChange:o,onAttrChange:s,effects:f,declared:D,persist:qt}),z();const Lt=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]";G().push({selector:t,attribute:e,ComponentFn:n,onInit:i,onSubtreeChange:d,query:Lt}),ft(),window[e]=v;function X(){N()>0?F(function(){v(document.body)}):v(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",X):X(),v}function Q(t){return(t||"").replace(/^#/,"")}function k(t){const e=t===void 0?location.hash:t,n={},a=Q(e);if(!a)return n;const r=a.split("&");for(let l=0;l<r.length;l++){const o=r[l];if(!o)continue;const d=o.indexOf(":"),i=d>-1?o.slice(0,d):o,s=d>-1?o.slice(d+1):"";if(i)try{n[i]=decodeURIComponent(s)}catch{n[i]=s}}return n}function pt(t){if(!t)return null;const e=k();return t in e?e[t]:null}function ht(t,e){if(!t)return;const n=k();e==null?delete n[t]:n[t]=String(e);const r=Object.keys(n).map(function(l){const o=n[l];return o===""?l:l+":"+encodeURIComponent(o)}).join("&");Q(location.hash)!==r&&(location.hash=r)}function mt(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}function gt(t,e){if(!t||!t.hasAttribute("data-ln-hash"))return null;const n=t.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const a=t.getAttribute("data-ln-sort")||t.getAttribute("data-ln-search-for")||t.getAttribute("data-ln-search")||t.getAttribute("data-ln-filter")||t.id;return a?e?a+"-"+e:a:e||null}function yt(t,e){return!e||e==="none"||t===null||t===void 0?null:String(t)+"."+e}function Ct(t){return!t||typeof t!="string"?null:t.endsWith(".asc")?{fieldOrColumn:t.slice(0,-4),direction:"asc"}:t.endsWith(".desc")?{fieldOrColumn:t.slice(0,-5),direction:"desc"}:null}function vt(t,e){return!t||!Array.isArray(e)||e.length===0?null:t+":"+e.map(encodeURIComponent).join(",")}function At(t){if(!t||typeof t!="string")return null;const e=t.indexOf(":");if(e===-1)return null;const n=t.slice(0,e),a=t.slice(e+1),r=a?a.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:n,values:r}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=k,window.lnCore.hashGet=pt,window.lnCore.hashSet=ht,window.lnCore.hashLinkClick=mt,window.lnCore.resolveHashNamespace=gt,window.lnCore.hashSortEncode=yt,window.lnCore.hashSortDecode=Ct,window.lnCore.hashFilterEncode=vt,window.lnCore.hashFilterDecode=At);const x=new Set(["data-ln-accordion","data-ln-ajax","data-ln-api-base-url","data-ln-api-connector","data-ln-api-connector-query-debounce","data-ln-api-headers","data-ln-api-param-limit","data-ln-api-param-offset","data-ln-api-param-search","data-ln-api-param-sort-dir","data-ln-api-param-sort-field","data-ln-api-path","data-ln-api-queue","data-ln-api-queue-online","data-ln-attr","data-ln-autoresize","data-ln-autosave","data-ln-autosave-clear","data-ln-autosave-debounce-input","data-ln-autosave-exclude","data-ln-chart","data-ln-chart-area","data-ln-chart-count","data-ln-chart-empty","data-ln-chart-labels","data-ln-chart-line","data-ln-chart-max","data-ln-chart-min","data-ln-chart-padding","data-ln-chart-plot","data-ln-chart-sort","data-ln-chart-source","data-ln-chart-type","data-ln-chart-x","data-ln-chart-y","data-ln-chart-zero","data-ln-circular-progress","data-ln-circular-progress-label","data-ln-circular-progress-max","data-ln-class","data-ln-col","data-ln-confirm","data-ln-confirm-active","data-ln-confirm-announcer","data-ln-confirm-idle","data-ln-confirm-state","data-ln-confirm-timeout","data-ln-couchdb-auth","data-ln-couchdb-connector","data-ln-couchdb-db","data-ln-couchdb-headers","data-ln-couchdb-url","data-ln-data-coordinator","data-ln-data-coordinator-dict","data-ln-data-coordinator-filters","data-ln-data-coordinator-mapper","data-ln-data-coordinator-no-autosync","data-ln-data-coordinator-scope","data-ln-data-coordinator-search","data-ln-data-coordinator-sort-direction","data-ln-data-coordinator-sort-field","data-ln-data-coordinator-stale","data-ln-data-store","data-ln-data-store-frozen","data-ln-data-store-indexes","data-ln-data-store-no-autosync","data-ln-data-store-no-local-query","data-ln-data-store-search-fields","data-ln-data-store-stale","data-ln-data-store-window","data-ln-data-store-window-page","data-ln-date","data-ln-date-dict","data-ln-date-dict-key","data-ln-date-field","data-ln-date-format","data-ln-date-label","data-ln-date-locale","data-ln-debug","data-ln-dropdown","data-ln-dropdown-menu","data-ln-dropdown-placement","data-ln-dropdown-position","data-ln-editor","data-ln-editor-action","data-ln-editor-source","data-ln-empty","data-ln-empty-state","data-ln-empty-when","data-ln-error","data-ln-external-link","data-ln-field","data-ln-fill-as","data-ln-fill-form","data-ln-fill-id","data-ln-fillable","data-ln-filter","data-ln-filter-col","data-ln-filter-hide","data-ln-filter-key","data-ln-filter-options","data-ln-filter-reset","data-ln-filter-search","data-ln-filter-value","data-ln-filter-values","data-ln-form","data-ln-form-action-edit","data-ln-form-action-method","data-ln-hash","data-ln-include","data-ln-item","data-ln-item-action","data-ln-item-id","data-ln-item-select","data-ln-key","data-ln-key-allow-input","data-ln-key-for","data-ln-key-modifier","data-ln-key-target","data-ln-link","data-ln-list","data-ln-list-body","data-ln-list-count","data-ln-list-empty","data-ln-list-field","data-ln-list-filtered","data-ln-list-select-all","data-ln-list-selectable","data-ln-list-selected","data-ln-list-source","data-ln-list-total","data-ln-list-window","data-ln-list-window-page","data-ln-list-window-threshold","data-ln-mapper","data-ln-modal","data-ln-modal-close","data-ln-modal-for","data-ln-modal-mode","data-ln-modal-when","data-ln-nav","data-ln-nav-exact","data-ln-number","data-ln-number-decimals","data-ln-number-max","data-ln-number-min","data-ln-obfuscator","data-ln-obfuscator-codec","data-ln-obfuscator-key","data-ln-options","data-ln-options-label","data-ln-options-value","data-ln-outlet","data-ln-panel","data-ln-persist","data-ln-persist-scope","data-ln-picklist","data-ln-picklist-list","data-ln-picklist-max","data-ln-popover","data-ln-popover-for","data-ln-popover-placement","data-ln-popover-position","data-ln-progress","data-ln-progress-max","data-ln-render-key","data-ln-route","data-ln-route-keep","data-ln-route-target","data-ln-route-title","data-ln-router-hydrate","data-ln-scroll","data-ln-scroll-behavior","data-ln-scroll-block","data-ln-scroll-delay","data-ln-scroll-focus","data-ln-scroll-set","data-ln-scroll-update-hash","data-ln-search","data-ln-search-clear","data-ln-search-clear-for","data-ln-search-exclude","data-ln-search-fields","data-ln-search-for","data-ln-search-hide","data-ln-search-items","data-ln-show","data-ln-slug-from","data-ln-sort","data-ln-sort-dir","data-ln-sort-exclude","data-ln-sort-field","data-ln-sort-icon","data-ln-sort-items","data-ln-sort-state","data-ln-sortable","data-ln-sortable-handle","data-ln-stat","data-ln-stat-card","data-ln-stat-filter","data-ln-stat-label","data-ln-stat-trend","data-ln-stat-value","data-ln-step","data-ln-step-label","data-ln-stepper","data-ln-store","data-ln-tab","data-ln-table","data-ln-table-body","data-ln-table-cell-attr","data-ln-table-clear","data-ln-table-clear-all","data-ln-table-col","data-ln-table-col-filter","data-ln-table-col-select","data-ln-table-col-sort","data-ln-table-coordinator","data-ln-table-count","data-ln-table-dict","data-ln-table-empty","data-ln-table-empty-when","data-ln-table-filter-col","data-ln-table-filtered","data-ln-table-row","data-ln-table-row-action","data-ln-table-row-id","data-ln-table-row-select","data-ln-table-select-all-label","data-ln-table-selectable","data-ln-table-selected","data-ln-table-sort","data-ln-table-source","data-ln-table-total","data-ln-table-window","data-ln-table-window-page","data-ln-table-window-threshold","data-ln-tabs","data-ln-tabs-active","data-ln-tabs-default","data-ln-tabs-focus","data-ln-tabs-key","data-ln-template","data-ln-time","data-ln-time-locale","data-ln-toast","data-ln-toast-close","data-ln-toast-item","data-ln-toast-max","data-ln-toast-timeout","data-ln-toast-when","data-ln-toggle","data-ln-toggle-action","data-ln-toggle-for","data-ln-tooltip","data-ln-tooltip-enhance","data-ln-tooltip-enhanced","data-ln-tooltip-placement","data-ln-tooltip-position","data-ln-translatable","data-ln-translatable-lang","data-ln-translations","data-ln-translations-active","data-ln-translations-add","data-ln-translations-default","data-ln-translations-lang","data-ln-translations-locales","data-ln-translations-placeholder","data-ln-translations-prefix","data-ln-translations-remove-label","data-ln-ui-coordinator","data-ln-ui-coordinator-dict","data-ln-upload","data-ln-upload-accept","data-ln-upload-action","data-ln-upload-delete","data-ln-upload-dict","data-ln-upload-ext","data-ln-upload-file-field","data-ln-upload-id","data-ln-upload-ids-field","data-ln-upload-item","data-ln-upload-list","data-ln-upload-local-id","data-ln-upload-max-files","data-ln-upload-max-size","data-ln-upload-progress","data-ln-upload-size","data-ln-upload-state","data-ln-upload-zone","data-ln-validate","data-ln-validate-error","data-ln-validate-errors","data-ln-value","data-ln-websocket-connector","data-ln-websocket-connector-url"]);function St(t,e){if(t===e)return 0;if(!t.length)return e.length;if(!e.length)return t.length;const n=[];for(let a=0;a<=e.length;a++)n[a]=[a];for(let a=0;a<=t.length;a++)n[0][a]=a;for(let a=1;a<=e.length;a++)for(let r=1;r<=t.length;r++)e.charAt(a-1)===t.charAt(r-1)?n[a][r]=n[a-1][r-1]:n[a][r]=Math.min(n[a-1][r-1]+1,n[a][r-1]+1,n[a-1][r]+1);return n[e.length][t.length]}function _t(t,e=x){if(e.has(t))return null;let n=null,a=1/0;for(const l of e){const o=St(t,l);o<a&&(a=o,n=l)}const r=Math.max(3,Math.floor(t.length*.4));return a<=r?n:null}function K(t){return typeof CSS<"u"&&CSS.escape?CSS.escape(t):t.replace(/([!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~])/g,"\\$1")}function kt(t=document){const e=t.ownerDocument||t,n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&i.name.endsWith("-for")){const s=(i.value||"").trim();if(!s){a.push({type:"id-empty",element:o,attribute:i.name,targetId:"",message:`[ln-debug] Empty ID reference in <${o.tagName.toLowerCase()} ${i.name}="">.`});continue}e.getElementById(s)||e.querySelector("#"+K(s))||a.push({type:"id-unresolved",element:o,attribute:i.name,targetId:s,message:`[ln-debug] Unresolved ID reference: <${o.tagName.toLowerCase()} ${i.name}="${s}"> targets "#${s}", but no element with id="${s}" exists in the document.`})}}}return a}function xt(t=document){const e=t.ownerDocument||t,n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&(i.name.endsWith("-source")||i.name.endsWith("-store"))&&i.name!=="data-ln-data-store"){const c=(i.value||"").trim();if(!c){a.push({type:"store-empty",element:o,attribute:i.name,storeName:"",message:`[ln-debug] Empty store reference in <${o.tagName.toLowerCase()} ${i.name}="">.`});continue}const u=K(c),f=e.querySelector(`[data-ln-data-store="${u}"], [data-ln-store="${u}"]`),D=typeof window<"u"&&window.lnDataStore&&typeof window.lnDataStore.getStore=="function"&&window.lnDataStore.getStore(c);!f&&!D&&a.push({type:"store-unresolved",element:o,attribute:i.name,storeName:c,message:`[ln-debug] Unresolved store reference: <${o.tagName.toLowerCase()} ${i.name}="${c}"> targets store "${c}", but no [data-ln-data-store="${c}"] exists in the document.`})}}}return a}function $t(t=document){t.ownerDocument;const e=t.nodeType===9?t.body||t.documentElement:t;if(!e)return[];const n=[],a=Array.from(e.querySelectorAll("[data-ln-data-store]"));e.hasAttribute&&e.hasAttribute("data-ln-data-store")&&a.unshift(e);const r=new Map;for(let l=0;l<a.length;l++){const o=a[l],d=(o.getAttribute("data-ln-data-store")||"").trim();d&&(r.has(d)||r.set(d,[]),r.get(d).push(o))}for(const[l,o]of r.entries())o.length>1&&n.push({type:"store-duplicate",storeName:l,elements:o,message:`[ln-debug] Duplicate store name: Multiple elements declare data-ln-data-store="${l}". Store names must be unique across the document.`});return n}function Dt(t=document,e=x){const n=t.nodeType===9?t.body||t.documentElement:t;if(!n)return[];const a=[],r=[n,...n.querySelectorAll("*")];for(let l=0;l<r.length;l++){const o=r[l];if(o.attributes)for(let d=0;d<o.attributes.length;d++){const i=o.attributes[d];if(i.name.startsWith("data-ln-")&&!e.has(i.name)){const s=_t(i.name,e),c=s?` Did you mean "${s}"?`:"";a.push({type:"attribute-unknown",element:o,attribute:i.name,suggestion:s,message:`[ln-debug] Unknown attribute "${i.name}" on <${o.tagName.toLowerCase()}>.${c}`})}}}return a}function C(t=typeof document<"u"?document:null,e={}){if(!t)return{idIssues:[],storeIssues:[],uniquenessIssues:[],spellingIssues:[],total:0};const n=e.validAttributes||x,a=kt(t),r=xt(t),l=$t(t),o=Dt(t,n),d=[...a,...r,...l,...o];if(!e.silent)for(let i=0;i<d.length;i++)console.warn(d[i].message);return{idIssues:a,storeIssues:r,uniquenessIssues:l,spellingIssues:o,total:d.length}}let h=null;function m(t=typeof document<"u"?document:null,e=50,n=null){if(!t)return;h&&(clearTimeout(h),h=null);function a(){h=setTimeout(()=>{h=null;const r=C(t);n&&n(r)},e)}N()>0?F(a):a()}function It(t,e,n,a){t==="event"?(console.groupCollapsed("[ln-debug] event",e),console.log("target",n),console.log("detail",a),console.groupEnd()):t==="attr"&&(console.groupCollapsed("[ln-debug] attr",e),console.log("target",n),console.log("old → new",a.oldValue,"→",a.newValue),console.groupEnd())}let b=[];function Et(){b=Array.from(document.body.querySelectorAll("[data-ln-debug]")),document.body.hasAttribute("data-ln-debug")&&b.push(document.body)}function J(t){if(t===window||t===document)return b.indexOf(document.body)!==-1;for(let e=0;e<b.length;e++)if(b[e].contains(t))return!0;return!1}function Ot(t,e,n,a){J(n)&&It(t,e,n,a)}function $(){Et(),Y(b.length>0?Ot:null,b.length>0?J:null)}function P(){$()}function Tt(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._debugGateBound&&(window.lnCore._debugGateBound=!0,p(function(){$(),wt(["data-ln-debug"],$)},"ln-debug")))}return(function(){const t="data-ln-debug",e="lnDebug";if(typeof window<"u"&&window[e]!==void 0)return;const n={"data-ln-debug":{type:"marker",description:"Enables developer diagnostics overlay, live validation badges, and inspection logging"}};Tt();function a(l){return this.dom=l,m(l.ownerDocument||document),P(),this}a.prototype.verify=function(l,o){return C(l||(this.dom?this.dom.ownerDocument||this.dom:document),o)},a.prototype.destroy=function(){delete this.dom[e],P()};const r=bt(t,e,a,"ln-debug",{attributes:n,onInit:function(l){typeof document<"u"&&m(l&&l.ownerDocument?l.ownerDocument:document)},onSubtreeChange:function(l){typeof document<"u"&&m(l&&l.ownerDocument?l.ownerDocument:document)}});r.verify=function(l,o){return C(l||document,o)},r.schedule=function(l,o,d){return m(l||document,o,d)}})(),y.scheduleVerification=m,y.verifyDOM=C,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"}),y})({});
@@ -0,0 +1,28 @@
1
+ {
2
+ "$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
3
+ "component": "ln-debug",
4
+ "generator": "scripts/sync-ln-schemas.mjs",
5
+ "attributes": {
6
+ "data-ln-data-store": {
7
+ "direction": "author",
8
+ "sources": [
9
+ "src/debug-verifier.js"
10
+ ]
11
+ },
12
+ "data-ln-debug": {
13
+ "direction": "author",
14
+ "sources": [
15
+ "src/gate.js",
16
+ "src/ln-debug.js"
17
+ ],
18
+ "type": "marker",
19
+ "description": "Enables developer diagnostics overlay, live validation badges, and inspection logging"
20
+ },
21
+ "data-ln-store": {
22
+ "direction": "author",
23
+ "sources": [
24
+ "src/debug-verifier.js"
25
+ ]
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,19 @@
1
+ // Console observation layer — the logger half of the console observation
2
+ // gate. Installed as ln-core's debug sink (see gate.js) only while
3
+ // data-ln-debug is active; ln-core calls this with zero knowledge of what
4
+ // it does. Pure — no DOM reads, no state, no data-ln-debug check of its
5
+ // own (the gate owns that decision exactly once).
6
+
7
+ export function consoleSink(kind, name, element, payload) {
8
+ if (kind === 'event') {
9
+ console.groupCollapsed('[ln-debug] event', name);
10
+ console.log('target', element);
11
+ console.log('detail', payload);
12
+ console.groupEnd();
13
+ } else if (kind === 'attr') {
14
+ console.groupCollapsed('[ln-debug] attr', name);
15
+ console.log('target', element);
16
+ console.log('old → new', payload.oldValue, '→', payload.newValue);
17
+ console.groupEnd();
18
+ }
19
+ }
@@ -0,0 +1,331 @@
1
+ import { VALID_ATTRIBUTES } from './generated-attributes.js';
2
+ import { pendingCount, queueBoot } from '../../ln-core/index.js';
3
+
4
+ /**
5
+ * Calculates Levenshtein distance between two strings.
6
+ * @param {string} a
7
+ * @param {string} b
8
+ * @returns {number}
9
+ */
10
+ export function levenshtein(a, b) {
11
+ if (a === b) return 0;
12
+ if (!a.length) return b.length;
13
+ if (!b.length) return a.length;
14
+
15
+ const matrix = [];
16
+ for (let i = 0; i <= b.length; i++) matrix[i] = [i];
17
+ for (let j = 0; j <= a.length; j++) matrix[0][j] = j;
18
+
19
+ for (let i = 1; i <= b.length; i++) {
20
+ for (let j = 1; j <= a.length; j++) {
21
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
22
+ matrix[i][j] = matrix[i - 1][j - 1];
23
+ } else {
24
+ matrix[i][j] = Math.min(
25
+ matrix[i - 1][j - 1] + 1,
26
+ matrix[i][j - 1] + 1,
27
+ matrix[i - 1][j] + 1
28
+ );
29
+ }
30
+ }
31
+ }
32
+ return matrix[b.length][a.length];
33
+ }
34
+
35
+ /**
36
+ * Finds the closest valid attribute from the validSet for a given attribute name.
37
+ * @param {string} attrName
38
+ * @param {Set<string>} validSet
39
+ * @returns {string|null}
40
+ */
41
+ export function findClosestAttribute(attrName, validSet = VALID_ATTRIBUTES) {
42
+ if (validSet.has(attrName)) return null;
43
+
44
+ let bestMatch = null;
45
+ let minDistance = Infinity;
46
+
47
+ for (const valid of validSet) {
48
+ const dist = levenshtein(attrName, valid);
49
+ if (dist < minDistance) {
50
+ minDistance = dist;
51
+ bestMatch = valid;
52
+ }
53
+ }
54
+
55
+ const maxAllowedDist = Math.max(3, Math.floor(attrName.length * 0.4));
56
+ if (minDistance <= maxAllowedDist) {
57
+ return bestMatch;
58
+ }
59
+ return null;
60
+ }
61
+
62
+ /**
63
+ * Escapes CSS selector identifiers safely.
64
+ * @param {string} str
65
+ * @returns {string}
66
+ */
67
+ function escapeSelector(str) {
68
+ if (typeof CSS !== 'undefined' && CSS.escape) {
69
+ return CSS.escape(str);
70
+ }
71
+ return str.replace(/([!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~])/g, '\\$1');
72
+ }
73
+
74
+ /**
75
+ * Verifies that all data-ln-*-for attributes resolve to an existing element ID in the document.
76
+ * @param {HTMLElement|Document} root
77
+ * @returns {Array<{ type: string, element: Element, attribute: string, targetId: string, message: string }>}
78
+ */
79
+ export function verifyIdReferences(root = document) {
80
+ const doc = root.ownerDocument || root;
81
+ const scope = root.nodeType === 9 ? root.body || root.documentElement : root;
82
+ if (!scope) return [];
83
+
84
+ const issues = [];
85
+ const elements = [scope, ...scope.querySelectorAll('*')];
86
+
87
+ for (let i = 0; i < elements.length; i++) {
88
+ const el = elements[i];
89
+ if (!el.attributes) continue;
90
+
91
+ for (let j = 0; j < el.attributes.length; j++) {
92
+ const attr = el.attributes[j];
93
+ if (attr.name.startsWith('data-ln-') && attr.name.endsWith('-for')) {
94
+ const targetId = (attr.value || '').trim();
95
+ if (!targetId) {
96
+ issues.push({
97
+ type: 'id-empty',
98
+ element: el,
99
+ attribute: attr.name,
100
+ targetId: '',
101
+ message: `[ln-debug] Empty ID reference in <${el.tagName.toLowerCase()} ${attr.name}="">.`
102
+ });
103
+ continue;
104
+ }
105
+
106
+ const targetEl = doc.getElementById(targetId) || doc.querySelector('#' + escapeSelector(targetId));
107
+ if (!targetEl) {
108
+ issues.push({
109
+ type: 'id-unresolved',
110
+ element: el,
111
+ attribute: attr.name,
112
+ targetId: targetId,
113
+ message: `[ln-debug] Unresolved ID reference: <${el.tagName.toLowerCase()} ${attr.name}="${targetId}"> targets "#${targetId}", but no element with id="${targetId}" exists in the document.`
114
+ });
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ return issues;
121
+ }
122
+
123
+ /**
124
+ * Verifies that all data-ln-*-source / data-ln-*-store attributes resolve to a declared data store.
125
+ * @param {HTMLElement|Document} root
126
+ * @returns {Array<{ type: string, element: Element, attribute: string, storeName: string, message: string }>}
127
+ */
128
+ export function verifyStoreReferences(root = document) {
129
+ const doc = root.ownerDocument || root;
130
+ const scope = root.nodeType === 9 ? root.body || root.documentElement : root;
131
+ if (!scope) return [];
132
+
133
+ const issues = [];
134
+ const elements = [scope, ...scope.querySelectorAll('*')];
135
+
136
+ for (let i = 0; i < elements.length; i++) {
137
+ const el = elements[i];
138
+ if (!el.attributes) continue;
139
+
140
+ for (let j = 0; j < el.attributes.length; j++) {
141
+ const attr = el.attributes[j];
142
+ const isSource = attr.name.startsWith('data-ln-') &&
143
+ (attr.name.endsWith('-source') || attr.name.endsWith('-store')) &&
144
+ attr.name !== 'data-ln-data-store';
145
+
146
+ if (isSource) {
147
+ const storeName = (attr.value || '').trim();
148
+ if (!storeName) {
149
+ issues.push({
150
+ type: 'store-empty',
151
+ element: el,
152
+ attribute: attr.name,
153
+ storeName: '',
154
+ message: `[ln-debug] Empty store reference in <${el.tagName.toLowerCase()} ${attr.name}="">.`
155
+ });
156
+ continue;
157
+ }
158
+
159
+ const escaped = escapeSelector(storeName);
160
+ const storeEl = doc.querySelector(`[data-ln-data-store="${escaped}"], [data-ln-store="${escaped}"]`);
161
+ const isGlobalRegistered = typeof window !== 'undefined' &&
162
+ window.lnDataStore && typeof window.lnDataStore.getStore === 'function' &&
163
+ window.lnDataStore.getStore(storeName);
164
+
165
+ if (!storeEl && !isGlobalRegistered) {
166
+ issues.push({
167
+ type: 'store-unresolved',
168
+ element: el,
169
+ attribute: attr.name,
170
+ storeName: storeName,
171
+ message: `[ln-debug] Unresolved store reference: <${el.tagName.toLowerCase()} ${attr.name}="${storeName}"> targets store "${storeName}", but no [data-ln-data-store="${storeName}"] exists in the document.`
172
+ });
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ return issues;
179
+ }
180
+
181
+ /**
182
+ * Verifies that all declared data store names are unique in the document.
183
+ * @param {HTMLElement|Document} root
184
+ * @returns {Array<{ type: string, storeName: string, elements: Element[], message: string }>}
185
+ */
186
+ export function verifyStoreUniqueness(root = document) {
187
+ const doc = root.ownerDocument || root;
188
+ const scope = root.nodeType === 9 ? root.body || root.documentElement : root;
189
+ if (!scope) return [];
190
+
191
+ const issues = [];
192
+ const storeElements = Array.from(scope.querySelectorAll('[data-ln-data-store]'));
193
+ if (scope.hasAttribute && scope.hasAttribute('data-ln-data-store')) {
194
+ storeElements.unshift(scope);
195
+ }
196
+
197
+ const storeMap = new Map();
198
+ for (let i = 0; i < storeElements.length; i++) {
199
+ const el = storeElements[i];
200
+ const name = (el.getAttribute('data-ln-data-store') || '').trim();
201
+ if (!name) continue;
202
+
203
+ if (!storeMap.has(name)) {
204
+ storeMap.set(name, []);
205
+ }
206
+ storeMap.get(name).push(el);
207
+ }
208
+
209
+ for (const [name, elements] of storeMap.entries()) {
210
+ if (elements.length > 1) {
211
+ issues.push({
212
+ type: 'store-duplicate',
213
+ storeName: name,
214
+ elements: elements,
215
+ message: `[ln-debug] Duplicate store name: Multiple elements declare data-ln-data-store="${name}". Store names must be unique across the document.`
216
+ });
217
+ }
218
+ }
219
+
220
+ return issues;
221
+ }
222
+
223
+ /**
224
+ * Verifies attribute spelling against the generated VALID_ATTRIBUTES manifest.
225
+ * @param {HTMLElement|Document} root
226
+ * @param {Set<string>} validSet
227
+ * @returns {Array<{ type: string, element: Element, attribute: string, suggestion: string|null, message: string }>}
228
+ */
229
+ export function verifyAttributeSpelling(root = document, validSet = VALID_ATTRIBUTES) {
230
+ const scope = root.nodeType === 9 ? root.body || root.documentElement : root;
231
+ if (!scope) return [];
232
+
233
+ const issues = [];
234
+ const elements = [scope, ...scope.querySelectorAll('*')];
235
+
236
+ for (let i = 0; i < elements.length; i++) {
237
+ const el = elements[i];
238
+ if (!el.attributes) continue;
239
+
240
+ for (let j = 0; j < el.attributes.length; j++) {
241
+ const attr = el.attributes[j];
242
+ if (attr.name.startsWith('data-ln-')) {
243
+ if (!validSet.has(attr.name)) {
244
+ const suggestion = findClosestAttribute(attr.name, validSet);
245
+ const suggestionMsg = suggestion ? ` Did you mean "${suggestion}"?` : '';
246
+ issues.push({
247
+ type: 'attribute-unknown',
248
+ element: el,
249
+ attribute: attr.name,
250
+ suggestion: suggestion,
251
+ message: `[ln-debug] Unknown attribute "${attr.name}" on <${el.tagName.toLowerCase()}>.${suggestionMsg}`
252
+ });
253
+ }
254
+ }
255
+ }
256
+ }
257
+
258
+ return issues;
259
+ }
260
+
261
+ /**
262
+ * Performs a complete contract verification scan of the DOM.
263
+ * @param {HTMLElement|Document} root
264
+ * @param {object} options
265
+ * @param {boolean} [options.silent=false]
266
+ * @param {Set<string>} [options.validAttributes]
267
+ * @returns {{ idIssues: Array, storeIssues: Array, uniquenessIssues: Array, spellingIssues: Array, total: number }}
268
+ */
269
+ export function verifyDOM(root = (typeof document !== 'undefined' ? document : null), options = {}) {
270
+ if (!root) {
271
+ return { idIssues: [], storeIssues: [], uniquenessIssues: [], spellingIssues: [], total: 0 };
272
+ }
273
+
274
+ const validSet = options.validAttributes || VALID_ATTRIBUTES;
275
+ const idIssues = verifyIdReferences(root);
276
+ const storeIssues = verifyStoreReferences(root);
277
+ const uniquenessIssues = verifyStoreUniqueness(root);
278
+ const spellingIssues = verifyAttributeSpelling(root, validSet);
279
+
280
+ const allIssues = [
281
+ ...idIssues,
282
+ ...storeIssues,
283
+ ...uniquenessIssues,
284
+ ...spellingIssues
285
+ ];
286
+
287
+ if (!options.silent) {
288
+ for (let i = 0; i < allIssues.length; i++) {
289
+ console.warn(allIssues[i].message);
290
+ }
291
+ }
292
+
293
+ return {
294
+ idIssues,
295
+ storeIssues,
296
+ uniquenessIssues,
297
+ spellingIssues,
298
+ total: allIssues.length
299
+ };
300
+ }
301
+
302
+ let _debounceTimer = null;
303
+
304
+ /**
305
+ * Schedules a verification scan taking lifecycle holds and DOM settling into account.
306
+ * @param {HTMLElement|Document} root
307
+ * @param {number} [delay=50]
308
+ * @param {function} [callback]
309
+ */
310
+ export function scheduleVerification(root = (typeof document !== 'undefined' ? document : null), delay = 50, callback = null) {
311
+ if (!root) return;
312
+
313
+ if (_debounceTimer) {
314
+ clearTimeout(_debounceTimer);
315
+ _debounceTimer = null;
316
+ }
317
+
318
+ function run() {
319
+ _debounceTimer = setTimeout(() => {
320
+ _debounceTimer = null;
321
+ const report = verifyDOM(root);
322
+ if (callback) callback(report);
323
+ }, delay);
324
+ }
325
+
326
+ if (pendingCount() > 0) {
327
+ queueBoot(run);
328
+ } else {
329
+ run();
330
+ }
331
+ }
@@ -0,0 +1,95 @@
1
+ import { guardBody, observeAttributes, setDebugSink } from '../../ln-core/index.js';
2
+ import { consoleSink } from './console-sink.js';
3
+
4
+ // ─── Console Observation Gate ──────────────────────────────
5
+ //
6
+ // The single place that decides which data-ln-debug hosts are active and
7
+ // scopes the console sink to them. A host is any element carrying
8
+ // data-ln-debug; multiple hosts may coexist. No other component ever
9
+ // carries a debug conditional.
10
+ //
11
+ // Scope: host containment. An event or attribute mutation logs only when
12
+ // some active host .contains() the target element — this layer observes
13
+ // its own subtree, exactly like every other component in the library.
14
+ // Exception: a handful of dispatch() calls target window or document
15
+ // directly (no element subtree can contain them) — those log only when
16
+ // document.body itself is a host.
17
+ //
18
+ // data-ln-debug is read from document.body's subtree via the shared
19
+ // attribute observer (ln-core's observeAttributes), which fires on both
20
+ // add and remove — so the host list stays correct when an attribute is
21
+ // removed, not just when it's added. <html> is outside that subtree and
22
+ // is not a supported host for this layer.
23
+
24
+ let _hosts = [];
25
+
26
+ // Scans exactly the subtree ln-core's shared attribute observer covers
27
+ // (document.body's subtree, body itself included) — never document-wide.
28
+ // A document-wide scan would pick up a stray <html data-ln-debug> on some
29
+ // consumer page; that element would become a "host" whose REMOVAL can
30
+ // never be observed (the shared observer can't see <html>, it's the
31
+ // parent of the observed subtree, not inside it), leaving a permanently
32
+ // stale _hosts entry and silently reviving <html> support D3 removed.
33
+ //
34
+ // No `document.body &&` guard: this function is only ever reached from
35
+ // inside the guardBody callback below (direct call, or via
36
+ // observeAttributes' mutation handler, which itself can only fire after
37
+ // ln-core's own body-scoped observer was installed) — document.body is
38
+ // guaranteed to exist on every call path this file has. Guarding for a
39
+ // call path that doesn't exist is exactly the defensive coding this
40
+ // project forbids.
41
+ function _refreshHosts() {
42
+ _hosts = Array.from(document.body.querySelectorAll('[data-ln-debug]'));
43
+ if (document.body.hasAttribute('data-ln-debug')) _hosts.push(document.body);
44
+ }
45
+
46
+ function _isContained(target) {
47
+ if (target === window || target === document) {
48
+ return _hosts.indexOf(document.body) !== -1;
49
+ }
50
+ for (let i = 0; i < _hosts.length; i++) {
51
+ if (_hosts[i].contains(target)) return true;
52
+ }
53
+ return false;
54
+ }
55
+
56
+ function _scopedSink(kind, name, element, payload) {
57
+ if (_isContained(element)) {
58
+ consoleSink(kind, name, element, payload);
59
+ }
60
+ }
61
+
62
+ function _syncSink() {
63
+ _refreshHosts();
64
+ setDebugSink(_hosts.length > 0 ? _scopedSink : null, _hosts.length > 0 ? _isContained : null);
65
+ }
66
+
67
+ /**
68
+ * Re-derive the active host list. Called by ln-debug's component lifecycle
69
+ * (construction and destruction) so a host inserted or removed as a whole
70
+ * element — a childList mutation, which the attribute observer never sees —
71
+ * is picked up immediately, not just an attribute toggled on an element
72
+ * that was already in the DOM.
73
+ */
74
+ export function refreshDebugHosts() {
75
+ _syncSink();
76
+ }
77
+
78
+ export function ensureDebugGate() {
79
+ if (typeof window === 'undefined') return;
80
+ window.lnCore = window.lnCore || {};
81
+ if (window.lnCore._debugGateBound) return;
82
+ window.lnCore._debugGateBound = true;
83
+
84
+ // _debugGateBound is set synchronously, above, before guardBody runs —
85
+ // so a second ensureDebugGate() call (another bundle) short-circuits at
86
+ // the guard check above and never reaches guardBody, even if
87
+ // document.body doesn't exist yet. Only one DOMContentLoaded callback is
88
+ // ever scheduled. Mirrors _ensureAttrObserver / ensureLocaleObserver in
89
+ // ln-core/helpers.js, both of which use this exact guard-then-guardBody
90
+ // shape.
91
+ guardBody(function () {
92
+ _syncSink();
93
+ observeAttributes(['data-ln-debug'], _syncSink);
94
+ }, 'ln-debug');
95
+ }