arcane-os 0.1.0-dev.5

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 (248) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/COMMERCIAL-LICENSE.md +13 -0
  3. package/LICENSE +661 -0
  4. package/NOTICE +70 -0
  5. package/README.md +448 -0
  6. package/bin/arcane-test.mjs +741 -0
  7. package/bin/arcane.mjs +5 -0
  8. package/docs/architecture.md +234 -0
  9. package/docs/compatibility.md +36 -0
  10. package/docs/event-manager.md +166 -0
  11. package/docs/platform-targets.md +108 -0
  12. package/docs/publishing.md +203 -0
  13. package/docs/reference/README.md +117 -0
  14. package/docs/reference/arcane-ollama.md +288 -0
  15. package/docs/reference/availability-and-normalization.md +123 -0
  16. package/docs/reference/behavioral-testing.md +86 -0
  17. package/docs/reference/cli.md +569 -0
  18. package/docs/reference/core/README.md +62 -0
  19. package/docs/reference/core/arcane-ai-contracts.md +873 -0
  20. package/docs/reference/core/arcane-api.md +601 -0
  21. package/docs/reference/core/arcane-entities.md +65 -0
  22. package/docs/reference/core/arcane-events.md +134 -0
  23. package/docs/reference/core/ollama-module.md +181 -0
  24. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +1909 -0
  25. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +1057 -0
  26. package/docs/reference/core/reference/arcane-api/core-and-events.md +320 -0
  27. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +610 -0
  28. package/docs/reference/core/reference/arcane-api/namespaces.md +1157 -0
  29. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +1423 -0
  30. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +315 -0
  31. package/docs/reference/event-manager.md +957 -0
  32. package/docs/reference/inventory/package-api.json +2632 -0
  33. package/docs/reference/inventory/runtime-components.json +934 -0
  34. package/docs/reference/inventory/runtime-entities.json +26 -0
  35. package/docs/reference/inventory/runtime-modules.json +1249 -0
  36. package/docs/reference/protocols.md +242 -0
  37. package/docs/reference/runtime-components.md +1098 -0
  38. package/docs/reference/runtime-entities.md +303 -0
  39. package/docs/reference/runtime-modules.md +2010 -0
  40. package/docs/reference/sdk-api.md +4901 -0
  41. package/docs/roadmap.md +79 -0
  42. package/docs/work-amplification.md +124 -0
  43. package/node_modules/event-pubsub/CHANGELOG.md +55 -0
  44. package/node_modules/event-pubsub/MIGRATION.md +70 -0
  45. package/node_modules/event-pubsub/README.md +363 -0
  46. package/node_modules/event-pubsub/SECURITY.md +37 -0
  47. package/node_modules/event-pubsub/index.js +141 -0
  48. package/node_modules/event-pubsub/licence +21 -0
  49. package/node_modules/event-pubsub/package.json +59 -0
  50. package/node_modules/strong-type/README.md +408 -0
  51. package/node_modules/strong-type/assets/strong-type-header.png +0 -0
  52. package/node_modules/strong-type/index.js +1151 -0
  53. package/node_modules/strong-type/licence +21 -0
  54. package/node_modules/strong-type/node.js +125 -0
  55. package/node_modules/strong-type/package.json +61 -0
  56. package/package.json +95 -0
  57. package/runtime/ARCANE_RUNTIME_RELEASE.json +791 -0
  58. package/runtime/arcane/components/app-bar.html +468 -0
  59. package/runtime/arcane/components/assistant-panel.html +715 -0
  60. package/runtime/arcane/components/calculator.html +8 -0
  61. package/runtime/arcane/components/chart.html +655 -0
  62. package/runtime/arcane/components/chat.html +1225 -0
  63. package/runtime/arcane/components/conversation-view.html +13 -0
  64. package/runtime/arcane/components/dashboard-config.html +341 -0
  65. package/runtime/arcane/components/data-maintenance.html +112 -0
  66. package/runtime/arcane/components/data-view.html +92 -0
  67. package/runtime/arcane/components/directory-picker.html +197 -0
  68. package/runtime/arcane/components/document-inspector.html +252 -0
  69. package/runtime/arcane/components/file-drop.html +264 -0
  70. package/runtime/arcane/components/file-inspector.html +293 -0
  71. package/runtime/arcane/components/file-manager.html +1715 -0
  72. package/runtime/arcane/components/header.html +142 -0
  73. package/runtime/arcane/components/integration-settings.html +14 -0
  74. package/runtime/arcane/components/local-ai-status.html +360 -0
  75. package/runtime/arcane/components/markdown-document.html +1048 -0
  76. package/runtime/arcane/components/markdown-editor.html +360 -0
  77. package/runtime/arcane/components/media-embed.html +8 -0
  78. package/runtime/arcane/components/modal.html +402 -0
  79. package/runtime/arcane/components/output-panel.html +259 -0
  80. package/runtime/arcane/components/preferences-form.html +135 -0
  81. package/runtime/arcane/components/record-timeline.html +105 -0
  82. package/runtime/arcane/components/relationship-board.html +116 -0
  83. package/runtime/arcane/components/screen-capture.html +8 -0
  84. package/runtime/arcane/components/source-code-viewer.html +441 -0
  85. package/runtime/arcane/components/source-explanation.html +124 -0
  86. package/runtime/arcane/components/speech.html +365 -0
  87. package/runtime/arcane/components/summary-strip.html +177 -0
  88. package/runtime/arcane/components/table.html +77 -0
  89. package/runtime/arcane/components/task-progress.html +282 -0
  90. package/runtime/arcane/components/terminal-workspace.html +65 -0
  91. package/runtime/arcane/components/theme-editor.html +41 -0
  92. package/runtime/arcane/components/theme-switcher.html +46 -0
  93. package/runtime/arcane/components/unified-inbox.html +20 -0
  94. package/runtime/arcane/components/voice-transcription.html +476 -0
  95. package/runtime/arcane/components/weather-widget.html +8 -0
  96. package/runtime/arcane/components/web-navigator.html +239 -0
  97. package/runtime/arcane/css/communications.css +1 -0
  98. package/runtime/arcane/css/dashboard-config.css +45 -0
  99. package/runtime/arcane/css/document-site.css +981 -0
  100. package/runtime/arcane/css/layout.css +438 -0
  101. package/runtime/arcane/css/primitives.css +321 -0
  102. package/runtime/arcane/css/theme.css +112 -0
  103. package/runtime/arcane/css/utility-workspace.css +1 -0
  104. package/runtime/arcane/entities/ApiModelRecord.js +20 -0
  105. package/runtime/arcane/entities/Calculation.js +13 -0
  106. package/runtime/arcane/entities/Chat.js +581 -0
  107. package/runtime/arcane/entities/CommunicationMessage.js +29 -0
  108. package/runtime/arcane/entities/CommunicationThread.js +21 -0
  109. package/runtime/arcane/entities/Document.js +10 -0
  110. package/runtime/arcane/entities/File.js +143 -0
  111. package/runtime/arcane/entities/Image.js +135 -0
  112. package/runtime/arcane/entities/IntentEnvelope.js +834 -0
  113. package/runtime/arcane/entities/Preference.js +83 -0
  114. package/runtime/arcane/entities/TWiNPolicyDecision.js +1092 -0
  115. package/runtime/arcane/entities/TerminalSession.js +46 -0
  116. package/runtime/arcane/entities/Theme.js +107 -0
  117. package/runtime/arcane/entities/User.js +1046 -0
  118. package/runtime/arcane/entities/Weather.js +23 -0
  119. package/runtime/arcane/img/arcane-os-everywhere.png +0 -0
  120. package/runtime/arcane/img/arrow-left.png +0 -0
  121. package/runtime/arcane/img/arrow-right.png +0 -0
  122. package/runtime/arcane/img/doc.svg +5 -0
  123. package/runtime/arcane/img/folder.svg +4 -0
  124. package/runtime/arcane/img/image.svg +5 -0
  125. package/runtime/arcane/img/refresh.png +0 -0
  126. package/runtime/arcane/img/send.svg +9 -0
  127. package/runtime/arcane/img/trash.svg +5 -0
  128. package/runtime/arcane/img/upload.svg +5 -0
  129. package/runtime/arcane/modules/AI.js +2048 -0
  130. package/runtime/arcane/modules/AIPreferenceRuntime.js +32 -0
  131. package/runtime/arcane/modules/AIPreferenceTuple.js +92 -0
  132. package/runtime/arcane/modules/AIResponseLength.js +42 -0
  133. package/runtime/arcane/modules/AIResponseURLPolicy.js +626 -0
  134. package/runtime/arcane/modules/AnsiText.js +53 -0
  135. package/runtime/arcane/modules/ApiModelDatabase.js +25 -0
  136. package/runtime/arcane/modules/AppDataScope.js +245 -0
  137. package/runtime/arcane/modules/AppearancePreferences.js +28 -0
  138. package/runtime/arcane/modules/ArcaneCommunicationBridge.js +22 -0
  139. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +135 -0
  140. package/runtime/arcane/modules/ArcaneNetworkPolicy.js +255 -0
  141. package/runtime/arcane/modules/AsyncBoundary.js +161 -0
  142. package/runtime/arcane/modules/BrowserTestSuite.js +326 -0
  143. package/runtime/arcane/modules/CalculatorEngine.js +20 -0
  144. package/runtime/arcane/modules/CaseEvidenceIndexer.js +134 -0
  145. package/runtime/arcane/modules/ChartLibrary.js +35 -0
  146. package/runtime/arcane/modules/ChatRecords.js +13 -0
  147. package/runtime/arcane/modules/CommunicationAppController.js +43 -0
  148. package/runtime/arcane/modules/CommunicationHub.js +16 -0
  149. package/runtime/arcane/modules/CommunicationPreferences.js +13 -0
  150. package/runtime/arcane/modules/CommunicationProviderRegistry.js +16 -0
  151. package/runtime/arcane/modules/ComponentContracts.js +586 -0
  152. package/runtime/arcane/modules/ConfiguredAIChatSession.js +288 -0
  153. package/runtime/arcane/modules/ConversationActionItems.js +488 -0
  154. package/runtime/arcane/modules/ConversationClosingReport.js +274 -0
  155. package/runtime/arcane/modules/ConversationTimebox.js +527 -0
  156. package/runtime/arcane/modules/CoreLocalModelCatalog.js +255 -0
  157. package/runtime/arcane/modules/DBLS.js +171 -0
  158. package/runtime/arcane/modules/DBOPFS.js +1154 -0
  159. package/runtime/arcane/modules/DBOPFSWorker.js +116 -0
  160. package/runtime/arcane/modules/DataMaintenance.js +91 -0
  161. package/runtime/arcane/modules/DevelopmentWorkspace.js +74 -0
  162. package/runtime/arcane/modules/DirectoryPicker.js +109 -0
  163. package/runtime/arcane/modules/DocumentNavigation.js +223 -0
  164. package/runtime/arcane/modules/Errors.js +1025 -0
  165. package/runtime/arcane/modules/GifEncoder.js +29 -0
  166. package/runtime/arcane/modules/HTMLImport.js +114 -0
  167. package/runtime/arcane/modules/InMemoryCommunicationProvider.js +14 -0
  168. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +275 -0
  169. package/runtime/arcane/modules/LocalAIReadiness.js +870 -0
  170. package/runtime/arcane/modules/LocalAIReadinessController.js +156 -0
  171. package/runtime/arcane/modules/MD.js +111 -0
  172. package/runtime/arcane/modules/Mail.js +352 -0
  173. package/runtime/arcane/modules/MailTransport.mjs +180 -0
  174. package/runtime/arcane/modules/Marked.min.js +71 -0
  175. package/runtime/arcane/modules/MemoryRecords.js +44 -0
  176. package/runtime/arcane/modules/MessageAdvisory.js +38 -0
  177. package/runtime/arcane/modules/ModelDefinition.js +189 -0
  178. package/runtime/arcane/modules/Ollama.js +74 -0
  179. package/runtime/arcane/modules/OllamaModelIdentifier.js +21 -0
  180. package/runtime/arcane/modules/OllamaSettings.js +24 -0
  181. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +14 -0
  182. package/runtime/arcane/modules/PreferenceStore.js +109 -0
  183. package/runtime/arcane/modules/QRCode.min.js +1 -0
  184. package/runtime/arcane/modules/Questionnaire.js +61 -0
  185. package/runtime/arcane/modules/RecordLinkIndex.js +24 -0
  186. package/runtime/arcane/modules/RecordPassageIndex.js +222 -0
  187. package/runtime/arcane/modules/RecordReviewStore.js +94 -0
  188. package/runtime/arcane/modules/RevocableProjectionLedger.js +1623 -0
  189. package/runtime/arcane/modules/RiskSignalAnalyzer.js +37 -0
  190. package/runtime/arcane/modules/ScamRiskPolicy.js +62 -0
  191. package/runtime/arcane/modules/ScopedOPFSCache.js +183 -0
  192. package/runtime/arcane/modules/ScreenCapture.js +20 -0
  193. package/runtime/arcane/modules/SpeechPlayback.js +581 -0
  194. package/runtime/arcane/modules/StaticDocumentCatalog.js +1248 -0
  195. package/runtime/arcane/modules/SystemAppearance.js +20 -0
  196. package/runtime/arcane/modules/SystemPlatformPresentation.js +51 -0
  197. package/runtime/arcane/modules/SystemToolRegistry.js +28 -0
  198. package/runtime/arcane/modules/TerminalClient.js +52 -0
  199. package/runtime/arcane/modules/TerminalCommandRegistry.js +50 -0
  200. package/runtime/arcane/modules/ThemeBootstrap.js +26 -0
  201. package/runtime/arcane/modules/ThemeManager.js +131 -0
  202. package/runtime/arcane/modules/TimeGuard.js +149 -0
  203. package/runtime/arcane/modules/ToolCallRouter.js +83 -0
  204. package/runtime/arcane/modules/WaitForComponent.js +102 -0
  205. package/runtime/arcane/modules/YouTubeMedia.js +16 -0
  206. package/runtime/arcane/modules/uPlot.LICENSE.txt +21 -0
  207. package/runtime/arcane/modules/uPlot.iife.min.js +2 -0
  208. package/runtime/arcane/modules/uPlot.min.css +1 -0
  209. package/runtime/arcane/security/arcane-network-policy.json +6 -0
  210. package/runtime/strong-type/index.js +352 -0
  211. package/runtime/strong-type/licence +21 -0
  212. package/runtime/strong-type/package.json +45 -0
  213. package/schemas/arcane-app-bundle.schema.json +125 -0
  214. package/schemas/arcane-app.schema.json +329 -0
  215. package/schemas/arcane-lock.schema.json +86 -0
  216. package/schemas/arcane-package.schema.json +224 -0
  217. package/schemas/cli-event.schema.json +122 -0
  218. package/schemas/event-stack.schema.json +152 -0
  219. package/schemas/native-build-plan.schema.json +176 -0
  220. package/schemas/target-adapter.schema.json +117 -0
  221. package/src/app-descriptor.mjs +500 -0
  222. package/src/cli/main.mjs +561 -0
  223. package/src/constants.mjs +31 -0
  224. package/src/dev-server.mjs +718 -0
  225. package/src/doctor.mjs +315 -0
  226. package/src/dom-event-instrumentation.mjs +594 -0
  227. package/src/errors.mjs +75 -0
  228. package/src/event-manager.mjs +1342 -0
  229. package/src/event-queue.mjs +138 -0
  230. package/src/events.mjs +219 -0
  231. package/src/index.mjs +177 -0
  232. package/src/integrated-provider-loader.mjs +432 -0
  233. package/src/native-plan.mjs +698 -0
  234. package/src/native-provider-loader.mjs +1126 -0
  235. package/src/packager/core.mjs +2691 -0
  236. package/src/process.mjs +353 -0
  237. package/src/release-bundle.mjs +2523 -0
  238. package/src/repository.mjs +90 -0
  239. package/src/runtime.mjs +452 -0
  240. package/src/scaffold.mjs +380 -0
  241. package/src/targets/index.mjs +436 -0
  242. package/src/templates/assets/app-icon.png +0 -0
  243. package/src/templates/workspace-template.mjs +388 -0
  244. package/src/testing-loader.mjs +9 -0
  245. package/src/testing.mjs +427 -0
  246. package/src/toolchain.mjs +1335 -0
  247. package/src/update-check.mjs +307 -0
  248. package/src/workspace.mjs +449 -0
