@livenetworks/ashlar 2.0.7 → 2.0.9

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 (213) hide show
  1. package/LICENSE +641 -641
  2. package/components/COMPONENTS.md +1116 -1116
  3. package/components/index.js +81 -81
  4. package/components/ln-accordion/ln-accordion-dev.scss +8 -8
  5. package/components/ln-accordion/ln-accordion.js +1 -1
  6. package/components/ln-accordion/ln-accordion.schema.json +30 -30
  7. package/components/ln-ajax/ln-ajax-dev.scss +8 -8
  8. package/components/ln-ajax/ln-ajax.js +1 -1
  9. package/components/ln-ajax/ln-ajax.schema.json +30 -30
  10. package/components/ln-api-connector/ln-api-connector.js +1 -1
  11. package/components/ln-api-connector/ln-api-connector.schema.json +9 -0
  12. package/components/ln-api-connector/src/ln-api-connector.js +2 -0
  13. package/components/ln-api-queue/ln-api-queue.js +1 -1
  14. package/components/ln-api-queue/ln-api-queue.schema.json +34 -34
  15. package/components/ln-api-queue/src/ln-api-queue.js +3 -13
  16. package/components/ln-autoresize/ln-autoresize-dev.scss +8 -8
  17. package/components/ln-autoresize/ln-autoresize.js +1 -1
  18. package/components/ln-autoresize/ln-autoresize.schema.json +22 -22
  19. package/components/ln-autosave/ln-autosave-dev.scss +13 -13
  20. package/components/ln-autosave/ln-autosave.js +1 -1
  21. package/components/ln-autosave/ln-autosave.schema.json +48 -48
  22. package/components/ln-autosave/src/autosave-model.js +34 -34
  23. package/components/ln-chart/ln-chart.js +1 -1
  24. package/components/ln-chart/ln-chart.schema.json +146 -146
  25. package/components/ln-chart/src/chart-model.js +154 -154
  26. package/components/ln-circular-progress/ln-circular-progress.js +1 -1
  27. package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -42
  28. package/components/ln-confirm/ln-confirm-dev.scss +24 -24
  29. package/components/ln-confirm/ln-confirm.js +1 -1
  30. package/components/ln-confirm/ln-confirm.schema.json +66 -66
  31. package/components/ln-confirm/src/ln-confirm.js +178 -178
  32. package/components/ln-core/attrs.js +13 -0
  33. package/components/ln-core/crypto.js +286 -265
  34. package/components/ln-core/dom.js +115 -115
  35. package/components/ln-core/form.js +146 -136
  36. package/components/ln-core/helpers.js +33 -33
  37. package/components/ln-core/http.js +48 -48
  38. package/components/ln-core/index.js +1 -1
  39. package/components/ln-core/lifecycle.js +5 -0
  40. package/components/ln-core/ln-core.schema.json +3 -2
  41. package/components/ln-core/locale.js +55 -55
  42. package/components/ln-core/matching.js +78 -78
  43. package/components/ln-core/number.js +125 -125
  44. package/components/ln-core/template.js +206 -206
  45. package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -1
  46. package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -50
  47. package/components/ln-couchdb-connector/src/ln-couchdb-connector.js +1 -0
  48. package/components/ln-data-coordinator/README.md +9 -38
  49. package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -8
  50. package/components/ln-data-coordinator/ln-data-coordinator.js +1 -1
  51. package/components/ln-data-coordinator/ln-data-coordinator.schema.json +16 -16
  52. package/components/ln-data-coordinator/src/data-read-policy.js +0 -7
  53. package/components/ln-data-coordinator/src/ln-data-coordinator.js +432 -1308
  54. package/components/ln-data-store/ln-data-store-dev.scss +13 -13
  55. package/components/ln-data-store/ln-data-store.js +1 -1
  56. package/components/ln-data-store/ln-data-store.schema.json +84 -84
  57. package/components/ln-data-store/src/data-store-model.js +184 -184
  58. package/components/ln-data-store/src/ln-data-store.js +1 -1
  59. package/components/ln-date/ln-date.js +1 -1
  60. package/components/ln-date/ln-date.schema.json +92 -92
  61. package/components/ln-date/src/date-model.js +186 -186
  62. package/components/ln-debug/ln-debug.js +1 -1
  63. package/components/ln-debug/ln-debug.schema.json +28 -28
  64. package/components/ln-debug/src/console-sink.js +19 -19
  65. package/components/ln-debug/src/gate.js +95 -95
  66. package/components/ln-debug/src/generated-attributes.js +4 -2
  67. package/components/ln-dropdown/ln-dropdown-dev.scss +13 -13
  68. package/components/ln-dropdown/ln-dropdown.js +1 -1
  69. package/components/ln-dropdown/ln-dropdown.schema.json +90 -90
  70. package/components/ln-editor/ln-editor.js +1 -1
  71. package/components/ln-editor/ln-editor.schema.json +58 -58
  72. package/components/ln-external-links/ln-external-links.js +1 -1
  73. package/components/ln-external-links/ln-external-links.schema.json +18 -18
  74. package/components/ln-fill/ln-fill.js +1 -1
  75. package/components/ln-fill/ln-fill.schema.json +23 -23
  76. package/components/ln-filter/ln-filter.js +1 -1
  77. package/components/ln-filter/ln-filter.schema.json +153 -153
  78. package/components/ln-filter/src/filter-model.js +185 -185
  79. package/components/ln-form/ln-form-dev.scss +8 -8
  80. package/components/ln-form/ln-form.js +1 -1
  81. package/components/ln-form/ln-form.schema.json +6 -0
  82. package/components/ln-form/src/ln-form.js +21 -0
  83. package/components/ln-http/ln-http.js +1 -1
  84. package/components/ln-http/ln-http.schema.json +6 -6
  85. package/components/ln-icon/ln-icon.schema.json +6 -6
  86. package/components/ln-include/ln-include.js +1 -1
  87. package/components/ln-include/ln-include.schema.json +23 -23
  88. package/components/ln-key/ln-key-dev.scss +18 -18
  89. package/components/ln-key/ln-key.js +1 -1
  90. package/components/ln-key/ln-key.schema.json +56 -56
  91. package/components/ln-key/src/ln-key.js +10 -10
  92. package/components/ln-link/ln-link-dev.scss +8 -8
  93. package/components/ln-link/ln-link.js +1 -1
  94. package/components/ln-link/ln-link.schema.json +22 -22
  95. package/components/ln-list/README.md +152 -152
  96. package/components/ln-list/ln-list-dev.scss +8 -8
  97. package/components/ln-list/ln-list.js +1 -1
  98. package/components/ln-list/ln-list.schema.json +166 -166
  99. package/components/ln-modal/ln-modal.js +1 -1
  100. package/components/ln-modal/ln-modal.schema.json +65 -65
  101. package/components/ln-nav/ln-nav.js +1 -1
  102. package/components/ln-nav/ln-nav.schema.json +25 -25
  103. package/components/ln-number/ln-number.js +1 -1
  104. package/components/ln-number/ln-number.schema.json +63 -63
  105. package/components/ln-number/src/ln-number.js +26 -0
  106. package/components/ln-number/src/number-model.js +31 -31
  107. package/components/ln-obfuscator/README.md +60 -60
  108. package/components/ln-obfuscator/ln-obfuscator.js +1 -1
  109. package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -49
  110. package/components/ln-obfuscator/src/ln-obfuscator.js +159 -159
  111. package/components/ln-obfuscator/src/obfuscator-model.js +250 -250
  112. package/components/ln-options/ln-options.js +1 -1
  113. package/components/ln-options/ln-options.schema.json +6 -0
  114. package/components/ln-options/src/ln-options.js +4 -4
  115. package/components/ln-persist/README.md +151 -151
  116. package/components/ln-persist/ln-persist.js +1 -1
  117. package/components/ln-persist/ln-persist.schema.json +28 -28
  118. package/components/ln-persist/src/ln-persist.js +83 -83
  119. package/components/ln-picklist/README.md +230 -230
  120. package/components/ln-picklist/ln-picklist-dev.scss +22 -22
  121. package/components/ln-picklist/ln-picklist.js +1 -1
  122. package/components/ln-picklist/ln-picklist.schema.json +49 -49
  123. package/components/ln-picklist/src/ln-picklist.js +228 -228
  124. package/components/ln-popover/ln-popover-dev.scss +13 -13
  125. package/components/ln-popover/ln-popover.js +1 -1
  126. package/components/ln-popover/ln-popover.schema.json +82 -82
  127. package/components/ln-progress/ln-progress-dev.scss +8 -8
  128. package/components/ln-progress/ln-progress.js +1 -1
  129. package/components/ln-progress/ln-progress.schema.json +40 -40
  130. package/components/ln-router/ln-router.js +1 -1
  131. package/components/ln-router/ln-router.schema.json +76 -76
  132. package/components/ln-scroll/README.md +45 -45
  133. package/components/ln-scroll/ln-scroll.js +1 -1
  134. package/components/ln-scroll/ln-scroll.schema.json +85 -85
  135. package/components/ln-scroll/src/ln-scroll.js +150 -150
  136. package/components/ln-search/README.md +188 -188
  137. package/components/ln-search/ln-search.js +1 -1
  138. package/components/ln-search/ln-search.schema.json +103 -103
  139. package/components/ln-slug/ln-slug.js +1 -1
  140. package/components/ln-slug/ln-slug.schema.json +23 -23
  141. package/components/ln-slug/src/ln-slug.js +25 -1
  142. package/components/ln-sort/ln-sort.js +1 -1
  143. package/components/ln-sort/ln-sort.schema.json +104 -104
  144. package/components/ln-sort/src/ln-sort.js +321 -321
  145. package/components/ln-sort/src/sort-model.js +117 -117
  146. package/components/ln-sortable/ln-sortable-dev.scss +13 -13
  147. package/components/ln-sortable/ln-sortable.js +1 -1
  148. package/components/ln-sortable/ln-sortable.schema.json +36 -36
  149. package/components/ln-stat/ln-stat-dev.scss +8 -8
  150. package/components/ln-stat/ln-stat.js +1 -1
  151. package/components/ln-stat/ln-stat.schema.json +32 -32
  152. package/components/ln-stat/src/stat-model.js +28 -28
  153. package/components/ln-table/ln-table.js +1 -1
  154. package/components/ln-table/ln-table.schema.json +211 -211
  155. package/components/ln-table/src/table-model.js +98 -98
  156. package/components/ln-table-coordinator/ln-table-coordinator.js +1 -1
  157. package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -93
  158. package/components/ln-tabs/ln-tabs.js +1 -1
  159. package/components/ln-tabs/ln-tabs.schema.json +75 -75
  160. package/components/ln-tabs/src/ln-tabs.js +208 -208
  161. package/components/ln-tabs/src/tabs-model.js +82 -82
  162. package/components/ln-time/ln-time-dev.scss +13 -13
  163. package/components/ln-time/ln-time.js +1 -1
  164. package/components/ln-time/ln-time.schema.json +38 -38
  165. package/components/ln-toast/ln-toast.js +1 -1
  166. package/components/ln-toast/ln-toast.schema.json +65 -65
  167. package/components/ln-toggle/ln-toggle.js +1 -1
  168. package/components/ln-toggle/ln-toggle.schema.json +52 -52
  169. package/components/ln-tooltip/ln-tooltip.js +1 -1
  170. package/components/ln-tooltip/ln-tooltip.schema.json +86 -86
  171. package/components/ln-translations/ln-translations.js +1 -1
  172. package/components/ln-translations/ln-translations.schema.json +120 -120
  173. package/components/ln-ui-coordinator/README.md +62 -62
  174. package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -1
  175. package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +28 -28
  176. package/components/ln-ui-coordinator/src/ln-ui-coordinator.js +140 -140
  177. package/components/ln-upload/ln-upload.js +1 -1
  178. package/components/ln-upload/ln-upload.schema.json +193 -193
  179. package/components/ln-upload/src/upload-model.js +78 -78
  180. package/components/ln-validate/ln-validate.js +1 -1
  181. package/components/ln-validate/ln-validate.schema.json +50 -50
  182. package/components/ln-validate/src/validate-model.js +64 -64
  183. package/components/ln-websocket-connector/README.md +166 -166
  184. package/components/ln-websocket-connector/ln-websocket-connector.js +1 -1
  185. package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -29
  186. package/components/ln-websocket-connector/src/ln-websocket-connector.js +283 -279
  187. package/ln-ashlar.html-data.json +15 -8
  188. package/package.json +85 -84
  189. package/theme/brand.css +73 -73
  190. package/theme/components/_confirm.scss +6 -6
  191. package/theme/components/_picklist.scss +3 -3
  192. package/theme/config/_palette.scss +274 -274
  193. package/theme/config/_theme.scss +292 -292
  194. package/theme/config/_tokens.scss +285 -285
  195. package/theme/config/mixins/_index.scss +62 -62
  196. package/theme/config/mixins/_picklist.scss +66 -66
  197. package/theme/ln-ashlar-dev.scss +66 -66
  198. package/theme/ln-ashlar-landing.scss +56 -56
  199. package/theme/ln-ashlar-theme.scss +63 -63
  200. package/theme/presentation/_bento.scss +151 -151
  201. package/theme/presentation/_cta.scss +111 -111
  202. package/theme/presentation/_effects.scss +216 -216
  203. package/theme/presentation/_features.scss +108 -108
  204. package/theme/presentation/_footer.scss +129 -129
  205. package/theme/presentation/_hero.scss +158 -158
  206. package/theme/presentation/_layout.scss +170 -170
  207. package/theme/presentation/_navbar.scss +140 -140
  208. package/theme/presentation/_pricing.scss +262 -262
  209. package/theme/presentation/_stats.scss +87 -87
  210. package/theme/presentation/_testimonials.scss +124 -124
  211. package/theme/presentation/_tokens.scss +39 -39
  212. package/theme/presentation/_typography.scss +163 -163
  213. package/web-types.json +26 -12
