@camstack/addon-admin-ui 1.2.439 → 1.2.440

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 (136) hide show
  1. package/dist/assets/{AddonAssetIcon-BDSwFXgm.js → AddonAssetIcon-DoCqXzAv.js} +1 -1
  2. package/dist/assets/Addons-CrSVEbe3.js +4 -0
  3. package/dist/assets/{AdminPage-CgbWYJ_a.js → AdminPage-KGO_m_yt.js} +1 -1
  4. package/dist/assets/{AdminSectionedPage-Cx5lBMEy.js → AdminSectionedPage-BiMhPKOP.js} +1 -1
  5. package/dist/assets/AiProfiles-D8mKo1K9.js +3 -0
  6. package/dist/assets/{BrokerForm-vhYWxL3G.js → BrokerForm-yx58WRgh.js} +1 -1
  7. package/dist/assets/{Build-DU8TYYdP.js → Build-BArewEF3.js} +5 -5
  8. package/dist/assets/{Calendars-nXT3Wrbf.js → Calendars-BdN8ZQmv.js} +1 -1
  9. package/dist/assets/{Cluster-i581brrb.js → Cluster-Bn5YZafT.js} +1 -1
  10. package/dist/assets/{ClusterStepModel-COT7-UPr.js → ClusterStepModel-DPmlzTfm.js} +1 -1
  11. package/dist/assets/CompositionEditor-BhL25d6e.js +1 -0
  12. package/dist/assets/CompositionEditorPage-BwqVkeY-.js +1 -0
  13. package/dist/assets/Data-BvY-zVHv.js +2 -0
  14. package/dist/assets/DeviceDetail-g2esa6u-.js +2 -0
  15. package/dist/assets/{DeviceDoActionFields-B1mTzp5D.js → DeviceDoActionFields-C6f9gioM.js} +1 -1
  16. package/dist/assets/Devices-CtivG8K9.js +1 -0
  17. package/dist/assets/{EmbedPlayerPage-BPwqAqDS.js → EmbedPlayerPage-BD-Z7zz-.js} +1 -1
  18. package/dist/assets/Identity-BQNP0wku.js +1 -0
  19. package/dist/assets/IntegrationDetail-CzEG-I4B.js +1 -0
  20. package/dist/assets/IntegrationHub-tqxee2Rm.js +1 -0
  21. package/dist/assets/Integrations-C7Ptcn3c.js +1 -0
  22. package/dist/assets/Integrations-GZm_SrQK.js +1 -0
  23. package/dist/assets/Library-ToUHY4O3.js +1 -0
  24. package/dist/assets/Locations-CPFCvUKd.js +3 -0
  25. package/dist/assets/{Logs-DQzkH4DL.js → Logs-Ds6SPC6o.js} +1 -1
  26. package/dist/assets/{MaskShapeCanvas-B01TLLz0.js → MaskShapeCanvas-BoY32Qvt.js} +1 -1
  27. package/dist/assets/{MotionZonesSettings-Ccp-7wRO.js → MotionZonesSettings-DBW4jTEr.js} +1 -1
  28. package/dist/assets/{MyAccess-d8Soqp8x.js → MyAccess-2mSUBp14.js} +1 -1
  29. package/dist/assets/{Network-DUXIj2Zk.js → Network-BddKO6B1.js} +1 -1
  30. package/dist/assets/{NodeAddonsSettingsPanel-BfK00QUN.js → NodeAddonsSettingsPanel-CIISQuIL.js} +1 -1
  31. package/dist/assets/Notifications-DWJcnXvV.js +1 -0
  32. package/dist/assets/{PrivacyMaskSettings-BnmGNc7h.js → PrivacyMaskSettings-z8P3R0fA.js} +1 -1
  33. package/dist/assets/Recordings-g1Jxg_Lr.js +1 -0
  34. package/dist/assets/{ScanNetworkModal-BuYymusi.js → ScanNetworkModal-D7N2aC7y.js} +1 -1
  35. package/dist/assets/{SceneMonitorEditor-COIi86yu.js → SceneMonitorEditor-CyjEekEM.js} +1 -1
  36. package/dist/assets/SessionsList-bmTxxIOE.js +2 -0
  37. package/dist/assets/{Showroom-B-HvuRyq.js → Showroom-PlFtcQrL.js} +1 -1
  38. package/dist/assets/{System-D1S9FZIN.js → System-DxszqVYV.js} +1 -1
  39. package/dist/assets/{Terminal-VExSxhFn.js → Terminal-BMG2w8DZ.js} +3 -3
  40. package/dist/assets/{Viewer-CNtlq-6t.js → Viewer-CRLD_tt7.js} +1 -1
  41. package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-B5lRPMSE.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-GapjKGVe.js} +1 -1
  42. package/dist/assets/{addon-icons-context-O3QiZWCa.js → addon-icons-context-BrgGsfoE.js} +1 -1
  43. package/dist/assets/{archive-NnMWQRLb.js → archive-Dx-auPAN.js} +1 -1
  44. package/dist/assets/{authed-media-B64j5Vsu.js → authed-media-MhMmWNH3.js} +1 -1
  45. package/dist/assets/{bell-off-DR6rLD11.js → bell-off-BQQTURVF.js} +1 -1
  46. package/dist/assets/{board-model-CUEDqTvL.js → board-model-Bdetmchn.js} +1 -1
  47. package/dist/assets/{boxes-B64NRkVe.js → boxes-BIK98bHo.js} +1 -1
  48. package/dist/assets/circle-slash-DKE4hxbW.js +1 -0
  49. package/dist/assets/client-Cy6wyTLQ.js +358 -0
  50. package/dist/assets/{cloud-upload-Ck1AcqSa.js → cloud-upload-FvK6xW2I.js} +1 -1
  51. package/dist/assets/crop-7vsE3Qcd.js +1 -0
  52. package/dist/assets/{device-integration-icon-CdWFmoUD.js → device-integration-icon-ClmWzwM_.js} +1 -1
  53. package/dist/assets/device-picker-model-DVvq9nYp.js +1 -0
  54. package/dist/assets/dist-BPMeH1J4.js +358 -0
  55. package/dist/assets/dist-CEnfZ10I.js +1 -0
  56. package/dist/assets/{eraser-CHm7ildU.js → eraser-CUAqtnBD.js} +1 -1
  57. package/dist/assets/{hard-drive-download-DVmQAuw3.js → hard-drive-download-XGtks2vE.js} +1 -1
  58. package/dist/assets/{history-2q2gbNuR.js → history-DqvhlzWX.js} +1 -1
  59. package/dist/assets/{hostInit-BJE3f_CH.js → hostInit-DzBGXsvZ.js} +1 -1
  60. package/dist/assets/i18n-B1bxeya5.js +1 -0
  61. package/dist/assets/{icons-DQaWDMUW.js → icons-DNRi-jSy.js} +1 -1
  62. package/dist/assets/index-CN7xsFJi.css +2 -0
  63. package/dist/assets/index-yoPG03d0.js +4 -0
  64. package/dist/assets/{key-N9xPL69Y.js → key-bw9xhRgT.js} +1 -1
  65. package/dist/assets/{key-round-DetnHyGS.js → key-round-BngMS2dZ.js} +1 -1
  66. package/dist/assets/{layers-DdcQNtFW.js → layers-CIl8QXpN.js} +1 -1
  67. package/dist/assets/{linked-devices-model-Ca0JeX-b.js → linked-devices-model-CclOXMLj.js} +1 -1
  68. package/dist/assets/{list-ordered-CG0tknH1.js → list-ordered-_52_xrQ7.js} +1 -1
  69. package/dist/assets/location-owned-usage-5eb6nny3.js +1 -0
  70. package/dist/assets/{log-in-eXylJY9j.js → log-in-DH9Lu6bJ.js} +1 -1
  71. package/dist/assets/{memory-stick-DASwwt0F.js → memory-stick-CzaP6KiN.js} +1 -1
  72. package/dist/assets/{message-square-plus-DqkHZSG8.js → message-square-plus-vMywres_.js} +1 -1
  73. package/dist/assets/{mf-entry-bootstrap-0-3bcba670.js → mf-entry-bootstrap-0-54468006.js} +2 -2
  74. package/dist/assets/{mic-off-Dn3D8U5T.js → mic-off-Da09u2hl.js} +1 -1
  75. package/dist/assets/{monitor-off-BFFE28-j.js → monitor-off-jOOWdiSg.js} +1 -1
  76. package/dist/assets/{monitor-smartphone-Df6JhoUF.js → monitor-smartphone-D_W4zyWO.js} +1 -1
  77. package/dist/assets/mount-DVvq9nYp.js +1 -0
  78. package/dist/assets/notification-schedule-field-LytDFkpQ.js +1 -0
  79. package/dist/assets/{player-overlays-CikRdqm6.js → player-overlays-CCZE3o8q.js} +1 -1
  80. package/dist/assets/{recycle-CeQJmMoH.js → recycle-BVcCaHVd.js} +1 -1
  81. package/dist/assets/remoteEntry-BOaeaEWk.js +1 -0
  82. package/dist/assets/{scan-eye-uX_isL7a.js → scan-eye-CHwWv39K.js} +1 -1
  83. package/dist/assets/{scissors-Bi6HP2Jp.js → scissors-BrUBwnKn.js} +1 -1
  84. package/dist/assets/{search-x-CScyd-pU.js → search-x-BcR2pidC.js} +1 -1
  85. package/dist/assets/{send-D2QbbJQk.js → send-8R5TbxHN.js} +1 -1
  86. package/dist/assets/{settings-2-CkjM7VHr.js → settings-2-C4PaSGfb.js} +1 -1
  87. package/dist/assets/{speaker-C3Z3o0NO.js → speaker-CBRM7GNH.js} +1 -1
  88. package/dist/assets/src-Cw4W7OtK.js +67 -0
  89. package/dist/assets/{timer-reset-C_TvCMnb.js → timer-reset-DlfKkTg_.js} +1 -1
  90. package/dist/assets/{ungroup-IELE1M3H.js → ungroup-BzlNECzG.js} +1 -1
  91. package/dist/assets/{unlink-CLHtJAsY.js → unlink-HIuzqEig.js} +1 -1
  92. package/dist/assets/{usb-DncvObAi.js → usb-DqboQtO8.js} +1 -1
  93. package/dist/assets/{use-scenes-feed-BgX1JX4l.js → use-scenes-feed-Cnl4Is6T.js} +1 -1
  94. package/dist/assets/{use-stationary-objects-BzSycd9M.js → use-stationary-objects-DmFWTPK0.js} +1 -1
  95. package/dist/assets/useEventInvalidation-DVvq9nYp.js +1 -0
  96. package/dist/assets/{useNodeUrlSelection-D3zWAXku.js → useNodeUrlSelection-CSh6gqLc.js} +1 -1
  97. package/dist/assets/user-round-C4K7vDWN.js +1 -0
  98. package/dist/assets/{user-x-B-NhZXl-.js → user-x-ciro8k7Z.js} +1 -1
  99. package/dist/assets/{video-IXUGebu2.js → video-BJUj4GaK.js} +1 -1
  100. package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-5Br3X_S3.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CwjeQPZx.js} +2 -2
  101. package/dist/index.html +11 -11
  102. package/dist/server/addon.js +252 -45
  103. package/package.json +1 -1
  104. package/dist/assets/Addons-BNdKgh4A.js +0 -4
  105. package/dist/assets/AiProfiles-Bcw_Zupz.js +0 -3
  106. package/dist/assets/CompositionEditor-ChpgaVIC.js +0 -1
  107. package/dist/assets/CompositionEditorPage-ChGD20-A.js +0 -1
  108. package/dist/assets/Data-NVQyqefj.js +0 -2
  109. package/dist/assets/DeviceDetail-UQPY3O77.js +0 -2
  110. package/dist/assets/Devices-DNkljEPT.js +0 -1
  111. package/dist/assets/Identity-SFG32MYD.js +0 -1
  112. package/dist/assets/IntegrationDetail-DOpZe3Ca.js +0 -1
  113. package/dist/assets/IntegrationHub-DbxSPB_Z.js +0 -1
  114. package/dist/assets/Integrations--ssC4t1F.js +0 -1
  115. package/dist/assets/Integrations-6eDOiK1G.js +0 -1
  116. package/dist/assets/Library-Bi_LuV1_.js +0 -1
  117. package/dist/assets/Locations-Cg0m1b4l.js +0 -3
  118. package/dist/assets/Notifications-M4WZNbHV.js +0 -1
  119. package/dist/assets/Recordings-DalG2LLq.js +0 -1
  120. package/dist/assets/SessionsList-CoUCGhgk.js +0 -2
  121. package/dist/assets/circle-slash-CEYz4tuU.js +0 -1
  122. package/dist/assets/client-Ca-96r9I.js +0 -358
  123. package/dist/assets/crop-C-IooyeF.js +0 -1
  124. package/dist/assets/device-picker-model-Dep-E57-.js +0 -1
  125. package/dist/assets/dist-BSOkO07t.js +0 -1
  126. package/dist/assets/dist-vJSNSRqs.js +0 -358
  127. package/dist/assets/i18n-ATfMbes1.js +0 -1
  128. package/dist/assets/index-CIQcOfrF.js +0 -4
  129. package/dist/assets/index-M0Q7O5pF.css +0 -2
  130. package/dist/assets/location-owned-usage-CPVIHMbS.js +0 -1
  131. package/dist/assets/mount-Dep-E57-.js +0 -1
  132. package/dist/assets/notification-schedule-field-DX8l1Z0c.js +0 -1
  133. package/dist/assets/remoteEntry-B_6E82lR.js +0 -1
  134. package/dist/assets/src-Bt0KiIin.js +0 -67
  135. package/dist/assets/useEventInvalidation-Dep-E57-.js +0 -1
  136. package/dist/assets/user-round-BCHxFTod.js +0 -1
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
- //#region ../types/dist/event-category-BvOFi6PY.mjs
3
+ //#region ../types/dist/event-category-DOl51-Ij.mjs
4
4
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
5
5
  EventCategory["SystemBoot"] = "system.boot";