@@ -0,0 +1,468 @@
1
+ <style>
2
+ :host{
3
+ --app-bar-surface:var(--primary-color,#172238);
4
+ --app-bar-text:var(--button-text-color,#fff);
5
+ --app-bar-accent:var(--secondary-color,#c49a52);
6
+ --app-bar-active-text:var(--text-color,#fff);
7
+ --app-bar-border:var(--border-color,rgba(255,255,255,.18));
8
+ box-sizing:border-box;
9
+ display:block;
10
+ min-width:0;
11
+ color:var(--app-bar-text);
12
+ }
13
+
14
+ *,*::before,*::after{
15
+ box-sizing:border-box;
16
+ }
17
+
18
+ nav{
19
+ display:flex;
20
+ align-items:center;
21
+ gap:clamp(.7rem,2vw,1.5rem);
22
+ min-width:0;
23
+ min-height:4.25rem;
24
+ padding:.55rem clamp(.7rem,2vw,1.4rem);
25
+ color:inherit;
26
+ background:var(--app-bar-surface);
27
+ border-bottom:1px solid var(--app-bar-accent);
28
+ box-shadow:0 .35rem 1.1rem var(--shadow-color,rgba(0,0,0,.18));
29
+ }
30
+
31
+ .brand{
32
+ display:flex;
33
+ flex:0 0 auto;
34
+ align-items:center;
35
+ gap:.65rem;
36
+ min-width:0;
37
+ color:inherit;
38
+ text-decoration:none;
39
+ }
40
+
41
+ .brand-mark{
42
+ display:grid;
43
+ place-items:center;
44
+ width:2.45rem;
45
+ height:2.45rem;
46
+ overflow:hidden;
47
+ border:1px solid color-mix(in srgb,var(--app-bar-accent) 74%,white);
48
+ border-radius:.5rem;
49
+ color:var(--app-bar-active-text);
50
+ background:var(--app-bar-accent);
51
+ font:800 1.15rem/1 system-ui,sans-serif;
52
+ }
53
+
54
+ .product-name{
55
+ overflow:hidden;
56
+ font:750 .98rem/1.15 system-ui,sans-serif;
57
+ letter-spacing:.035em;
58
+ text-overflow:ellipsis;
59
+ white-space:nowrap;
60
+ }
61
+
62
+ .routes{
63
+ flex:1 1 auto;
64
+ min-width:0;
65
+ overflow-x:auto;
66
+ scrollbar-width:thin;
67
+ }
68
+
69
+ #navigationSlot,
70
+ #generatedNavigation{
71
+ display:flex;
72
+ align-items:center;
73
+ justify-content:center;
74
+ gap:.18rem;
75
+ min-width:max-content;
76
+ }
77
+
78
+ #generatedNavigation:empty{
79
+ display:none;
80
+ }
81
+
82
+ #generatedNavigation a,
83
+ ::slotted([slot="navigation"]){
84
+ display:block;
85
+ border:1px solid transparent;
86
+ border-radius:.5rem;
87
+ padding:.62rem .72rem;
88
+ color:inherit;
89
+ background:transparent;
90
+ font:680 .8rem/1 system-ui,sans-serif;
91
+ text-decoration:none;
92
+ white-space:nowrap;
93
+ }
94
+
95
+ #generatedNavigation a:hover,
96
+ #generatedNavigation a[aria-current="page"],
97
+ ::slotted([slot="navigation"]:hover),
98
+ ::slotted([slot="navigation"][aria-current="page"]){
99
+ color:var(--app-bar-active-text);
100
+ background:var(--app-bar-accent);
101
+ border-color:color-mix(in srgb,var(--app-bar-accent) 65%,white);
102
+ }
103
+
104
+ a:focus-visible,
105
+ ::slotted([slot="navigation"]:focus-visible),
106
+ ::slotted([slot="trailing"]:focus-visible){
107
+ outline:.18rem solid var(--focus-color,var(--app-bar-accent));
108
+ outline-offset:.14rem;
109
+ }
110
+
111
+ @media(forced-colors:active){
112
+ .brand-mark,
113
+ #generatedNavigation a:hover,
114
+ #generatedNavigation a[aria-current="page"],
115
+ ::slotted([slot="navigation"]:hover),
116
+ ::slotted([slot="navigation"][aria-current="page"]){
117
+ background:Highlight;
118
+ border-color:Highlight;
119
+ color:HighlightText;
120
+ forced-color-adjust:auto;
121
+ }
122
+ }
123
+
124
+ .end{
125
+ display:flex;
126
+ flex:0 0 auto;
127
+ align-items:center;
128
+ gap:.55rem;
129
+ min-width:0;
130
+ }
131
+
132
+ .status{
133
+ display:flex;
134
+ align-items:center;
135
+ gap:.42rem;
136
+ min-width:0;
137
+ color:color-mix(in srgb,var(--app-bar-text) 82%,transparent);
138
+ font:650 .72rem/1.2 system-ui,sans-serif;
139
+ }
140
+
141
+ .status-dot{
142
+ width:.5rem;
143
+ height:.5rem;
144
+ flex:0 0 auto;
145
+ border-radius:50%;
146
+ background:var(--app-bar-status-color,var(--app-bar-accent));
147
+ box-shadow:0 0 0 .16rem color-mix(in srgb,var(--app-bar-status-color,var(--app-bar-accent)) 20%,transparent);
148
+ }
149
+
150
+ :host([data-status-tone="success"]) .status{--app-bar-status-color:var(--success-color,#4f9a6b)}
151
+ :host([data-status-tone="warning"]) .status{--app-bar-status-color:var(--warning-color,#d69a32)}
152
+ :host([data-status-tone="error"]) .status{--app-bar-status-color:var(--danger-color,#c64c43)}
153
+ :host([data-status-tone="muted"]) .status{--app-bar-status-color:var(--app-bar-border)}
154
+ :host(:not([data-status])) #defaultStatus{display:none}
155
+
156
+ #defaultStatus{
157
+ display:flex;
158
+ align-items:center;
159
+ gap:.42rem;
160
+ }
161
+
162
+ .trailing{
163
+ display:flex;
164
+ align-items:center;
165
+ gap:.4rem;
166
+ }
167
+
168
+ @media(max-width:48rem){
169
+ nav{
170
+ flex-wrap:wrap;
171
+ gap:.45rem .75rem;
172
+ padding:.55rem .7rem;
173
+ }
174
+
175
+ .brand{
176
+ flex:1 1 auto;
177
+ }
178
+
179
+ .routes{
180
+ order:3;
181
+ flex-basis:100%;
182
+ overflow-x:visible;
183
+ }
184
+
185
+ #navigationSlot,
186
+ #generatedNavigation{
187
+ flex-wrap:wrap;
188
+ justify-content:flex-start;
189
+ min-width:0;
190
+ }
191
+
192
+ #generatedNavigation{
193
+ inline-size:100%;
194
+ }
195
+ }
196
+
197
+ @media(max-width:30rem){
198
+ .product-name{
199
+ max-width:9rem;
200
+ }
201
+
202
+ .status-text{
203
+ max-width:6rem;
204
+ overflow:hidden;
205
+ text-overflow:ellipsis;
206
+ white-space:nowrap;
207
+ }
208
+ }
209
+ </style>
210
+
211
+ <nav aria-label="Primary navigation" part="nav">
212
+ <a class="brand" id="brandLink" href="./" part="brand">
213
+ <span class="brand-mark" part="brand-mark"><slot name="brand-mark"><span id="defaultBrandMark">A</span></slot></span>
214
+ <span class="product-name" part="product-name"><slot name="product-name"><span id="defaultProductName">Application</span></slot></span>
215
+ </a>
216
+
217
+ <div class="routes" part="routes">
218
+ <slot name="navigation" id="navigationSlot"><div id="generatedNavigation" part="navigation"></div></slot>
219
+ </div>
220
+
221
+ <div class="end" part="end">
222
+ <div class="status" role="status" aria-live="polite" part="status">
223
+ <slot name="status">
224
+ <span id="defaultStatus">
225
+ <span class="status-dot" aria-hidden="true"></span>
226
+ <span class="status-text" id="statusText"></span>
227
+ </span>
228
+ </slot>
229
+ </div>
230
+ <div class="trailing" part="trailing"><slot name="trailing"></slot></div>
231
+ </div>
232
+ </nav>
233
+
234
+ <script type="module">
235
+ const host=this;
236
+ const root=host.shadowRoot;
237
+ const nav=root.querySelector('nav');
238
+ const brandLink=root.querySelector('#brandLink');
239
+ const navigationSlot=root.querySelector('#navigationSlot');
240
+ const generatedNavigation=root.querySelector('#generatedNavigation');
241
+ const statusText=root.querySelector('#statusText');
242
+ const statusTones=new Set(['default','success','warning','error','muted']);
243
+
244
+ let navigation=[];
245
+
246
+ host.setNavigation=setNavigation;
247
+ host.setActiveRoute=setActiveRoute;
248
+ host.setStatus=setStatus;
249
+ host.refresh=refresh;
250
+
251
+ Object.defineProperties(
252
+ host,
253
+ {
254
+ activeRoute:{
255
+ configurable:true,
256
+ get:()=>host.getAttribute('data-active-route')||routeFromLocation(),
257
+ set:value=>setActiveRoute(value)
258
+ },
259
+ navigation:{
260
+ configurable:true,
261
+ get:()=>navigation.slice(),
262
+ set:value=>setNavigation(value)
263
+ },
264
+ status:{
265
+ configurable:true,
266
+ get:()=>host.getAttribute('data-status')||'',
267
+ set:value=>setStatus(value,host.getAttribute('data-status-tone')||'default')
268
+ }
269
+ }
270
+ );
271
+
272
+ navigationSlot.addEventListener('slotchange',updateCurrent);
273
+ window.addEventListener('hashchange',onLocationChange);
274
+ window.addEventListener('popstate',onLocationChange);
275
+
276
+ const observer=new MutationObserver(
277
+ records=>{
278
+ const attributes=new Set(records.map(record=>record.attributeName));
279
+
280
+ if(attributes.has('data-brand-mark')||attributes.has('data-product-name')||attributes.has('data-brand-href')||attributes.has('data-label')){
281
+ syncBrand();
282
+ }
283
+ if(attributes.has('data-active-route')){
284
+ updateCurrent();
285
+ }
286
+ if(attributes.has('data-status')||attributes.has('data-status-tone')){
287
+ syncStatus();
288
+ }
289
+ if(attributes.has('data-navigation')){
290
+ readNavigationAttribute();
291
+ }
292
+ }
293
+ );
294
+
295
+ observer.observe(
296
+ host,
297
+ {
298
+ attributes:true,
299
+ attributeFilter:['data-brand-mark','data-product-name','data-brand-href','data-label','data-active-route','data-status','data-status-tone','data-navigation']
300
+ }
301
+ );
302
+
303
+ function syncBrand(){
304
+ root.querySelector('#defaultBrandMark').textContent=host.dataset.brandMark||'A';
305
+ root.querySelector('#defaultProductName').textContent=host.dataset.productName||'Application';
306
+ brandLink.href=host.dataset.brandHref||'./';
307
+ nav.setAttribute('aria-label',host.dataset.label||'Primary navigation');
308
+ }
309
+
310
+ function normalizeNavigation(items=[]){
311
+ if(!Array.isArray(items)){
312
+ return [];
313
+ }
314
+
315
+ return items.filter(item=>item&&typeof item==='object').map(
316
+ item=>({
317
+ label:String(item.label||item.name||item.route||''),
318
+ href:String(item.href||'#'),
319
+ route:String(item.route||item.id||'')
320
+ })
321
+ ).filter(item=>item.label);
322
+ }
323
+
324
+ function setNavigation(items=[]){
325
+ navigation=normalizeNavigation(items);
326
+ generatedNavigation.replaceChildren(
327
+ ...navigation.map(
328
+ item=>{
329
+ const link=document.createElement('a');
330
+ link.textContent=item.label;
331
+ link.href=item.href;
332
+ if(item.route){
333
+ link.dataset.route=item.route;
334
+ }
335
+ return link;
336
+ }
337
+ )
338
+ );
339
+ updateCurrent();
340
+ return navigation.slice();
341
+ }
342
+
343
+ function readNavigationAttribute(){
344
+ const source=host.getAttribute('data-navigation');
345
+
346
+ if(!source){
347
+ if(navigation.length){
348
+ setNavigation([]);
349
+ }
350
+ return;
351
+ }
352
+
353
+ try{
354
+ setNavigation(JSON.parse(source));
355
+ }catch(error){
356
+ console.warn('Unable to parse app-bar data-navigation.',error);
357
+ setNavigation([]);
358
+ }
359
+ }
360
+
361
+ function routeFromLocation(){
362
+ const hash=globalThis.location?.hash?.replace(/^#/,'');
363
+ return hash||globalThis.location?.pathname||'';
364
+ }
365
+
366
+ function routeForLink(link){
367
+ if(link.dataset.route){
368
+ return link.dataset.route;
369
+ }
370
+ if(link.dataset.view){
371
+ return link.dataset.view;
372
+ }
373
+
374
+ try{
375
+ const url=new URL(link.href,globalThis.location?.href||'http://localhost/');
376
+ return url.hash.replace(/^#/,'')||url.pathname;
377
+ }catch{
378
+ return link.getAttribute('href')||'';
379
+ }
380
+ }
381
+
382
+ function navigationLinks(){
383
+ const assigned=navigationSlot.assignedElements({flatten:true});
384
+ const roots=assigned.length?assigned:[generatedNavigation];
385
+ const links=[];
386
+
387
+ roots.forEach(element=>{
388
+ if(element.matches?.('a[href],[data-route],[data-view]')){
389
+ links.push(element);
390
+ }
391
+ links.push(...element.querySelectorAll('a[href],[data-route],[data-view]'));
392
+ });
393
+
394
+ return [...new Set(links)];
395
+ }
396
+
397
+ function setActiveRoute(route=''){
398
+ if(route){
399
+ host.setAttribute('data-active-route',String(route).replace(/^#/,''));
400
+ }else{
401
+ host.removeAttribute('data-active-route');
402
+ }
403
+ updateCurrent();
404
+ return host.activeRoute;
405
+ }
406
+
407
+ function updateCurrent(){
408
+ const current=String(host.activeRoute||'').replace(/^#/,'');
409
+
410
+ navigationLinks().forEach(link=>{
411
+ const active=!link.hidden&&routeForLink(link).replace(/^#/,'')===current;
412
+ if(active){
413
+ link.setAttribute('aria-current','page');
414
+ }else{
415
+ link.removeAttribute('aria-current');
416
+ }
417
+ });
418
+ }
419
+
420
+ function onLocationChange(){
421
+ if(!host.hasAttribute('data-active-route')){
422
+ updateCurrent();
423
+ }
424
+ }
425
+
426
+ function setStatus(message='',tone='default'){
427
+ if(message===null||message===''){
428
+ host.removeAttribute('data-status');
429
+ }else{
430
+ host.setAttribute('data-status',String(message));
431
+ }
432
+ host.setAttribute('data-status-tone',statusTones.has(tone)?tone:'default');
433
+ syncStatus();
434
+ return host.status;
435
+ }
436
+
437
+ function syncStatus(){
438
+ statusText.textContent=host.dataset.status||'';
439
+ const tone=statusTones.has(host.dataset.statusTone)?host.dataset.statusTone:'default';
440
+ if(host.dataset.statusTone!==tone){
441
+ host.dataset.statusTone=tone;
442
+ }
443
+ }
444
+
445
+ function refresh(){
446
+ syncBrand();
447
+ syncStatus();
448
+ updateCurrent();
449
+ return host;
450
+ }
451
+
452
+ syncBrand();
453
+ syncStatus();
454
+ readNavigationAttribute();
455
+ updateCurrent();
456
+
457
+ host.ready=true;
458
+ host.dispatchEvent(
459
+ new CustomEvent(
460
+ 'app-bar-ready',
461
+ {
462
+ detail:{appBar:host},
463
+ bubbles:true,
464
+ composed:true
465
+ }
466
+ )
467
+ );
468
+ </script>