@powerhousedao/connect 6.1.0-dev.5 → 6.1.0-dev.6

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 (30) hide show
  1. package/dist/{ClearStorageModal-x5YChNQM.js → ClearStorageModal-Dx_kY08P.js} +4 -4
  2. package/dist/{ClearStorageModal-x5YChNQM.js.map → ClearStorageModal-Dx_kY08P.js.map} +1 -1
  3. package/dist/{DebugSettingsModal-DTwoo4sR.js → DebugSettingsModal-CFk_kZiG.js} +6 -6
  4. package/dist/{DebugSettingsModal-DTwoo4sR.js.map → DebugSettingsModal-CFk_kZiG.js.map} +1 -1
  5. package/dist/{InspectorModal-CCzUCfvG.js → InspectorModal-DRoE6sso.js} +4 -4
  6. package/dist/{InspectorModal-CCzUCfvG.js.map → InspectorModal-DRoE6sso.js.map} +1 -1
  7. package/dist/{SettingsModal--JkI5IR3.js → SettingsModal-BRgHRZDb.js} +6 -6
  8. package/dist/{SettingsModal--JkI5IR3.js.map → SettingsModal-BRgHRZDb.js.map} +1 -1
  9. package/dist/{build-info-DiuZRcOH.js → build-info-VpEvSquo.js} +4 -4
  10. package/dist/{build-info-DiuZRcOH.js.map → build-info-VpEvSquo.js.map} +1 -1
  11. package/dist/{connect.config-Cuh0hj_Q.js → connect.config-B2xP5Iez.js} +9 -3
  12. package/dist/{connect.config-Cuh0hj_Q.js.map → connect.config-B2xP5Iez.js.map} +1 -1
  13. package/dist/{i18n-4rfcgnb9.js → i18n-BuVT7wFQ.js} +4 -4
  14. package/dist/{i18n-4rfcgnb9.js.map → i18n-BuVT7wFQ.js.map} +1 -1
  15. package/dist/{load-DveXDmRN.js → load-DBhrZTcC.js} +6 -6
  16. package/dist/{load-DveXDmRN.js.map → load-DBhrZTcC.js.map} +1 -1
  17. package/dist/main.js +1 -1
  18. package/dist/{package-D0Iw_kmi.js → package-Cz5kA211.js} +15 -9
  19. package/dist/package-Cz5kA211.js.map +1 -0
  20. package/dist/{reactor-BrrBiRjT.js → reactor-BqTMQT3A.js} +4 -4
  21. package/dist/{reactor-BrrBiRjT.js.map → reactor-BqTMQT3A.js.map} +1 -1
  22. package/dist/{registerServiceWorker-CMRF2LWE.js → registerServiceWorker-5FDz0DvH.js} +4 -4
  23. package/dist/{registerServiceWorker-CMRF2LWE.js.map → registerServiceWorker-5FDz0DvH.js.map} +1 -1
  24. package/dist/{sidebar-DPz78uG1.js → sidebar-1Vu1bx0C.js} +371 -13
  25. package/dist/sidebar-1Vu1bx0C.js.map +1 -0
  26. package/dist/start-connect.js +1 -1
  27. package/dist/style.css +29 -0
  28. package/package.json +18 -12
  29. package/dist/package-D0Iw_kmi.js.map +0 -1
  30. package/dist/sidebar-DPz78uG1.js.map +0 -1
@@ -1,13 +1,14 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5b1d7a07-2b7c-56f8-8b06-e3bea15efbff")}catch(e){}}();
3
- import { n as defaultPHAppConfig, r as defaultPHDocumentEditorConfig, t as connectConfig } from "./connect.config-Cuh0hj_Q.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5a417e42-ad53-5ab7-a264-5f81414a1e25")}catch(e){}}();
3
+ import { n as defaultPHAppConfig, r as defaultPHDocumentEditorConfig, t as connectConfig } from "./connect.config-B2xP5Iez.js";
4
4
  import { n as toast, t as ToastContainer } from "./toast-DnODOv28.js";