6
6
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -79,9 +79,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
79
79
  /**
80
80
  * The node's one-shot runner boot check (D877): planned runners against the
81
81
  * process service, `degraded` when any is failed, refused or missing. The
82
- * alert centre turns it into one alert and a direct critical push.
82
+ * alert centre turns it into one critical alert.
83
83
  */
84
84
  EventCategory["SystemRunnerCheck"] = "system.runner-check";
85
+ /**
86
+ * An alert EPISODE opened or closed, emitted by the alert centre for alerts
87
+ * of severity `critical` or `error` (`AlertEpisodePayload`). The alert
88
+ * centre sends no notification of its own: Notification Center turns this
89
+ * into the `alert-critical` / `alert-error` / `alert-critical-resolved`
90
+ * system-event kinds, and reconciles from the alerts store because a bus
91
+ * event may be dropped (D8, D11).
92
+ */
93
+ EventCategory["AlertEpisode"] = "alert.episode";
85
94
  EventCategory["AddonError"] = "addon.error";
86
95
  EventCategory["AddonPageReady"] = "addon.page-ready";
87
96
  EventCategory["AddonWidgetReady"] = "addon.widget-ready";
@@ -5406,7 +5415,7 @@ var ZodIssueCode = {
5406
5415
  var ZodFirstPartyTypeKind;
5407
5416
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5408
5417
  //#endregion
5409
- //#region ../types/dist/sleep-BegKjwUu.mjs
5418
+ //#region ../types/dist/sleep-BxjU_fJM.mjs
5410
5419
  /**
5411
5420
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5412
5421
  * window to float samples (D455).
@@ -13106,7 +13115,14 @@ var AlertSeveritySchema = _enum([
13106
13115
  ]);
13107
13116
  var AlertActionSchema = object({
13108
13117
  label: string(),
13109
- href: string().optional()
13118
+ href: string().optional(),
13119
+ /**
13120
+ * How `href` is followed. Absent / `app`: an admin-ui route (client-side).
13121
+ * `server`: a route the HUB serves (an addon HTTP route such as an OAuth
13122
+ * start) — the browser must leave the SPA with a full navigation, because
13123
+ * the SPA has no such route and would bounce to the home page.
13124
+ */
13125
+ navigation: _enum(["app", "server"]).optional()
13110
13126
  });
13111
13127
  var AlertStatusSchema = _enum([
13112
13128
  "active",
@@ -41482,6 +41498,9 @@ var NcSystemEventKindSchema = _enum([
41482
41498
  "server-updated",
41483
41499
  "export-completed",
41484
41500
  "backup-completed",
41501
+ "alert-critical",
41502
+ "alert-error",
41503
+ "alert-critical-resolved",
41485
41504
  "camera-online",
41486
41505
  "camera-offline",
41487
41506
  "camera-disabled",
@@ -50514,7 +50533,10 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
50514
50533
  }), method(object({ jobId: string().optional() }), StorageMigrationJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
50515
50534
  kind: "mutation",
50516
50535
  auth: "admin"
50517
- }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
50536
+ }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({ locationIds: array(string()).readonly() }), object({
50537
+ clear: boolean(),
50538
+ repointLocationId: string().optional()
50539
+ }), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
50518
50540
  kind: "mutation",
50519
50541
  auth: "admin"
50520
50542
  }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
