@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
@@ -1,12 +1,27 @@
1
- import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from '../../ln-core';
1
+ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders, defineAttrs, attrSpec, attrStr } from '../../ln-core';
2
2
 
3
3
  (function () {
4
4
  const DOM_SELECTOR = 'data-ln-couchdb-connector';
5
5
  const DOM_ATTRIBUTE = 'lnCouchDbConnector';
6
6
  const DOM_ALIAS = 'lnConnector';
7
-
8
7
  if (window[DOM_ATTRIBUTE] !== undefined) return;
9
8
 
9
+ // ─── Attribute Contract (SSOT) ──────────────────────────
10
+ function _syncAttribute(el) {
11
+ const instance = el[DOM_ATTRIBUTE];
12
+ if (!instance) return;
13
+ instance.refreshConfig();
14
+ }
15
+
16
+ const ATTRIBUTES = {
17
+ 'data-ln-couchdb-connector': { type: 'marker', description: 'Mounts CouchDB/PouchDB connector bridging database and ln-ashlar data coordinators' },
18
+ 'data-ln-couchdb-url': { prop: 'url', read: attrStr, type: 'string', fallback: '', effect: _syncAttribute, description: 'CouchDB server base endpoint URL' },
19
+ 'data-ln-couchdb-db': { prop: 'db', read: attrStr, type: 'string', fallback: '', effect: _syncAttribute, description: 'Target CouchDB database name' },
20
+ 'data-ln-couchdb-auth': { prop: 'auth', read: attrStr, type: 'string', fallback: '', effect: _syncAttribute, description: 'Authentication credentials for CouchDB requests' },
21
+ 'data-ln-couchdb-headers': { effect: _syncAttribute, type: 'json', fallback: null, description: 'Custom HTTP headers in JSON or semicolon-separated format' }
22
+ };
23
+ const ATTR_SPEC = attrSpec(ATTRIBUTES);
24
+
10
25
  // ─── Response Envelope Unwrap (presence-checked `{message, content}`) ──
11
26
  // Raw CouchDB never sends this envelope (content=body, message=null — no-op).
12
27
  // A proxy/gateway in front of CouchDB may wrap responses; this makes that
@@ -21,6 +36,7 @@ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from
21
36
 
22
37
  function _component(dom) {
23
38
  this.dom = dom;
39
+ defineAttrs(this, dom, ATTR_SPEC);
24
40
  dom[DOM_ATTRIBUTE] = this;
25
41
  dom[DOM_ALIAS] = this; // Alias for 3-tier compatibility
26
42
 
@@ -36,9 +52,6 @@ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from
36
52
  _component.prototype.refreshConfig = function () {
37
53
  const dom = this.dom;
38
54
 
39
- this.url = dom.getAttribute('data-ln-couchdb-url') || '';
40
- this.db = dom.getAttribute('data-ln-couchdb-db') || '';
41
- this.auth = dom.getAttribute('data-ln-couchdb-auth') || '';
42
55
  this.credentials = 'same-origin';
43
56
 
44
57
  const rawHeaders = dom.getAttribute('data-ln-couchdb-headers') || '';
@@ -341,16 +354,11 @@ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from
341
354
  }
342
355
  };
343
356
 
344
- // Bind events for CouchDB namespaces and also REST/API connector namespaces for 3-tier compatibility
345
- const namespaces = ['ln-couchdb-connector', 'ln-api-connector', 'ln-rest-connector'];
346
- namespaces.forEach(function (ns) {
347
- self.dom.addEventListener(ns + ':request-sync', self._handlers.sync);
348
- self.dom.addEventListener(ns + ':request-fetch', self._handlers.sync);
349
- self.dom.addEventListener(ns + ':request-create', self._handlers.create);
350
- self.dom.addEventListener(ns + ':request-update', self._handlers.update);
351
- self.dom.addEventListener(ns + ':request-delete', self._handlers.delete);
352
- self.dom.addEventListener(ns + ':request-bulk-delete', self._handlers.bulkDelete);
353
- });
357
+ self.dom.addEventListener('ln-couchdb-connector:request-sync', self._handlers.sync);
358
+ self.dom.addEventListener('ln-couchdb-connector:request-create', self._handlers.create);
359
+ self.dom.addEventListener('ln-couchdb-connector:request-update', self._handlers.update);
360
+ self.dom.addEventListener('ln-couchdb-connector:request-delete', self._handlers.delete);
361
+ self.dom.addEventListener('ln-couchdb-connector:request-bulk-delete', self._handlers.bulkDelete);
354
362
  }
355
363
 
356
364
  _component.prototype.destroy = function () {
@@ -358,41 +366,19 @@ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from
358
366
 
359
367
  const self = this;
360
368
  if (self._handlers) {
361
- const namespaces = ['ln-couchdb-connector', 'ln-api-connector', 'ln-rest-connector'];
362
- namespaces.forEach(function (ns) {
363
- self.dom.removeEventListener(ns + ':request-sync', self._handlers.sync);
364
- self.dom.removeEventListener(ns + ':request-fetch', self._handlers.sync);
365
- self.dom.removeEventListener(ns + ':request-create', self._handlers.create);
366
- self.dom.removeEventListener(ns + ':request-update', self._handlers.update);
367
- self.dom.removeEventListener(ns + ':request-delete', self._handlers.delete);
368
- self.dom.removeEventListener(ns + ':request-bulk-delete', self._handlers.bulkDelete);
369
- });
369
+ self.dom.removeEventListener('ln-couchdb-connector:request-sync', self._handlers.sync);
370
+ self.dom.removeEventListener('ln-couchdb-connector:request-create', self._handlers.create);
371
+ self.dom.removeEventListener('ln-couchdb-connector:request-update', self._handlers.update);
372
+ self.dom.removeEventListener('ln-couchdb-connector:request-delete', self._handlers.delete);
373
+ self.dom.removeEventListener('ln-couchdb-connector:request-bulk-delete', self._handlers.bulkDelete);
370
374
  self._handlers = null;
371
375
  }
372
376
 
373
- dispatch(this.dom, 'ln-couchdb-connector:destroyed', { target: this.dom });
374
-
375
377
  delete this.dom[DOM_ATTRIBUTE];
376
378
  delete this.dom[DOM_ALIAS];
377
379
  };
378
380
 
379
- // ─── Attribute Sync ────────────────────────────────────────
380
-
381
- function _syncAttribute(el) {
382
- const instance = el[DOM_ATTRIBUTE];
383
- if (!instance) return;
384
- instance.refreshConfig();
385
- }
386
-
387
- // ─── Registration ──────────────────────────────────────
388
-
389
381
  registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-couchdb-connector', {
390
- extraAttributes: [
391
- 'data-ln-couchdb-url',
392
- 'data-ln-couchdb-db',
393
- 'data-ln-couchdb-auth',
394
- 'data-ln-couchdb-headers'
395
- ],
396
- onAttributeChange: _syncAttribute
382
+ attributes: ATTRIBUTES
397
383
  });
398
384
  })();
@@ -1,8 +1,9 @@
1
1
  # `data-ln-data-coordinator`
2
2
 
3
- A zero-dependency, Local-First **Data Coordinator** component that orchestrates the full 3-Tier Data Layer in `ln-ashlar`: it bridges the local cache store to remote connectors **and** delivers live data to bound view components (tables, lists, selects, stat counters) with zero application JavaScript.
4
-
5
- This component monitors its DOM subtree, intercepts events, and coordinates the lifecycle between a **Local Storage Cache** (`data-ln-data-store`) and any **Transport Gateway** (`data-ln-*-connector`). It also listens on `document` for view-binding requests and refreshes all bound view elements on every store mutation.
3
+ > Applied to a parent container (`<ul data-ln-data-coordinator hidden>`) enclosing a `data-ln-data-store` and a
4
+ > `data-ln-api-connector`. It catches store staleness and pagination requests to dispatch fetch events to the connector,
5
+ > populating the store with server responses (`request-populate`). On store data mutations, it executes local queries and
6
+ > dispatches `set-data` events directly to bound view elements (`data-ln-table-source`, `data-ln-list-source`).
6
7
 
7
8
  ---
8
9
 
@@ -12,12 +13,13 @@ Add these attributes to view elements to bind them to this coordinator's child s
12
13
 
13
14
  | Attribute | Applied To | Description |
14
15
  |---|---|---|
15
- | `data-ln-table-store="<storeName>"` | `[data-ln-table]` | Binds a table — receives `ln-table:set-data` automatically. |
16
- | `data-ln-list-store="<storeName>"` | `[data-ln-list]` | Binds a list — receives `ln-list:set-data` automatically. |
16
+ | `data-ln-table-source="<storeName>"` | `[data-ln-table]` | Binds a table — receives `ln-table:set-data` automatically. |
17
+ | `data-ln-list-source="<storeName>"` | `[data-ln-list]` | Binds a list — receives `ln-list:set-data` automatically. |
18
+ | `data-ln-chart-source="<storeName>"` | `[data-ln-chart]` | Binds a chart; receives `ln-chart:set-data` automatically. |
17
19
  | `data-ln-options="<storeName>"` | `<select>` | Populated by `ln-options` via `ln-options:set-data`. |
18
20
  | `data-ln-stat="<storeName>"` | Inline element | Receives count via `ln-stat:set-count`. |
19
21
 
20
- `<storeName>` = the value of `data-ln-data-store` on the coordinator's child store. Multiple coordinators on one page each serve only their own store — isolated by the `_ownsStore(name)` guard.
22
+ `<storeName>` = the `id` of the coordinator's child store element. The presentation layer always addresses the **store**, never the coordinator. Multiple coordinators on one page each serve only their own store — isolated by the `_ownsStore(name)` guard.
21
23
 
22
24
  ### Presenter / Binder Split
23
25
 
@@ -26,21 +28,18 @@ Add these attributes to view elements to bind them to this coordinator's child s
26
28
 
27
29
  Use `setPresenters` for fields like `updated_display`, `size_display`, `status_label`. The binder delivers them as-is.
28
30
 
29
- ### Store-Change Refresh
30
-
31
- The coordinator listens on `this.dom` for `ln-data-store:ready`, `loaded`, `created`, `updated`, `deleted`, and `synced` (only when `changed`). On any of these, `_refreshAll()` re-queries all bound view elements using their last cached query parameters.
31
+ The coordinator listens on `this.dom` for `ln-data-store:ready`, `loaded`, `created`, `updated`, `deleted`, `synced` (only when `changed`), `ln-data-store:query-changed`, and `ln-data-store:request-page`. On request-page, it converts page offsets into a `request-query` call on the paired connector's namespace (`ln-api-connector:request-query` or `ln-websocket-connector:request-query`, depending on which connector is present). On other store-change events, `_refreshAll()` re-queries all bound view elements using their last cached query parameters.
32
32
 