5
- import { t as i18n } from "./i18n-4rfcgnb9.js";
5
+ import { t as i18n } from "./i18n-BuVT7wFQ.js";
6
6
  import { c as subscribeReactorPgMajor, d as createFileDataStore, f as idbError, l as IDB_STORE_NAME, m as readPgVersionFile, p as openIdb, r as getCachedReactorPgMajor, u as PRIMARY_IDB_NAMES } from "./pglite-runtime-Btp8ZXVH.js";
7
- import { t as serviceWorkerManager } from "./registerServiceWorker-CMRF2LWE.js";
8
- import { driveCollectionId, getRevisionFromDate, logout, openRenown, setPHAppConfig, setPHDocumentEditorConfig, setRevisionHistoryVisible, setSelectedDrive, setSelectedNode, showPHModal, useAppModuleById, useDefaultAppModule, useDocumentById, useDocumentModelModuleById, useDocumentOperations, useDrives, useEditorModuleById, useFallbackEditorModule, useNodeParentFolderById, usePHModal, usePackageDiscoveryService, useRevisionHistoryVisible, useSelectedDocument, useSelectedDocumentId, useSelectedDriveSafe, useSelectedFolder, useSelectedTimelineItem, useSyncList, useUser, useVetraPackageManager, useVetraPackages } from "@powerhousedao/reactor-browser";
7
+ import { t as serviceWorkerManager } from "./registerServiceWorker-5FDz0DvH.js";
8
+ import { driveCollectionId, getRevisionFromDate, logout, openRenown, setPHAppConfig, setPHDocumentEditorConfig, setRevisionHistoryVisible, setSelectedDrive, setSelectedNode, showPHModal, useAppModuleById, useDefaultAppModule, useDocumentById, useDocumentModelModuleById, useDocumentOperations, useDrives, useEditorModuleById, useFallbackEditorModule, useNodeParentFolderById, usePHModal, usePackageDiscoveryService, useReactorClientModule, useRevisionHistoryVisible, useSelectedDocument, useSelectedDocumentId, useSelectedDriveSafe, useSelectedFolder, useSelectedTimelineItem, useSyncList, useUser, useVetraPackageManager, useVetraPackages } from "@powerhousedao/reactor-browser";
9
9
  import { childLogger } from "document-model";