@@ -1,193 +1,193 @@
1
- {
2
- "$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
3
- "component": "ln-upload",
4
- "generator": "scripts/sync-ln-schemas.mjs",
5
- "attributes": {
6
- "data-ln-debug": {
7
- "direction": null,
8
- "sources": [
9
- "ln-upload-dev.scss"
10
- ]
11
- },
12
- "data-ln-field": {
13
- "direction": "author",
14
- "sources": [
15
- "src/ln-upload.js"
16
- ]
17
- },
18
- "data-ln-progress": {
19
- "direction": "both",
20
- "sources": [
21
- "src/ln-upload.js"
22
- ]
23
- },
24
- "data-ln-upload": {
25
- "direction": null,
26
- "sources": [
27
- "ln-upload-dev.scss",
28
- "ln-upload.scss",
29
- "src/ln-upload.js"
30
- ],
31
- "type": "string",
32
- "fallback": "",
33
- "description": "Endpoint URL for file uploads"
34
- },
35
- "data-ln-upload-accept": {
36
- "direction": "author",
37
- "sources": [
38
- "src/ln-upload.js"
39
- ],
40
- "type": "string",
41
- "description": "Comma-separated list of allowed file extensions or MIME types"
42
- },
43
- "data-ln-upload-action": {
44
- "direction": "author",
45
- "sources": [
46
- "src/ln-upload.js"
47
- ],
48
- "type": "enum",
49
- "values": [
50
- "remove",
51
- "retry"
52
- ],
53
- "description": "Action button within upload item"
54
- },
55
- "data-ln-upload-delete": {
56
- "direction": null,
57
- "sources": [
58
- "src/ln-upload.js"
59
- ],
60
- "type": "string",
61
- "fallback": "",
62
- "description": "Endpoint URL pattern for deleting uploaded files"
63
- },
64
- "data-ln-upload-dict": {
65
- "direction": null,
66
- "sources": [
67
- "ln-upload.scss",
68
- "src/ln-upload.js"
69
- ],
70
- "type": "string",
71
- "description": "Dictionary key prefix mapping for translatable upload messages"
72
- },
73
- "data-ln-upload-ext": {
74
- "direction": "runtime",
75
- "sources": [
76
- "src/ln-upload.js"
77
- ],
78
- "type": "string",
79
- "description": "Normalized file extension"
80
- },
81
- "data-ln-upload-file-field": {
82
- "direction": null,
83
- "sources": [
84
- "src/ln-upload.js"
85
- ],
86
- "type": "string",
87
- "description": "Form data field name used for file payloads"
88
- },
89
- "data-ln-upload-id": {
90
- "direction": "both",
91
- "sources": [
92
- "src/ln-upload.js"
93
- ],
94
- "type": "string",
95
- "description": "Server-assigned file identifier for completed upload"
96
- },
97
- "data-ln-upload-ids-field": {
98
- "direction": null,
99
- "sources": [
100
- "src/ln-upload.js"
101
- ],
102
- "type": "string",
103
- "description": "Form field name for submitting uploaded file IDs"
104
- },
105
- "data-ln-upload-item": {
106
- "direction": "both",
107
- "sources": [
108
- "ln-upload.scss",
109
- "src/ln-upload.js"
110
- ],
111
- "type": "marker",
112
- "description": "Container element for an individual file upload item"
113
- },
114
- "data-ln-upload-list": {
115
- "direction": "author",
116
- "sources": [
117
- "ln-upload-dev.scss",
118
- "src/ln-upload.js"
119
- ],
120
- "type": "marker",
121
- "description": "Container element holding rendered upload items"
122
- },
123
- "data-ln-upload-local-id": {
124
- "direction": "both",
125
- "sources": [
126
- "src/ln-upload.js"
127
- ],
128
- "type": "string",
129
- "description": "Client-generated unique ID for tracking file item in DOM"
130
- },
131
- "data-ln-upload-max-files": {
132
- "direction": null,
133
- "sources": [
134
- "src/ln-upload.js"
135
- ],
136
- "type": "integer",
137
- "fallback": 0,
138
- "min": 0,
139
- "description": "Maximum number of files allowed in upload queue (0 for unlimited)"
140
- },
141
- "data-ln-upload-max-size": {
142
- "direction": null,
143
- "sources": [
144
- "src/ln-upload.js"
145
- ],
146
- "type": "integer",
147
- "fallback": 0,
148
- "min": 0,
149
- "description": "Maximum allowed file size in bytes (0 for unlimited)"
150
- },
151
- "data-ln-upload-progress": {
152
- "direction": null,
153
- "sources": [
154
- "ln-upload.scss"
155
- ]
156
- },
157
- "data-ln-upload-size": {
158
- "direction": "author",
159
- "sources": [
160
- "src/ln-upload.js"
161
- ],
162
- "type": "integer",
163
- "min": 0,
164
- "description": "File size in bytes"
165
- },
166
- "data-ln-upload-state": {
167
- "direction": "runtime",
168
- "sources": [
169
- "ln-upload.scss",
170
- "src/ln-upload.js"
171
- ],
172
- "type": "enum",
173
- "values": [
174
- "ready",
175
- "dragover",
176
- "pending",
177
- "uploading",
178
- "success",
179
- "error"
180
- ],
181
- "description": "Runtime status of dropzone or individual upload item"
182
- },
183
- "data-ln-upload-zone": {
184
- "direction": "author",
185
- "sources": [
186
- "ln-upload-dev.scss",
187
- "src/ln-upload.js"
188
- ],
189
- "type": "marker",
190
- "description": "Designates container as dropzone for drag-and-drop file uploads"
191
- }
192
- }
193
- }
1
+ {
2
+ "$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
3
+ "component": "ln-upload",
4
+ "generator": "scripts/sync-ln-schemas.mjs",
5
+ "attributes": {
6
+ "data-ln-debug": {
7
+ "direction": null,
8
+ "sources": [
9
+ "ln-upload-dev.scss"
10
+ ]
11
+ },
12
+ "data-ln-field": {
13
+ "direction": "author",
14
+ "sources": [
15
+ "src/ln-upload.js"
16
+ ]
17
+ },
18
+ "data-ln-progress": {
19
+ "direction": "both",
20
+ "sources": [
21
+ "src/ln-upload.js"
22
+ ]
23
+ },
24
+ "data-ln-upload": {
25
+ "direction": null,
26
+ "sources": [
27
+ "ln-upload-dev.scss",
28
+ "ln-upload.scss",
29
+ "src/ln-upload.js"
30
+ ],
31
+ "type": "string",
32
+ "fallback": "",
33
+ "description": "Endpoint URL for file uploads"
34
+ },
35
+ "data-ln-upload-accept": {
36
+ "direction": "author",
37
+ "sources": [
38
+ "src/ln-upload.js"
39
+ ],
40
+ "type": "string",
41
+ "description": "Comma-separated list of allowed file extensions or MIME types"
42
+ },
43
+ "data-ln-upload-action": {
44
+ "direction": "author",
45
+ "sources": [
46
+ "src/ln-upload.js"
47
+ ],
48
+ "type": "enum",
49
+ "values": [
50
+ "remove",
51
+ "retry"
52
+ ],
53
+ "description": "Action button within upload item"
54
+ },
55
+ "data-ln-upload-delete": {
56
+ "direction": null,
57
+ "sources": [
58
+ "src/ln-upload.js"
59
+ ],
60
+ "type": "string",
61
+ "fallback": "",
62
+ "description": "Endpoint URL pattern for deleting uploaded files"
63
+ },
64
+ "data-ln-upload-dict": {
65
+ "direction": null,
66
+ "sources": [
67
+ "ln-upload.scss",
68
+ "src/ln-upload.js"
69
+ ],
70
+ "type": "string",
71
+ "description": "Dictionary key prefix mapping for translatable upload messages"
72
+ },
73
+ "data-ln-upload-ext": {
74
+ "direction": "runtime",
75
+ "sources": [
76
+ "src/ln-upload.js"
77
+ ],
78
+ "type": "string",
79
+ "description": "Normalized file extension"
80
+ },
81
+ "data-ln-upload-file-field": {
82
+ "direction": null,
83
+ "sources": [
84
+ "src/ln-upload.js"
85
+ ],
86
+ "type": "string",
87
+ "description": "Form data field name used for file payloads"
88
+ },
89
+ "data-ln-upload-id": {
90
+ "direction": "both",
91
+ "sources": [
92
+ "src/ln-upload.js"
93
+ ],
94
+ "type": "string",
95
+ "description": "Server-assigned file identifier for completed upload"
96
+ },
97
+ "data-ln-upload-ids-field": {
98
+ "direction": null,
99
+ "sources": [
100
+ "src/ln-upload.js"
101
+ ],
102
+ "type": "string",
103
+ "description": "Form field name for submitting uploaded file IDs"
104
+ },
105
+ "data-ln-upload-item": {
106
+ "direction": "both",
107
+ "sources": [
108
+ "ln-upload.scss",
109
+ "src/ln-upload.js"
110
+ ],
111
+ "type": "marker",
112
+ "description": "Container element for an individual file upload item"
113
+ },
114
+ "data-ln-upload-list": {
115
+ "direction": "author",
116
+ "sources": [
117
+ "ln-upload-dev.scss",
118
+ "src/ln-upload.js"
119
+ ],
120
+ "type": "marker",
121
+ "description": "Container element holding rendered upload items"
122
+ },
123
+ "data-ln-upload-local-id": {
124
+ "direction": "both",
125
+ "sources": [
126
+ "src/ln-upload.js"
127
+ ],
128
+ "type": "string",
129
+ "description": "Client-generated unique ID for tracking file item in DOM"
130
+ },
131
+ "data-ln-upload-max-files": {
132
+ "direction": null,
133
+ "sources": [
134
+ "src/ln-upload.js"
135
+ ],
136
+ "type": "integer",
137
+ "fallback": 0,
138
+ "min": 0,
139
+ "description": "Maximum number of files allowed in upload queue (0 for unlimited)"
140
+ },
141
+ "data-ln-upload-max-size": {
142
+ "direction": null,
143
+ "sources": [
144
+ "src/ln-upload.js"
145
+ ],
146
+ "type": "integer",
147
+ "fallback": 0,
148
+ "min": 0,
149
+ "description": "Maximum allowed file size in bytes (0 for unlimited)"
150
+ },
151
+ "data-ln-upload-progress": {
152
+ "direction": null,
153
+ "sources": [
154
+ "ln-upload.scss"
155
+ ]
156
+ },
157
+ "data-ln-upload-size": {
158
+ "direction": "author",
159
+ "sources": [
160
+ "src/ln-upload.js"
161
+ ],
162
+ "type": "integer",
163
+ "min": 0,
164
+ "description": "File size in bytes"
165
+ },
166
+ "data-ln-upload-state": {
167
+ "direction": "runtime",
168
+ "sources": [
169
+ "ln-upload.scss",
170
+ "src/ln-upload.js"
171
+ ],
172
+ "type": "enum",
173
+ "values": [
174
+ "ready",
175
+ "dragover",
176
+ "pending",
177
+ "uploading",
178
+ "success",
179
+ "error"
180
+ ],
181
+ "description": "Runtime status of dropzone or individual upload item"
182
+ },
183
+ "data-ln-upload-zone": {
184
+ "direction": "author",
185
+ "sources": [
186
+ "ln-upload-dev.scss",
187
+ "src/ln-upload.js"
188
+ ],
189
+ "type": "marker",
190
+ "description": "Designates container as dropzone for drag-and-drop file uploads"
191
+ }
192
+ }
193
+ }
@@ -1,78 +1,78 @@
1
- /**
2
- * Parses accept string into normalized array of lowercase extensions and mime types.
3
- * @param {string|null|undefined} acceptStr
4
- * @returns {string[]|null}
5
- */
6
- export function parseAcceptExtensions(acceptStr) {
7
- if (!acceptStr) return null;
8
- const parts = String(acceptStr)
9
- .split(',')
10
- .map(s => s.trim().toLowerCase())
11
- .filter(Boolean)
12
- .map(s => (s.startsWith('.') ? s.slice(1) : s));
13
- return parts.length ? parts : null;
14
- }
15
-
16
- /**
17
- * Extracts file extension from filename.
18
- * @param {string|null|undefined} filename
19
- * @returns {string}
20
- */
21
- export function getFileExtension(filename) {
22
- if (!filename || typeof filename !== 'string' || !filename.includes('.')) return '';
23
- return filename.split('.').pop().toLowerCase();
24
- }
25
-
26
- /**
27
- * Evaluates whether a file matches allowed extensions or mime types.
28
- * @param {{ name?: string, type?: string }} file
29
- * @param {string[]|null} allowedExts
30
- * @returns {boolean}
31
- */
32
- export function isFileTypeAllowed(file, allowedExts) {
33
- if (!allowedExts || allowedExts.length === 0) return true;
34
- if (!file) return false;
35
-
36
- const ext = getFileExtension(file.name);
37
- const mime = String(file.type || '').toLowerCase();
38
-
39
- return allowedExts.some(allowed => {
40
- if (allowed.includes('/')) {
41
- if (allowed.endsWith('/*')) {
42
- const prefix = allowed.slice(0, -1);
43
- return mime.startsWith(prefix);
44
- }
45
- return mime === allowed;
46
- }
47
- return ext === allowed;
48
- });
49
- }
50
-
51
- /**
52
- * Formats byte size into human-readable unit with locale formatting.
53
- * @param {number} bytes
54
- * @param {string} [locale='en']
55
- * @param {Record<string, string>} [dict={}]
56
- * @returns {string}
57
- */
58
- export function formatFileSize(bytes, locale = 'en', dict = {}) {
59
- if (typeof bytes !== 'number' || isNaN(bytes) || bytes === 0) {
60
- return '0 ' + (dict['unit-b'] || 'B');
61
- }
62
- const k = 1024;
63
- const sizes = [
64
- dict['unit-b'] || 'B',
65
- dict['unit-kb'] || 'KB',
66
- dict['unit-mb'] || 'MB',
67
- dict['unit-gb'] || 'GB'
68
- ];
69
- const i = Math.floor(Math.log(bytes) / Math.log(k));
70
- const unitIndex = Math.min(i, sizes.length - 1);
71
- const num = bytes / Math.pow(k, unitIndex);
72
- const formattedNum = new Intl.NumberFormat(locale, {
73
- maximumFractionDigits: 1,
74
- minimumFractionDigits: 0
75
- }).format(num);
76
-
77
- return formattedNum + ' ' + sizes[unitIndex];
78
- }
1
+ /**
2
+ * Parses accept string into normalized array of lowercase extensions and mime types.
3
+ * @param {string|null|undefined} acceptStr
4
+ * @returns {string[]|null}
5
+ */
6
+ export function parseAcceptExtensions(acceptStr) {
7
+ if (!acceptStr) return null;
8
+ const parts = String(acceptStr)
9
+ .split(',')
10
+ .map(s => s.trim().toLowerCase())
11
+ .filter(Boolean)
12
+ .map(s => (s.startsWith('.') ? s.slice(1) : s));
13
+ return parts.length ? parts : null;
14
+ }
15
+
16
+ /**
17
+ * Extracts file extension from filename.
18
+ * @param {string|null|undefined} filename
19
+ * @returns {string}
20
+ */
21
+ export function getFileExtension(filename) {
22
+ if (!filename || typeof filename !== 'string' || !filename.includes('.')) return '';
23
+ return filename.split('.').pop().toLowerCase();
24
+ }
25
+
26
+ /**
27
+ * Evaluates whether a file matches allowed extensions or mime types.
28
+ * @param {{ name?: string, type?: string }} file
29
+ * @param {string[]|null} allowedExts
30
+ * @returns {boolean}
31
+ */
32
+ export function isFileTypeAllowed(file, allowedExts) {
33
+ if (!allowedExts || allowedExts.length === 0) return true;
34
+ if (!file) return false;
35
+
36
+ const ext = getFileExtension(file.name);
37
+ const mime = String(file.type || '').toLowerCase();
38
+
39
+ return allowedExts.some(allowed => {
40
+ if (allowed.includes('/')) {
41
+ if (allowed.endsWith('/*')) {
42
+ const prefix = allowed.slice(0, -1);
43
+ return mime.startsWith(prefix);
44
+ }
45
+ return mime === allowed;
46
+ }
47
+ return ext === allowed;
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Formats byte size into human-readable unit with locale formatting.
53
+ * @param {number} bytes
54
+ * @param {string} [locale='en']
55
+ * @param {Record<string, string>} [dict={}]
56
+ * @returns {string}
57
+ */
58
+ export function formatFileSize(bytes, locale = 'en', dict = {}) {
59
+ if (typeof bytes !== 'number' || isNaN(bytes) || bytes === 0) {
60
+ return '0 ' + (dict['unit-b'] || 'B');
61
+ }
62
+ const k = 1024;
63
+ const sizes = [
64
+ dict['unit-b'] || 'B',
65
+ dict['unit-kb'] || 'KB',
66
+ dict['unit-mb'] || 'MB',
67
+ dict['unit-gb'] || 'GB'
68
+ ];
69
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
70
+ const unitIndex = Math.min(i, sizes.length - 1);
71
+ const num = bytes / Math.pow(k, unitIndex);
72
+ const formattedNum = new Intl.NumberFormat(locale, {
73
+ maximumFractionDigits: 1,
74
+ minimumFractionDigits: 0
75
+ }).format(num);
76
+
77
+ return formattedNum + ' ' + sizes[unitIndex];
78
+ }
@@ -1 +1 @@
1
- (function(){"use strict";function q(){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 _(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===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 e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let o=null;for(let i=1;i<t.length;i++)if(t[i]&&t[i].nodeType===1){o=t[i];break}if(!_(o))return}e.apply(console,t)}}function A(e,t,n){const o=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,o),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:o}))}function v(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){v(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}const I={};function U(e,t){I[e]=t}function K(e){return I[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=U,window.lnCore.getDataMapper=K);function P(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,v(function(){new MutationObserver(function(){A(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const D={};function G(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];D[n]=t}function Q(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return D[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=G,window.lnCore.getLocaleFallback=Q,window.lnCore.ensureLocaleObserver=P);const S={};function z(e,t){S[e]||(S[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=S[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function T(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let s=0;s<n.length;s++){const a=n[s],r=a.getAttribute("data-ln-field");t[r]!=null&&(a.textContent=t[r])}const o=e.querySelectorAll("[data-ln-attr]");for(let s=0;s<o.length;s++){const a=o[s],r=a.getAttribute("data-ln-attr").split(",");for(let d=0;d<r.length;d++){const c=r[d].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),w=c[1].trim();t[w]!=null&&a.setAttribute(u,t[w])}}const i=e.querySelectorAll("[data-ln-show]");for(let s=0;s<i.length;s++){const a=i[s],r=a.getAttribute("data-ln-show");r in t&&a.classList.toggle("hidden",!t[r])}const l=e.querySelectorAll("[data-ln-class]");for(let s=0;s<l.length;s++){const a=l[s],r=a.getAttribute("data-ln-class").split(",");for(let d=0;d<r.length;d++){const c=r[d].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),w=c[1].trim();w in t&&a.classList.toggle(u,!!t[w])}}return e}function J(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let o=0;o<n.length;o++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[o],t??null),n[o].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)T(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function F(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const l=n.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(s,a){return t[a]!==void 0?t[a]:""}))}const o=function(l,s){return t[s]!==void 0?t[s]:""},i=Array.from(e.querySelectorAll("*"));e.nodeType===1&&i.push(e);for(let l=0;l<i.length;l++){const s=i[l],a=s.attributes;for(let r=0;r<a.length;r++){const d=a[r];d.value.indexOf("{{")!==-1&&s.setAttribute(d.name,d.value.replace(/\{\{\s*(\w+)\s*\}\}/g,o))}}return e}function X(e,t,n,o,i,l){const s={};for(let r=0;r<e.children.length;r++){const d=e.children[r],c=d.getAttribute("data-ln-render-key");c&&(s[c]=d)}const a=document.createDocumentFragment();for(let r=0;r<t.length;r++){const d=t[r],c=String(o(d));let u=s[c];if(u)i(u,d,r);else{const w=z(n,l);if(!w||(F(w,d),u=w.firstElementChild,!u))continue;u.setAttribute("data-ln-render-key",c),i(u,d,r)}a.appendChild(u)}e.textContent="",e.appendChild(a)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=F,window.lnCore.fill=T,window.lnCore.lnFill=J,window.lnCore.renderList=X);function $(e,t,n,o,i){if(!e||t===null)return!0;const l=o||"ln-component",s=e.type;if(s==="trigger"||s==="marker"||s==="string"||s==="list"||!s||t===""&&e.fallback!==void 0)return!0;const a=r=>{i?console.warn(r,i):console.warn(r)};if(s==="boolean"){const r=t.trim().toLowerCase();return r!==""&&r!=="true"&&r!=="false"&&r!=="1"&&r!=="0"?(a(`[${l}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(s==="enum"){const r=e.values||[];return r.includes(t)?!0:(a(`[${l}] Invalid value "${t}" for attribute "${n}". Allowed: ${r.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(s==="integer"){if(!/^-?\d+$/.test(t))return a(`[${l}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const r=parseInt(t,10);return e.min!==void 0&&r<e.min?(a(`[${l}] Value ${r} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&r>e.max?(a(`[${l}] Value ${r} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(s==="float")return isNaN(Number(t))?(a(`[${l}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(s==="json")try{return JSON.parse(t),!0}catch(r){return a(`[${l}] Invalid JSON for attribute "${n}": ${r.message}. Fallback: ${e.fallback}.`),!1}return!0}function Y(e){const t={};for(const n in e){const o=e[n];o&&o.effect&&(t[n]=o.effect)}return Object.keys(t).length?t:null}function Z(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}function E(e,t,n,o){if(e.nodeType!==1)return;const l=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",s=Array.from(e.querySelectorAll(l));e.matches&&e.matches(l)&&s.push(e);for(const a of s)if(!a[n]){window.lnCore._persistSink&&a.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(a,t);try{a[n]=new o(a)}catch(r){console.error("["+n+"] init failed",a,r)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function ee(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function te(e){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(e):setTimeout(e,0)):e()}function V(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function ne(e){const t=V(),n=e.observed||[];for(let o=0;o<n.length;o++){const i=n[o];t.byAttr.has(i)||t.byAttr.set(i,[]),t.byAttr.get(i).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const o in e.attributes){t.byDeclaredAttr.has(o)||t.byDeclaredAttr.set(o,[]);const i=t.byDeclaredAttr.get(o);i.some(l=>l.componentTag===e.componentTag)||i.push({spec:e.attributes[o],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const o=Z(e);if(o===null)t.reactiveWildcard.push(e);else for(const i of o)t.byReactive.has(i)||t.byReactive.set(i,[]),t.byReactive.get(i).push(e)}e.persist&&t.persist.push(e)}function M(e,t,n,o){for(let i=0;i<e.length;i++){const l=e[i];if(!t[l.attribute])continue;const s=l.effects&&l.effects[n];s?s(t,n,o):l.onAttrChange&&(!l.declared||l.declared.has(n))&&l.onAttrChange(t,n,o)}}function oe(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const o=V(),i=o.byAttr.get(n);if(q()&&o.byDeclaredAttr&&o.byDeclaredAttr.has(n)&&_(t)){const l=o.byDeclaredAttr.get(n),s=t.getAttribute(n);for(let a=0;a<l.length;a++)$(l[a].spec,s,n,l[a].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||i)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const l=o.byReactive.get(n);l&&M(l,t,n,e.oldValue),o.reactiveWildcard.length&&M(o.reactiveWildcard,t,n,e.oldValue)}if(i)for(let l=0;l<i.length;l++){const s=i[l];if(s.handler){s.handler(t,n,e.oldValue);continue}s.onAttributeChange&&t[s.attribute]?s.onAttributeChange(t,n):(E(t,s.selector,s.attribute,s.ComponentFn),s.onInit&&s.onInit(t))}}function re(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,v(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{oe(t[n])}catch(o){console.error("[ln-core] mutation handler failed",t[n].target,o)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function B(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function ie(e){const t=B();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const o=t[n];if(o.onSubtreeChange){const i=o.query,l=e.target.nodeType===1?e.target.matches(i)?e.target:e.target.closest(i):e.target.parentElement?e.target.parentElement.closest(i):null;l&&o.onSubtreeChange(l,e)}}for(let n=0;n<e.addedNodes.length;n++){const o=e.addedNodes[n];if(o.nodeType===1)for(let i=0;i<t.length;i++){const l=t[i];E(o,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(o)}}for(let n=0;n<e.removedNodes.length;n++){const o=e.removedNodes[n];if(o.nodeType===1)for(let i=0;i<t.length;i++){const l=t[i],s=l.query,a=Array.from(o.querySelectorAll(s));o.matches&&o.matches(s)&&a.push(o);for(let r=0;r<a.length;r++){const d=a[r];if(!document.contains(d)){const c=d[l.attribute];if(c&&typeof c.destroy=="function")try{c.destroy()}catch(u){console.error("["+l.attribute+"] destroy failed",d,u)}delete d[l.attribute]}}}}}}function le(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,v(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const o=t[n];if(o.type==="childList")try{ie(o)}catch(i){console.error("[ln-core] lifecycle handler failed",o.target,i)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function se(e,t,n,o,i={}){const l=i.extraAttributes||[],s=i.onAttributeChange||null,a=i.onSubtreeChange||null,r=i.onInit||null,d=i.onAttrChange||null,c=i.effects||null,u=i.attributes||null,w=u?Y(u):c,g=u?new Set(Object.keys(u)):null,b=i.persist||null;function f(O){const m=O||document.body;if(E(m,e,t,n),u&&q())for(const C in u){const me=u[C],k=Array.from(m.querySelectorAll("["+C+"]"));m.matches&&m.matches("["+C+"]")&&k.push(m);for(let R=0;R<k.length;R++){const x=k[R];_(x)&&$(me,x.getAttribute(C),C,o,x)}}r&&r(m)}const h=[];if(e.indexOf("[")!==-1){const O=/\[([\w-]+)/g;let m;for(;(m=O.exec(e))!==null;)h.push(m[1])}else h.push(e);ne({selector:e,attribute:t,componentTag:o,attributes:u,ComponentFn:n,onInit:r,observed:h.concat(l),onAttributeChange:s,onAttrChange:d,effects:w,declared:g,persist:b}),re();const y=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";B().push({selector:e,attribute:t,ComponentFn:n,onInit:r,onSubtreeChange:a,query:y}),le(),window[t]=f;function H(){ee()>0?te(function(){f(document.body)}):f(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",H):H(),f}function N(e){return(e||"").replace(/^#/,"")}function L(e){const t=e===void 0?location.hash:e,n={},o=N(t);if(!o)return n;const i=o.split("&");for(let l=0;l<i.length;l++){const s=i[l];if(!s)continue;const a=s.indexOf(":"),r=a>-1?s.slice(0,a):s,d=a>-1?s.slice(a+1):"";if(r)try{n[r]=decodeURIComponent(d)}catch{n[r]=d}}return n}function ae(e){if(!e)return null;const t=L();return e in t?t[e]:null}function de(e,t){if(!e)return;const n=L();t==null?delete n[e]:n[e]=String(t);const i=Object.keys(n).map(function(l){const s=n[l];return s===""?l:l+":"+encodeURIComponent(s)}).join("&");N(location.hash)!==i&&(location.hash=i)}function ce(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function ue(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const o=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return o?t?o+"-"+t:o:t||null}function fe(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function he(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function we(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function be(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),o=e.slice(t+1),i=o?o.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:n,values:i}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=L,window.lnCore.hashGet=ae,window.lnCore.hashSet=de,window.lnCore.hashLinkClick=ce,window.lnCore.resolveHashNamespace=ue,window.lnCore.hashSortEncode=fe,window.lnCore.hashSortDecode=he,window.lnCore.hashFilterEncode=we,window.lnCore.hashFilterDecode=be);const j={required:"valueMissing",typeMismatch:"typeMismatch",tooShort:"tooShort",tooLong:"tooLong",patternMismatch:"patternMismatch",rangeUnderflow:"rangeUnderflow",rangeOverflow:"rangeOverflow"};function W(e,t=0){return e?!!(e.valid&&t===0):t===0}function ge(e){return e.type==="checkbox"||e.type==="radio"?!!e.checked:!!(e.value&&e.value.trim()!=="")}function pe(e,t){const n=[];if(e){const o=Object.keys(j);for(let i=0;i<o.length;i++){const l=o[i],s=j[l];e[s]&&n.push(l)}}if(t){const o=Array.from(t);for(let i=0;i<o.length;i++)o[i]&&n.indexOf(o[i])===-1&&n.push(o[i])}return n}(function(){const e="data-ln-validate",t="lnValidate",n="data-ln-validate-errors",o="data-ln-validate-error",i="ln-validate-valid",l="ln-validate-invalid";if(window[t]!==void 0)return;const s={"data-ln-validate":{type:"marker",description:"Activates validation on form input or field"},"data-ln-validate-errors":{type:"marker",description:"Container element holding validation error message elements"},"data-ln-validate-error":{type:"string",description:"Identifies error message template for a specific validation rule"}};function a(r){this.dom=r,this._touched=!1,this._customErrors=new Set;const d=this,c=r.tagName,u=r.type,w=c==="SELECT"||u==="checkbox"||u==="radio";this._onInput=function(){d._touched=!0,d.validate()},this._onChange=function(){d._touched=!0,d.validate()},this._onSetCustom=function(b){const f=b.detail&&b.detail.error;if(!f)return;d._customErrors.add(f),d._touched=!0;const h=r.closest(".form-element");if(h){const p=h.querySelector("["+o+'="'+f+'"]');p&&p.classList.remove("hidden")}r.classList.remove(i),r.classList.add(l),r.setAttribute("aria-invalid","true")},this._onClearCustom=function(b){const f=b.detail&&b.detail.error,h=r.closest(".form-element");if(f){if(d._customErrors.delete(f),h){const p=h.querySelector("["+o+'="'+f+'"]');p&&p.classList.add("hidden")}}else d._customErrors.forEach(function(p){if(h){const y=h.querySelector("["+o+'="'+p+'"]');y&&y.classList.add("hidden")}}),d._customErrors.clear();d._touched&&d.validate()},w||r.addEventListener("input",this._onInput),r.addEventListener("change",this._onChange),r.addEventListener("ln-validate:set-custom",this._onSetCustom),r.addEventListener("ln-validate:clear-custom",this._onClearCustom);const g=r.form;return g&&(g.hasAttribute("novalidate")||g.setAttribute("novalidate",""),this._onFormReset=function(){d.reset()},this._onValidateRequest=function(b){d._touched=!0,!d.validate()&&b.detail&&b.detail.invalidFields&&b.detail.invalidFields.push(d.dom)},g.addEventListener("reset",this._onFormReset),g.addEventListener("ln-validate:request-validate",this._onValidateRequest),g._lnValidateGateBound||(g._lnValidateGateBound=!0,g.addEventListener("submit",function(b){const f={invalidFields:[]};A(g,"ln-validate:request-validate",f),f.invalidFields.length>0&&(b.preventDefault(),f.invalidFields.sort((h,p)=>h.compareDocumentPosition(p)&Node.DOCUMENT_POSITION_PRECEDING?-1:1),f.invalidFields[0].focus())}))),ge(r)&&(this._touched=!0,this.validate()),this}a.prototype.validate=function(){const r=this.dom,d=r.validity,c=W(d,this._customErrors.size),u=pe(d,this._customErrors),w=r.closest(".form-element");if(w){const b=w.querySelector("["+n+"]");if(b){const f=b.querySelectorAll("["+o+"]");for(let h=0;h<f.length;h++){const p=f[h].getAttribute(o);f[h].classList.toggle("hidden",!u.includes(p))}}}return r.classList.toggle(i,c),r.classList.toggle(l,!c),r.setAttribute("aria-invalid",c?"false":"true"),A(r,c?"ln-validate:valid":"ln-validate:invalid",{target:r,field:r.name,errors:u}),c},a.prototype.reset=function(){this._touched=!1,this._customErrors.clear(),this.dom.classList.remove(i,l),this.dom.removeAttribute("aria-invalid");const r=this.dom.closest(".form-element");if(r){const d=r.querySelectorAll("["+o+"]");for(let c=0;c<d.length;c++)d[c].classList.add("hidden")}},Object.defineProperty(a.prototype,"isValid",{get:function(){return W(this.dom.validity,this._customErrors.size)}}),a.prototype.destroy=function(){if(!this.dom[t])return;this.dom.removeEventListener("input",this._onInput),this.dom.removeEventListener("change",this._onChange),this.dom.removeEventListener("ln-validate:set-custom",this._onSetCustom),this.dom.removeEventListener("ln-validate:clear-custom",this._onClearCustom);const r=this.dom.form;r&&(this._onFormReset&&r.removeEventListener("reset",this._onFormReset),this._onValidateRequest&&r.removeEventListener("ln-validate:request-validate",this._onValidateRequest)),this.dom.classList.remove(i,l),this.dom.removeAttribute("aria-invalid"),delete this.dom[t]},se(e,t,a,"ln-validate",{attributes:s})})()})();
1
+ (function(){"use strict";function q(){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 _(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===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 e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let r=null;for(let i=1;i<t.length;i++)if(t[i]&&t[i].nodeType===1){r=t[i];break}if(!_(r))return}e.apply(console,t)}}function A(e,t,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,r),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:r}))}function y(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){y(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function Z(e){const t=e.querySelector('input[name="_method"]');return((t&&t.value!==""?t.value:e.method)||"").toUpperCase()}function ee(e,t){const n=!!(t&&t.typed),r=t&&t.exclude,i={},s=e.elements,l={};if(n)for(let a=0;a<s.length;a++){const o=s[a];o.name&&o.type==="checkbox"&&!o.disabled&&(l[o.name]=(l[o.name]||0)+1)}for(let a=0;a<s.length;a++){const o=s[a];if(!(!o.name||o.disabled||o.type==="file"||o.type==="submit"||o.type==="button")&&!(r&&o.matches&&o.matches(r)))if(o.type==="checkbox")n&&l[o.name]===1?i[o.name]=o.checked:(i[o.name]||(i[o.name]=[]),o.checked&&i[o.name].push(o.value));else if(o.type==="radio")o.checked&&(i[o.name]=o.value);else if(o.type==="select-multiple"){i[o.name]=[];for(let c=0;c<o.options.length;c++)o.options[c].selected&&i[o.name].push(o.options[c].value)}else if(n&&o.type==="hidden")i[o.name]=o.value;else if(n&&(o.type==="number"||o.type==="range")){const c=Number(o.value);i[o.name]=o.value===""||isNaN(c)?null:c}else i[o.name]=o.value}return i}function te(e){if(typeof e!="string")return!!e;const t=e.trim().toLowerCase();return t!=="false"&&t!=="0"&&t!==""&&t!=="off"&&t!=="no"}function ne(e,t){const n=e.elements,r=[],i={};for(let s=0;s<n.length;s++){const l=n[s];l.name&&l.type==="checkbox"&&(i[l.name]=(i[l.name]||0)+1)}for(let s=0;s<n.length;s++){const l=n[s];if(l.type==="file"||l.type==="submit"||l.type==="button")continue;const a=l.getAttribute("data-ln-fill-as")||l.name;if(!a||!(a in t))continue;const o=t[a];if(l.type==="checkbox"){if(Array.isArray(o))l.checked=o.indexOf(l.value)!==-1;else if(i[l.name]>1){const c=String(o).split(",").map(function(d){return d.trim()});l.checked=c.indexOf(l.value)!==-1}else l.checked=te(o);r.push(l)}else if(l.type==="radio")l.checked=l.value===String(o),r.push(l);else if(l.type==="select-multiple"){if(Array.isArray(o))for(let c=0;c<l.options.length;c++)l.options[c].selected=o.indexOf(l.options[c].value)!==-1;r.push(l)}else l.value=o,l.tagName==="SELECT"&&o!=null&&l.setAttribute("data-ln-value",o),r.push(l)}return r}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.populateForm=ne,window.lnCore.serializeForm=ee,window.lnCore.resolveFormMethod=Z);const D={};function oe(e,t){D[e]=t}function re(e){return D[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=oe,window.lnCore.getDataMapper=re);function ie(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,y(function(){new MutationObserver(function(){A(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const N={};function le(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];N[n]=t}function se(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return N[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=le,window.lnCore.getLocaleFallback=se,window.lnCore.ensureLocaleObserver=ie);const x={};function ae(e,t){x[e]||(x[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=x[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function T(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let l=0;l<n.length;l++){const a=n[l],o=a.getAttribute("data-ln-field");t[o]!=null&&(a.textContent=t[o])}const r=e.querySelectorAll("[data-ln-attr]");for(let l=0;l<r.length;l++){const a=r[l],o=a.getAttribute("data-ln-attr").split(",");for(let c=0;c<o.length;c++){const d=o[c].trim().split(":");if(d.length!==2)continue;const u=d[0].trim(),h=d[1].trim();t[h]!=null&&a.setAttribute(u,t[h])}}const i=e.querySelectorAll("[data-ln-show]");for(let l=0;l<i.length;l++){const a=i[l],o=a.getAttribute("data-ln-show");o in t&&a.classList.toggle("hidden",!t[o])}const s=e.querySelectorAll("[data-ln-class]");for(let l=0;l<s.length;l++){const a=s[l],o=a.getAttribute("data-ln-class").split(",");for(let c=0;c<o.length;c++){const d=o[c].trim().split(":");if(d.length!==2)continue;const u=d[0].trim(),h=d[1].trim();h in t&&a.classList.toggle(u,!!t[h])}}return e}function ce(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let r=0;r<n.length;r++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[r],t??null),n[r].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)T(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function M(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const s=n.currentNode;s.textContent.indexOf("{{")!==-1&&(s.textContent=s.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(l,a){return t[a]!==void 0?t[a]:""}))}const r=function(s,l){return t[l]!==void 0?t[l]:""},i=Array.from(e.querySelectorAll("*"));e.nodeType===1&&i.push(e);for(let s=0;s<i.length;s++){const l=i[s],a=l.attributes;for(let o=0;o<a.length;o++){const c=a[o];c.value.indexOf("{{")!==-1&&l.setAttribute(c.name,c.value.replace(/\{\{\s*(\w+)\s*\}\}/g,r))}}return e}function de(e,t,n,r,i,s){const l={};for(let o=0;o<e.children.length;o++){const c=e.children[o],d=c.getAttribute("data-ln-render-key");d&&(l[d]=c)}const a=document.createDocumentFragment();for(let o=0;o<t.length;o++){const c=t[o],d=String(r(c));let u=l[d];if(u)i(u,c,o);else{const h=ae(n,s);if(!h||(M(h,c),u=h.firstElementChild,!u))continue;u.setAttribute("data-ln-render-key",d),i(u,c,o)}a.appendChild(u)}e.textContent="",e.appendChild(a)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=M,window.lnCore.fill=T,window.lnCore.lnFill=ce,window.lnCore.renderList=de);function S(e,t,n){const r=e.getAttribute(t);return r===null?n:r}function $(e,t,n){const r=parseInt(e.getAttribute(t),10);return isNaN(r)?n:r}function B(e,t,n=!1){const r=e.getAttribute(t);if(r===null)return!!n;const i=r.trim().toLowerCase();return!(i==="false"||i==="0")}function V(e,t){return(e.getAttribute(t)||"").split(",").map(n=>n.trim()).filter(Boolean)}const k=new Map;function j(e,t){const n=(e?e.join("|"):"")+"::"+t;if(k.has(n))return k.get(n);const r=new Set(e||[]),i=function(s,l){const a=s.getAttribute(l);return a!==null&&r.has(a)?a:t};return k.set(n,i),i}function W(e,t,n){const r=parseFloat(e.getAttribute(t));return isNaN(r)?n:r}function U(e,t,n){const r=e.getAttribute(t);if(!r)return n;try{return JSON.parse(r)}catch{return n}}function H(e,t,n,r,i){if(!e||t===null)return!0;const s=r||"ln-component",l=e.type;if(l==="trigger"||l==="marker"||l==="string"||l==="list"||!l||t===""&&e.fallback!==void 0)return!0;const a=o=>{i?console.warn(o,i):console.warn(o)};if(l==="boolean"){const o=t.trim().toLowerCase();return o!==""&&o!=="true"&&o!=="false"&&o!=="1"&&o!=="0"?(a(`[${s}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(l==="enum"){const o=e.values||[];return o.includes(t)?!0:(a(`[${s}] Invalid value "${t}" for attribute "${n}". Allowed: ${o.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(l==="integer"){if(!/^-?\d+$/.test(t))return a(`[${s}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const o=parseInt(t,10);return e.min!==void 0&&o<e.min?(a(`[${s}] Value ${o} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&o>e.max?(a(`[${s}] Value ${o} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(l==="float")return isNaN(Number(t))?(a(`[${s}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(l==="json")try{return JSON.parse(t),!0}catch(o){return a(`[${s}] Invalid JSON for attribute "${n}": ${o.message}. Fallback: ${e.fallback}.`),!1}return!0}function ue(e,t,n){for(const r in n){const[i,s,l]=n[r];Object.defineProperty(e,r,{get:function(){return i(t,s,l)},enumerable:!0,configurable:!0})}return e}function fe(e){const t={};for(const n in e){const r=e[n];if(!r||!r.prop)continue;let i=r.read;if(!i&&r.type)switch(r.type){case"enum":i=j(r.values,r.fallback);break;case"integer":i=$;break;case"float":i=W;break;case"boolean":i=B;break;case"list":i=V;break;case"json":i=U;break;case"string":default:i=S;break}i||(i=S),t[r.prop]=[i,n,r.fallback]}return t}function we(e){const t={};for(const n in e){const r=e[n];r&&r.effect&&(t[n]=r.effect)}return Object.keys(t).length?t:null}function he(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.defineAttrs=ue,window.lnCore.attrSpec=fe,window.lnCore.attrStr=S,window.lnCore.attrInt=$,window.lnCore.attrBool=B,window.lnCore.attrList=V,window.lnCore.attrEnum=j,window.lnCore.attrFloat=W,window.lnCore.attrJson=U);function E(e,t,n,r){if(e.nodeType!==1)return;const s=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",l=Array.from(e.querySelectorAll(s));e.matches&&e.matches(s)&&l.push(e);for(const a of l)if(!a[n]){window.lnCore._persistSink&&a.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(a,t);try{a[n]=new r(a)}catch(o){console.error("["+n+"] init failed",a,o)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function pe(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function be(e){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(e):setTimeout(e,0)):e()}function K(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function me(e){const t=K(),n=e.observed||[];for(let r=0;r<n.length;r++){const i=n[r];t.byAttr.has(i)||t.byAttr.set(i,[]),t.byAttr.get(i).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const r in e.attributes){t.byDeclaredAttr.has(r)||t.byDeclaredAttr.set(r,[]);const i=t.byDeclaredAttr.get(r);i.some(s=>s.componentTag===e.componentTag)||i.push({spec:e.attributes[r],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const r=he(e);if(r===null)t.reactiveWildcard.push(e);else for(const i of r)t.byReactive.has(i)||t.byReactive.set(i,[]),t.byReactive.get(i).push(e)}e.persist&&t.persist.push(e)}function P(e,t,n,r){for(let i=0;i<e.length;i++){const s=e[i];if(!t[s.attribute])continue;const l=s.effects&&s.effects[n];l?l(t,n,r):s.onAttrChange&&(!s.declared||s.declared.has(n))&&s.onAttrChange(t,n,r)}}function ge(e){const t=e.target,n=e.attributeName;if(e.oldValue===t.getAttribute(n))return;const r=K(),i=r.byAttr.get(n);if(q()&&r.byDeclaredAttr&&r.byDeclaredAttr.has(n)&&_(t)){const s=r.byDeclaredAttr.get(n),l=t.getAttribute(n);for(let a=0;a<s.length;a++)H(s[a].spec,l,n,s[a].componentTag,t)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||i)&&window.lnCore._debugSink("attr",n,t,{oldValue:e.oldValue,newValue:t.getAttribute(n)}),n.indexOf("data-ln-")===0){const s=r.byReactive.get(n);s&&P(s,t,n,e.oldValue),r.reactiveWildcard.length&&P(r.reactiveWildcard,t,n,e.oldValue)}if(i)for(let s=0;s<i.length;s++){const l=i[s];if(l.handler){l.handler(t,n,e.oldValue);continue}l.onAttributeChange&&t[l.attribute]?l.onAttributeChange(t,n):(E(t,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(t))}}function Ce(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,y(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{ge(t[n])}catch(r){console.error("[ln-core] mutation handler failed",t[n].target,r)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function G(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function ye(e){const t=G();if(t.length){if(e.target)for(let n=0;n<t.length;n++){const r=t[n];if(r.onSubtreeChange){const i=r.query,s=e.target.nodeType===1?e.target.matches(i)?e.target:e.target.closest(i):e.target.parentElement?e.target.parentElement.closest(i):null;s&&r.onSubtreeChange(s,e)}}for(let n=0;n<e.addedNodes.length;n++){const r=e.addedNodes[n];if(r.nodeType===1)for(let i=0;i<t.length;i++){const s=t[i];E(r,s.selector,s.attribute,s.ComponentFn),s.onInit&&s.onInit(r)}}for(let n=0;n<e.removedNodes.length;n++){const r=e.removedNodes[n];if(r.nodeType===1)for(let i=0;i<t.length;i++){const s=t[i],l=s.query,a=Array.from(r.querySelectorAll(l));r.matches&&r.matches(l)&&a.push(r);for(let o=0;o<a.length;o++){const c=a[o];if(!document.contains(c)){const d=c[s.attribute];if(d&&typeof d.destroy=="function")try{d.destroy()}catch(u){console.error("["+s.attribute+"] destroy failed",c,u)}delete c[s.attribute]}}}}}}function ve(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,y(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++){const r=t[n];if(r.type==="childList")try{ye(r)}catch(i){console.error("[ln-core] lifecycle handler failed",r.target,i)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function J(e,t,n,r,i={}){const s=i.extraAttributes||[],l=i.onAttributeChange||null,a=i.onSubtreeChange||null,o=i.onInit||null,c=i.onAttrChange||null,d=i.effects||null,u=i.attributes||null,h=u?we(u):d,b=u?new Set(Object.keys(u)):null,p=i.persist||null;function f(O){const g=O||document.body;if(E(g,e,t,n),u&&q())for(const C in u){const qe=u[C],R=Array.from(g.querySelectorAll("["+C+"]"));g.matches&&g.matches("["+C+"]")&&R.push(g);for(let I=0;I<R.length;I++){const F=R[I];_(F)&&H(qe,F.getAttribute(C),C,r,F)}}o&&o(g)}const w=[];if(e.indexOf("[")!==-1){const O=/\[([\w-]+)/g;let g;for(;(g=O.exec(e))!==null;)w.push(g[1])}else w.push(e);me({selector:e,attribute:t,componentTag:r,attributes:u,ComponentFn:n,onInit:o,observed:w.concat(s),onAttributeChange:l,onAttrChange:c,effects:h,declared:b,persist:p}),Ce();const v=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";G().push({selector:e,attribute:t,ComponentFn:n,onInit:o,onSubtreeChange:a,query:v}),ve(),window[t]=f,typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerComponent=J);function Y(){pe()>0?be(function(){f(document.body)}):f(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",Y):Y(),f}function Q(e){return(e||"").replace(/^#/,"")}function L(e){const t=e===void 0?location.hash:e,n={},r=Q(t);if(!r)return n;const i=r.split("&");for(let s=0;s<i.length;s++){const l=i[s];if(!l)continue;const a=l.indexOf(":"),o=a>-1?l.slice(0,a):l,c=a>-1?l.slice(a+1):"";if(o)try{n[o]=decodeURIComponent(c)}catch{n[o]=c}}return n}function _e(e){if(!e)return null;const t=L();return e in t?t[e]:null}function Ae(e,t){if(!e)return;const n=L();t==null?delete n[e]:n[e]=String(t);const i=Object.keys(n).map(function(s){const l=n[s];return l===""?s:s+":"+encodeURIComponent(l)}).join("&");Q(location.hash)!==i&&(location.hash=i)}function xe(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function Se(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const r=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return r?t?r+"-"+t:r:t||null}function ke(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function Ee(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function Le(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function Oe(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),r=e.slice(t+1),i=r?r.split(",").map(function(s){try{return decodeURIComponent(s)}catch{return s}}).filter(Boolean):[];return{key:n,values:i}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=L,window.lnCore.hashGet=_e,window.lnCore.hashSet=Ae,window.lnCore.hashLinkClick=xe,window.lnCore.resolveHashNamespace=Se,window.lnCore.hashSortEncode=ke,window.lnCore.hashSortDecode=Ee,window.lnCore.hashFilterEncode=Le,window.lnCore.hashFilterDecode=Oe);function Re(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.uuid=Re);const z={required:"valueMissing",typeMismatch:"typeMismatch",tooShort:"tooShort",tooLong:"tooLong",patternMismatch:"patternMismatch",rangeUnderflow:"rangeUnderflow",rangeOverflow:"rangeOverflow"};function X(e,t=0){return e?!!(e.valid&&t===0):t===0}function Ie(e){return e.type==="checkbox"||e.type==="radio"?!!e.checked:!!(e.value&&e.value.trim()!=="")}function Fe(e,t){const n=[];if(e){const r=Object.keys(z);for(let i=0;i<r.length;i++){const s=r[i],l=z[s];e[l]&&n.push(s)}}if(t){const r=Array.from(t);for(let i=0;i<r.length;i++)r[i]&&n.indexOf(r[i])===-1&&n.push(r[i])}return n}(function(){const e="data-ln-validate",t="lnValidate",n="data-ln-validate-errors",r="data-ln-validate-error",i="ln-validate-valid",s="ln-validate-invalid";if(window[t]!==void 0)return;const l={"data-ln-validate":{type:"marker",description:"Activates validation on form input or field"},"data-ln-validate-errors":{type:"marker",description:"Container element holding validation error message elements"},"data-ln-validate-error":{type:"string",description:"Identifies error message template for a specific validation rule"}};function a(o){this.dom=o,this._touched=!1,this._customErrors=new Set;const c=this,d=o.tagName,u=o.type,h=d==="SELECT"||u==="checkbox"||u==="radio";this._onInput=function(){c._touched=!0,c.validate()},this._onChange=function(){c._touched=!0,c.validate()},this._onSetCustom=function(p){const f=p.detail&&p.detail.error;if(!f)return;c._customErrors.add(f),c._touched=!0;const w=o.closest(".form-element");if(w){const m=w.querySelector("["+r+'="'+f+'"]');m&&m.classList.remove("hidden")}o.classList.remove(i),o.classList.add(s),o.setAttribute("aria-invalid","true")},this._onClearCustom=function(p){const f=p.detail&&p.detail.error,w=o.closest(".form-element");if(f){if(c._customErrors.delete(f),w){const m=w.querySelector("["+r+'="'+f+'"]');m&&m.classList.add("hidden")}}else c._customErrors.forEach(function(m){if(w){const v=w.querySelector("["+r+'="'+m+'"]');v&&v.classList.add("hidden")}}),c._customErrors.clear();c._touched&&c.validate()},h||o.addEventListener("input",this._onInput),o.addEventListener("change",this._onChange),o.addEventListener("ln-validate:set-custom",this._onSetCustom),o.addEventListener("ln-validate:clear-custom",this._onClearCustom);const b=o.form;return b&&(b.hasAttribute("novalidate")||b.setAttribute("novalidate",""),this._onFormReset=function(){c.reset()},this._onValidateRequest=function(p){c._touched=!0,!c.validate()&&p.detail&&p.detail.invalidFields&&p.detail.invalidFields.push(c.dom)},b.addEventListener("reset",this._onFormReset),b.addEventListener("ln-validate:request-validate",this._onValidateRequest),b._lnValidateGateBound||(b._lnValidateGateBound=!0,b.addEventListener("submit",function(p){const f={invalidFields:[]};A(b,"ln-validate:request-validate",f),f.invalidFields.length>0&&(p.preventDefault(),f.invalidFields.sort((w,m)=>w.compareDocumentPosition(m)&Node.DOCUMENT_POSITION_PRECEDING?-1:1),f.invalidFields[0].focus())}))),Ie(o)&&(this._touched=!0,this.validate()),this}a.prototype.validate=function(){const o=this.dom,c=o.validity,d=X(c,this._customErrors.size),u=Fe(c,this._customErrors),h=o.closest(".form-element");if(h){const p=h.querySelector("["+n+"]");if(p){const f=p.querySelectorAll("["+r+"]");for(let w=0;w<f.length;w++){const m=f[w].getAttribute(r);f[w].classList.toggle("hidden",!u.includes(m))}}}return o.classList.toggle(i,d),o.classList.toggle(s,!d),o.setAttribute("aria-invalid",d?"false":"true"),A(o,d?"ln-validate:valid":"ln-validate:invalid",{target:o,field:o.name,errors:u}),d},a.prototype.reset=function(){this._touched=!1,this._customErrors.clear(),this.dom.classList.remove(i,s),this.dom.removeAttribute("aria-invalid");const o=this.dom.closest(".form-element");if(o){const c=o.querySelectorAll("["+r+"]");for(let d=0;d<c.length;d++)c[d].classList.add("hidden")}},Object.defineProperty(a.prototype,"isValid",{get:function(){return X(this.dom.validity,this._customErrors.size)}}),a.prototype.destroy=function(){if(!this.dom[t])return;this.dom.removeEventListener("input",this._onInput),this.dom.removeEventListener("change",this._onChange),this.dom.removeEventListener("ln-validate:set-custom",this._onSetCustom),this.dom.removeEventListener("ln-validate:clear-custom",this._onClearCustom);const o=this.dom.form;o&&(this._onFormReset&&o.removeEventListener("reset",this._onFormReset),this._onValidateRequest&&o.removeEventListener("ln-validate:request-validate",this._onValidateRequest)),this.dom.classList.remove(i,s),this.dom.removeAttribute("aria-invalid"),delete this.dom[t]},J(e,t,a,"ln-validate",{attributes:l})})()})();