33
33
  ### Zero-JS Example
34
34
 
35
35
  ```html
36
- <ul data-ln-data-coordinator hidden>
37
- <li data-ln-data-store="people"></li>
38
- <li data-ln-api-connector data-ln-api-endpoint="/api/people"></li>
36
+ <ul id="people-module" data-ln-data-coordinator hidden>
37
+ <li id="people" data-ln-data-store></li>
38
+ <li data-ln-api-connector data-ln-api-connector-path="/api/people"></li>
39
39
  </ul>
40
40
 
41
41
  <section data-ln-table="people"
42
42
  data-ln-table-source="people"
43
- data-ln-table-store="people"
44
43
  id="people-table">
45
44
  <table>
46
45
  <thead>
@@ -82,18 +81,18 @@ No `<script>` block needed. The coordinator wires everything.
82
81
  The coordinator acts as a parent wrapper enclosing the database cache and transport connector:
83
82
 
84
83
  ```html
85
- <ul data-ln-data-coordinator="documents"
86
- data-ln-data-mapper="documents" hidden>
84
+ <ul id="documents-module" data-ln-data-coordinator
85
+ data-ln-data-coordinator-mapper="documents" hidden>
87
86
 
88
87
  <!-- Tier 1: Local Cache Database (IndexedDB - pure and network-blind) -->
89
- <li data-ln-data-store
88
+ <li id="documents" data-ln-data-store
90
89
  data-ln-data-store-indexes="status,updated_at">
91
90
  </li>
92
91
 
93
92
  <!-- Tier 2: Transport Gateway (API / REST Connector) -->
94
93
  <li data-ln-api-connector
95
- data-ln-api-base-url="https://api.livenetworks.com/v1"
96
- data-ln-api-path="/documents">
94
+ data-ln-api-connector-base-url="https://api.livenetworks.com/v1"
95
+ data-ln-api-connector-path="/documents">
97
96
  </li>
98
97
  </ul>
99
98
  ```
@@ -104,8 +103,44 @@ The coordinator acts as a parent wrapper enclosing the database cache and transp
104
103
 
105
104
  | Attribute | Category | Description |
106
105
  |-----------|----------|-------------|
107
- | `data-ln-data-coordinator` | Selector | Creates the coordinator instance. The value acts as the domain/scope name (e.g. `documents`). |
108
- | `data-ln-data-mapper` | Mapping | Reference to an externally registered data mapper name (e.g. `documents`). |
106
+ | `id="name"` | Identity | Unique identifier of the coordinator (the coordinator name/domain/scope). |
107
+ | `data-ln-data-coordinator` | Selector | Marker attribute to declare the component. Its value is the coordinator's name; falls back to `id`. Views and query controls address **this** name, never a child's. |
108
+ | `data-ln-data-coordinator-mapper` | Mapping | Reference to an externally registered data mapper name (e.g. `documents`). Defaults to `id` if omitted. |
109
+ | `data-ln-data-coordinator-scope` | Scope | Opts an external `<form>` into this coordinator's write intake loop. |
110
+ | `data-ln-data-coordinator-search` | Query | Current search term, a plain string. Absent or empty means no search. |
111
+ | `data-ln-data-coordinator-filters` | Query | Active filters as a URL query string. A multi-value filter is a **repeated key**: `status=open&status=pending&type=invoice`. Absent means no filters. |
112
+ | `data-ln-data-coordinator-sort-field` | Query | Field the result set is sorted by. Meaningful only together with `-sort-direction`. |
113
+ | `data-ln-data-coordinator-sort-direction` | Query | `asc` or `desc`. Both sort attributes are removed together when sorting is cleared. |
114
+
115
+ ### The query lives here, in the form a browser would produce
116
+
117
+ The coordinator is the only participant guaranteed to be present in its layer — the cache,
118
+ the transport and the queue are all optional. The address and the query state are therefore
119
+ **its own**, never a child's. A query is not a property of the cache; the cache is one thing
120
+ that can *answer* a query.
121
+
122
+ ```html
123
+ <ul data-ln-data-coordinator="documents"
124
+ data-ln-data-coordinator-search="acme"
125
+ data-ln-data-coordinator-sort-field="updated_at"
126
+ data-ln-data-coordinator-sort-direction="desc"
127
+ data-ln-data-coordinator-filters="status=open&status=pending&type=invoice" hidden>
128
+ ```
129
+
130
+ Without JavaScript, a form does a `GET` and the browser lays the values out in a URL query
131
+ string. JS only enhances: it takes that same thing and forwards it over AJAX. Every flip of
132
+ representation between those two points is an unnecessary chance to get it wrong, so the
133
+ attribute carries the form the browser itself would produce — parsed with native
134
+ `URLSearchParams`, and a multi-value filter is the repeated key a checkbox group submits on
135
+ its own. Sort is two axes rather than the connector's `sort_field` / `sort_dir`, because
136
+ those names are transport configuration (overridable per connector via `paramKeys`) and do
137
+ not belong in the coordinator's contract.
138
+
139
+ All four are read **live** at the moment of use — never parsed once and cached in a JS field.
140
+ An author may seed them in markup as the initial query, and a script or devtools may write
141
+ them directly: an attribute write is honoured exactly like an `ln-search:change` event,
142
+ because the reaction is declared on the attribute, not on the event. Writes are batched, so
143
+ clearing a sort (two attribute removals) re-queries once, not twice.
109
144
 
110
145
  ---
111
146
 
@@ -114,33 +149,14 @@ The coordinator acts as a parent wrapper enclosing the database cache and transp
114
149
  The coordinator is built to be highly dynamic, reacting to runtime modifications in its DOM subtree.
115
150
 
116
151
  1. **Child Discovery**: The coordinator automatically locates its child components by querying its DOM subtree:
117
- * **Store Cache**: Looks for `[data-ln-data-store]` and accesses `el.lnDataStore || el.lnStore`.
118
- * **Transport Connector**: Looks for any connector selector (`[data-ln-api-connector]`, `[data-ln-couchdb-connector]`, `[data-ln-websocket-connector]`, `[data-ln-rest-connector]`) and accesses the universal alias `el.lnConnector`.
152
+ * **Store Cache**: Looks for `[data-ln-data-store]` and accesses `el.lnDataStore`.
153
+ * **Transport Connector**: The request connector is `[data-ln-api-connector]` or `[data-ln-couchdb-connector]` when present, otherwise `[data-ln-websocket-connector]`; the coordinator accesses the matching instance (`el.lnApiConnector`, `el.lnCouchDbConnector` or `el.lnWebsocketConnector`). The request event namespace (`ln-api-connector:*`, `ln-couchdb-connector:*` or `ln-websocket-connector:*`) is derived from whichever selector matched, not hardcoded. Responses are heard from all three namespaces, so a socket beside a REST connector still delivers its pushes (`:fetched`) to the store.
154
+ * **Live Socket Catch-up**: On every `ln-websocket-connector:connected` the coordinator runs `store.forceSync()` — a delta since `lastSyncedAt` over the request connector — so changes missed while the socket was down are fetched.
119
155
  * **Offline Outbox (optional Child 3)**: Looks for `[data-ln-api-queue]` and accesses `el.lnApiQueue`. When present, write routing (below) enqueues instead of calling the connector directly. When absent, behavior is byte-for-byte the direct-connector path described in this document.
120
156
 
121
- 2. **Mapper Resolution**: The coordinator resolves mapping functions using two strategies:
122
- * **Inline Script (Highly Encapsulated)**: Looks for a nested `<script type="application/javascript" data-ln-mapper>` tag in its subtree:
123
- ```html
124
- <script type="application/javascript" data-ln-mapper>
125
- ({
126
- ingress(serverRaw) {
127
- return {
128
- id: serverRaw.id,
129
- title: serverRaw.title,
130
- status: serverRaw.status,
131
- updated_at: Date.parse(serverRaw.updated_at) / 1000
132
- };
133
- },
134
- egress(localDb) {
135
- return {
136
- title: localDb.title,
137
- status: localDb.status
138
- };
139
- }
140
- })
141
- </script>
142
- ```
143
- * **External Registry (Reusability)**: If no inline script exists, it reads the `data-ln-data-mapper` attribute and looks up the mapper via `window.lnCore.getDataMapper(name)`.
157
+ 2. **Mapper Resolution**: The coordinator resolves mapping functions securely using the registry:
158
+ * **External Registry (Recommended & Secure)**: Reads the `data-ln-data-coordinator-mapper` attribute — falling back to the host element's `id` when the attribute is absent — and looks up the mapper via `window.lnCore.getDataMapper(name)`. Mappers are registered via `window.lnCore.registerDataMapper(name, mapper)`.
159
+ * **Inline Script Deprecation**: Nested `<script data-ln-mapper>` tags are deprecated and disabled due to XSS vulnerability risks (unsafe-eval).
144
160
  * **Fallback**: Defaults to a safe no-op mapper: `{ ingress: r => r, egress: r => r }`.
145
161
 
146
162
  ---
@@ -149,6 +165,31 @@ The coordinator is built to be highly dynamic, reacting to runtime modifications
149
165
 
150
166
  Because all events dispatched by the child components bubble up, the coordinator listens directly on its own DOM boundary. It manages the following flows seamlessly:
151
167
 
168
+ ### Query Intake — `ln-search:change` / `ln-filter:change` / `ln-sort:change`
169
+
170
+ Query controls announce a **speech act**; the coordinator stores the resulting **state**. The
171
+ handlers do exactly one thing: write the attribute. They never re-query directly.
172
+
173
+ | Event | `detail` read | Written to |
174
+ |---|---|---|
175
+ | `ln-search:change` | `term` | `data-ln-data-coordinator-search` |
176
+ | `ln-filter:change` | `key`, `values` | merged into `data-ln-data-coordinator-filters` |
177
+ | `ln-sort:change` | `field`, `direction` | `-sort-field` + `-sort-direction` |
178
+
179
+ Each handler calls `preventDefault()` to claim the event, and diffs against the current
180
+ attribute value first — a filter reset that was never set, or a re-click producing the same
181
+ sort, is not a query change and does nothing.
182
+
183
+ `ln-filter:change` carries **one key** per control, so the attribute accumulates keys across
184
+ however many filter controls are bound. An empty `values` array removes that key; when the
185
+ last key goes, the attribute is removed rather than left as an empty string. `ln-sort:change`
186
+ emits `direction: 'none'` to mean "sort removed", and `field` is `null` for a column-index
187
+ sort — both are treated as "no sort", since neither is a meaningful server sort key.
188
+
189
+ The re-query is **not** triggered from these handlers. It is declared once, as a reaction to
190
+ the four query attributes (`extraAttributes` + `onAttributeChange`), and batched — so one
191
+ sort change, which writes two attributes, still re-queries once.
192
+
152
193
  ### 0. Form Write Intake (native `submit`, claimed via `preventDefault()`)
153
194
 
154
195
  The coordinator listens for the native `submit` event on `document`
@@ -157,7 +198,7 @@ the form itself always runs first). On every submit bubbling through:
157
198
 
158
199
  1. `if (e.defaultPrevented) return` — either `ln-validate`'s validation
159
200
  gate blocked an invalid submit, or another coordinator already claimed it.
160
- 2. Reads `data-ln-form-scope` off `e.target` (the form). Absent → the
201
+ 2. Reads `data-ln-data-coordinator-scope` off `e.target` (the form). Absent → the
161
202
  form never opted in; leave the native submit alone.
162
203
  3. Claims it if either holds: scope value `=== this._name` (named
163
204
  override), or the scope is empty and the form is a DOM descendant of
@@ -308,7 +349,7 @@ only when the queue later commands the coordinator to send.
308
349
  The queue entry's opaque `meta.action` (the form's resource URL,
309
350
  persisted across sessions) now rides into the connector request's `url`
310
351
  field at send time; the connector executes the write against it, joined
311
- with `data-ln-api-base-url` exactly like the `path` fallback.
352
+ with `data-ln-api-connector-base-url` exactly like the `path` fallback.
312
353
 
313
354
  The coordinator listens for `ln-api-queue:send` on the queue element. It
314
355
  maps `op` to the matching connector `:request-*` event (same egress/ingress flow as the
@@ -328,7 +369,7 @@ identity. The coordinator does not fall back to a possibly stale `meta.id`.
328
369
 
329
370
  > Remap also rewrites `meta.action` if it contains the old key as a
330
371
  > substring (string replace) — keeps a persisted per-record URL in sync
331
- > after a create resolves. See `js/ln-api-queue/README.md`.
372
+ > after a create resolves. See `components/ln-api-queue/README.md`.
332
373
 
333
374
  Every success path also calls `_toastFromMessage(e.detail.message)` — see
334
375
  Toasts below.
@@ -362,8 +403,8 @@ connector, no queue — is a first-class, supported configuration, not a
362
403
  degraded fallback:
363
404
 
364
405
  ```html