10
10
  import React, { StrictMode, Suspense, lazy, useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
11
+ import { z } from "zod";
11
12
  import { Trans, useTranslation } from "react-i18next";
12
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
14
  import { Outlet, RouterProvider, createBrowserRouter, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from "react-router-dom";
@@ -55,6 +56,224 @@ const useAcceptedCookies = () => {
55
56
  return [useSyncExternalStore(subscribe$1, getCookies, getCookies), setCookies];
56
57
  };
57
58
  //#endregion
59
+ //#region src/services/openpanel/buffer.ts
60
+ const buffer = [];
61
+ let errorHandler;
62
+ function defaultOnError(err) {
63
+ console.warn("[useOpenPanel] track failed:", err);
64
+ }
65
+ /**
66
+ * Forward a single event to the active client, swallowing any throw.
67
+ *
68
+ * The outer try/catch handles synchronous throws from `client.track`; the
69
+ * inner `.catch()` handles rejected promises. Both are needed because
70
+ * `Promise.resolve(x).catch()` cannot catch a throw from evaluating `x`.
71
+ */
72
+ function forward(client, name, props) {
73
+ try {
74
+ Promise.resolve(client.track(name, props)).catch((err) => (errorHandler ?? defaultOnError)(err));
75
+ } catch (err) {
76
+ (errorHandler ?? defaultOnError)(err);
77
+ }
78
+ }
79
+ /**
80
+ * Drain the pre-init buffer in FIFO order through `client.track`, then forward
81
+ * subsequent events directly. Called once from `getOpenPanelClient()`.
82
+ */
83
+ function drainOpenPanelBuffer(client, onError) {
84
+ errorHandler = onError;
85
+ const pending = buffer.splice(0, buffer.length);
86
+ for (const [name, props] of pending) forward(client, name, props);
87
+ }
88
+ /**
89
+ * Clear the buffer and reset the active client. Buffered pre-consent events
90
+ * are discarded so they are not replayed if the user later re-accepts.
91
+ */
92
+ function clearOpenPanelBuffer() {
93
+ buffer.length = 0;
94
+ errorHandler = void 0;
95
+ }
96
+ //#endregion
97
+ //#region src/services/openpanel/client.ts
98
+ let client;
99
+ /**
100
+ * Returns the cached `OpenPanel` singleton, building it on first call.
101
+ *
102
+ * When `config.clientId` is empty it returns `undefined` without importing
103
+ * `@openpanel/web`, so the bundler can tree-shake the SDK out of production.
104
+ */
105
+ async function getOpenPanelClient(config) {
106
+ if (!config.clientId) return;
107
+ if (client) return client;
108
+ const { OpenPanel: OpenPanelClass } = await import("@openpanel/web");
109
+ client = new OpenPanelClass({
110
+ clientId: config.clientId,
111
+ ...config.apiUrl ? { apiUrl: config.apiUrl } : {}
112
+ });
113
+ drainOpenPanelBuffer(client);
114
+ return client;
115
+ }
116
+ /**
117
+ * Clears the cached singleton and the pre-init buffer. Call on consent
118
+ * revocation or during tests; buffered events are discarded, not replayed.
119
+ */
120
+ function resetOpenPanelClient() {
121
+ client = void 0;
122
+ clearOpenPanelBuffer();
123
+ }
124
+ //#endregion
125
+ //#region src/services/openpanel/events.json
126
+ var events_default = [
127
+ {
128
+ "documentType": "powerhouse/document-drive",
129
+ "actionTypes": [
130
+ "ADD_FOLDER",
131
+ "DELETE_NODE",
132
+ "ADD_FILE",
133
+ "UPDATE_FILE",
134
+ "COPY_NODE",
135
+ "MOVE_NODE",
136
+ "SET_DRIVE_NAME",
137
+ "SET_DRIVE_ICON"
138
+ ]
139
+ },
140
+ {
141
+ "documentType": "powerhouse/document-model",
142
+ "actionTypes": [
143
+ "SET_MODEL_NAME",
144
+ "SET_MODEL_ID",
145
+ "ADD_MODULE",
146
+ "DELETE_MODULE",
147
+ "ADD_OPERATION",
148
+ "DELETE_OPERATION"
149
+ ]
150
+ },
151
+ {
152
+ "documentType": "powerhouse/reactor-drive",
153
+ "actionTypes": [
154
+ "ADD_FOLDER",
155
+ "REMOVE_FOLDER",
156
+ "UPDATE_FOLDER"
157
+ ]
158
+ }
159
+ ];
160
+ //#endregion
161
+ //#region src/services/openpanel/events.ts
162
+ const EventMappingSchema = z.object({
163
+ documentType: z.string().min(1),
164
+ actionTypes: z.array(z.string().min(1)).min(1),
165
+ alias: z.string().optional()
166
+ }).strict();
167
+ const EventMappingsSchema = z.array(EventMappingSchema).readonly();
168
+ /**
169
+ * Parses and validates the event mapping table, returning the validated array
170
+ * and an O(1) lookup map. Accepts a `raw` override for tests. Throws on zod
171
+ * failures and on duplicate `(documentType, actionType)` pairs.
172
+ */
173
+ function loadEvents(raw = events_default) {
174
+ const result = EventMappingsSchema.safeParse(raw);
175
+ if (!result.success) throw new Error(`Invalid OpenPanel events.json: ${result.error.message}`);
176
+ const mappings = result.data;
177
+ const lookupMap = /* @__PURE__ */ new Map();
178
+ for (const mapping of mappings) {
179
+ let inner = lookupMap.get(mapping.documentType);
180
+ if (!inner) {
181
+ inner = /* @__PURE__ */ new Map();
182
+ lookupMap.set(mapping.documentType, inner);
183
+ }
184
+ for (const actionType of mapping.actionTypes) {
185
+ if (inner.has(actionType)) throw new Error(`Duplicate OpenPanel event mapping for ${mapping.documentType}/${actionType}`);
186
+ inner.set(actionType, mapping);
187
+ }
188
+ }
189
+ return {
190
+ mappings,
191
+ lookupMap
192
+ };
193
+ }
194
+ const { mappings: defaultMappings, lookupMap: defaultLookupMap } = loadEvents();
195
+ /** Validated mapping array from the bundled events.json. */
196
+ const eventMappings = defaultMappings;
197
+ /** O(1) lookup map: documentType → actionType → mapping. */
198
+ const eventLookupMap = defaultLookupMap;
199
+ /**
200
+ * Normalizes a document type into a safe event-name segment: lowercased, `/`
201
+ * replaced with `.`, and any character outside `[a-z0-9._-]` stripped.
202
+ * e.g. `powerhouse/document-drive` → `powerhouse.document-drive`.
203
+ */
204
+ function normalize(documentType) {
205
+ return documentType.toLowerCase().replace(/\//g, ".").replace(/[^a-z0-9._-]/g, "");
206
+ }
207
+ /**
208
+ * Derives the OpenPanel event name: `mapping.alias` when present, otherwise
209
+ * `${normalize(documentType)}.${actionType.toLowerCase()}`.
210
+ */
211
+ function deriveEventName(mapping, op) {
212
+ if (mapping.alias) return mapping.alias;
213
+ return `${normalize(op.context.documentType)}.${op.operation.action.type.toLowerCase()}`;
214
+ }
215
+ /** Builds the default properties attached to every OpenPanel event. */
216
+ function buildDefaultProperties(op) {
217
+ return {
218
+ documentType: op.context.documentType,
219
+ actionType: op.operation.action.type,
220
+ documentId: op.context.documentId,
221
+ scope: op.context.scope,
222
+ branch: op.context.branch,
223
+ app: "connect"
224
+ };
225
+ }
226
+ //#endregion
227
+ //#region src/services/openpanel/processor.ts
228
+ /**
229
+ * Read-only reactor `IProcessor` that translates matching document operations
230
+ * into OpenPanel analytics events. Operations whose `(documentType, actionType)`
231
+ * pair is absent from the lookup map are skipped; per-operation errors are
232
+ * routed to `onError` and never thrown back to the manager.
233
+ */
234
+ var OpenPanelProcessor = class {
235
+ constructor(client, lookupMap, onError = (err) => console.warn("[OpenPanelProcessor] Error tracking event:", err)) {
236
+ this.client = client;
237
+ this.lookupMap = lookupMap;
238
+ this.onError = onError;
239
+ }
240
+ async onOperations(operations) {
241
+ for (const op of operations) {
242
+ const inner = this.lookupMap.get(op.context.documentType);
243
+ if (!inner) continue;
244
+ const mapping = inner.get(op.operation.action.type);
245
+ if (!mapping) continue;
246
+ const name = deriveEventName(mapping, op);
247
+ const payload = buildDefaultProperties(op);
248
+ try {
249
+ await this.client.track(name, payload);
250
+ } catch (err) {
251
+ this.onError(err, op);
252
+ }
253
+ }
254
+ }
255
+ async onDisconnect() {
256
+ this.client.flush?.();
257
+ }
258
+ };
259
+ //#endregion
260
+ //#region src/services/openpanel/factory.ts
261
+ /**
262
+ * Returns a `ProcessorFactory` that, for each drive, creates a single
263
+ * `OpenPanelProcessor` record whose `filter.documentType` is the union of all
264
+ * document types present in the event mapping table.
265
+ */
266
+ function createOpenPanelProcessorFactory(config) {
267
+ return function openPanelProcessorFactory(_driveHeader) {
268
+ const documentType = Array.from(config.events.lookupMap.keys());
269
+ return [{
270
+ processor: new OpenPanelProcessor(config.client, config.events.lookupMap, config.onError),
271
+ filter: { documentType },
272
+ startFrom: config.startFrom ?? "current"
273
+ }];
274
+ };
275
+ }
276
+ //#endregion
58
277
  //#region src/hooks/useIsEmbedded.ts
59
278
  /**
60
279
  * Detects whether Connect is being rendered inside another app (e.g. inside
@@ -229,6 +448,144 @@ const Analytics = () => {
229
448
  return null;
230
449
  };
231
450
  //#endregion
451
+ //#region src/components/openpanel-traits.ts
452
+ /**
453
+ * Builds the OpenPanel identity traits from a renown User.
454
+ *
455
+ * Rules:
456
+ * - `credential` (contains a JWT) is **never** forwarded.
457
+ * - `did` / `profileId` is sent as the top-level `profileId` key in the
458
+ * `client.identify()` call — it is **not** duplicated inside traits.
459
+ * - Optional fields (`ens`, `profile`) are only included when their value is
460
+ * non-nullish (guards against `null` from `RenownProfile` fields as well
461
+ * as plain `undefined`).
462
+ *
463
+ * Mirror the Sentry pattern in `store/user.ts`: destructure off `credential`
464
+ * first, then assemble the trait payload from the remainder.
465
+ */
466
+ function buildTraits(user) {
467
+ const { credential: _credential, ...rest } = user;
468
+ const traits = {
469
+ address: rest.address,
470
+ networkId: rest.networkId,
471
+ chainId: rest.chainId
472
+ };
473
+ if (rest.ens?.name != null) traits.ensName = rest.ens.name;
474
+ if (rest.ens?.avatarUrl != null) traits.ensAvatar = rest.ens.avatarUrl;
475
+ if (rest.profile?.username != null) traits.username = rest.profile.username;
476
+ if (rest.profile?.userImage != null) traits.userImage = rest.profile.userImage;
477
+ if (rest.profile?.documentId != null) traits.profileDocumentId = rest.profile.documentId;
478
+ if (rest.profile?.createdAt != null) traits.profileCreatedAt = rest.profile.createdAt;
479
+ return traits;
480
+ }
481
+ //#endregion
482
+ //#region src/components/openpanel.tsx
483
+ /**
484
+ * `OpenPanel` is a `null`-rendering component that manages the full lifecycle
485
+ * of the OpenPanel analytics subsystem.
486
+ *
487
+ * Gates:
488
+ * - `useAcceptedCookies().analytics === true` — the existing analytics cookie.
489
+ * - `connectConfig.openPanel.clientId` non-empty — no client ID → no-op.
490
+ *
491
+ * Behaviour when both gates pass:
492
+ * 1. Lazy-imports `@openpanel/web` and builds the singleton via
493
+ * `getOpenPanelClient(connectConfig.openPanel)`.
494
+ * 2. Exposes the client on `window.openPanel` for the card-6 `useOpenPanel()`
495
+ * hook to consume.
496
+ * 3. If `connectConfig.openPanel.trackOperations`, registers the processor
497
+ * factory against `processorManager` so document operations are forwarded.
498
+ * 4. Calls `client.identify()` when the renown user transitions from
499
+ * `undefined` → defined (login).
500
+ * 5. Calls `client.clear()` when the user transitions from defined →
501
+ * `undefined` (logout).
502
+ *
503
+ * Teardown (unmount **or** consent revocation):
504
+ * - `unregisterFactory("openpanel")` to remove the processor.
505
+ * - `resetOpenPanelClient()` to clear the singleton.
506
+ * - `window.openPanel` is cleared.
507
+ *
508
+ * Mirrors the Sentry pattern in `store/user.ts` for login/logout detection.
509
+ * Analytics failures are caught and forwarded to `console.warn` — they must
510
+ * never throw into the application.
511
+ *
512
+ * Mounted next to `<Analytics />` in `app.tsx`.
513
+ */
514
+ function OpenPanel() {
515
+ const [{ analytics }] = useAcceptedCookies();
516
+ const user = useUser();
517
+ const reactorClientModule = useReactorClientModule();
518
+ const [client, setClient] = useState();
519
+ /**
520
+ * Tracks the previous `user` value so we can detect the two transitions:
521
+ * undefined → defined (login)
522
+ * defined → undefined (logout)
523
+ */
524
+ const prevUserRef = useRef(void 0);
525
+ const enabled = analytics && !!connectConfig.openPanel.clientId;
526
+ const processorManager = reactorClientModule?.reactorModule?.processorManager;
527
+ useEffect(() => {
528
+ if (!enabled) return;
529
+ let cancelled = false;
530
+ (async () => {
531
+ let builtClient;
532
+ try {
533
+ builtClient = await getOpenPanelClient(connectConfig.openPanel);
534
+ } catch (err) {
535
+ console.warn("[OpenPanel] Failed to build client:", err);
536
+ return;
537
+ }
538
+ if (cancelled || !builtClient) return;
539
+ setClient(builtClient);
540
+ window.openPanel = builtClient;
541
+ if (connectConfig.openPanel.trackOperations && processorManager) try {
542
+ await processorManager.registerFactory("openpanel", createOpenPanelProcessorFactory({
543
+ client: builtClient,
544
+ events: {
545
+ mappings: eventMappings,
546
+ lookupMap: eventLookupMap
547
+ },
548
+ startFrom: "current"
549
+ }));
550
+ if (cancelled) await processorManager.unregisterFactory("openpanel").catch((err) => console.warn("[OpenPanel] Failed to unregister factory after cancellation:", err));
551
+ } catch (err) {
552
+ console.warn("[OpenPanel] Failed to register processor factory:", err);
553
+ }
554
+ })();
555
+ return () => {
556
+ cancelled = true;
557
+ prevUserRef.current = void 0;
558
+ if (connectConfig.openPanel.trackOperations && processorManager) processorManager.unregisterFactory("openpanel").catch((err) => console.warn("[OpenPanel] Failed to unregister processor factory:", err));
559
+ resetOpenPanelClient();
560
+ window.openPanel = void 0;
561
+ setClient(void 0);
562
+ };
563
+ }, [enabled, processorManager]);
564
+ useEffect(() => {
565
+ if (!enabled || !client) return;
566
+ const prev = prevUserRef.current;
567
+ prevUserRef.current = user;
568
+ if (!prev && user) try {
569
+ client.identify({
570
+ profileId: user.did,
571
+ properties: buildTraits(user)
572
+ });
573
+ } catch (err) {
574
+ console.warn("[OpenPanel] Failed to identify user:", err);
575
+ }
576
+ else if (prev && !user) try {
577
+ client.clear();
578
+ } catch (err) {
579
+ console.warn("[OpenPanel] Failed to clear user:", err);
580
+ }
581
+ }, [
582
+ client,
583
+ user,
584
+ enabled
585
+ ]);
586
+ return null;
587
+ }
588
+ //#endregion
232
589
  //#region src/components/document-editor-container.tsx
233
590
  function DocumentEditorContainer() {
234
591
  const [selectedDocument] = useSelectedDocument();
@@ -890,16 +1247,16 @@ const MigrationBanner = () => {
890
1247
  //#endregion
891
1248
  //#region src/components/modal/modals-container.tsx
892
1249
  const AddDriveModal$1 = lazy(() => import("./AddDriveModal-ZK9-BWMB.js").then((m) => ({ default: m.AddDriveModal })));
893
- const ClearStorageModal = lazy(() => import("./ClearStorageModal-x5YChNQM.js").then((m) => ({ default: m.ClearStorageModal })));
1250
+ const ClearStorageModal = lazy(() => import("./ClearStorageModal-Dx_kY08P.js").then((m) => ({ default: m.ClearStorageModal })));
894
1251
  const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-DiXQV82b.js").then((m) => ({ default: m.CookiesPolicyModal })));
895
1252
  const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-BhJh4nWt.js").then((m) => ({ default: m.CreateDocumentModal })));
896
- const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-DTwoo4sR.js").then((m) => ({ default: m.DebugSettingsModal })));
1253
+ const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-CFk_kZiG.js").then((m) => ({ default: m.DebugSettingsModal })));
897
1254
  const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-CbuIdjKY.js").then((m) => ({ default: m.DeleteDriveModal })));
898
1255
  const DeleteItemModal = lazy(() => import("./DeleteItemModal-9ErYlauT.js").then((m) => ({ default: m.DeleteItemModal })));
899
1256
  const DisclaimerModal = lazy(() => import("./DisclaimerModal-CfDeiBz8.js").then((m) => ({ default: m.DisclaimerModal })));
900
1257
  const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-DEk05PS7.js").then((m) => ({ default: m.DriveSettingsModal })));
901
1258
  const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-KZGWQ4J7.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
902
- const SettingsModal$1 = lazy(() => import("./SettingsModal--JkI5IR3.js").then((m) => ({ default: m.SettingsModal })));
1259
+ const SettingsModal$1 = lazy(() => import("./SettingsModal-BRgHRZDb.js").then((m) => ({ default: m.SettingsModal })));
903
1260
  const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-BwI5E5k3.js").then((m) => ({ default: m.UpgradeDriveModal })));
904
1261
  const modalComponents = {
905
1262
  addDrive: AddDriveModal$1,
@@ -912,7 +1269,7 @@ const modalComponents = {
912
1269
  disclaimer: DisclaimerModal,
913
1270
  driveSettings: DriveSettingsModal$1,
914
1271
  downloadDocumentWithErrors: DownloadDocumentWithErrorsModal,
915
- inspector: lazy(() => import("./InspectorModal-CCzUCfvG.js").then((m) => ({ default: m.InspectorModal }))),
1272
+ inspector: lazy(() => import("./InspectorModal-DRoE6sso.js").then((m) => ({ default: m.InspectorModal }))),
916
1273
  settings: SettingsModal$1,
917
1274
  upgradeDrive: UpgradeDriveModal,
918
1275
  missingPackage: lazy(() => import("./MissingPackageModal-CUdcDjSO.js").then((m) => ({ default: m.ConnectMissingPackageModal })))
@@ -935,7 +1292,7 @@ const ModalsContainer = lazy(async () => {
935
1292
  //#endregion
936
1293
  //#region src/components/app-loader.tsx
937
1294
  const AppLoader = (props) => {
938
- const Load = lazy(() => import("./load-DveXDmRN.js").then((m) => m.loadComponent(props.localPackage)));
1295
+ const Load = lazy(() => import("./load-DBhrZTcC.js").then((m) => m.loadComponent(props.localPackage)));
939
1296
  return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsxs(ErrorBoundary$1, {
940
1297
  fallbackRender: (props) => /* @__PURE__ */ jsx(AppSkeleton, { children: /* @__PURE__ */ jsx(DetailedFallback, { ...props }) }),
941
1298
  resetKeys: [props.localPackage],
@@ -1135,7 +1492,8 @@ const App = () => {
1135
1492
  /* @__PURE__ */ jsx(MissingModelBanner, {}),
1136
1493
  /* @__PURE__ */ jsx(Router, {}),
1137
1494
  /* @__PURE__ */ jsx(PackageInstallPrompt, {}),
1138
- /* @__PURE__ */ jsx(Analytics, {})
1495
+ /* @__PURE__ */ jsx(Analytics, {}),
1496
+ /* @__PURE__ */ jsx(OpenPanel, {})
1139
1497
  ] });
1140
1498
  };
1141
1499
  //#endregion
@@ -1496,5 +1854,5 @@ function Sidebar() {
1496
1854
  //#endregion
1497
1855
  export { AppLoader as t };
1498
1856
 
1499
- //# sourceMappingURL=sidebar-DPz78uG1.js.map
1500
- //# debugId=5b1d7a07-2b7c-56f8-8b06-e3bea15efbff
1857
+ //# sourceMappingURL=sidebar-1Vu1bx0C.js.map
1858
+ //# debugId=5a417e42-ad53-5ab7-a264-5f81414a1e25