@@ -53949,6 +53971,11 @@ object({
53949
53971
  *
53950
53972
  * `kind: 'poll'` — cloud REST APIs typically have no push channel; the
53951
53973
  * provider refreshes the slice on an interval and eagerly after commands.
53974
+ *
53975
+ * UNKNOWN IS NOT OFF. Every field the appliance reports separately is
53976
+ * nullable: `null` means "not known right now" (the appliance has not said,
53977
+ * the link is down, or the description does not carry it) and is never
53978
+ * rendered or exported as `false` / `0`. `availability` says why.
53952
53979
  */
53953
53980
  var DishwasherStateSchema = _enum([
53954
53981
  "idle",
@@ -53958,112 +53985,227 @@ var DishwasherStateSchema = _enum([
53958
53985
  "error",
53959
53986
  "unavailable"
53960
53987
  ]);
53988
+ /**
53989
+ * The appliance's own operation state, uncollapsed. `state` above is the coarse
53990
+ * view for compact surfaces; this is what the appliance said.
53991
+ */
53992
+ var DishwasherOperationStateSchema = _enum([
53993
+ "Inactive",
53994
+ "Ready",
53995
+ "DelayedStart",
53996
+ "Run",
53997
+ "Pause",
53998
+ "ActionRequired",
53999
+ "Finished",
54000
+ "Error",
54001
+ "Aborting"
54002
+ ]);
54003
+ /**
54004
+ * Why fields may be `null`:
54005
+ * - `available` — the link is up and the description is loaded;
54006
+ * - `offline` — the local link is down (values are unknown, not last-known);
54007
+ * - `description-missing` — the link is up but the appliance's description could not
54008
+ * be loaded, so its values cannot be decoded.
54009
+ */
54010
+ var DishwasherAvailabilitySchema = _enum([
54011
+ "available",
54012
+ "offline",
54013
+ "description-missing"
54014
+ ]);
53961
54015
  var DishwasherConsumableLevelSchema = _enum([
53962
54016
  "ok",
53963
54017
  "low",
53964
54018
  "empty"
53965
54019
  ]);
53966
54020
  object({
54021
+ availability: DishwasherAvailabilitySchema,
54022
+ /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
53967
54023
  state: DishwasherStateSchema,
53968
- /** Active program id/name, or null when none selected / unknown. */
54024
+ /** The appliance's operation state as reported; null when not known. */
54025
+ operationState: DishwasherOperationStateSchema.nullable(),
54026
+ /** Feature key of the ACTIVE (running) program, or null when none runs / not known. */
53969
54027
  program: string().nullable(),
53970
- /** Program tokens the hardware accepts — drives the UI selector. */
54028
+ /** Feature key of the SELECTED program (what Start would run), or null when none / not known. */
54029
+ selectedProgram: string().nullable(),
54030
+ /** Feature keys of the programs the appliance currently offers — drives the UI selector. */
53971
54031
  availablePrograms: array(string()),
53972
- /** Minutes remaining on the active cycle, or null when not running. */
53973
- remainingMinutes: number().int().nonnegative().nullable(),
54032
+ /** Seconds remaining on the active cycle, or null when not running / not known. */
54033
+ remainingSeconds: number().int().nonnegative().nullable(),
54034
+ /** Seconds the delayed start is set to (time until the cycle starts), or null. */
54035
+ delayedStartSeconds: number().int().nonnegative().nullable(),
53974
54036
  /** Cycle completion 0..100, or null when not applicable. */
53975
54037
  progressPercent: number().min(0).max(100).nullable(),
53976
- /** True when the door is reported open. */
53977
- doorOpen: boolean(),
53978
- /** True when remote start is allowed (door closed, power on, etc.). */
53979
- remoteStartAllowed: boolean(),
53980
- /** Main power / switched-on state. */
53981
- powerOn: boolean(),
54038
+ /** True when the door is reported open; null when the door state is not known. */
54039
+ doorOpen: boolean().nullable(),
54040
+ /** True when the door is latched (locked) during a cycle; null when not reported. */
54041
+ doorLocked: boolean().nullable(),
54042
+ /** True when remote start is allowed (door closed, power on, etc.); null when not known. */
54043
+ remoteStartAllowed: boolean().nullable(),
54044
+ /** True when the appliance accepts remote control now; null when not known. */
54045
+ remoteControlActive: boolean().nullable(),
54046
+ /** True while somebody operates the appliance at its panel; null when not reported. */
54047
+ localControlActive: boolean().nullable(),
54048
+ /** Main power / switched-on state; null when not known. */
54049
+ powerOn: boolean().nullable(),
54050
+ /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
54051
+ powerState: string().nullable(),
53982
54052
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
53983
54053
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
53984
- halfLoad: boolean(),
53985
- hygienePlus: boolean(),
54054
+ /** Option states: null when the appliance does not expose the option or has not said. */
54055
+ halfLoad: boolean().nullable(),
54056
+ hygienePlus: boolean().nullable(),
53986
54057
  /** Extra dry option when the appliance exposes it. */
53987
- extraDry: boolean(),
54058
+ extraDry: boolean().nullable(),
53988
54059
  /** Intensive zone (lower basket) when the appliance exposes it. */
53989
- intensiveZone: boolean(),
54060
+ intensiveZone: boolean().nullable(),
53990
54061
  /** VarioSpeed / VarioSpeed+ when the appliance exposes it. */
53991
- varioSpeedPlus: boolean(),
53992
- /** Child lock (controls disabled on the appliance). */
53993
- childLock: boolean(),
54062
+ varioSpeedPlus: boolean().nullable(),
54063
+ /** Child lock (controls disabled on the appliance); null when not known. */
54064
+ childLock: boolean().nullable(),
54065
+ /** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
54066
+ activeEvents: array(string()),
54067
+ /** Numeric error code when the appliance reports one; null otherwise. */
53994
54068
  errorCode: number().nullable(),
54069
+ /** Name of the raised alert-level event while the appliance is in error; null otherwise. */
53995
54070
  errorLabel: string().nullable(),
54071
+ /** Ms epoch of the last value received from the appliance; 0 = never. */
53996
54072
  lastFetchedAt: number()
53997
54073
  });
53998
- DeviceType.Dishwasher, method(object({ deviceId: number().int().nonnegative() }), _void(), {
54074
+ var DeviceIdSchema = number().int().nonnegative();
54075
+ /** A value a program option or setting can take. */
54076
+ var DishwasherValueSchema = union([
54077
+ boolean(),
54078
+ string(),
54079
+ number()
54080
+ ]);
54081
+ var DishwasherAccessSchema = _enum([
54082
+ "none",
54083
+ "read",
54084
+ "readWrite",
54085
+ "writeOnly",
54086
+ "readStatic"
54087
+ ]);
54088
+ /**
54089
+ * One option or setting the appliance declares, with the constraints its description
54090
+ * gives. A `readWrite` descriptor that is `available` is what `setOption` accepts.
54091
+ */
54092
+ var DishwasherOptionDescriptorSchema = object({
54093
+ /** Feature key (`Dishcare.Dishwasher.Option.ExtraDry`). */
54094
+ key: string(),
54095
+ /** Last segment of the key, for display. */
54096
+ name: string(),
54097
+ type: _enum([
54098
+ "boolean",
54099
+ "number",
54100
+ "enum",
54101
+ "string"
54102
+ ]),
54103
+ access: DishwasherAccessSchema,
54104
+ /** The appliance reports this entity as currently available. */
54105
+ available: boolean(),
54106
+ /** Unit the description declares for a number; null when it declares none. */
54107
+ unit: string().nullable(),
54108
+ min: number().nullable(),
54109
+ max: number().nullable(),
54110
+ step: number().nullable(),
54111
+ /** Allowed members of an enum; null for other types. */
54112
+ enumValues: array(string()).nullable(),
54113
+ defaultValue: DishwasherValueSchema.nullable()
54114
+ });
54115
+ var DishwasherProgramSchema = object({
54116
+ /** Feature key (`Dishcare.Dishwasher.Program.Eco50`) — what `setProgram` / `start` take. */
54117
+ key: string(),
54118
+ name: string(),
54119
+ /** The appliance currently offers this program. */
54120
+ available: boolean(),
54121
+ /** The options this program lists, with the program-level access / availability / default. */
54122
+ options: array(DishwasherOptionDescriptorSchema)
54123
+ });
54124
+ var DishwasherOptionsSchema = object({
54125
+ availability: DishwasherAvailabilitySchema,
54126
+ /** What the appliance can be told to do, from the commands its description declares. */
54127
+ supportsStart: boolean(),
54128
+ supportsPause: boolean(),
54129
+ supportsResume: boolean(),
54130
+ supportsStop: boolean(),
54131
+ supportsPower: boolean(),
54132
+ /** Every program the description lists, with its options. */
54133
+ programs: array(DishwasherProgramSchema),
54134
+ /** Every option and setting entity the description lists (programs reference these by key). */
54135
+ options: array(DishwasherOptionDescriptorSchema)
54136
+ });
54137
+ DeviceType.Dishwasher, method(object({
54138
+ deviceId: DeviceIdSchema,
54139
+ program: string().min(1).optional(),
54140
+ options: record(string(), DishwasherValueSchema).optional()
54141
+ }), _void(), {
53999
54142
  kind: "mutation",
54000
54143
  auth: "protected"
54001
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54144
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54002
54145
  kind: "mutation",
54003
54146
  auth: "protected"
54004
- }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
54147
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54148
+ kind: "mutation",
54149
+ auth: "protected"
54150
+ }), method(object({ deviceId: DeviceIdSchema }), _void(), {
54005
54151
  kind: "mutation",
54006
54152
  auth: "protected"
54007
54153
  }), method(object({
54008
- deviceId: number().int().nonnegative(),
54154
+ deviceId: DeviceIdSchema,
54009
54155
  program: string().min(1)
54010
54156
  }), _void(), {
54011
54157
  kind: "mutation",
54012
54158
  auth: "protected"
54013
54159
  }), method(object({
54014
- deviceId: number().int().nonnegative(),
54160
+ deviceId: DeviceIdSchema,
54015
54161
  on: boolean()
54016
54162
  }), _void(), {
54017
54163
  kind: "mutation",
54018
54164
  auth: "protected"
54019
54165
  }), method(object({
54020
- deviceId: number().int().nonnegative(),
54166
+ deviceId: DeviceIdSchema,
54021
54167
  on: boolean()
54022
54168
  }), _void(), {
54023
54169
  kind: "mutation",
54024
54170
  auth: "protected"
54025
54171
  }), method(object({
54026
- deviceId: number().int().nonnegative(),
54172
+ deviceId: DeviceIdSchema,
54027
54173
  on: boolean()
54028
54174
  }), _void(), {
54029
54175
  kind: "mutation",
54030
54176
  auth: "protected"
54031
54177
  }), method(object({
54032
- deviceId: number().int().nonnegative(),
54178
+ deviceId: DeviceIdSchema,
54033
54179
  on: boolean()
54034
54180
  }), _void(), {
54035
54181
  kind: "mutation",
54036
54182
  auth: "protected"
54037
54183
  }), method(object({
54038
- deviceId: number().int().nonnegative(),
54184
+ deviceId: DeviceIdSchema,
54039
54185
  on: boolean()
54040
54186
  }), _void(), {
54041
54187
  kind: "mutation",
54042
54188
  auth: "protected"
54043
54189
  }), method(object({
54044
- deviceId: number().int().nonnegative(),
54190
+ deviceId: DeviceIdSchema,
54045
54191
  on: boolean()
54046
54192
  }), _void(), {
54047
54193
  kind: "mutation",
54048
54194
  auth: "protected"
54049
54195
  }), method(object({
54050
- deviceId: number().int().nonnegative(),
54196
+ deviceId: DeviceIdSchema,
54051
54197
  on: boolean()
54052
54198
  }), _void(), {
54053
54199
  kind: "mutation",
54054
54200
  auth: "protected"
54055
54201
  }), method(object({
54056
- deviceId: number().int().nonnegative(),
54202
+ deviceId: DeviceIdSchema,
54057
54203
  key: string().min(1),
54058
- value: union([
54059
- boolean(),
54060
- string(),
54061
- number()
54062
- ])
54204
+ value: DishwasherValueSchema
54063
54205
  }), _void(), {
54064
54206
  kind: "mutation",
54065
54207
  auth: "protected"
54066
- });
54208
+ }), method(object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" });
54067
54209
  object({
54068
54210
  /** Ms epoch of the last press. null = never observed since this provider started. */
54069
54211
  lastPressedAt: number().nullable(),
@@ -64123,6 +64265,12 @@ Object.freeze({
64123
64265
  addonId: null,
64124
64266
  access: "view"
64125
64267
  },
64268
+ "dishwasher.getOptions": {
64269
+ capName: "dishwasher",
64270
+ capScope: "device",
64271
+ addonId: null,
64272
+ access: "view"
64273
+ },
64126
64274
  "dishwasher.getStatus": {
64127
64275
  capName: "dishwasher",
64128
64276
  capScope: "device",
@@ -64135,6 +64283,12 @@ Object.freeze({
64135
64283
  addonId: null,
64136
64284
  access: "create"
64137
64285
  },
64286
+ "dishwasher.resume": {
64287
+ capName: "dishwasher",
64288
+ capScope: "device",
64289
+ addonId: null,
64290
+ access: "create"
64291
+ },
64138
64292
  "dishwasher.setChildLock": {
64139
64293
  capName: "dishwasher",
64140
64294
  capScope: "device",
@@ -68635,6 +68789,12 @@ Object.freeze({
68635
68789
  addonId: null,
68636
68790
  access: "view"
68637
68791
  },
68792
+ "storageMigration.moverClearance": {
68793
+ capName: "storage-migration",
68794
+ capScope: "system",
68795
+ addonId: null,
68796
+ access: "view"
68797
+ },
68638
68798
  "storageMigration.movers": {
68639
68799
  capName: "storage-migration",
68640
68800
  capScope: "system",
@@ -70828,6 +70988,11 @@ Object.freeze({
70828
70988
  form: "single",
70829
70989
  optional: false
70830
70990
  }],
70991
+ "dishwasher.getOptions": [{
70992
+ name: "deviceId",
70993
+ form: "single",
70994
+ optional: false
70995
+ }],
70831
70996
  "dishwasher.getStatus": [{
70832
70997
  name: "deviceId",
70833
70998
  form: "single",
@@ -70838,6 +71003,11 @@ Object.freeze({
70838
71003
  form: "single",
70839
71004
  optional: false
70840
71005
  }],
71006
+ "dishwasher.resume": [{
71007
+ name: "deviceId",
71008
+ form: "single",
71009
+ optional: false
71010
+ }],
70841
71011
  "dishwasher.setChildLock": [{
70842
71012
  name: "deviceId",
70843
71013
  form: "single",
@@ -72924,6 +73094,9 @@ new Map(Object.entries({
72924
73094
  "wrapper-update-available": "system",
72925
73095
  "backup-completed": "system",
72926
73096
  "export-completed": "system",
73097
+ "alert-critical": "system",
73098
+ "alert-error": "system",
73099
+ "alert-critical-resolved": "system",
72927
73100
  "storage-location-low": "system",
72928
73101
  "storage-location-critical": "system",
72929
73102
  "storage-location-ok": "system",
@@ -73048,6 +73221,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
73048
73221
  "storage-location-ok"
73049
73222
  ]
73050
73223
  },
73224
+ {
73225
+ id: "alerts",
73226
+ family: "system",
73227
+ label: "Alerts",
73228
+ kinds: [
73229
+ "alert-critical",
73230
+ "alert-error",
73231
+ "alert-critical-resolved"
73232
+ ]
73233
+ },
73051
73234
  {
73052
73235
  id: "alarm",
73053
73236
  family: "alarm",
@@ -73092,6 +73275,21 @@ var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.ent
73092
73275
  return [[descriptor.kind, field]];
73093
73276
  })));
73094
73277
  Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
73278
+ object({
73279
+ phase: _enum(["raised", "resolved"]),
73280
+ episodeId: string().min(1),
73281
+ alertId: string().min(1),
73282
+ severity: AlertSeveritySchema,
73283
+ category: string(),
73284
+ title: string(),
73285
+ message: string(),
73286
+ sourceType: string().optional(),
73287
+ sourceId: string().optional(),
73288
+ nodeId: string().optional(),
73289
+ /** The alert's own action link (where the operator acts on it), when it has one. */
73290
+ actionUrl: string().optional(),
73291
+ at: number()
73292
+ });
73095
73293
  var RULE_BODY_ONLY = ["body"];
73096
73294
  var RULE_TEXT = ["title", "body"];
73097
73295
  var BATTERY = ["device-battery-low", "device-battery-normal"];
@@ -73101,6 +73299,11 @@ var TANK = [
73101
73299
  "device-tank-full",
73102
73300
  "device-tank-normal"
73103
73301
  ];
73302
+ var ALERT_EPISODE = [
73303
+ "alert-critical",
73304
+ "alert-error",
73305
+ "alert-critical-resolved"
73306
+ ];
73104
73307
  var UPDATES = [
73105
73308
  "addon-update-available",
73106
73309
  "server-update-available",
@@ -73293,14 +73496,14 @@ var STATE_SUMMARY_VARS = [
73293
73496
  ([...RULE_TEXT], [...CONSUMABLE]),
73294
73497
  ([...RULE_TEXT], [...TANK]),
73295
73498
  [...RULE_TEXT],
73296
- ([...RULE_TEXT], [...UPDATES]),
73297
- ([...RULE_TEXT], [...UPDATES]),
73298
- [...RULE_TEXT],
73499
+ ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
73500
+ ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
73299
73501
  [...RULE_TEXT],
73300
73502
  [...RULE_TEXT],
73301
73503
  [...RULE_TEXT],
73302
73504
  [...RULE_TEXT],
73303
73505
  [...RULE_TEXT],
73506
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73304
73507
  [...RULE_TEXT],
73305
73508
  [...RULE_TEXT],
73306
73509
  [...RULE_TEXT],
@@ -73318,7 +73521,11 @@ var STATE_SUMMARY_VARS = [
73318
73521
  [...RULE_TEXT],
73319
73522
  [...RULE_TEXT],
73320
73523
  [...RULE_TEXT],
73321
- [...RULE_TEXT],
73524
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73525
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73526
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73527
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73528
+ ([...RULE_TEXT], [...ALERT_EPISODE]),
73322
73529
  [...RULE_TEXT],
73323
73530
  [...RULE_TEXT],
73324
73531
  [...RULE_TEXT],
@@ -73877,7 +74084,7 @@ var AdminUIAddon = class extends BaseAddon {
73877
74084
  capability: adminUiCapability,
73878
74085
  provider: {
73879
74086
  getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
73880
- getVersion: async () => ({ version: "1.2.439" })
74087
+ getVersion: async () => ({ version: "1.2.440" })
73881
74088
  }
73882
74089
  }];
73883
74090
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-admin-ui",
3
- "version": "1.2.439",
3
+ "version": "1.2.440",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Admin UI — Vite frontend build and server-side addon",
@@ -1,4 +0,0 @@
1
- import{$ as e,B as t,G as n,J as r,L as i,S as a,b as o,o as s,q as c,x as l,z as u}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-CEHpkaJP.js";import{It as d,Nt as f,Ot as p,Q as m,Rn as h,Si as g,Tn as _,Wr as v,ai as y,bn as b,dt as x,fn as S,kn as C,or as w,pi as ee,pn as te,tn as T,un as E,vi as ne,xi as re}from"./player-overlays-CikRdqm6.js";import{Oi as ie}from"./client-Ca-96r9I.js";import{i as ae,l as oe}from"./video-IXUGebu2.js";import{$n as D,An as se,Br as ce,Cr as O,Dr as k,Dt as le,Er as ue,Fr as de,Hr as fe,K as A,Lr as j,Mn as pe,Mr as M,Nn as N,Nr as P,On as me,Or as he,Ot as F,Pn as I,Pr as ge,Rr as L,Tr as _e,Un as ve,Ur as R,Wr as z,cr as ye,er as B,jr as V,kn as be,kr as H,ru as xe,ts as U,tt as Se,vu as W,wr as G,xr as Ce,xu as K,zr as q}from"./src-Bt0KiIin.js";import{t as J}from"./useTranslation-D3Is_4B6.js";import"./mount-Dep-E57-.js";import{$ as Y,X,tt as we}from"./index-CIQcOfrF.js";import{t as Z}from"./AdminPage-CgbWYJ_a.js";import{t as Te}from"./NodeAddonsSettingsPanel-BfK00QUN.js";import{n as Q,t as Ee}from"./useNodeUrlSelection-D3zWAXku.js";function De(e){if(e===void 0)return null;switch(e.state){case`failed`:case`refused`:case`missing`:case`crashed`:return{kind:e.state,...e.reason===void 0?{}:{reason:e.reason}};default:return null}}e();var Oe={queued:{icon:y,bg:`bg-muted text-foreground-subtle`,labelKey:`addons.addonRowBadge.queued`},updating:{icon:w,bg:`bg-primary/10 text-primary`,labelKey:`addons.addonRowBadge.updating`,spin:!0},"done-pending-restart":{icon:b,bg:`bg-amber-500/10 text-amber-700`,labelKey:`addons.addonRowBadge.pendingRestart`},done:{icon:g,bg:`bg-success/10 text-success`,labelKey:`addons.addonRowBadge.done`},failed:{icon:ae,bg:`bg-danger/10 text-danger`,labelKey:`addons.addonRowBadge.failed`}};function ke({item:e}){let{t}=J(),n=Oe[e.status],r=n.icon;return a(`span`,{className:`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] rounded ${n.bg}`,title:e.error,children:[l(r,{className:`w-2.5 h-2.5 ${n.spin?`animate-spin`:``}`}),t(n.labelKey)]})}var Ae=new Set([`completed`,`failed`,`partially-failed`,`cancelled`]),je=new Set([`done`,`failed`,`skipped`]);function Me(e){return!je.has(e.phase)&&!Ae.has(e.jobState)}function Ne(e,t){let n=new Map,r=[...e].sort((e,t)=>e.createdAtMs-t.createdAtMs);for(let e of r){let r=Ae.has(e.state);for(let i of e.tasks)r&&i.finishedAtMs!==null&&t-i.finishedAtMs>6e4||n.set(i.packageName,{jobId:e.jobId,packageName:i.packageName,phase:i.phase,fromVersion:i.fromVersion,toVersion:i.toVersion,error:i.error,jobState:e.state,finishedAtMs:i.finishedAtMs})}return n}function Pe(){let{data:e}=M({activeOnly:!0},{refetchOnWindowFocus:!1,refetchInterval:e=>(e.state.data?.length??0)>0?3e3:!1}),{map:t}=K(ie.AddonsJobProgress,e=>e.job.jobId);return n(()=>{let n=new Map;for(let t of e??[])n.set(t.jobId,t);for(let[e,r]of t)n.set(e,r.job);return Ne([...n.values()],Date.now())},[e,t])}var Fe={queued:{icon:y,cls:`bg-muted text-foreground-subtle`,labelKey:`addons.jobProgress.queued`},fetching:{icon:w,cls:`bg-primary/10 text-primary`,labelKey:`addons.jobProgress.fetching`,spin:!0},staged:{icon:w,cls:`bg-primary/10 text-primary`,labelKey:`addons.jobProgress.staged`,spin:!0},validating:{icon:w,cls:`bg-primary/10 text-primary`,labelKey:`addons.jobProgress.validating`,spin:!0},applying:{icon:w,cls:`bg-primary/10 text-primary`,labelKey:`addons.jobProgress.applying`,spin:!0},restarting:{icon:w,cls:`bg-amber-500/10 text-amber-600 dark:text-amber-400`,labelKey:`addons.jobProgress.restarting`,spin:!0},applied:{icon:w,cls:`bg-primary/10 text-primary`,labelKey:`addons.jobProgress.finalizing`,spin:!0},done:{icon:g,cls:`bg-success/10 text-success`,labelKey:`addons.jobProgress.updated`},failed:{icon:ae,cls:`bg-danger/10 text-danger`,labelKey:`addons.jobProgress.failed`},skipped:{icon:T,cls:`bg-muted text-foreground-subtle`,labelKey:`addons.jobProgress.skipped`}};function Ie({progress:e}){let{t}=J(),n=Fe[e.phase],r=n.icon,i=e.error??`${e.packageName}: ${e.fromVersion??`?`} → ${e.toVersion}`;return a(`span`,{"data-testid":`addon-job-progress`,className:`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] rounded shrink-0 ${n.cls}`,title:i,children:[l(r,{className:`w-2.5 h-2.5 ${n.spin?`animate-spin`:``}`}),t(n.labelKey),a(`span`,{className:`font-mono`,children:[`→ `,e.toVersion]})]})}function Le(e,t){return e.filter(e=>e.packageName===t).slice().sort((e,t)=>e.isHub===t.isHub?e.nodeName.localeCompare(t.nodeName):e.isHub?-1:1)}function Re(e){let t=e.version===null?``:` ${e.version}`,n=e.isOnline?``:` (offline: removed when it reconnects)`;return`- ${e.nodeName}${t}${n}`}function ze(e,t,n){let r=[`${e} will be uninstalled from ${t.length} node(s). Its runners stop, its capabilities are deregistered and its code is deleted:`,...t.map(Re)];return n.length>0&&r.push(`Could not ask: ${n.join(`, `)} — not included.`),r.push(`This cannot be undone.`),r.join(`
2
- `)}function Be(e,t,n){let r=[`${e} will be uninstalled from ${t}: its runners stop and its code is deleted.`];return n.length>0&&r.push(`It stays installed on: ${n.map(e=>e.nodeName).join(`, `)}. Use "Everywhere" to remove it from every node.`),r.push(`This cannot be undone.`),r.join(`
3
- `)}var Ve={uninstalled:`uninstalled`,"not-installed":`was not installed`,refused:`REFUSED`,failed:`FAILED`,"pending-reconnect":`offline — removed when it reconnects`};function He(e,t){let n=[];for(let r of e.results){let e=r.runnersStopped.length>0?` (stopped ${r.runnersStopped.join(`, `)})`:``;n.push(`${t(r.nodeId)}: ${Ve[r.outcome]}${e}`),r.error!==void 0&&n.push(` ${r.error}`);for(let e of r.warnings)n.push(` ${e}`)}return n.join(`
4
- `)}var Ue={},We=3e4,Ge=`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-red-400 hover:border-red-500/30 hover:bg-red-500/10 disabled:opacity-50 transition-colors`;function Ke({packageName:e,displayName:t,selectedNode:n,hideNodeAction:r,disabled:i}){let{t:o}=J(),c=s(),u=B(),f=D(),p=V(Ue,{staleTime:We}),m=p.data?.installations??[],h=(p.data?.unreachable??[]).map(e=>e.nodeId),g=Le(m,e),_=e=>g.find(t=>t.nodeId===e)?.nodeName??(e===n.id?n.name:e),v=R({onSettled:()=>{c.invalidateQueries({queryKey:[[`addons`]]}),c.invalidateQueries({queryKey:[[`addonPages`]]}),c.invalidateQueries({queryKey:[[`capabilities`]]}),c.invalidateQueries({queryKey:[[`nodes`]]})}}),y=async e=>{await f({title:e.success?o(`addons.addonUninstallControls.uninstalled`,`{{displayName}} uninstalled`,{displayName:t}):o(`addons.addonUninstallControls.notEveryNodeWasCleaned`,`{{displayName}}: not every node was cleaned`,{displayName:t}),message:He(e,_),variant:e.success?`default`:`danger`})},b=async n=>{try{await y(await v.mutateAsync({packageName:e,...n}))}catch(e){await f({title:o(`addons.addonUninstallControls.uninstallFailed`,`Uninstall {{displayName}} failed`,{displayName:t}),message:e instanceof Error?e.message:String(e),variant:`danger`})}},x=async()=>{let e=g.filter(e=>e.nodeId!==n.id);await u({title:o(`addons.addonUninstallControls.uninstallFrom`,`Uninstall {{displayName}} from {{name}}?`,{displayName:t,name:n.name}),message:Be(t,n.name,e),confirmLabel:o(`addons.addonUninstallControls.uninstall`,`Uninstall`),variant:`danger`})&&await b(n.isHub?{}:{nodeId:n.id})},S=async()=>{let n=(await p.refetch()).data;if(n===void 0){await f({title:o(`addons.addonUninstallControls.cannotListTheNodes`,`Cannot list the nodes`),message:o(`addons.addonUninstallControls.theHubDidNotAnswer`,`The hub did not answer which nodes have this package — nothing was removed.`),variant:`danger`});return}let r=Le(n.installations,e);await u({title:o(`addons.addonUninstallControls.uninstallEverywhere`,`Uninstall {{displayName}} everywhere?`,{displayName:t}),message:ze(t,r,n.unreachable.map(e=>e.nodeId)),confirmLabel:o(`addons.addonUninstallControls.uninstallFromNodeS`,`Uninstall from {{length}} node(s)`,{length:r.length}),variant:`danger`})&&await b({everywhere:!0})},C=v.isPending||i===!0;return a(`div`,{className:`flex items-center gap-1.5`,children:[r!==!0&&a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),x()},disabled:C,className:Ge,title:o(`addons.addonUninstallControls.uninstallFrom2`,`Uninstall from {{name}}`,{name:n.name}),children:[l(d,{className:`h-3 w-3`}),v.isPending?o(`addons.addonUninstallControls.removing`,`Removing...`):o(`addons.addonUninstallControls.uninstall`,`Uninstall`)]}),(g.length>1||r===!0||h.length>0)&&a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),S()},disabled:C,className:Ge,title:o(`addons.addonUninstallControls.uninstallFromEveryNodeThat`,`Uninstall from every node that has it`),children:[l(oe,{className:`h-3 w-3`}),g.length>0?o(`addons.uninstallControls.everywhereCount`,{count:g.length}):o(`addons.uninstallControls.everywhere`)]})]})}function qe({packageName:e,currentVersion:t,installSource:n,onInstall:r,onClose:i,onSelect:s,selectedVersion:c}){let{t:u}=J(),d=n===`upload`||n===`local`,{data:f,isLoading:m}=k({name:e});return a(`div`,{className:`fixed z-50 w-72 rounded-lg border border-border bg-surface shadow-xl overflow-hidden`,style:{top:`auto`,bottom:`auto`},ref:e=>{if(!e)return;let t=e.parentElement?.getBoundingClientRect();if(!t)return;let n=window.innerHeight-t.bottom,r=t.top;n<280&&r>n?(e.style.bottom=`${window.innerHeight-t.top+4}px`,e.style.top=`auto`):(e.style.top=`${t.bottom+4}px`,e.style.bottom=`auto`),e.style.right=`${window.innerWidth-t.right}px`},onClick:e=>e.stopPropagation(),children:[a(`div`,{className:`flex items-center justify-between px-3 py-2 border-b border-border`,children:[l(`span`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle font-medium`,children:u(`addons.versionPicker.versions`,`Versions`)}),l(`button`,{type:`button`,onClick:i,className:`text-foreground-subtle hover:text-foreground`,children:l(x,{className:`h-3 w-3`})})]}),d&&a(`div`,{className:`flex items-start gap-2 px-3 py-2 border-b border-border bg-cyan-500/10 text-[10px]`,children:[l(p,{className:`h-3 w-3 mt-0.5 text-cyan-500 shrink-0`}),a(`div`,{className:`text-cyan-700 dark:text-cyan-200`,children:[l(`span`,{className:`font-semibold`,children:u(`addons.versionPicker.inPlace`,{kind:n===`upload`?u(`addons.versionPicker.uploadedCopy`,`Uploaded copy`):u(`addons.versionPicker.localCopy`,`Local copy`)})}),` `,l(X,{i18nKey:`addons.versionPicker.reinstall`,values:{version:t},components:{mono:l(`span`,{className:`font-mono`})}})]})]}),m&&a(`div`,{className:`flex items-center justify-center gap-2 py-6 text-[10px] text-foreground-subtle`,children:[l(w,{className:`h-3.5 w-3.5 animate-spin`}),u(`addons.versionPicker.loadingVersions`,`Loading versions...`)]}),f&&l(`div`,{className:`max-h-64 overflow-auto divide-y divide-border`,children:f.map(e=>{let n=e.version===t,i=s!==void 0&&e.version===c,d=/-(alpha|beta|rc|dev|canary|next)/i.test(e.version),f=a(o,{children:[l(`span`,{className:`font-mono flex-1 text-left ${n?`text-primary font-semibold`:d?`text-amber-400`:`text-foreground`}`,children:e.version}),n&&l(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium bg-primary/10 text-primary`,children:u(`common.current`)}),e.distTags.map(e=>l(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e===`latest`?`bg-emerald-500/15 text-emerald-400`:e===`beta`?`bg-amber-500/15 text-amber-400`:`bg-gray-500/15 text-gray-400`}`,children:e},e)),e.deprecated&&l(`span`,{className:`text-[9px] text-red-400 line-through`,children:u(`common.deprecated`)}),l(`span`,{className:`text-[9px] text-foreground-subtle shrink-0`,children:new Date(e.publishedAt).toLocaleDateString()})]});return s?a(`button`,{type:`button`,"aria-label":u(`addons.versionPicker.select`,`Select {{version}}`,{version:e.version}),onClick:()=>s(e.version),className:`w-full flex items-center gap-2 px-3 py-2 text-[11px] ${i?`bg-primary/5`:`hover:bg-surface-hover`} transition-colors`,children:[f,i?l(g,{className:`h-3 w-3 text-primary shrink-0`}):l(`span`,{className:`w-3 shrink-0`})]},e.version):a(`div`,{className:`flex items-center gap-2 px-3 py-2 text-[11px] ${n?`bg-primary/5`:`hover:bg-surface-hover`} transition-colors`,children:[f,l(`button`,{type:`button`,onClick:()=>r(e.version),className:`shrink-0 rounded p-0.5 hover:bg-primary/20 text-foreground-subtle hover:text-primary transition-colors`,title:n?u(`addons.versionPicker.reInstallFromNpm`,`Re-install {{version}} from npm`,{version:e.version}):u(`addons.versionPicker.install`,`Install {{version}}`,{version:e.version}),children:l(v,{className:`h-3 w-3`})})]},e.version)})}),f&&f.length===0&&l(`div`,{className:`py-4 text-center text-[10px] text-foreground-subtle`,children:u(`addons.versionPicker.noVersionsFound`,`No versions found`)})]})}e();var Je=`device-export`;function Ye(e){return e.capabilities.some(e=>(typeof e==`string`?e:e.name)===Je)}function Xe(e){return e!==`local`&&e!==`upload`}function Ze({isBundle:e,installSource:t,addonId:n,iconPath:i,color:o}){let[s,c]=r(!1),u=o?{backgroundColor:`${o.startsWith(`#`)?o:`#${o}`}26`}:void 0,d=e?`bg-indigo-500/20 text-indigo-700 dark:text-indigo-300`:`bg-purple-500/20 text-purple-700 dark:text-purple-300`,f=n&&i?m(`/api/addon-assets/${n}/${i}`):null,g=!!f&&!s;return a(`div`,{className:`relative flex-shrink-0`,children:[l(`div`,{className:`h-8 w-8 rounded-md flex items-center justify-center ${u?``:d}`,style:u,children:g?l(`img`,{src:f,alt:n,className:`h-4 w-4`,onError:()=>c(!0)}):l(e?h:_,{className:`h-3.5 w-3.5`})}),t===`local`&&l(`span`,{className:`absolute -top-1.5 -left-1.5 text-[7px] font-bold leading-none bg-orange-500 text-white px-1 py-0.5 rounded -rotate-12 shadow-sm`,children:`DEV`}),Xe(t)&&l(`span`,{className:`absolute -top-1 -left-1 w-4 h-4 rounded bg-[#cb3837] flex items-center justify-center -rotate-12 shadow-sm`,children:l(`svg`,{viewBox:`0 0 780 250`,className:`w-[11px] h-[11px]`,children:l(`path`,{fill:`#fff`,d:`M240 250h100V50h100v200h340V0H0v250z`})})}),t===`upload`&&l(`span`,{className:`absolute -top-1.5 -left-1.5 flex items-center justify-center h-4 w-4 rounded bg-cyan-500 -rotate-12 shadow-sm`,children:l(p,{className:`h-2.5 w-2.5 text-white`})})]})}function Qe({version:e,availableUpdate:t,selectedVersion:n,isUpdating:r,installSource:i,disabled:o,onUpdate:s,onOpenPicker:c,children:u}){let{t:d}=J();if(r)return a(`span`,{className:`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] font-medium border border-blue-500/30 bg-blue-500/10 text-blue-400 shrink-0`,children:[l(w,{className:`h-3 w-3 animate-spin`}),d(`addons.addonCard.updating`,`Updating…`)]});if(t){let r=n??t;return a(`div`,{className:`relative inline-flex items-center gap-1 shrink-0`,children:[s&&a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),s()},disabled:o,className:`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] font-semibold border border-blue-500/30 bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,title:d(`addons.addonCard.updateTo`,`Update to {{target}}`,{target:r}),children:[l(v,{className:`h-3 w-3`}),d(`addons.addonCard.update`,`Update`)]}),a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),c()},disabled:o,"aria-label":d(`addons.addonCard.selectVersionToInstall`,`Select version to install`),title:d(`addons.addonCard.installedUpdateAvailableSelectedTap`,`Installed {{version}} — update available. Selected {{target}}; tap to choose another version.`,{version:e,target:r}),className:`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] font-bold font-mono border border-amber-500/40 bg-amber-500/15 text-amber-500 hover:bg-amber-500/25 animate-pulse disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,children:[l(`span`,{className:`font-normal opacity-70`,children:e}),l(`span`,{className:`font-normal opacity-70`,children:`→`}),r,l(re,{className:`h-3 w-3`})]}),u]})}return a(`div`,{className:`relative inline-flex items-center gap-1 shrink-0`,children:[a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),c()},disabled:o,className:[`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] font-bold font-mono border transition-colors disabled:opacity-50 disabled:cursor-not-allowed`,i===`local`?`border-orange-500/30 bg-orange-500/10 text-orange-400 hover:bg-orange-500/20`:`border-emerald-500/30 bg-emerald-500/10 text-emerald-400 hover:bg-emerald-500/20`].join(` `),title:d(`addons.addonCard.versionTapToViewAll`,`Version {{version}} — tap to view all versions`,{version:e}),children:[e,l(re,{className:`h-3 w-3 opacity-50`})]}),u]})}function $e({addonId:e}){let t=s(),{data:n=`inherit`}=G({addonId:e}),r=q({onSuccess:()=>{t.invalidateQueries({queryKey:[[`addons`,`getAddonAutoUpdate`]]})}});return l(`div`,{className:`flex rounded-lg border border-border overflow-hidden text-[10px] font-medium`,children:[`inherit`,`off`,`latest`,`beta`].map(t=>l(`button`,{type:`button`,onClick:n=>{n.stopPropagation(),r.mutate({addonId:e,channel:t})},disabled:r.isPending,className:`px-2.5 py-1 transition-colors capitalize ${n===t?t===`inherit`?`bg-gray-700/50 text-gray-700 dark:text-gray-300`:t===`off`?`bg-gray-700 text-gray-700 dark:text-gray-300`:t===`latest`?`bg-blue-500/20 text-blue-400`:`bg-amber-500/20 text-amber-400`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`} ${t===`inherit`?``:`border-l border-border`}`,children:t},t))})}var et={id:`hub`,name:`Hub`,isHub:!0};function tt({addon:e,agents:n=[],clusterStatus:i,hideVersion:c,availableUpdate:u,onUpdate:d,isUpdating:f,jobProgress:p,bundle:m,bulkItem:g,disabledByBulk:_,isSystem:v,selectedNode:y}){let{t:S}=J(),[w,ee]=r(!1),[T,ie]=r(!1),[oe,D]=r(!1),[ce,O]=r(null);t(()=>{O(null)},[u]);let k=ce??u,[ue,fe]=r(!1),[A,M]=r(!1),[P,ge]=r(`logs`),L=s(),_e=Y(),{manifest:R}=e,z=e.installedOn??[],ye=!m&&!R.protected&&R.removable!==!1,B=!!m,V=m?.displayName??R.name,H=m?.packageName??R.packageName,xe=m?.version??R.packageVersion??R.version,U=m?.installSource??e.installSource,W=m?m.bundle?.description??m.addons[0]?.manifest.description:R.description,G=de({onSuccess:()=>{L.invalidateQueries({queryKey:[[`addons`]]})}}),Ce=he({onSuccess:()=>{L.invalidateQueries({queryKey:[[`addons`]]}),L.invalidateQueries({queryKey:[[`addonPages`]]}),L.invalidateQueries({queryKey:[[`capabilities`]]}),L.invalidateQueries({queryKey:[[`integrations`]]})}}),K=j({onSuccess:()=>{L.invalidateQueries({queryKey:[[`addons`]]}),L.invalidateQueries({queryKey:[[`alerts`]]})}}),q=e.health,X=q?.phase===`failed`&&!q.inGracePeriod,we=X&&q?.nextRetryAt&&!q.retrying,Z=De(e.process);return a(`div`,{className:`rounded-md border bg-surface overflow-hidden ${X?`border-red-500/50`:`border-border`}`,children:[X&&q&&a(`div`,{className:`bg-danger/10 border-b border-danger/30 px-3 py-2 flex items-start gap-2`,children:[l(ae,{className:`h-4 w-4 text-danger shrink-0 mt-0.5`}),a(`div`,{className:`flex-1 min-w-0`,children:[l(`div`,{className:`text-xs font-semibold text-danger`,children:S(`addons.addonCard.failedToLoad`,{attempt:q.retryCount})}),l(`div`,{className:`text-[11px] text-foreground mt-0.5 break-words font-mono`,children:q.lastError?.message??S(`addons.addonCard.unknownError`,`Unknown error`)}),we&&q.nextRetryAt&&l(`div`,{className:`text-[10px] text-foreground-subtle mt-1`,children:S(`addons.addonCard.autoRetryAt`,{time:new Date(q.nextRetryAt).toLocaleTimeString()})})]}),a(`button`,{type:`button`,disabled:K.isPending||q.retrying,onClick:e=>{e.stopPropagation(),K.mutate({packageName:H})},className:`inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-[11px] font-semibold border border-red-400/40 bg-red-400/10 text-red-700 dark:text-red-300 hover:bg-red-400/20 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0`,title:S(`addons.addonCard.resetRetryCounterAndForce`,`Reset retry counter and force immediate reload`),children:[l(b,{className:`h-3 w-3 ${K.isPending||q.retrying?`animate-spin`:``}`}),S(`addons.addonCard.retryNow`,`Retry now`)]})]}),Z!==null&&a(`div`,{className:`bg-danger/10 border-b border-danger/30 px-3 py-2 flex items-start gap-2`,children:[l(ae,{className:`h-4 w-4 text-danger shrink-0 mt-0.5`}),a(`div`,{className:`flex-1 min-w-0`,children:[l(`div`,{className:`text-xs font-semibold text-danger`,children:S(`addons.addonCard.processProblem.${Z.kind}`)}),Z.reason!==void 0&&l(`div`,{className:`text-[11px] text-foreground mt-0.5 break-words font-mono`,children:Z.reason})]})]}),a(`div`,{className:`flex items-start gap-2.5 px-3 py-2`,children:[l(Ze,{isBundle:B||!!R.components&&R.components.length>1,installSource:U,addonId:B?m.addons[0]?.manifest.id:R.id,iconPath:B?m.bundle?.icon??m.addons[0]?.manifest.icon:R.icon,color:B?m.addons[0]?.manifest.color:R.color}),a(`div`,{className:`flex-1 min-w-0`,children:[a(`div`,{className:`flex items-start justify-between gap-2`,children:[l(`span`,{className:`text-xs font-semibold text-foreground truncate min-w-0`,children:V}),!c&&l(Qe,{version:xe,availableUpdate:u,...k===void 0?{}:{selectedVersion:k},isUpdating:f,installSource:U,disabled:_,...d&&k!==void 0?{onUpdate:()=>d(k)}:{},onOpenPicker:()=>D(e=>!e),children:oe&&l(qe,{packageName:H,currentVersion:xe,...U?{installSource:U}:{},...u!==void 0&&k!==void 0?{selectedVersion:k,onSelect:e=>{O(e),D(!1)}}:{},onInstall:e=>{D(!1),Ce.mutate({packageName:H,version:e})},onClose:()=>D(!1)})})]}),a(`div`,{className:`flex flex-wrap items-center gap-x-1.5 gap-y-1 mt-0.5`,children:[H!==V&&l(`span`,{className:`text-[10px] text-foreground-subtle font-mono truncate max-w-full`,children:H}),B&&a(`span`,{className:`text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium shrink-0 inline-flex items-center gap-1`,children:[l(h,{className:`h-3 w-3`}),m.addons.length]}),v&&a(`span`,{className:`text-[10px] rounded-full bg-amber-500/15 text-amber-700 dark:text-amber-300 px-2 py-0.5 font-medium shrink-0 inline-flex items-center gap-1`,title:S(`addons.addonCard.systemPackageUpdatingRestartsThe`,`System package — updating restarts the hub`),children:[l(b,{className:`h-3 w-3`}),S(`addons.addonCard.system`,`System`)]}),g!=null&&l(ke,{item:g}),p!=null&&l(Ie,{progress:p})]}),W&&l(`p`,{className:`text-[10px] text-foreground-subtle mt-1 line-clamp-1`,children:W}),!B&&e.process&&a(`div`,{className:`flex flex-wrap items-center gap-1.5 mt-1`,children:[l(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.mode===`forked`?`bg-blue-500/15 text-blue-400`:`bg-gray-500/15 text-gray-400`}`,children:e.process.mode===`forked`?S(`addons.addonCard.forked`):S(`addons.addonCard.inProcess`)}),e.process.pid!=null&&a(`span`,{className:`text-[9px] font-mono text-foreground-subtle`,children:[`PID `,e.process.pid]}),l(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.state===`running`?`bg-emerald-500/15 text-emerald-400`:Z===null?`bg-gray-500/15 text-gray-400`:`bg-red-500/15 text-red-400`}`,children:e.process.state})]})]})]}),!B&&a(`div`,{className:`flex items-center gap-1 px-3 py-1 border-t border-border/50 bg-surface-hover/20`,children:[a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),G.mutate({addonId:R.id})},disabled:G.isPending||_,className:`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] font-medium border border-border text-foreground-subtle hover:text-blue-400 hover:border-blue-500/30 hover:bg-blue-500/10 disabled:opacity-50 transition-colors`,children:[l(b,{className:`h-3 w-3 ${G.isPending?`animate-spin`:``}`}),S(`addons.addonCard.restart`,`Restart`)]}),a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),fe(e=>!e)},className:`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] font-medium border transition-colors ${ue?`border-primary/30 bg-primary/10 text-primary`:`border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10`}`,children:[l(te,{className:`h-3 w-3`}),S(`addons.addonCard.logs`,`Logs`)]}),!B&&a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),M(!0)},className:`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] font-medium border transition-colors ${A?`border-primary/30 bg-primary/10 text-primary`:`border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10`}`,children:[l(E,{className:`h-3 w-3`}),S(`addons.addonCard.settings`,`Settings`)]}),l(`div`,{className:`flex-1`}),ye&&l(Ke,{packageName:R.packageName,displayName:R.name,selectedNode:y??et,disabled:_})]}),i&&i.nodes.length>1&&!B&&a(`div`,{className:`border-t border-border px-3 py-1.5 bg-muted/10`,children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle mb-1.5`,children:S(`addons.addonCard.clusterDeployment`,`Cluster Deployment`)}),l(`div`,{className:`space-y-1`,children:i.nodes.map(e=>a(`div`,{className:`flex items-center gap-2 text-[10px]`,children:[l(`div`,{className:`h-1.5 w-1.5 rounded-full shrink-0 ${e.status===`offline`?`bg-muted-foreground/30`:e.synced?`bg-success`:`bg-amber-500`}`}),l(`span`,{className:`font-medium text-foreground min-w-[60px]`,children:e.name}),l(`span`,{className:`font-mono text-foreground-subtle`,children:e.version}),!e.synced&&e.status!==`offline`&&l(`span`,{className:`text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-400 border border-amber-500/20`,children:S(`addons.addonCard.outdated`)}),e.status===`offline`&&l(`span`,{className:`text-[9px] px-1 py-0.5 rounded bg-muted text-muted-foreground`,children:S(`common.offline`)}),e.synced&&e.status!==`offline`&&l(`span`,{className:`text-[9px] text-success`,children:S(`common.synced`)})]},e.nodeId))})]}),ue&&!B&&a(`div`,{className:`border-t border-border`,children:[a(`div`,{className:`flex items-center px-3 py-0.5 bg-surface-hover/20 border-b border-border/50`,children:[a(`div`,{className:`flex rounded border border-border overflow-hidden text-[9px]`,children:[l(`button`,{type:`button`,onClick:()=>ge(`logs`),className:`px-2 py-0.5 transition-colors ${P===`logs`?`bg-primary/10 text-primary`:`text-foreground-subtle hover:bg-surface-hover`}`,children:S(`addons.addonCard.logs`,`Logs`)}),l(`button`,{type:`button`,onClick:()=>ge(`events`),className:`px-2 py-0.5 border-l border-border transition-colors ${P===`events`?`bg-primary/10 text-primary`:`text-foreground-subtle hover:bg-surface-hover`}`,children:S(`addons.addonCard.events`,`Events`)})]}),l(`div`,{className:`flex-1`}),l(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),fe(!1)},className:`text-foreground-subtle hover:text-foreground`,children:l(x,{className:`h-3.5 w-3.5`})})]}),P===`logs`&&l(F,{addonId:R.id,maxHeight:`max-h-64`,showFilters:!1}),P===`events`&&l(le,{addonId:R.id,category:`addon.*`,maxHeight:`max-h-64`})]}),B&&a(o,{children:[l(`button`,{type:`button`,onClick:()=>ee(e=>!e),className:`w-full flex items-center justify-center border-t border-border py-1 hover:bg-surface-hover/50 transition-colors`,children:l(w?ne:re,{className:`h-3.5 w-3.5 text-foreground-subtle`})}),w&&l(`div`,{className:`border-t border-border px-2.5 py-1.5 space-y-1.5`,children:m.addons.map(e=>l(tt,{addon:e,agents:n,hideVersion:!0},e.manifest.id))})]}),A&&!B&&l(me,{open:!0,onOpenChange:e=>!e&&M(!1),children:a(se,{width:`lg`,placement:`sheet-on-mobile`,scroll:`body`,children:[l(N,{children:a(I,{className:`flex items-center gap-2`,children:[l(E,{className:`h-4 w-4 text-primary`}),S(`addons.addonCard.settingsTitle`,{name:V})]})}),a(be,{className:`space-y-4`,children:[l(`div`,{className:`text-[10px] text-foreground-subtle mb-2`,children:S(`addons.addonCard.clusterWideSettingsOneValue`,`Cluster-wide settings — one value for every node. Per-node settings live under Cluster → the node → Settings.`)}),l(Te,{nodeId:null,addonIds:[R.id],level:`global`,fieldScope:`cluster`,emptyMessage:S(`addons.addonCard.thisAddonExposesNoCluster`,`This addon exposes no cluster-wide settings. Anything it can configure is per-node — open it from Cluster → the node → Settings.`)}),Ye(R)&&a(`div`,{children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:S(`addons.addonCard.deviceExport`,`Device export`)}),l(Se,{addonId:R.id,onOpenDevice:e=>_e(`/devices/${e}`)})]}),Xe(U)&&a(`div`,{children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:S(`addons.addonCard.autoUpdate`,`Auto-Update`)}),l($e,{addonId:R.id})]}),R.components&&R.components.length>0&&a(`div`,{children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:S(`addons.addonCard.components`,{count:R.components.length})}),l(`div`,{className:`flex flex-wrap gap-1`,children:R.components.map(e=>l(`span`,{className:`text-[10px] rounded bg-background border border-border px-1.5 py-0.5 text-foreground-subtle font-mono`,children:e},e))})]}),n.length>=2&&a(`div`,{children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:S(`addons.addonCard.installedOn`,`Installed on`)}),a(`div`,{className:`flex items-center gap-1.5 flex-wrap`,children:[z.length===0&&l(`span`,{className:`text-[10px] text-foreground-subtle`,children:S(`addons.addonCard.hubLocal`,`Hub (local)`)}),z.map(e=>l(`span`,{className:`rounded-full bg-surface-hover border border-border px-2 py-0.5 text-[10px] text-foreground-subtle`,children:e},e)),a(`div`,{className:`relative`,children:[a(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),ie(e=>!e)},className:`inline-flex items-center gap-1 rounded-full border border-dashed border-border px-2 py-0.5 text-[10px] text-foreground-subtle hover:text-foreground hover:border-primary transition-colors`,title:S(`addons.addonCard.installOnMoreAgents`,`Install on more agents`),children:[l(C,{className:`h-3 w-3`}),S(`addons.addonCard.addAgent`,`Add agent`)]}),T&&a(`div`,{className:`absolute left-0 top-full mt-1 z-10 min-w-[160px] rounded-md border border-border bg-surface shadow-lg overflow-hidden`,children:[n.filter(e=>!e.isHub&&!z.includes(e.name)).map(e=>l(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),ie(!1)},className:`w-full text-left px-3 py-1.5 text-[10px] text-foreground hover:bg-surface-hover transition-colors`,children:e.name},e.id)),n.filter(e=>!e.isHub&&!z.includes(e.name)).length===0&&l(`div`,{className:`px-3 py-1.5 text-[10px] text-foreground-subtle`,children:S(`addons.addonCard.noAvailableAgents`,`No available agents`)})]})]})]})]})]}),l(pe,{children:l(ve,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>M(!1),children:S(`common.close`,`Close`)})})]})})]})}e();var nt=`.tgz,.tar.gz,.zip`;function rt({onUploadSuccess:e}){let{t}=J(),[n,s]=r(!1),u=c(null),d=i(async t=>{s(!0);let n=new FormData;n.append(`file`,t);let r=localStorage.getItem(`camstack_admin_token`)??``;try{(await(await fetch(m(`/api/addons/upload`),{method:`POST`,headers:{Authorization:`Bearer ${r}`},body:n})).json()).success&&e()}finally{s(!1)}},[e]);return a(o,{children:[l(`input`,{ref:u,type:`file`,accept:nt,onChange:i(e=>{let t=e.target.files?.[0];t&&d(t),e.target.value=``},[d]),className:`hidden`}),a(`button`,{type:`button`,onClick:()=>u.current?.click(),disabled:n,className:`flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,children:[n?l(w,{className:`w-3.5 h-3.5 animate-spin`}):l(p,{className:`w-3.5 h-3.5`}),n?t(`addons.addonUploadZone.uploading`,`Uploading...`):t(`addons.addonUploadZone.upload`,`Upload`)]})]})}var it=new Set([`@camstack/system`,`@camstack/types`,`@camstack/sdk`,`@camstack/ui-library`,`@camstack/addon-agent-ui`]);function at(e,t){let n=new Map;for(let r of e){if(r.isHub||r.onHub||it.has(r.packageName)||!t.isHub&&r.nodeId!==t.id)continue;let e=n.get(r.packageName)??[];e.push(r),n.set(r.packageName,e)}return[...n].map(([e,t])=>({packageName:e,rows:t})).sort((e,t)=>e.packageName.localeCompare(t.packageName))}function ot({selectedNode:e}){let{t}=J(),{data:n}=V(Ue,{staleTime:We});if(n===void 0)return null;let r=at(n.installations,e),i=n.unreachable.filter(t=>e.isHub||t.nodeId===e.id);return r.length===0&&i.length===0?null:a(`div`,{className:`rounded-lg border border-warning/30 bg-warning/5 px-3 py-2.5 space-y-2`,children:[a(`div`,{className:`flex items-center gap-2 text-[11px] font-semibold text-foreground`,children:[l(f,{className:`h-3.5 w-3.5 text-warning`}),e.isHub?t(`addons.nodeOnlyPackagesPanel.installedOnAgentsButNot`,`Installed on agents but not on the hub`):t(`addons.nodeOnlyPackagesPanel.installedOnButNotOn`,`Installed on {{name}} but not on the hub`,{name:e.name})]}),i.length>0&&l(`div`,{className:`text-[10px] text-foreground-subtle`,children:t(`addons.nodeOnlyPackagesPanel.unreachable`,{nodes:i.map(e=>e.nodeId).join(`, `)})}),r.map(t=>a(`div`,{className:`flex items-center justify-between gap-3 flex-wrap rounded-md border border-border bg-surface px-3 py-2`,children:[a(`div`,{className:`min-w-0`,children:[l(`div`,{className:`text-xs font-mono text-foreground break-all`,children:t.packageName}),l(`div`,{className:`text-[10px] text-foreground-subtle`,children:t.rows.map(e=>`${e.nodeName}${e.version===null?``:` ${e.version}`}${e.isOnline?``:` (offline)`}`).join(` · `)})]}),l(Ke,{packageName:t.packageName,displayName:t.packageName,selectedNode:e,hideNodeAction:e.isHub})]},t.packageName))]})}function st({addon:e,installing:t,onInstall:n}){let{t:r}=J();return a(`div`,{className:`flex items-center gap-3 px-3 py-2 hover:bg-surface-hover transition-colors`,children:[l(`div`,{className:`w-6 h-6 rounded-md bg-primary/10 flex items-center justify-center text-primary text-[9px] font-bold shrink-0`,children:e.name.replace(`@camstack/addon-`,``).charAt(0).toUpperCase()}),a(`div`,{className:`flex-1 min-w-0`,children:[a(`div`,{className:`flex items-baseline gap-2 min-w-0`,children:[l(`span`,{className:`text-[11px] font-semibold break-words`,children:e.name.replace(/^@camstack\/(addon-)?/,``)}),a(`span`,{className:`text-[10px] text-foreground-subtle shrink-0`,children:[`v`,e.version]})]}),l(`div`,{className:`font-mono text-[9px] text-foreground-subtle/80 truncate`,children:e.name}),e.description&&l(`div`,{className:`text-[10px] text-foreground-subtle truncate`,children:e.description})]}),e.installed?l(ye,{variant:`success`,icon:l(g,{className:`h-3 w-3`}),children:e.installedVersion??r(`system.capabilityCatalog.installed`,`Installed`)}):a(ve,{size:`sm`,onClick:()=>n(e.name),disabled:t,className:`shrink-0`,children:[t?l(w,{className:`h-3 w-3 animate-spin`}):l(v,{className:`h-3 w-3`}),r(`system.capabilityCatalog.install`,`Install`)]})]})}function ct({capability:e,installing:t,onInstall:n}){let{t:r}=J(),{data:i,isPending:o,isError:s}=L({capability:e}),c;if(s)c=l(`div`,{className:`px-3 py-2 text-xs text-danger`,children:r(`system.capabilityCatalog.couldNotSearchTheNpm`,`Could not search the npm catalog right now. Try again in a moment.`)});else if(o||i===void 0)c=a(`div`,{className:`flex items-center gap-2 px-3 py-2 text-xs text-foreground-subtle`,children:[l(w,{className:`h-3 w-3 animate-spin`}),r(`system.capabilityCatalog.searchingTheNpmCatalog`,`Searching the npm catalog…`)]});else{let a=i.filter(e=>!e.installed);c=a.length===0?l(`div`,{className:`px-3 py-2 text-xs text-foreground-subtle`,children:i.length===0?r(`system.capabilityCatalog.noPublishedAddonDeclaresThe`,`No published addon declares the "{{capability}}" capability.`,{capability:e}):r(`system.capabilityCatalog.everyPublishedAddonThatDeclares`,`Every published addon that declares "{{capability}}" is already installed.`,{capability:e})}):l(`div`,{className:`divide-y divide-border`,children:a.map(e=>l(st,{addon:e,installing:t,onInstall:n},e.name))})}return a(`section`,{className:`rounded-md border border-border bg-surface overflow-hidden`,"aria-label":r(`system.capabilityCatalog.availableToInstall`,`Available to install`),children:[l(`h2`,{className:`px-3 py-1.5 text-[10px] uppercase tracking-wide text-foreground-subtle border-b border-border`,children:r(`system.capabilityCatalog.availableToInstall`,`Available to install`)}),c]})}e();function lt(e){return e===`npm`||e===`dev`?e:null}var ut=`rounded-full border border-primary bg-primary/10 px-2 py-0.5 text-[10px] text-foreground`,dt=`rounded-full border border-border px-2 py-0.5 text-[10px] text-foreground-muted hover:bg-surface-hover`,ft=[{seconds:900,label:`15m`},{seconds:3600,label:`1h`},{seconds:21600,label:`6h`},{seconds:43200,label:`12h`},{seconds:86400,label:`24h`}],pt=new Set([`@camstack/system`,`@camstack/types`,`@camstack/sdk`,`@camstack/shm-ring`,`@camstack/ui-library`]);function mt(e){return e!==void 0&&pt.has(e)}var ht={id:`hub`,name:`Hub`,isHub:!0,isOnline:!0};function gt(e,t){let n=e??`hub-only`;return n===`any-node`?!0:n===`hub-only`?t:!t}function _t(e){return e===`local`?`dev`:`npm`}function vt(e){let t=e;if(!t?.manifest)return null;let n={...t.manifest,name:t.manifest.name??t.manifest.id,version:t.manifest.version??`0.0.0`,capabilities:t.manifest.capabilities??[]},r=t.process,i=r?{pid:r.pid,mode:r.mode===`forked`?`forked`:`in-process`,state:r.state??`unknown`,...r.reason===void 0?{}:{reason:r.reason}}:void 0,a=t.health,o=t.declaration?.execution,s=t.manifest.execution,c=o?.placement??s?.placement;return{manifest:n,enabled:!0,source:t.source,installSource:t.installSource,installedOn:[],...i?{process:i}:{},hasBackup:t.hasBackup,...a?{health:a}:{},...c?{placement:c}:{}}}function yt(e){let t=new Map,n=[];for(let r of e){let e=r.manifest.packageName;if(!e){n.push(r);continue}let i=t.get(e);if(i)i.addons.push(r);else{let n=r.manifest.bundle,i={packageName:e,displayName:n?.displayName??r.manifest.packageDisplayName??r.manifest.name,version:r.manifest.packageVersion,addons:[r],...r.installSource===void 0?{}:{installSource:r.installSource},...n===void 0?{}:{bundle:n}};t.set(e,i)}}let r=[];for(let e of t.values())e.bundle!==void 0||e.addons.length>=2?r.push({bundle:e,representative:e.addons[0]}):r.push(e.addons[0]);return r.push(...n),r}function $(e){return`bundle`in e}function bt({addons:e,clusterStatus:o,selectedNode:d,onRefresh:f,isRefreshing:p}){let{t:m}=J(),h=s(),[g,_]=r(``),y=u(g),[x,C]=r(!1),te=c(null);t(()=>{if(!x)return;let e=e=>{te.current&&!te.current.contains(e.target)&&C(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[x]);let{data:T}=P({nodeId:d.id}),E=n(()=>{let e=new Map;for(let t of T??[])e.set(t.name,t.latestVersion);return e},[T]),ne=n(()=>(T??[]).filter(e=>!e.isSystem).length,[T]),[re,ie]=r(()=>new Set),[ae,oe]=r(()=>new Map),D=i(e=>{ie(t=>new Set(t).add(e))},[]),se=i(e=>{ie(t=>{if(!t.has(e))return t;let n=new Set(t);return n.delete(e),n})},[]),O=i((e,t)=>{oe(n=>new Map(n).set(e,t))},[]),k=i(e=>{oe(t=>{if(!t.has(e))return t;let n=new Map(t);return n.delete(e),n})},[]),le=z({onMutate:e=>{D(e.name),k(e.name)},onSuccess:(e,t)=>{se(t.name);let n=e;if(n&&n.success===!1){O(t.name,n.error??`Update failed (no error message returned by server)`);return}h.invalidateQueries({queryKey:[[`addons`]]}),h.invalidateQueries({queryKey:[[`addons`,`listUpdates`]]})},onError:(e,t)=>{se(t.name),O(t.name,e instanceof Error?e.message:String(e))}}),de=Pe(),A=c(new Set);t(()=>{let e=new Set;for(let[t,n]of de)Me(n)&&e.add(t);let t=[...A.current].some(t=>!e.has(t));A.current=e,t&&(h.invalidateQueries({queryKey:[[`addons`]]}),h.invalidateQueries({queryKey:[[`addons`,`listUpdates`]]}))},[de,h]);let{data:j}=_e(void 0),pe=Ce({onSuccess:()=>{h.invalidateQueries({queryKey:[[`addons`,`getAutoUpdateSettings`]]})}}),M=ce({onSuccess:()=>{h.invalidateQueries({queryKey:[[`addons`,`getAutoUpdateSettings`]]})}}),{data:N,isFetching:me}=L({query:y||void 0},{enabled:x}),F=fe(),{data:I}=ue(void 0),ge=I?.requestedAt,[ve,R]=r(null),[ye,V]=r(!1);t(()=>{if(I?.kind===`framework-bulk-update`&&I.requestedAt!==ve){R(I.requestedAt),V(!0);let e=window.setTimeout(()=>V(!1),6e3);return()=>window.clearTimeout(e)}},[ge,ve,I]),B();let be=i(async()=>{let e=(T??[]).filter(e=>!e.isSystem);if(e.length!==0){if(!d.isHub){for(let t of e)await le.mutateAsync({name:t.name,version:t.latestVersion,nodeId:d.id});return}await F.mutateAsync({kind:`update`,targets:e.map(e=>({name:e.name,version:e.latestVersion})),nodeIds:[d.id]})}},[T,d.id,d.isHub,F,le]),H=he({onSuccess:()=>{h.invalidateQueries({queryKey:[[`addons`]]}),h.invalidateQueries({queryKey:[[`addonPages`]]}),h.invalidateQueries({queryKey:[[`capabilities`]]}),h.invalidateQueries({queryKey:[[`integrations`]]})}}),[U,Se]=r(`type`),[W,G]=r(()=>typeof window>`u`?`grouped`:window.localStorage.getItem(`camstack.addons.viewMode`)===`flat`?`flat`:`grouped`),K=e=>{G(e),typeof window<`u`&&window.localStorage.setItem(`camstack.addons.viewMode`,e)},[q,Y]=we(),X=q.get(`capability`),Z=q.get(`updatable`)===`1`,Te=q.get(`error`)===`1`,Q=lt(q.get(`source`)),Ee=i(e=>{let t=new URLSearchParams(q);e?t.set(`updatable`,`1`):t.delete(`updatable`),Y(t,{replace:!0})},[q,Y]),Oe=i(e=>{let t=new URLSearchParams(q);e?t.set(`error`,`1`):t.delete(`error`),Y(t,{replace:!0})},[q,Y]),ke=i(e=>{let t=new URLSearchParams(q);e===null?t.delete(`source`):t.set(`source`,e),Y(t,{replace:!0})},[q,Y]),Ae=n(()=>e.filter(e=>De(e.process)!==null).length,[e]),je=n(()=>{let t=e.filter(e=>!mt(e.manifest.packageName));return d.isHub||(t=t.filter(e=>gt(e.placement,d.isHub))),X&&(t=t.filter(e=>(e.manifest.capabilities??[]).some(e=>(typeof e==`string`?e:e.name)===X))),Z&&(t=t.filter(e=>{let t=e.manifest.packageName;return t!==void 0&&E.has(t)})),Q!==null&&(t=t.filter(e=>_t(e.installSource)===Q)),Te&&(t=t.filter(e=>De(e.process)!==null)),t},[e,d.isHub,X,Z,Q,Te,E]),Ne=()=>{let e=new URLSearchParams(q);e.delete(`capability`),Y(e,{replace:!0})},Fe=W===`flat`?je:yt(je),Ie=n(()=>{let e=[...Fe];switch(U){case`type`:e.sort((e,t)=>{let n=+!$(e),r=+!$(t);if(n!==r)return n-r;let i=$(e)?e.bundle.displayName:e.manifest.name,a=$(t)?t.bundle.displayName:t.manifest.name;return i.localeCompare(a)});break;case`name`:e.sort((e,t)=>{let n=$(e)?e.bundle.displayName:e.manifest.name,r=$(t)?t.bundle.displayName:t.manifest.name;return n.localeCompare(r)});break;case`source`:e.sort((e,t)=>{let n=$(e)?e.bundle.installSource??``:e.installSource??``,r=$(t)?t.bundle.installSource??``:t.installSource??``;return n.localeCompare(r)});break}return e},[Fe,U]);return a(`div`,{className:`space-y-3`,children:[[...ae.entries()].map(([e,t])=>l(`div`,{className:`rounded-md border border-danger/30 bg-danger/5 px-2.5 py-1.5 text-[11px]`,children:a(`div`,{className:`flex items-start justify-between gap-3`,children:[a(`div`,{className:`space-y-0.5`,children:[l(`div`,{className:`font-medium text-danger`,children:m(`systemPage.addons.updateFailed`,{name:e})}),l(`div`,{className:`text-foreground-subtle font-mono`,children:t})]}),l(`button`,{type:`button`,onClick:()=>k(e),className:`text-foreground-subtle hover:text-foreground text-[10px]`,children:m(`common.dismiss`)})]})},e)),a(`div`,{className:`flex items-center gap-x-2 gap-y-1.5 flex-wrap`,children:[a(`div`,{className:`flex items-center gap-1.5`,children:[l(`span`,{className:`text-[10px] text-foreground-subtle`,children:m(`admin.system.addons.sort`,`Sort:`)}),a(`select`,{value:U,onChange:e=>Se(e.target.value),className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground focus:outline-none focus:border-primary/50`,children:[l(`option`,{value:`type`,children:m(`admin.system.addons.bundlesFirst`,`Bundles first`)}),l(`option`,{value:`name`,children:m(`admin.system.addons.name`,`Name`)}),l(`option`,{value:`source`,children:m(`admin.system.addons.installSource`,`Install source`)})]})]}),a(`div`,{className:`flex items-center gap-1.5`,children:[l(`span`,{className:`text-[10px] text-foreground-subtle`,children:m(`admin.system.addons.view`,`View:`)}),l(`div`,{className:`flex rounded-md border border-border overflow-hidden text-[10px] font-medium`,children:[`grouped`,`flat`].map(e=>l(`button`,{type:`button`,onClick:()=>K(e),className:`px-2 py-1 transition-colors capitalize ${W===e?`bg-primary/10 text-primary`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`}`,title:e===`grouped`?m(`admin.system.addons.groupMultiAddonPackagesInto`,`Group multi-addon packages into a bundle card`):m(`admin.system.addons.showEveryAddonAsIts`,`Show every addon as its own card`),children:e},e))})]}),d.isHub&&a(`div`,{className:`flex items-center gap-1.5`,children:[l(b,{className:`h-3 w-3 text-foreground-subtle`}),l(`span`,{className:`text-[10px] text-foreground-subtle`,children:m(`admin.system.addons.autoUpdate`,`Auto-Update:`)}),l(`div`,{className:`flex rounded-md border border-border overflow-hidden text-[10px] font-medium`,children:[`off`,`latest`,`beta`].map(e=>l(`button`,{type:`button`,onClick:()=>pe.mutate({channel:e}),disabled:pe.isPending,className:`px-2 py-1 transition-colors capitalize ${j?.channel===e?e===`off`?`bg-gray-700 text-gray-200`:e===`latest`?`bg-blue-500/20 text-blue-400`:`bg-amber-500/20 text-amber-400`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`} ${e===`off`?``:`border-l border-border`}`,children:e},e))})]}),d.isHub&&a(`div`,{className:`flex items-center gap-1.5`,children:[l(`span`,{className:`text-[10px] text-foreground-subtle`,children:m(`admin.system.addons.checkEvery`,`Check every:`)}),l(`select`,{className:`rounded-md border border-border bg-transparent px-1.5 py-1 text-[10px] font-medium text-foreground-subtle`,value:j?.updateCheckIntervalSeconds??21600,disabled:M.isPending||j===void 0,onChange:e=>{j!==void 0&&M.mutate({channel:j.channel,updateCheckIntervalSeconds:Number(e.target.value)})},children:ft.map(e=>l(`option`,{value:e.seconds,children:e.label},e.seconds))})]}),ne>0&&a(`button`,{type:`button`,onClick:()=>void be(),disabled:F.isPending,className:`flex items-center gap-1 px-2 py-1 text-[11px] rounded-md bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 border border-blue-500/30 disabled:opacity-50 transition-colors font-medium`,children:[F.isPending?l(w,{className:`w-3 h-3 animate-spin`}):l(v,{className:`w-3 h-3`}),F.isPending?m(`admin.system.addons.updating`,`Updating…`):m(`admin.system.addons.updateAll`,`Update All ({{nonSystemUpdateCount}})`,{nonSystemUpdateCount:ne})]}),a(`button`,{type:`button`,onClick:f,disabled:p||F.isPending,className:`flex items-center gap-1 px-2 py-1 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,children:[l(b,{className:`w-3 h-3 ${p?`animate-spin`:``}`}),m(`common.refresh`,`Refresh`)]})]}),a(`div`,{className:`flex flex-wrap items-center gap-1.5`,role:`group`,"aria-label":m(`admin.system.addons.filterInstalledAddons`,`Filter installed addons`),children:[l(`span`,{className:`text-[10px] text-foreground-subtle`,children:m(`admin.system.addons.filter`,`Filter:`)}),[{id:`updatable`,label:m(`admin.system.addons.updatable`,`Updatable`),pressed:Z,toggle:()=>Ee(!Z)},{id:`error`,label:m(`admin.system.addons.inError`,`In error ({{count}})`,{count:Ae}),pressed:Te,toggle:()=>Oe(!Te)},{id:`npm`,label:`npm`,pressed:Q===`npm`,toggle:()=>ke(Q===`npm`?null:`npm`)},{id:`dev`,label:m(`admin.system.addons.dev`,`Dev`),pressed:Q===`dev`,toggle:()=>ke(Q===`dev`?null:`dev`)}].map(e=>l(`button`,{type:`button`,"aria-pressed":e.pressed,onClick:e.toggle,className:e.pressed?ut:dt,children:e.label},e.id))]}),a(`div`,{className:`flex flex-col gap-1.5 sm:flex-row sm:items-center sm:gap-2`,children:[a(`div`,{className:`relative flex-1 min-w-0 sm:min-w-[200px]`,ref:te,children:[l(xe,{type:`text`,value:g,onChange:e=>{_(e.target.value),C(!0)},onFocus:()=>C(!0),placeholder:m(`admin.system.addons.searchAddonsOnNpm`,`Search addons on npm...`),"aria-label":m(`admin.system.addons.searchAddonsOnNpm2`,`Search addons on npm`),disabled:F.isPending,leftSlot:l(S,{className:`h-3.5 w-3.5`,"aria-hidden":!0}),rightSlot:me?l(w,{className:`h-3 w-3 animate-spin`}):void 0}),x&&N&&N.length>0&&a(`div`,{className:`absolute left-0 right-0 top-full mt-1 z-40 rounded-md border border-border bg-surface shadow-xl overflow-hidden`,children:[N.length>0&&l(`div`,{className:`px-3 py-1.5 text-[10px] uppercase tracking-wide text-foreground-subtle border-b border-border`,children:m(`systemPage.addons.npmResults`,{count:N.length})}),N&&N.length>0&&l(`div`,{className:`max-h-72 overflow-auto divide-y divide-border`,children:N.map(e=>l(st,{addon:e,installing:H.isPending,onInstall:e=>H.mutate({packageName:e})},e.name))})]})]}),l(rt,{onUploadSuccess:()=>{h.invalidateQueries({queryKey:[[`addons`]]}),f()}})]}),X&&a(`div`,{className:`flex items-center gap-2 px-2.5 py-1.5 rounded-md bg-primary/10 border border-primary/30 text-xs`,children:[l(`span`,{className:`text-foreground-subtle`,children:m(`admin.system.addons.filteringByCapability`,`Filtering by capability:`)}),l(`span`,{className:`font-mono text-primary font-semibold`,children:X}),l(`button`,{type:`button`,onClick:Ne,className:`ml-auto text-xs text-foreground-subtle hover:text-foreground underline`,children:m(`admin.system.addons.clear`,`Clear`)})]}),X&&l(ct,{capability:X,installing:H.isPending,onInstall:e=>H.mutate({packageName:e})}),X&&je.length>0&&l(`h2`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:m(`admin.system.addons.installed`,`Installed`)}),ye&&a(`div`,{className:`fixed top-[calc(env(safe-area-inset-top)+1rem)] right-[calc(env(safe-area-inset-right)+1rem)] z-50 flex items-start gap-2 px-3 py-2.5 rounded-md border border-green-500/30 bg-green-500/10 shadow-lg backdrop-blur-sm max-w-sm pointer-events-auto`,children:[l(ee,{className:`w-4 h-4 shrink-0 mt-0.5 text-green-400`}),a(`div`,{children:[l(`div`,{className:`text-[11px] font-semibold text-foreground`,children:m(`admin.system.addons.bulkUpdateCompleted`,`Bulk update completed`)}),l(`div`,{className:`text-[10px] text-foreground-subtle mt-0.5`,children:m(`admin.system.addons.systemPackagesUpdatedHubRestarted`,`System packages updated — hub restarted successfully.`)})]})]}),je.length===0&&l(`div`,{className:`text-xs text-foreground-subtle`,children:e.length===0?m(`admin.system.addons.noAddonsInstalled`,`No addons installed`):X?m(`admin.system.addons.noInstalledAddonDeclaresThe`,`No installed addon declares the "{{capabilityFilter}}" capability. Any addon you can install appears under "Available to install" above.`,{capabilityFilter:X}):m(`admin.system.addons.noAddonsCompatibleWithPlacement`,`No addons compatible with {{name}} (placement filter active)`,{name:d.name})}),l(`div`,{className:`space-y-1.5`,children:Ie.map(e=>{let t=$(e)?e.bundle.packageName:e.manifest.packageName,n=E.get(t),r=$(e)?e.representative:e,i=n?e=>le.mutate({name:t,version:e,nodeId:d.id}):void 0,a=de.get(t)??null,s=a!==null&&Me(a);return l(tt,{addon:r,clusterStatus:o?.[r.manifest.id],bundle:$(e)?e.bundle:void 0,availableUpdate:n,isUpdating:re.has(t)||s,jobProgress:a,onUpdate:i,disabledByBulk:F.isPending,selectedNode:d},$(e)?t:e.manifest.id)})})]})}function xt(){let{t:e}=J(),n=s(),{data:r}=U(void 0),{nodes:i}=W(),{selection:o,selectNode:u,requestedNodeId:d}=Ee(i.length>0?i:[ht]),f=o.node??ht,p=f.id,m=i.length>0?o.staleNodeId:null,{data:h,isLoading:g,isError:_}=H({nodeId:p}),v=O(),y=ge(),x=v.isPending||y.isPending,S=async()=>{await v.mutateAsync({nodeId:p}),await y.mutateAsync(),n.invalidateQueries({queryKey:[[`addons`]]})},C=c(v);C.current=v;let w=c(d??`hub`);t(()=>{C.current.mutate({nodeId:w.current})},[]);let ee=(h??[]).map(vt).filter(e=>e!==null);return a(Z,{children:[a(`div`,{className:`flex items-center justify-between gap-2 flex-wrap`,children:[l(A,{selectedNodeId:p,onSelect:u}),a(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[!g&&!_&&l(`span`,{className:`text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium`,children:e(`systemPage.addons.installedCount`,{count:ee.length})}),a(`button`,{type:`button`,onClick:()=>void S(),disabled:x,className:`inline-flex items-center gap-1 px-2 py-1 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,title:e(`admin.system.addons.reFetchAddonsCheckNpm`,`Re-fetch addons + check npm for new versions`),children:[l(b,{className:`w-3 h-3 ${x?`animate-spin`:``}`}),e(`admin.system.addons.checkForUpdates`,`Check for updates`)]})]})]}),l(Q,{staleNodeId:m,shownNodeName:f.name}),l(ot,{selectedNode:f}),g&&l(`div`,{className:`text-xs text-foreground-subtle animate-pulse`,children:e(`common.loading`,`Loading…`)}),_&&l(`div`,{className:`text-xs text-danger`,children:e(`admin.system.addons.failedToLoadAddons`,`Failed to load addons`)}),!g&&!_&&l(bt,{addons:ee,clusterStatus:r,selectedNode:f,onRefresh:()=>void S(),isRefreshing:x})]})}export{xt as AddonsPage};