365
- <ul data-ln-data-coordinator="drafts" hidden>
366
- <li data-ln-data-store="drafts"></li>
406
+ <ul id="drafts-module" data-ln-data-coordinator hidden>
407
+ <li id="drafts" data-ln-data-store></li>
367
408
  </ul>
368
409
  ```
369
410
 
@@ -424,9 +465,9 @@ ignored otherwise):
424
465
  `buildDict()` helper `ln-upload` uses for its dictionary):
425
466
 
426
467
  ```html
427
- <ul data-ln-data-coordinator="documents" hidden>
428
- <li data-ln-data-store="documents"></li>
429
- <li data-ln-api-connector data-ln-api-base-url="/api" data-ln-api-path="/documents"></li>
468
+ <ul id="documents-module" data-ln-data-coordinator hidden>
469
+ <li id="documents" data-ln-data-store></li>
470
+ <li data-ln-api-connector data-ln-api-connector-base-url="/api" data-ln-api-connector-path="/documents"></li>
430
471
 
431
472
  <!-- consumed once at init, then removed from the DOM -->
432
473
  <span data-ln-data-coordinator-dict="auth" hidden>Your session expired — please sign in again.</span>
@@ -457,9 +498,9 @@ The coordinator — not the store — decides WHEN to sync:
457
498
  * A module-level singleton wires **one shared** `window 'online'`,
458
499
  `window 'offline'`, and `document 'visibilitychange'` listener set across
459
500
  every coordinator instance on the page (not one per instance). On
460
- `online`, dispatches `ln-data-store:online` on `document` once, then for each
501
+ `online`, dispatches `ln-data-coordinator:online` on `document` once, then for each
461
502
  coordinator with a loaded, non-syncing store: `store.forceSync()`. On
462
- `offline`, dispatches `ln-data-store:offline` on `document` once. On
503
+ `offline`, dispatches `ln-data-coordinator:offline` on `document` once. On
463
504
  `visibilitychange` (tab visible again), for each coordinator whose store
464
505
  is stale: `store.forceSync()`.
465
506
 
@@ -474,18 +515,17 @@ view reads use the remote source directly.
474
515
  | `data-ln-data-coordinator-stale` | Seconds threshold before the store is considered stale; falls back to the store's own `data-ln-data-store-stale`; default 300; `-1` / `never` = never stale. |
475
516
  | `data-ln-data-coordinator-no-autosync` | Presence opts the coordinator out of online/visibility auto-sync; falls back to the store's own `data-ln-data-store-no-autosync`. |
476
517
 
477
- `ln-data-store:online` / `ln-data-store:offline` now require a coordinator on the
478
- page — the store itself no longer dispatches them (see the
479
- [ln-data-store README](../ln-data-store/README.md)).
518
+ `ln-data-coordinator:online` / `ln-data-coordinator:offline` indicate network status
519
+ for data coordination across the page.
480
520
 
481
521
  ---
482
522
 
483
523
  ## 💡 JS API (On the element)
484
524
 
485
- Access the coordinator instance programmatically via the `lnDataCoordinator` or `lnCoordinator` properties:
525
+ Access the coordinator instance programmatically via the `lnDataCoordinator` property:
486
526
 
487
527
  ```javascript
488
- const coordinator = document.querySelector('[data-ln-data-coordinator="documents"]').lnDataCoordinator;
528
+ const coordinator = document.getElementById('documents-module').lnDataCoordinator;
489
529
 
490
530
  // Force a remote configuration refresh
491
531
  coordinator.refreshConfig();
@@ -501,35 +541,31 @@ const { ingress, egress } = coordinator.mapper;
501
541
 
502
542
  ## 🔧 Internals — View-Binding Layer
503
543
 
504
- Source: `js/ln-data-coordinator/src/ln-data-coordinator.js`. The write pipeline (fan-out, sync, queue, toasts) is documented above; this section covers the coordinator's second role — serving live data to bound view components with zero application JS.
544
+ Source: `components/ln-data-coordinator/src/ln-data-coordinator.js`. The write pipeline (fan-out, sync, queue, toasts) is documented above; this section covers the coordinator's second role — serving live data to bound view components with zero application JS.
505
545
 
506
546
  ### Binding attributes
507
547
 
508
548
  | Attribute | Applied to | Served by |
509
549
  |---|---|---|
510
- | `data-ln-table-store="<name>"` | `[data-ln-table]` | `ln-table:set-data` |
511
- | `data-ln-list-store="<name>"` | `[data-ln-list]` | `ln-list:set-data` |
550
+ | `data-ln-table-source="<name>"` | `[data-ln-table]` | `ln-table:set-data` |
551
+ | `data-ln-list-source="<name>"` | `[data-ln-list]` | `ln-list:set-data` |
552
+ | `data-ln-chart-source="<name>"` | `[data-ln-chart]` | `ln-chart:set-data` |
512
553
  | `data-ln-options="<name>"` | `<select>` | `ln-options:set-data` |
513
554
  | `data-ln-stat="<name>"` | inline element | `ln-stat:set-count` |
514
555
 
515
- `<name>` must match the coordinator's own child store's `data-ln-data-store` value. Every document-level handler guards with `_ownsStore(name)` first (`children.store && children.store._name === name`), so multiple coordinators on one page coexist without cross-talk.
556
+ `<name>` must match the coordinator's own child store's `id` value. Every document-level handler guards with `_ownsStore(name)` first (`children.store && children.store._name === name`), so multiple coordinators on one page coexist without cross-talk.
516
557
 
517
558
  ### Presenter / binder split
518
559
 
519
560
  Presenters (`store.setPresenters({computed})`) are registered once per store; computed display fields (`updated_display`, `status_label`, …) flow through `getAll → set-data` automatically. The coordinator is a pure binder — it transports whatever `getAll` produces to the requesting view element without transforming it.
520
561
 
521
- The binder awaits `store.ready` before choosing a source. Loaded non-windowed
522
- reads use the local store; an empty local-only store is also a valid source and
523
- returns `[]`. Windowed reads, connector-backed stores without a loaded cache,
524
- and stores with `initializationError` route remote. When IndexedDB is
525
- unavailable, table/list/options/stat responses are delivered directly to the
526
- requesting view instead of being forced through the failed store. Query
527
- failures clear loading and emit
528
- `ln-data-coordinator:error {operation:'query', kind, store, target, error}`.
562
+ When querying, the coordinator composes the final query payload: the view element provides pagination and sorting (`offset`, `limit`, `sort`), while the store cache provides the active filters and search terms (`filters`, `search`).
563
+
564
+ The binder awaits `store.ready` before choosing a source. If the store is loaded and has no initialization error, reads use the local store; otherwise, connector-backed stores route remote. When IndexedDB is unavailable, table/list/chart/options/stat responses are delivered directly to the requesting view instead of being forced through the failed store. Query failures clear loading and emit `ln-data-coordinator:error {operation:'query', kind, store, target, error}`.
529
565
 
530
566
  ### Refresh trigger
531
567
 
532
- On `ln-data-store:ready`/`loaded`/`created`/`updated`/`deleted`, and `synced` (only when `e.detail.changed`), `_refreshAll()` re-queries every bound view element using its last cached query parameters (or defaults) — so a filter/sort/search a user set on a table survives a background sync.
568
+ On `ln-data-store:ready`/`loaded`/`created`/`updated`/`deleted`, `synced` (only when `e.detail.changed`), and `ln-data-store:query-changed`, `_refreshAll()` re-queries every bound view element using its last cached query parameters (or defaults) — so a filter/sort/search a user set on a table survives a background sync.
533
569
 
534
570
  ### `data-ln-table-filter-options` — removed
535
571
 
@@ -0,0 +1,8 @@
1
+ @use '../../theme/config/mixins' as *;
2
+
3
+ [data-ln-debug] {
4
+ // 1. Child Store Check: data-ln-data-coordinator must contain a child [data-ln-data-store]
5
+ [data-ln-data-coordinator]:not(:has([data-ln-data-store])) {
6
+ @include dev-dom-error("[data-ln-data-coordinator] must contain a child [data-ln-data-store].");
7
+ }
8
+ }
@@ -0,0 +1 @@
1
+ (function(){"use strict";function J(){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 $(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 r=t.closest("[data-ln-debug]");return!(!r||typeof document<"u"&&r===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(...r){if(typeof r[0]=="string"&&(r[0].startsWith("[ln-")||r[0].startsWith("[lnCore"))){let a=null;for(let d=1;d<r.length;d++)if(r[d]&&r[d].nodeType===1){a=r[d];break}if(!$(a))return}t.apply(console,r)}}function h(t,r,i){const a=i||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",r,t,a),t.dispatchEvent(new CustomEvent(r,{bubbles:!0,detail:a}))}function N(t,r){if(!document.body){document.addEventListener("DOMContentLoaded",function(){N(t,r)}),console.warn("["+r+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function le(t){const r=t.querySelector('input[name="_method"]');return((r&&r.value!==""?r.value:t.method)||"").toUpperCase()}function ce(t,r){const i={},a=t.elements;for(let d=0;d<a.length;d++){const l=a[d];if(!(!l.name||l.disabled||l.type==="file"||l.type==="submit"||l.type==="button"))if(l.type==="checkbox")i[l.name]||(i[l.name]=[]),l.checked&&i[l.name].push(l.value);else if(l.type==="radio")l.checked&&(i[l.name]=l.value);else if(l.type==="select-multiple"){i[l.name]=[];for(let u=0;u<l.options.length;u++)l.options[u].selected&&i[l.name].push(l.options[u].value)}else i[l.name]=l.value}return i}const X={};function ue(t,r){X[t]=r}function fe(t){return X[t]||{ingress:r=>r,egress:r=>r}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=ue,window.lnCore.getDataMapper=fe);function he(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,N(function(){new MutationObserver(function(){h(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const Y={};function pe(t,r){if(!t||typeof r!="object")return;const i=t.toLowerCase().split("-")[0];Y[i]=r}function me(t){if(!t)return null;const r=t.toLowerCase().split("-")[0];return Y[r]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=pe,window.lnCore.getLocaleFallback=me,window.lnCore.ensureLocaleObserver=he);const B={};function ye(t,r){B[t]||(B[t]=document.querySelector('[data-ln-template="'+t+'"]'));const i=B[t];return i?i.content.cloneNode(!0):(console.warn("["+(r||"ln-core")+'] Template "'+t+'" not found'),null)}function Z(t,r){if(!t||!r)return t;const i=t.querySelectorAll("[data-ln-field]");for(let u=0;u<i.length;u++){const m=i[u],p=m.getAttribute("data-ln-field");r[p]!=null&&(m.textContent=r[p])}const a=t.querySelectorAll("[data-ln-attr]");for(let u=0;u<a.length;u++){const m=a[u],p=m.getAttribute("data-ln-attr").split(",");for(let v=0;v<p.length;v++){const S=p[v].trim().split(":");if(S.length!==2)continue;const A=S[0].trim(),L=S[1].trim();r[L]!=null&&m.setAttribute(A,r[L])}}const d=t.querySelectorAll("[data-ln-show]");for(let u=0;u<d.length;u++){const m=d[u],p=m.getAttribute("data-ln-show");p in r&&m.classList.toggle("hidden",!r[p])}const l=t.querySelectorAll("[data-ln-class]");for(let u=0;u<l.length;u++){const m=l[u],p=m.getAttribute("data-ln-class").split(",");for(let v=0;v<p.length;v++){const S=p[v].trim().split(":");if(S.length!==2)continue;const A=S[0].trim(),L=S[1].trim();L in r&&m.classList.toggle(A,!!r[L])}}return t}function ge(t,r){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",t,r??null),t.dispatchEvent(new CustomEvent("ln-fill",{detail:r??null,bubbles:!0})));const i=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<i.length;a++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",i[a],r??null),i[a].dispatchEvent(new CustomEvent("ln-fill",{detail:r??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)Z(t.target,t.detail);else{const r=t.target.querySelectorAll("[data-ln-field]");for(let i=0;i<r.length;i++)r[i].textContent=""}})));function ee(t,r){if(!t||!r)return t;const i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;i.nextNode();){const l=i.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(u,m){return r[m]!==void 0?r[m]:""}))}const a=function(l,u){return r[u]!==void 0?r[u]:""},d=Array.from(t.querySelectorAll("*"));t.nodeType===1&&d.push(t);for(let l=0;l<d.length;l++){const u=d[l],m=u.attributes;for(let p=0;p<m.length;p++){const v=m[p];v.value.indexOf("{{")!==-1&&u.setAttribute(v.name,v.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return t}function be(t,r,i,a,d,l){const u={};for(let p=0;p<t.children.length;p++){const v=t.children[p],S=v.getAttribute("data-ln-render-key");S&&(u[S]=v)}const m=document.createDocumentFragment();for(let p=0;p<r.length;p++){const v=r[p],S=String(a(v));let A=u[S];if(A)d(A,v,p);else{const L=ye(i,l);if(!L||(ee(L,v),A=L.firstElementChild,!A))continue;A.setAttribute("data-ln-render-key",S),d(A,v,p)}m.appendChild(A)}t.textContent="",t.appendChild(m)}function we(t,r){const i={},a=t.querySelectorAll("["+r+"]");for(let d=0;d<a.length;d++)i[a[d].getAttribute(r)]=a[d].textContent,a[d].remove();return i}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=ee,window.lnCore.fill=Z,window.lnCore.lnFill=ge,window.lnCore.renderList=be);function te(t,r,i){const a=t.getAttribute(r);return a===null?i:a}function _e(t,r,i){const a=parseInt(t.getAttribute(r),10);return isNaN(a)?i:a}function qe(t,r,i=!1){const a=t.getAttribute(r);if(a===null)return!!i;const d=a.trim().toLowerCase();return!(d==="false"||d==="0")}function Ee(t,r){return(t.getAttribute(r)||"").split(",").map(i=>i.trim()).filter(Boolean)}const U=new Map;function ve(t,r){const i=(t?t.join("|"):"")+"::"+r;if(U.has(i))return U.get(i);const a=new Set(t||[]),d=function(l,u){const m=l.getAttribute(u);return m!==null&&a.has(m)?m:r};return U.set(i,d),d}function Ce(t,r,i){const a=parseFloat(t.getAttribute(r));return isNaN(a)?i:a}function Ae(t,r,i){const a=t.getAttribute(r);if(!a)return i;try{return JSON.parse(a)}catch{return i}}function ne(t,r,i,a,d){if(!t||r===null)return!0;const l=a||"ln-component",u=t.type;if(u==="trigger"||u==="marker"||u==="string"||u==="list"||!u||r===""&&t.fallback!==void 0)return!0;const m=p=>{d?console.warn(p,d):console.warn(p)};if(u==="boolean"){const p=r.trim().toLowerCase();return p!==""&&p!=="true"&&p!=="false"&&p!=="1"&&p!=="0"?(m(`[${l}] Invalid value "${r}" for boolean attribute "${i}". Allowed: "true", "false", or presence-only.`),!1):!0}if(u==="enum"){const p=t.values||[];return p.includes(r)?!0:(m(`[${l}] Invalid value "${r}" for attribute "${i}". Allowed: ${p.join(", ")}. Fallback: "${t.fallback}".`),!1)}if(u==="integer"){if(!/^-?\d+$/.test(r))return m(`[${l}] Invalid integer "${r}" for attribute "${i}". Fallback: ${t.fallback}.`),!1;const p=parseInt(r,10);return t.min!==void 0&&p<t.min?(m(`[${l}] Value ${p} for attribute "${i}" is less than min (${t.min}).`),!1):t.max!==void 0&&p>t.max?(m(`[${l}] Value ${p} for attribute "${i}" is greater than max (${t.max}).`),!1):!0}if(u==="float")return isNaN(Number(r))?(m(`[${l}] Invalid float "${r}" for attribute "${i}". Fallback: ${t.fallback}.`),!1):!0;if(u==="json")try{return JSON.parse(r),!0}catch(p){return m(`[${l}] Invalid JSON for attribute "${i}": ${p.message}. Fallback: ${t.fallback}.`),!1}return!0}function Se(t,r,i){for(const a in i){const[d,l,u]=i[a];Object.defineProperty(t,a,{get:function(){return d(r,l,u)},enumerable:!0,configurable:!0})}return t}function ke(t){const r={};for(const i in t){const a=t[i];if(!a||!a.prop)continue;let d=a.read;if(!d&&a.type)switch(a.type){case"enum":d=ve(a.values,a.fallback);break;case"integer":d=_e;break;case"float":d=Ce;break;case"boolean":d=qe;break;case"list":d=Ee;break;case"json":d=Ae;break;case"string":default:d=te;break}d||(d=te),r[a.prop]=[d,i,a.fallback]}return r}function Le(t){const r={};for(const i in t){const a=t[i];a&&a.effect&&(r[i]=a.effect)}return Object.keys(r).length?r:null}function xe(t){if(t.onAttrChange&&!t.declared)return null;const r=new Set;if(t.effects)for(const i in t.effects)r.add(i);if(t.onAttrChange&&t.declared)for(const i of t.declared)r.add(i);return r}function z(t,r,i,a){if(t.nodeType!==1)return;const l=r.indexOf("[")!==-1||r.indexOf(".")!==-1||r.indexOf("#")!==-1?r:"["+r+"]",u=Array.from(t.querySelectorAll(l));t.matches&&t.matches(l)&&u.push(t);for(const m of u)if(!m[i]){window.lnCore._persistSink&&m.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(m,r);try{m[i]=new a(m)}catch(p){console.error("["+i+"] init failed",m,p)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function De(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function Ie(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 re(){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 Oe(t){const r=re(),i=t.observed||[];for(let a=0;a<i.length;a++){const d=i[a];r.byAttr.has(d)||r.byAttr.set(d,[]),r.byAttr.get(d).push(t)}if(r.byDeclaredAttr=r.byDeclaredAttr||new Map,t.attributes)for(const a in t.attributes){r.byDeclaredAttr.has(a)||r.byDeclaredAttr.set(a,[]);const d=r.byDeclaredAttr.get(a);d.some(l=>l.componentTag===t.componentTag)||d.push({spec:t.attributes[a],componentTag:t.componentTag})}if(t.onAttrChange||t.effects){r.reactive.push(t);const a=xe(t);if(a===null)r.reactiveWildcard.push(t);else for(const d of a)r.byReactive.has(d)||r.byReactive.set(d,[]),r.byReactive.get(d).push(t)}t.persist&&r.persist.push(t)}function oe(t,r,i,a){for(let d=0;d<t.length;d++){const l=t[d];if(!r[l.attribute])continue;const u=l.effects&&l.effects[i];u?u(r,i,a):l.onAttrChange&&(!l.declared||l.declared.has(i))&&l.onAttrChange(r,i,a)}}function Re(t){const r=t.target,i=t.attributeName;if(t.oldValue===r.getAttribute(i))return;const a=re(),d=a.byAttr.get(i);if(J()&&a.byDeclaredAttr&&a.byDeclaredAttr.has(i)&&$(r)){const l=a.byDeclaredAttr.get(i),u=r.getAttribute(i);for(let m=0;m<l.length;m++)ne(l[m].spec,u,i,l[m].componentTag,r)}if(window.lnCore._debugSink&&(i.indexOf("data-ln-")===0||d)&&window.lnCore._debugSink("attr",i,r,{oldValue:t.oldValue,newValue:r.getAttribute(i)}),i.indexOf("data-ln-")===0){const l=a.byReactive.get(i);l&&oe(l,r,i,t.oldValue),a.reactiveWildcard.length&&oe(a.reactiveWildcard,r,i,t.oldValue)}if(d)for(let l=0;l<d.length;l++){const u=d[l];if(u.handler){u.handler(r,i,t.oldValue);continue}u.onAttributeChange&&r[u.attribute]?u.onAttributeChange(r,i):(z(r,u.selector,u.attribute,u.ComponentFn),u.onInit&&u.onInit(r))}}function Ge(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,N(function(){new MutationObserver(function(r){for(let i=0;i<r.length;i++)try{Re(r[i])}catch(a){console.error("[ln-core] mutation handler failed",r[i].target,a)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function ie(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function Te(t){const r=ie();if(r.length){if(t.target)for(let i=0;i<r.length;i++){const a=r[i];if(a.onSubtreeChange){const d=a.query,l=t.target.nodeType===1?t.target.matches(d)?t.target:t.target.closest(d):t.target.parentElement?t.target.parentElement.closest(d):null;l&&a.onSubtreeChange(l,t)}}for(let i=0;i<t.addedNodes.length;i++){const a=t.addedNodes[i];if(a.nodeType===1)for(let d=0;d<r.length;d++){const l=r[d];z(a,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(a)}}for(let i=0;i<t.removedNodes.length;i++){const a=t.removedNodes[i];if(a.nodeType===1)for(let d=0;d<r.length;d++){const l=r[d],u=l.query,m=Array.from(a.querySelectorAll(u));a.matches&&a.matches(u)&&m.push(a);for(let p=0;p<m.length;p++){const v=m[p];if(!document.contains(v)){const S=v[l.attribute];if(S&&typeof S.destroy=="function")try{S.destroy()}catch(A){console.error("["+l.attribute+"] destroy failed",v,A)}delete v[l.attribute]}}}}}}function Me(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,N(function(){new MutationObserver(function(r){for(let i=0;i<r.length;i++){const a=r[i];if(a.type==="childList")try{Te(a)}catch(d){console.error("[ln-core] lifecycle handler failed",a.target,d)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function Fe(t,r,i,a,d={}){const l=d.extraAttributes||[],u=d.onAttributeChange||null,m=d.onSubtreeChange||null,p=d.onInit||null,v=d.onAttrChange||null,S=d.effects||null,A=d.attributes||null,L=A?Le(A):S,M=A?new Set(Object.keys(A)):null,F=d.persist||null;function O(Q){const C=Q||document.body;if(z(C,t,r,i),A&&J())for(const q in A){const V=A[q],e=Array.from(C.querySelectorAll("["+q+"]"));C.matches&&C.matches("["+q+"]")&&e.push(C);for(let n=0;n<e.length;n++){const o=e[n];$(o)&&ne(V,o.getAttribute(q),q,a,o)}}p&&p(C)}const G=[];if(t.indexOf("[")!==-1){const Q=/\[([\w-]+)/g;let C;for(;(C=Q.exec(t))!==null;)G.push(C[1])}else G.push(t);Oe({selector:t,attribute:r,componentTag:a,attributes:A,ComponentFn:i,onInit:p,observed:G.concat(l),onAttributeChange:u,onAttrChange:v,effects:L,declared:M,persist:F}),Ge();const W=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]";ie().push({selector:t,attribute:r,ComponentFn:i,onInit:p,onSubtreeChange:m,query:W}),Me(),window[r]=O;function R(){De()>0?Ie(function(){O(document.body)}):O(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",R):R(),O}function Qe(t,r){let i=!1;return function(){i||(i=!0,queueMicrotask(function(){i=!1,t()}))}}function ae(t){return(t||"").replace(/^#/,"")}function K(t){const r=t===void 0?location.hash:t,i={},a=ae(r);if(!a)return i;const d=a.split("&");for(let l=0;l<d.length;l++){const u=d[l];if(!u)continue;const m=u.indexOf(":"),p=m>-1?u.slice(0,m):u,v=m>-1?u.slice(m+1):"";if(p)try{i[p]=decodeURIComponent(v)}catch{i[p]=v}}return i}function je(t){if(!t)return null;const r=K();return t in r?r[t]:null}function Ne(t,r){if(!t)return;const i=K();r==null?delete i[t]:i[t]=String(r);const d=Object.keys(i).map(function(l){const u=i[l];return u===""?l:l+":"+encodeURIComponent(u)}).join("&");ae(location.hash)!==d&&(location.hash=d)}function Pe(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}function $e(t,r){if(!t||!t.hasAttribute("data-ln-hash"))return null;const i=t.getAttribute("data-ln-hash");if(i&&i.trim()!=="")return i.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?r?a+"-"+r:a:r||null}function Be(t,r){return!r||r==="none"||t===null||t===void 0?null:String(t)+"."+r}function Ue(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 ze(t,r){return!t||!Array.isArray(r)||r.length===0?null:t+":"+r.map(encodeURIComponent).join(",")}function Ke(t){if(!t||typeof t!="string")return null;const r=t.indexOf(":");if(r===-1)return null;const i=t.slice(0,r),a=t.slice(r+1),d=a?a.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:i,values:d}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=K,window.lnCore.hashGet=je,window.lnCore.hashSet=Ne,window.lnCore.hashLinkClick=Pe,window.lnCore.resolveHashNamespace=$e,window.lnCore.hashSortEncode=Be,window.lnCore.hashSortDecode=Ue,window.lnCore.hashFilterEncode=ze,window.lnCore.hashFilterDecode=Ke);function We(t){return t=t||{},{sort:t.sort,filters:t.filters,search:t.search,offset:t.offset,limit:t.limit,queryGen:t.queryGen}}function j(t,r){const i=!t||!!t.initializationError,a=!!(t&&t.noLocalQuery&&!t.windowed);return r&&(i||!t.canServe||a)?"remote":t&&!t.initializationError?"store":"none"}function P(t,r,i){return i==="store"&&!!r&&!(t&&t.windowed)}function se(t,r){const i=Object.assign({},t);return r&&(i.filters=r.filters,i.search=r.search,i.sort=r.sort),i}class Ve{constructor(){this._pending=new Map}wait(r){return new Promise((i,a)=>{this._pending.set(r,{resolve:i,reject:a})})}resolve(r){return this._settle(r,!1)}reject(r){return this._settle(r,!0)}close(r){const i=r||new Error("Mutation receipt registry closed");for(const a of this._pending.values())a.reject(i);this._pending.clear()}_settle(r,i){const a=r&&r.requestId;if(!a)return!1;const d=this._pending.get(a);return d?(this._pending.delete(a),i?d.reject(r.error||new Error("Store mutation failed")):d.resolve(r),!0):!1}}(function(){const t="data-ln-data-coordinator",r="lnDataCoordinator",i="data-ln-data-coordinator-scope",a="data-ln-data-coordinator-search",d="data-ln-data-coordinator-filters",l="data-ln-data-coordinator-sort-field",u="data-ln-data-coordinator-sort-direction";if(window[r]!==void 0)return;function m(e){const n=e[r];n&&n.refreshMapper()}function p(e){const n=e[r];n&&n._queueQueryRefresh()}function v(e,n){return e.getAttribute(n)||e.id}const S={"data-ln-data-coordinator":{prop:"_name",type:"string",read:v,description:"Coordinator name or identifier for data routing"},"data-ln-data-coordinator-scope":{type:"string",description:"Scope name addressing the bound data store and connector"},"data-ln-data-coordinator-mapper":{type:"string",effect:m,description:"Name of the registered data mapper transform"},"data-ln-data-coordinator-search":{type:"string",effect:p,description:"Active search query term"},"data-ln-data-coordinator-filters":{type:"string",effect:p,description:"Active encoded filter parameters"},"data-ln-data-coordinator-sort-field":{type:"string",effect:p,description:"Active sort field property name"},"data-ln-data-coordinator-sort-direction":{type:"enum",values:["asc","desc"],fallback:"asc",effect:p,description:"Sort direction"},"data-ln-data-coordinator-stale":{type:"marker",description:"Flag indicating data needs re-synchronization"},"data-ln-data-coordinator-no-autosync":{type:"boolean",description:"Disables automatic synchronization upon state changes"},"data-ln-data-coordinator-dict":{type:"marker",description:"Marks dictionary container for coordinator translatable messages"}},A=ke(S),L=new Set;let M=!1,F=null,O=null,G=null;function de(){M||(M=!0,F=function(){h(document,"ln-data-coordinator:online",{}),L.forEach(function(e){e._maybeSync()})},O=function(){h(document,"ln-data-coordinator:offline",{})},G=function(){document.visibilityState==="visible"&&L.forEach(function(e){const n=e.findChildren(),o=n.store;o&&n.connector&&o.isInitialized&&!o.initializationError&&!o.isSyncing&&!e._noAutosync&&(!o.hasCache||e._isStale())&&o.forceSync()})},window.addEventListener("online",F),window.addEventListener("offline",O),document.addEventListener("visibilitychange",G))}function W(){M&&(L.size>0||(window.removeEventListener("online",F),window.removeEventListener("offline",O),document.removeEventListener("visibilitychange",G),F=null,O=null,G=null,M=!1))}function R(){try{return crypto.randomUUID()}catch{return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const o=Math.random()*16|0;return(n==="x"?o:o&3|8).toString(16)})}}const Q=["ln-api-connector","ln-couchdb-connector","ln-websocket-connector"];function C(e){return e?e.hasAttribute("data-ln-couchdb-connector")?"ln-couchdb-connector":e.hasAttribute("data-ln-websocket-connector")?"ln-websocket-connector":"ln-api-connector":"ln-api-connector"}function q(e){const n=this;return this.dom=e,Se(this,e,A),this._name||console.warn("[ln-data-coordinator] missing id — the coordinator cannot be addressed",e),e[r]=this,this._destroyed=!1,this.mapper=null,this._handlers=null,this._boundQueries=new WeakMap,this._boundDelivered=new WeakMap,this._queryGens=new WeakMap,this._mutationReceipts=new Ve,this._dict=we(e,"data-ln-data-coordinator-dict"),this._queueQueryRefresh=Qe(function(){n._destroyed||n._refreshAll(null,!0)}),this.refreshConfig(),V(this),L.add(this),de(),this._checkInitialSync(),this}Object.defineProperty(q.prototype,"_staleThreshold",{get:function(){const n=this.findChildren().storeEl,o=this.dom.getAttribute("data-ln-data-coordinator-stale")||(n?n.getAttribute("data-ln-data-store-stale"):null);if(o==="never"||o==="-1")return-1;const s=parseInt(o,10);return isNaN(s)?300:s}}),Object.defineProperty(q.prototype,"_noAutosync",{get:function(){const n=this.findChildren().storeEl;return this.dom.hasAttribute("data-ln-data-coordinator-no-autosync")||(n?n.hasAttribute("data-ln-data-store-no-autosync"):!1)}}),q.prototype.refreshConfig=function(){this.refreshMapper()},q.prototype._isStale=function(){if(this._staleThreshold===-1)return!1;const n=this.findChildren().store;return!n||!n.lastSyncedAt?!0:Date.now()/1e3-n.lastSyncedAt>this._staleThreshold},q.prototype._maybeSync=function(){const e=this.findChildren(),n=e.store;!n||n.initializationError||!e.connector||this._noAutosync||!n.isInitialized||n.isSyncing||(!n.hasCache||this._isStale())&&n.forceSync()},q.prototype._checkInitialSync=function(){const e=this,o=this.findChildren().store;o&&Promise.resolve(o.ready).then(function(){if(e._destroyed)return;const s=e.findChildren(),c=s.store;if(c&&c.initializationError){e._reportReconciliationError("store-initialize",c.initializationError,null);return}!c||!s.connector||e._noAutosync||c.isSyncing||(!c.hasCache||e._isStale())&&c.forceSync()}).catch(function(s){e._destroyed||e._reportReconciliationError("store-initialize",s,null)})},q.prototype.refreshMapper=function(){this.mapper=null,this.dom.querySelector("script[data-ln-mapper]")&&console.error("[ln-data-coordinator] Security Error: Inline script mappers using <script data-ln-mapper> are deprecated and disabled due to XSS vulnerability risks (unsafe-eval). Please register your mappers securely via window.lnCore.registerDataMapper() instead.");const n=this.dom.getAttribute("data-ln-data-coordinator-mapper")||this.dom.id;n&&window.lnCore&&typeof window.lnCore.getDataMapper=="function"&&(this.mapper=window.lnCore.getDataMapper(n)),this.mapper||(this.mapper={}),typeof this.mapper.ingress!="function"&&(this.mapper.ingress=function(o){return o}),typeof this.mapper.egress!="function"&&(this.mapper.egress=function(o){return o})},q.prototype.findChildren=function(){const e=this.dom.querySelector("[data-ln-data-store]"),n=this.dom.querySelector("[data-ln-api-connector], [data-ln-couchdb-connector]")||this.dom.querySelector("[data-ln-websocket-connector]"),o=this.dom.querySelector("[data-ln-api-queue]");return{storeEl:e,connectorEl:n,queueEl:o,store:e?e.lnDataStore:null,connector:n?n.lnApiConnector||n.lnCouchDbConnector||n.lnWebsocketConnector:null,queue:o?o.lnApiQueue:null}},q.prototype._handleSubmitRecord=function(e){const n=this.findChildren();if(!n.storeEl&&!n.connectorEl){console.warn('[ln-data-coordinator] form submit claimed but neither [data-ln-data-store] nor a connector child found in "'+(this._name||"")+'"');return}const o=e.data||{},s=o.id,c=o.expected_version,f=Object.assign({},o);delete f.id,delete f.expected_version;const g=e.method.toUpperCase();g==="POST"?this._fanOutCreate(n,f,e.action):(g==="PUT"||g==="PATCH")&&this._fanOutUpdate(n,s,f,c,e.action)},q.prototype._fanOutCreate=function(e,n,o){this.refreshMapper();const s="_temp_"+R();e.storeEl&&h(e.storeEl,"ln-data-store:request-create",{tempId:s,data:n}),e.queue?h(e.queueEl,"ln-api-queue:request-enqueue",{chainKey:s,op:"create",targetId:null,payload:this.mapper.egress(n),expectedVersion:null,meta:{tempId:s,action:o}}):e.connector&&h(e.connectorEl,C(e.connectorEl)+":request-create",{data:this.mapper.egress(n),url:o,meta:{entryId:R(),queued:!1,op:"create",tempId:s}})},q.prototype._fanOutUpdate=function(e,n,o,s,c){this.refreshMapper(),e.storeEl&&h(e.storeEl,"ln-data-store:request-update",{id:n,data:o}),e.queue?h(e.queueEl,"ln-api-queue:request-enqueue",{chainKey:n,op:"update",targetId:n,payload:this.mapper.egress(o),expectedVersion:s,meta:{id:n,action:c}}):e.connector&&h(e.connectorEl,C(e.connectorEl)+":request-update",{id:n,data:this.mapper.egress(o),expected_version:s,url:c,meta:{entryId:R(),queued:!1,op:"update",id:n}})},q.prototype._fanOutDelete=function(e,n){this.refreshMapper(),e.storeEl&&h(e.storeEl,"ln-data-store:request-delete",{id:n}),e.queue?h(e.queueEl,"ln-api-queue:request-enqueue",{chainKey:n,op:"delete",targetId:n,payload:null,expectedVersion:null,meta:{id:n}}):e.connector&&h(e.connectorEl,C(e.connectorEl)+":request-delete",{id:n,meta:{entryId:R(),queued:!1,op:"delete",id:n}})},q.prototype._fanOutBulkDelete=function(e,n){this.refreshMapper();const o=n.join(",");e.storeEl&&h(e.storeEl,"ln-data-store:request-bulk-delete",{ids:n}),e.queue?h(e.queueEl,"ln-api-queue:request-enqueue",{chainKey:o,op:"bulk-delete",targetId:null,payload:{ids:n},expectedVersion:null,meta:{bulkKey:o,ids:n}}):e.connector&&h(e.connectorEl,C(e.connectorEl)+":request-bulk-delete",{ids:n,meta:{entryId:R(),queued:!1,op:"bulk-delete",bulkKey:o}})},q.prototype._toastFromMessage=function(e){e&&h(window,"ln-toast:enqueue",{type:e.type||"success",title:e.title||"",message:e.body||""})},q.prototype._toastFromDict=function(e){const n=this._dict[e];n&&h(window,"ln-toast:enqueue",{type:"error",title:"",message:n})},q.prototype._requestStoreMutation=function(e,n,o){const s=e.storeEl;if(!s)return Promise.reject(new Error("Store element not found"));const c=R(),f=this._mutationReceipts.wait(c);return h(s,"ln-data-store:request-"+n,Object.assign({},o,{requestId:c})),f},q.prototype._reportReconciliationError=function(e,n,o){this._destroyed||h(this.dom,"ln-data-coordinator:error",{operation:e,error:n,meta:o||null})};function V(e){e._handlers={sync:function(n){e.refreshMapper();const o=e.findChildren();if(!o.store||!o.connector){console.warn("[ln-data-coordinator] Cannot sync: store or connector not found in subtree");return}h(o.connectorEl,C(o.connectorEl)+":request-sync",{since:n.detail.since,meta:{op:"sync"}})},requestPage:function(n){const o=e.findChildren();if(!o.connectorEl)return;const s=n.detail||{};h(o.connectorEl,C(o.connectorEl)+":request-query",{query:Object.assign({},s.query,{offset:s.offset,limit:s.limit,queryGen:s.queryGen})})},reqCreate:function(n){const o=e.findChildren();e._fanOutCreate(o,n.detail.data||{},n.detail.action)},reqUpdate:function(n){const o=e.findChildren();e._fanOutUpdate(o,n.detail.id,n.detail.data||{},n.detail.expected_version,n.detail.action)},reqDelete:function(n){const o=e.findChildren();e._fanOutDelete(o,n.detail.id)},reqBulkDelete:function(n){const o=e.findChildren();e._fanOutBulkDelete(o,n.detail.ids||[])},queueFailed:function(){e._toastFromDict("network")},queueSend:function(n){e.refreshMapper();const o=e.findChildren();if(!o.store||!o.connector||!o.queue)return;const s=n.detail||{},c=s.entryId,f=s.op,g=s.targetId,y=s.payload,b=s.expectedVersion,w=s.meta||{},E=w.action||null,_=s.idempotencyKey||c;f==="create"?h(o.connectorEl,C(o.connectorEl)+":request-create",{data:y,url:E,idempotencyKey:_,meta:{entryId:c,queued:!0,op:"create",tempId:w.tempId}}):f==="update"?h(o.connectorEl,C(o.connectorEl)+":request-update",{id:g,data:y,expected_version:b,url:E,idempotencyKey:_,meta:{entryId:c,queued:!0,op:"update",id:g}}):f==="delete"?h(o.connectorEl,C(o.connectorEl)+":request-delete",{id:g,idempotencyKey:_,meta:{entryId:c,queued:!0,op:"delete",id:g}}):f==="bulk-delete"?h(o.connectorEl,C(o.connectorEl)+":request-bulk-delete",{ids:y&&y.ids?y.ids:[],idempotencyKey:_,meta:{entryId:c,queued:!0,op:"bulk-delete",bulkKey:w.bulkKey}}):console.warn("[ln-data-coordinator] Unknown queue op:",f)},formSubmit:function(n){const o=n.target;if(n.defaultPrevented)return;const s=o.hasAttribute(i)?o.getAttribute(i):null;if(s===null)return;let c;if(s?c=e._owns(s):c=o.closest("[data-ln-data-coordinator]")===e.dom,!c)return;const f=le(o);if(f!=="POST"&&f!=="PUT"&&f!=="PATCH")return;n.preventDefault();const g=ce(o);delete g._method,delete g._token,e._handleSubmitRecord({data:g,method:f,action:o.getAttribute("action")||""})},connFetched:function(n){const o=n.detail.meta||{},s=e.findChildren();e.refreshMapper();const c=n.detail.data;let f=[],g=[],y=null;Array.isArray(c)?(f=c,y=Math.floor(Date.now()/1e3)):c&&(f=Array.isArray(c.data)?c.data:[],g=Array.isArray(c.deleted)?c.deleted:[],y=c.synced_at!==void 0?c.synced_at:c.since!==void 0?c.since:null);const b=f.map(w=>e.mapper.ingress(w));if(s.store&&!s.store.initializationError)o.kind?o.kind==="table"||o.kind==="list"||o.kind==="chart"?s.store.applyQuery(b,{total:n.detail.total}).then(function(w){o.queryGen!=null&&!e._isCurrentGen(o.targetEl,o.queryGen)||(h(o.targetEl,"ln-"+o.kind+":set-loading",{loading:!1}),h(o.targetEl,"ln-"+o.kind+":set-data",{data:w,total:n.detail.total!==void 0?n.detail.total:w.length,filtered:n.detail.filtered!==void 0?n.detail.filtered:w.length,offset:n.detail.offset,queryGen:n.detail.queryGen}),e._boundDelivered.set(o.targetEl,!0))}):o.kind==="options"?s.store.applyQuery(b,{total:n.detail.total}).then(function(){return s.store.getAll({})}).then(function(w){o.queryGen!=null&&!e._isCurrentGen(o.targetEl,o.queryGen)||h(o.targetEl,"ln-options:set-data",{data:w.data})}):o.kind==="stat"&&s.store.applyQuery(b,{total:n.detail.total}).then(function(){if(o.queryGen!=null&&!e._isCurrentGen(o.targetEl,o.queryGen))return;const w=n.detail.filtered!==void 0?n.detail.filtered:n.detail.total!==void 0?n.detail.total:b.length;h(o.targetEl,"ln-stat:set-count",{count:w})}):s.store.applySync(b,g,y||Math.floor(Date.now()/1e3),{total:n.detail.total,filtered:n.detail.filtered,offset:n.detail.offset,queryGen:n.detail.queryGen,targetEl:o.targetEl});else if(o.targetEl&&o.kind){if(o.kind==="table"||o.kind==="list"||o.kind==="chart")h(o.targetEl,"ln-"+o.kind+":set-loading",{loading:!1}),h(o.targetEl,"ln-"+o.kind+":set-data",{data:b,total:n.detail.total!==void 0?n.detail.total:b.length,filtered:n.detail.filtered!==void 0?n.detail.filtered:b.length,offset:n.detail.offset,queryGen:n.detail.queryGen}),e._boundDelivered.set(o.targetEl,!0);else if(o.kind==="options")h(o.targetEl,"ln-options:set-data",{data:b});else if(o.kind==="stat"){const w=n.detail.filtered!==void 0?n.detail.filtered:n.detail.total!==void 0?n.detail.total:b.length;h(o.targetEl,"ln-stat:set-count",{count:w})}}},connCreated:function(n){const o=e.findChildren(),s=n.detail.meta||{},c=e.mapper.ingress(n.detail.record);(o.storeEl?e._requestStoreMutation(o,"update",{id:s.tempId,data:c}):Promise.resolve()).then(function(){e._toastFromMessage(n.detail.message),s.queued&&o.queue&&h(o.queueEl,"ln-api-queue:resolve-create",{entryId:s.entryId,oldKey:s.tempId,newId:c.id})}).catch(function(g){e._reportReconciliationError("create-reconcile",g,s)})},connUpdated:function(n){const o=e.findChildren(),s=n.detail.meta||{},c=e.mapper.ingress(n.detail.record);(o.storeEl?e._requestStoreMutation(o,"update",{id:s.id,data:c}):Promise.resolve()).then(function(){e._toastFromMessage(n.detail.message),s.queued&&o.queue&&h(o.queueEl,"ln-api-queue:ack",{entryId:s.entryId})}).catch(function(g){e._reportReconciliationError("update-reconcile",g,s)})},connDeleted:function(n){const o=e.findChildren(),s=n.detail.meta||{};e._toastFromMessage(n.detail.message),s.queued&&o.queue&&h(o.queueEl,"ln-api-queue:ack",{entryId:s.entryId})},connBulkDeleted:function(n){const o=e.findChildren(),s=n.detail.meta||{};e._toastFromMessage(n.detail.message),s.queued&&o.queue&&h(o.queueEl,"ln-api-queue:ack",{entryId:s.entryId})},connError:function(n){const o=n.detail||{},s=o.meta||{},c=s.op||o.action,f=o.status||o.error&&o.error.status||0,g=e.findChildren();if(c==="sync"){g.storeEl&&h(g.storeEl,"ln-data-store:request-sync-failed",{error:o.error,status:f}),console.error("[ln-data-coordinator] Sync failed:",o.error);return}if(c==="query"){s.targetEl&&s.kind&&(h(s.targetEl,"ln-"+s.kind+":set-loading",{loading:!1}),(s.kind==="table"||s.kind==="list")&&h(s.targetEl,"ln-"+s.kind+":page-failed",{offset:s.offset})),e._reportReconciliationError("query",o.error||o,s);return}const y=f===401||f===419,b=f===0||f>=500,w=f===409||f===412;if(y){e._toastFromDict("auth"),s.queued&&g.queue&&h(g.queueEl,"ln-api-queue:nack",{entryId:s.entryId,reason:"auth"});return}if(b){s.queued&&g.queue?h(g.queueEl,"ln-api-queue:nack",{entryId:s.entryId,reason:"retry"}):e._toastFromDict("network");return}let E=Promise.resolve();if(w&&c==="update"){const _=o.data&&o.data.remote?e.mapper.ingress(o.data.remote):null;_&&g.storeEl&&(E=e._requestStoreMutation(g,"update",{id:s.id,data:_})),e._toastFromDict("conflict")}else c==="create"&&g.storeEl&&(E=e._requestStoreMutation(g,"delete",{id:s.tempId})),e._toastFromDict("rejected");s.queued&&g.queue?E.then(function(){h(g.queueEl,"ln-api-queue:nack",{entryId:s.entryId,reason:"drop"})}).catch(function(_){e._reportReconciliationError("deterministic-reconcile",_,s)}):E.catch(function(_){e._reportReconciliationError("deterministic-reconcile",_,s)})},storeInitialized:function(n){const o=e.findChildren(),s=o.store;if(!s||s.initializationError||!o.connector||e._noAutosync||s.isSyncing)return;(n.detail||{}).hasCache?e._isStale()&&s.forceSync():s.forceSync()},socketConnected:function(){const n=e.findChildren(),o=n.store;!o||o.initializationError||!n.connector||e._noAutosync||!o.isInitialized||o.isSyncing||o.forceSync()},reqTableData:function(n){e._serveData(n,"table")},reqListData:function(n){e._serveData(n,"list")},reqChartData:function(n){e._serveData(n,"chart")},reqOptions:function(n){e._serveOptions(n)},reqStat:function(n){e._serveStat(n)},refreshQuery:function(){e._refreshAll(null,!0)},refresh:function(n){e._mutationReceipts.resolve(n.detail),e._refreshAll(null,!1)},mutationError:function(n){e._mutationReceipts.reject(n.detail)},refreshSynced:function(n){n.detail&&n.detail.changed&&e._refreshAll(n.detail.meta,!1)},searchChange:function(n){n.preventDefault();const o=n.detail&&n.detail.term!=null?n.detail.term:"";o!==(e.dom.getAttribute(a)||"")&&e.dom.setAttribute(a,o)},filterChange:function(n){n.preventDefault();const o=n.detail&&n.detail.key;if(!o)return;const s=(n.detail.values||[]).slice(),c=e._currentQuery().filters,f=c[o];if(f?f.length===s.length&&f.every((w,E)=>w===s[E]):!s.length)return;s.length?c[o]=s:delete c[o];const y=new URLSearchParams;Object.keys(c).forEach(function(w){c[w].forEach(function(E){y.append(w,E)})});const b=y.toString();b?e.dom.setAttribute(d,b):e.dom.removeAttribute(d)},sortChange:function(n){n.preventDefault();const o=n.detail&&n.detail.field,s=n.detail&&n.detail.direction,c=o&&s&&s!=="none"?{field:o,direction:s}:null,f=e._currentQuery().sort;!f&&!c||f&&c&&f.field===c.field&&f.direction===c.direction||(c?(e.dom.setAttribute(l,c.field),e.dom.setAttribute(u,c.direction)):(e.dom.removeAttribute(l),e.dom.removeAttribute(u)))}},e.dom.addEventListener("ln-data-store:request-remote-sync",e._handlers.sync),e.dom.addEventListener("ln-data-store:request-page",e._handlers.requestPage),e.dom.addEventListener("ln-data-coordinator:request-create",e._handlers.reqCreate),e.dom.addEventListener("ln-data-coordinator:request-update",e._handlers.reqUpdate),e.dom.addEventListener("ln-data-coordinator:request-delete",e._handlers.reqDelete),e.dom.addEventListener("ln-data-coordinator:request-bulk-delete",e._handlers.reqBulkDelete),e.dom.addEventListener("ln-api-queue:send",e._handlers.queueSend),e.dom.addEventListener("ln-api-queue:failed",e._handlers.queueFailed),e.dom.addEventListener("ln-data-store:initialized",e._handlers.storeInitialized),e.dom.addEventListener("ln-websocket-connector:connected",e._handlers.socketConnected),document.addEventListener("submit",e._handlers.formSubmit),Q.forEach(function(n){e.dom.addEventListener(n+":fetched",e._handlers.connFetched),e.dom.addEventListener(n+":created",e._handlers.connCreated),e.dom.addEventListener(n+":updated",e._handlers.connUpdated),e.dom.addEventListener(n+":deleted",e._handlers.connDeleted),e.dom.addEventListener(n+":bulk-deleted",e._handlers.connBulkDeleted),e.dom.addEventListener(n+":error",e._handlers.connError)}),document.addEventListener("ln-table:request-data",e._handlers.reqTableData),document.addEventListener("ln-list:request-data",e._handlers.reqListData),document.addEventListener("ln-chart:request-data",e._handlers.reqChartData),document.addEventListener("ln-options:request-data",e._handlers.reqOptions),document.addEventListener("ln-stat:request-count",e._handlers.reqStat),e.dom.addEventListener("ln-data-store:ready",e._handlers.refresh),e.dom.addEventListener("ln-data-store:created",e._handlers.refresh),e.dom.addEventListener("ln-data-store:updated",e._handlers.refresh),e.dom.addEventListener("ln-data-store:deleted",e._handlers.refresh),e.dom.addEventListener("ln-data-store:mutation-error",e._handlers.mutationError),e.dom.addEventListener("ln-data-store:synced",e._handlers.refreshSynced),e.dom.addEventListener("ln-data-store:query-changed",e._handlers.refreshQuery),e.dom.addEventListener("ln-search:change",e._handlers.searchChange),e.dom.addEventListener("ln-filter:change",e._handlers.filterChange),e.dom.addEventListener("ln-sort:change",e._handlers.sortChange)}q.prototype._owns=function(e){return!!e&&e===this._name},q.prototype._currentQuery=function(){const e=this.dom.getAttribute(l),n=this.dom.getAttribute(u),o=new URLSearchParams(this.dom.getAttribute(d)||""),s={};for(const c of new Set(o.keys()))s[c]=o.getAll(c);return{search:this.dom.getAttribute(a)||"",filters:s,sort:e&&n?{field:e,direction:n}:null}},q.prototype._nextQueryGen=function(e){const n=(this._queryGens.get(e)||0)+1;return this._queryGens.set(e,n),n},q.prototype._isCurrentGen=function(e,n){return this._queryGens.get(e)===n},q.prototype._serveData=function(e,n){const o=e.target,s=n==="table"?"data-ln-table-source":n==="list"?"data-ln-list-source":"data-ln-chart-source",c=o.getAttribute(s);if(!c||!this._owns(c))return;const f=e.detail||{},g=We(f);this._boundQueries.set(o,g);const y=this.findChildren(),b=this,w=y.store;return(w&&w.ready?w.ready:Promise.resolve()).then(function(){if(b._destroyed)return;const _=j(w,y.connector),k=se(g,b._currentQuery());if(_==="remote"){const I=b._nextQueryGen(o);h(o,"ln-"+n+":set-loading",{loading:!0}),h(y.connectorEl,C(y.connectorEl)+":request-query",{query:k,meta:{targetEl:o,kind:n,offset:k.offset,limit:k.limit,queryGen:I}});return}if(_!=="store"){h(o,"ln-"+n+":set-loading",{loading:!1});return}const x=P(w,y.connector,_),D=x?b._nextQueryGen(o):null;return x&&h(y.connectorEl,C(y.connectorEl)+":request-query",{query:k,meta:{targetEl:o,kind:n,offset:k.offset,limit:k.limit,queryGen:D}}),w.getAll(k).then(function(I){if(b._destroyed||!b._boundDelivered||x&&!b._isCurrentGen(o,D))return;const H={data:I.data,total:I.total,filtered:I.filtered,offset:f.offset!==void 0?f.offset:I.offset,queryGen:f.queryGen!==void 0?f.queryGen:I.queryGen,provisional:x||I.provisional===!0};h(o,"ln-"+n+":set-data",H),b._boundDelivered.set(o,!0)})}).catch(function(_){b._destroyed||(h(o,"ln-"+n+":set-loading",{loading:!1}),h(b.dom,"ln-data-coordinator:error",{operation:"query",kind:n,store:c,target:o,error:_}))})},q.prototype._serveOptions=function(e){const n=e.target,o=n.getAttribute("data-ln-options");if(!this._owns(o))return;const s=this.findChildren(),c=s.store,f=c&&c.ready?c.ready:Promise.resolve(),g=this;return f.then(function(){if(g._destroyed)return;const y=j(c,s.connector);if(y==="remote"){const E=g._nextQueryGen(n);h(s.connectorEl,C(s.connectorEl)+":request-query",{query:{},meta:{targetEl:n,kind:"options",queryGen:E}});return}if(y!=="store")return;const b=P(c,s.connector,y),w=b?g._nextQueryGen(n):null;return b&&h(s.connectorEl,C(s.connectorEl)+":request-query",{query:{},meta:{targetEl:n,kind:"options",queryGen:w}}),c.getAll({}).then(function(E){g._destroyed||b&&!g._isCurrentGen(n,w)||h(n,"ln-options:set-data",{data:E.data})})}).catch(function(y){g._destroyed||g._reportReconciliationError("options-query",y,{targetEl:n,kind:"options"})})},q.prototype._serveStat=function(e){const n=e.target,o=n.getAttribute("data-ln-stat");if(!this._owns(o))return;const s=e.detail&&e.detail.filters?e.detail.filters:null,c=this.findChildren(),f=c.store,g=f&&f.ready?f.ready:Promise.resolve(),y=this;return g.then(function(){if(y._destroyed)return;const b=s&&Object.keys(s).length>0,w=!!(c.connector&&f&&(f.windowed&&b||f.noLocalQuery)),E=w?"remote":j(f,c.connector);if(E==="remote"){const x=y._nextQueryGen(n);h(c.connectorEl,C(c.connectorEl)+":request-query",{query:{filters:s},meta:{targetEl:n,kind:"stat",queryGen:x}});return}if(E!=="store")return;const _=!w&&P(f,c.connector,E),k=_?y._nextQueryGen(n):null;return _&&h(c.connectorEl,C(c.connectorEl)+":request-query",{query:{filters:s},meta:{targetEl:n,kind:"stat",queryGen:k}}),f.count(s).then(function(x){y._destroyed||_&&!y._isCurrentGen(n,k)||h(n,"ln-stat:set-count",{count:x})})}).catch(function(b){y._destroyed||y._reportReconciliationError("stat-query",b,{targetEl:n,kind:"stat"})})},q.prototype._refreshAll=function(e,n){const o=this,s=document.querySelectorAll("[data-ln-table-source],[data-ln-list-source],[data-ln-chart-source],[data-ln-options],[data-ln-stat]");for(let c=0;c<s.length;c++){const f=s[c];let g,y;if(f.hasAttribute("data-ln-table-source")?(g=f.getAttribute("data-ln-table-source"),y="table"):f.hasAttribute("data-ln-list-source")?(g=f.getAttribute("data-ln-list-source"),y="list"):f.hasAttribute("data-ln-chart-source")?(g=f.getAttribute("data-ln-chart-source"),y="chart"):f.hasAttribute("data-ln-options")?(g=f.getAttribute("data-ln-options"),y="options"):f.hasAttribute("data-ln-stat")&&(g=f.getAttribute("data-ln-stat"),y="stat"),!o._owns(g))continue;const b=o.findChildren(),w=b.store;if(y==="table"||y==="list"){const E=y==="table"?"data-ln-table-window":"data-ln-list-window";if(f.hasAttribute(E)){h(f,"ln-"+y+(n?":request-invalidate":":request-revalidate"),{});continue}}if(y==="table"||y==="list"||y==="chart"){const E=o._boundQueries.get(f)||{sort:null,filters:{},search:""},_=se(E,o._currentQuery());if(j(w,b.connector)==="remote"){const D=o._nextQueryGen(f);h(f,"ln-"+y+":set-loading",{loading:!0}),h(b.connectorEl,C(b.connectorEl)+":request-query",{query:_,meta:{targetEl:f,kind:y,offset:_.offset,limit:_.limit,queryGen:D}});continue}const k=P(w,b.connector,j(w,b.connector)),x=k?o._nextQueryGen(f):null;k&&h(b.connectorEl,C(b.connectorEl)+":request-query",{query:_,meta:{targetEl:f,kind:y,offset:_.offset,limit:_.limit,queryGen:x}}),(function(D,I,H,He){w.getAll(_).then(function(T){if(o._destroyed||!o._boundDelivered||H&&!o._isCurrentGen(D,He))return;const Je={data:T.data,total:e&&e.total!==void 0?e.total:T.total,filtered:e&&e.filtered!==void 0?e.filtered:T.filtered,offset:T.offset!==void 0?T.offset:e&&e.offset!==void 0?e.offset:E.offset,queryGen:T.queryGen!==void 0?T.queryGen:e&&e.queryGen!==void 0?e.queryGen:E.queryGen};h(D,"ln-"+I+":set-loading",{loading:!1}),h(D,"ln-"+I+":set-data",Je),o._boundDelivered.set(D,!0)}).catch(function(){})})(f,y,k,x)}else if(y==="options")(function(E){w.getAll({}).then(function(_){o._destroyed||h(E,"ln-options:set-data",{data:_.data})}).catch(function(){})})(f);else if(y==="stat"){const E=f.getAttribute("data-ln-stat-filter");let _=null;if(E){const k=E.indexOf(":");if(k!==-1){const x=E.slice(0,k).trim(),D=E.slice(k+1).trim();x&&(_={},_[x]=[D])}}(function(k,x){w.count(x).then(function(D){o._destroyed||h(k,"ln-stat:set-count",{count:D})}).catch(function(){})})(f,_)}}},q.prototype.destroy=function(){if(!this.dom[r])return;this._destroyed=!0;const e=this;e._handlers&&(e.dom.removeEventListener("ln-data-store:request-remote-sync",e._handlers.sync),e.dom.removeEventListener("ln-data-store:request-page",e._handlers.requestPage),e.dom.removeEventListener("ln-data-coordinator:request-create",e._handlers.reqCreate),e.dom.removeEventListener("ln-data-coordinator:request-update",e._handlers.reqUpdate),e.dom.removeEventListener("ln-data-coordinator:request-delete",e._handlers.reqDelete),e.dom.removeEventListener("ln-data-coordinator:request-bulk-delete",e._handlers.reqBulkDelete),e.dom.removeEventListener("ln-api-queue:send",e._handlers.queueSend),e.dom.removeEventListener("ln-api-queue:failed",e._handlers.queueFailed),e.dom.removeEventListener("ln-data-store:initialized",e._handlers.storeInitialized),e.dom.removeEventListener("ln-websocket-connector:connected",e._handlers.socketConnected),document.removeEventListener("submit",e._handlers.formSubmit),Q.forEach(function(n){e.dom.removeEventListener(n+":fetched",e._handlers.connFetched),e.dom.removeEventListener(n+":created",e._handlers.connCreated),e.dom.removeEventListener(n+":updated",e._handlers.connUpdated),e.dom.removeEventListener(n+":deleted",e._handlers.connDeleted),e.dom.removeEventListener(n+":bulk-deleted",e._handlers.connBulkDeleted),e.dom.removeEventListener(n+":error",e._handlers.connError)}),document.removeEventListener("ln-table:request-data",e._handlers.reqTableData),document.removeEventListener("ln-list:request-data",e._handlers.reqListData),document.removeEventListener("ln-chart:request-data",e._handlers.reqChartData),document.removeEventListener("ln-options:request-data",e._handlers.reqOptions),document.removeEventListener("ln-stat:request-count",e._handlers.reqStat),e.dom.removeEventListener("ln-data-store:ready",e._handlers.refresh),e.dom.removeEventListener("ln-data-store:created",e._handlers.refresh),e.dom.removeEventListener("ln-data-store:updated",e._handlers.refresh),e.dom.removeEventListener("ln-data-store:deleted",e._handlers.refresh),e.dom.removeEventListener("ln-data-store:mutation-error",e._handlers.mutationError),e.dom.removeEventListener("ln-data-store:synced",e._handlers.refreshSynced),e.dom.removeEventListener("ln-data-store:query-changed",e._handlers.refreshQuery),e.dom.removeEventListener("ln-search:change",e._handlers.searchChange),e.dom.removeEventListener("ln-filter:change",e._handlers.filterChange),e.dom.removeEventListener("ln-sort:change",e._handlers.sortChange),e._handlers=null),e._boundQueries=null,e._boundDelivered=null,e._queryGens=null,e._queueQueryRefresh=null,e._mutationReceipts.close(new Error("Data coordinator destroyed")),e._mutationReceipts=null,L.delete(this),W(),delete this.dom[r]},Fe(t,r,q,"ln-data-coordinator",{attributes:S})})()})();