kritzel-stencil 0.4.1 → 0.4.2

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 (27) hide show
  1. package/dist/cjs/index.cjs.js +1 -1
  2. package/dist/cjs/kritzel-active-users_47.cjs.entry.js +118 -14
  3. package/dist/cjs/{schema.constants-IAt9YXDZ.js → schema.constants-C8hqt--r.js} +1 -1
  4. package/dist/collection/classes/core/workspace.class.js +1 -1
  5. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +128 -12
  6. package/dist/collection/constants/version.js +1 -1
  7. package/dist/components/index.js +1 -1
  8. package/dist/components/kritzel-editor.js +1 -1
  9. package/dist/components/kritzel-engine.js +1 -1
  10. package/dist/components/kritzel-settings.js +1 -1
  11. package/dist/components/kritzel-workspace-manager.js +1 -1
  12. package/dist/components/{p-BH4oJ7yX.js → p--Oazz-BP.js} +2 -2
  13. package/dist/components/{p-Co165PAZ.js → p-C3UQ-Zrg.js} +1 -1
  14. package/dist/components/{p-9692OaI_.js → p-ClFprFvz.js} +1 -1
  15. package/dist/components/{p-DhMlShij.js → p-DAwPPDMS.js} +1 -1
  16. package/dist/esm/index.js +2 -2
  17. package/dist/esm/kritzel-active-users_47.entry.js +118 -14
  18. package/dist/esm/{schema.constants-rIkxAcpB.js → schema.constants-uC7_X6yr.js} +1 -1
  19. package/dist/stencil/index.esm.js +1 -1
  20. package/dist/stencil/p-b64c3584.entry.js +9 -0
  21. package/dist/stencil/{p-rIkxAcpB.js → p-uC7_X6yr.js} +1 -1
  22. package/dist/stencil/stencil.esm.js +1 -1
  23. package/dist/types/classes/core/workspace.class.d.ts +1 -1
  24. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +7 -0
  25. package/dist/types/constants/version.d.ts +1 -1
  26. package/package.json +1 -1
  27. package/dist/stencil/p-966ca4b5.entry.js +0 -9
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var schema_constants = require('./schema.constants-IAt9YXDZ.js');
3
+ var schema_constants = require('./schema.constants-C8hqt--r.js');
4
4
  var Y = require('yjs');
5
5
  var yIndexeddb = require('y-indexeddb');
6
6
  var yWebsocket = require('y-websocket');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-Xav9JFHg.js');
4
- var schema_constants = require('./schema.constants-IAt9YXDZ.js');
4
+ var schema_constants = require('./schema.constants-C8hqt--r.js');
5
5
  var Y = require('yjs');
6
6
  require('y-indexeddb');
7
7
  require('y-websocket');
@@ -28853,8 +28853,25 @@ const KritzelEngine = class {
28853
28853
  if (!workspace) {
28854
28854
  throw new Error('Cannot export workspace: no active workspace is loaded');
28855
28855
  }
28856
+ await this.core.initializeAssetStorage();
28856
28857
  const serialized = workspace.serialize({ includeObjects: true });
28857
- return JSON.stringify(serialized, null, 2);
28858
+ const exportMode = this.getWorkspaceExportMode();
28859
+ const { objects, ...workspaceWithoutObjects } = serialized;
28860
+ const payload = {
28861
+ ...workspaceWithoutObjects,
28862
+ exportMode,
28863
+ ...(objects !== undefined ? { objects } : {}),
28864
+ };
28865
+ if (exportMode === 'portable') {
28866
+ const portableAssets = await this.collectPortableAssets(payload.objects);
28867
+ if (Object.keys(portableAssets).length > 0) {
28868
+ payload.assets = portableAssets;
28869
+ }
28870
+ }
28871
+ else {
28872
+ delete payload.assets;
28873
+ }
28874
+ return JSON.stringify(payload, null, 2);
28858
28875
  }
28859
28876
  /**
28860
28877
  * Imports a workspace from a JSON string into a new workspace.
@@ -28868,22 +28885,15 @@ const KritzelEngine = class {
28868
28885
  if (!data.__class__ || data.__class__ !== 'KritzelWorkspace') {
28869
28886
  throw new Error('Invalid workspace data: missing or incorrect __class__ identifier');
28870
28887
  }
28888
+ await this.core.initializeAssetStorage();
28889
+ await this.restorePortableAssets(data);
28871
28890
  if (data.version && data.version !== schema_constants.WORKSPACE_EXPORT_VERSION) {
28872
28891
  console.warn(`Workspace version mismatch: expected ${schema_constants.WORKSPACE_EXPORT_VERSION}, got ${data.version}`);
28873
28892
  }
28874
28893
  // Create a new workspace with a fresh ID but use the imported name
28875
28894
  const newWorkspaceId = schema_constants.ObjectHelper.generateUUID();
28876
- const importedName = data.name || 'Imported Workspace';
28877
- let importedViewport = data.viewport || { centerWorldX: 0, centerWorldY: 0, scale: 1 };
28878
- // Backward compatibility: convert legacy translateX/translateY to centerWorldX/centerWorldY
28879
- if ('translateX' in importedViewport && !('centerWorldX' in importedViewport)) {
28880
- const scale = importedViewport.scale ?? 1;
28881
- importedViewport = {
28882
- centerWorldX: -(importedViewport.translateX ?? 0) / scale,
28883
- centerWorldY: -(importedViewport.translateY ?? 0) / scale,
28884
- scale,
28885
- };
28886
- }
28895
+ const importedName = this.getImportedWorkspaceName(data.name);
28896
+ const importedViewport = this.getImportedWorkspaceViewport(data.viewport);
28887
28897
  const newWorkspace = new schema_constants.KritzelWorkspace(newWorkspaceId, importedName, importedViewport);
28888
28898
  // Save the new workspace
28889
28899
  this.core.createWorkspace(newWorkspace);
@@ -28922,6 +28932,8 @@ const KritzelEngine = class {
28922
28932
  if (!data.__class__ || data.__class__ !== 'KritzelWorkspace') {
28923
28933
  throw new Error('Invalid workspace data: missing or incorrect __class__ identifier');
28924
28934
  }
28935
+ await this.core.initializeAssetStorage();
28936
+ await this.restorePortableAssets(data);
28925
28937
  if (data.version && data.version !== schema_constants.WORKSPACE_EXPORT_VERSION) {
28926
28938
  console.warn(`Workspace version mismatch: expected ${schema_constants.WORKSPACE_EXPORT_VERSION}, got ${data.version}`);
28927
28939
  }
@@ -28948,6 +28960,98 @@ const KritzelEngine = class {
28948
28960
  this.core.rerender();
28949
28961
  return loadedCount;
28950
28962
  }
28963
+ getWorkspaceExportMode() {
28964
+ return this.core.assetResolver.hasRemoteProvider ? 'lightweight' : 'portable';
28965
+ }
28966
+ async collectPortableAssets(serializedObjects) {
28967
+ if (!Array.isArray(serializedObjects) || serializedObjects.length === 0) {
28968
+ return {};
28969
+ }
28970
+ const assetIds = new Set();
28971
+ for (const serializedObject of serializedObjects) {
28972
+ if (!serializedObject || typeof serializedObject !== 'object') {
28973
+ continue;
28974
+ }
28975
+ const maybeImage = serializedObject;
28976
+ if (maybeImage.__class__ === 'KritzelImage' && typeof maybeImage.assetId === 'string' && maybeImage.assetId.length > 0) {
28977
+ assetIds.add(maybeImage.assetId);
28978
+ }
28979
+ }
28980
+ const assets = {};
28981
+ for (const assetId of assetIds) {
28982
+ try {
28983
+ const blob = await this.core.assetResolver.fetchBlob(assetId);
28984
+ assets[assetId] = await this.blobToDataUrl(blob);
28985
+ }
28986
+ catch (error) {
28987
+ console.warn(`[Kritzel] Failed to embed asset ${assetId} in portable workspace export:`, error);
28988
+ }
28989
+ }
28990
+ return assets;
28991
+ }
28992
+ async restorePortableAssets(data) {
28993
+ const assets = data.assets;
28994
+ if (!assets || typeof assets !== 'object') {
28995
+ return;
28996
+ }
28997
+ for (const [assetId, dataUrl] of Object.entries(assets)) {
28998
+ if (!assetId || typeof dataUrl !== 'string' || !dataUrl.startsWith('data:')) {
28999
+ continue;
29000
+ }
29001
+ try {
29002
+ const blob = await this.dataUrlToBlob(dataUrl);
29003
+ await this.core.assetResolver.put(blob, {
29004
+ id: assetId,
29005
+ mimeType: blob.type || 'application/octet-stream',
29006
+ kind: 'image',
29007
+ });
29008
+ }
29009
+ catch (error) {
29010
+ console.warn(`[Kritzel] Failed to restore embedded asset ${assetId} from portable workspace import:`, error);
29011
+ }
29012
+ }
29013
+ }
29014
+ blobToDataUrl(blob) {
29015
+ return new Promise((resolve, reject) => {
29016
+ const reader = new FileReader();
29017
+ reader.onload = () => resolve(reader.result);
29018
+ reader.onerror = () => reject(reader.error ?? new Error('Failed to read blob as data URL'));
29019
+ reader.readAsDataURL(blob);
29020
+ });
29021
+ }
29022
+ async dataUrlToBlob(dataUrl) {
29023
+ const response = await fetch(dataUrl);
29024
+ return response.blob();
29025
+ }
29026
+ getImportedWorkspaceName(rawName) {
29027
+ if (typeof rawName === 'string' && rawName.trim().length > 0) {
29028
+ return rawName;
29029
+ }
29030
+ return 'Imported Workspace';
29031
+ }
29032
+ getImportedWorkspaceViewport(rawViewport) {
29033
+ if (!rawViewport || typeof rawViewport !== 'object') {
29034
+ return { centerWorldX: 0, centerWorldY: 0, scale: 1 };
29035
+ }
29036
+ const viewport = rawViewport;
29037
+ if (typeof viewport.centerWorldX === 'number' && typeof viewport.centerWorldY === 'number') {
29038
+ const scale = typeof viewport.scale === 'number' && viewport.scale > 0 ? viewport.scale : 1;
29039
+ return {
29040
+ centerWorldX: viewport.centerWorldX,
29041
+ centerWorldY: viewport.centerWorldY,
29042
+ scale,
29043
+ };
29044
+ }
29045
+ if (typeof viewport.translateX === 'number' || typeof viewport.translateY === 'number') {
29046
+ const scale = typeof viewport.scale === 'number' && viewport.scale > 0 ? viewport.scale : 1;
29047
+ return {
29048
+ centerWorldX: -(typeof viewport.translateX === 'number' ? viewport.translateX : 0) / scale,
29049
+ centerWorldY: -(typeof viewport.translateY === 'number' ? viewport.translateY : 0) / scale,
29050
+ scale,
29051
+ };
29052
+ }
29053
+ return { centerWorldX: 0, centerWorldY: 0, scale: 1 };
29054
+ }
28951
29055
  /**
28952
29056
  * Exports the current workspace as a JSON file and triggers a browser download.
28953
29057
  * @param filename - Optional custom filename (without extension). Defaults to workspace name with timestamp.
@@ -31635,7 +31739,7 @@ const KritzelPortal = class {
31635
31739
  * This file is auto-generated by the version bump scripts.
31636
31740
  * Do not modify manually.
31637
31741
  */
31638
- const KRITZEL_VERSION = '0.4.1';
31742
+ const KRITZEL_VERSION = '0.4.2';
31639
31743
 
31640
31744
  const kritzelSettingsCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}.shortcuts-list{display:flex;flex-direction:column;gap:24px}.shortcuts-category{display:flex;flex-direction:column;gap:8px}.shortcuts-category-title{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.shortcuts-group{display:flex;flex-direction:column;gap:4px}.shortcut-item{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-item-bg, rgba(0, 0, 0, 0.02))}.shortcut-label{font-size:14px;color:var(--kritzel-settings-content-text-color, #666666)}.shortcut-key{font-family:monospace;font-size:12px;padding:2px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-key-bg, #f0f0f0);color:var(--kritzel-settings-shortcut-key-color, #333333);border:1px solid var(--kritzel-settings-shortcut-key-border, #ddd)}`;
31641
31745
 
@@ -28109,7 +28109,7 @@ class HocuspocusProvider extends EventEmitter {
28109
28109
  }
28110
28110
 
28111
28111
  /** Current version of the workspace export format */
28112
- const WORKSPACE_EXPORT_VERSION = '1.2.0';
28112
+ const WORKSPACE_EXPORT_VERSION = '1.3.0';
28113
28113
  /**
28114
28114
  * Represents a workspace in the Kritzel canvas.
28115
28115
  * A workspace is an isolated canvas area with its own set of objects and viewport state.
@@ -1,5 +1,5 @@
1
1
  /** Current version of the workspace export format */
2
- export const WORKSPACE_EXPORT_VERSION = '1.2.0';
2
+ export const WORKSPACE_EXPORT_VERSION = '1.3.0';
3
3
  /**
4
4
  * Represents a workspace in the Kritzel canvas.
5
5
  * A workspace is an isolated canvas area with its own set of objects and viewport state.
@@ -1346,8 +1346,25 @@ export class KritzelEngine {
1346
1346
  if (!workspace) {
1347
1347
  throw new Error('Cannot export workspace: no active workspace is loaded');
1348
1348
  }
1349
+ await this.core.initializeAssetStorage();
1349
1350
  const serialized = workspace.serialize({ includeObjects: true });
1350
- return JSON.stringify(serialized, null, 2);
1351
+ const exportMode = this.getWorkspaceExportMode();
1352
+ const { objects, ...workspaceWithoutObjects } = serialized;
1353
+ const payload = {
1354
+ ...workspaceWithoutObjects,
1355
+ exportMode,
1356
+ ...(objects !== undefined ? { objects } : {}),
1357
+ };
1358
+ if (exportMode === 'portable') {
1359
+ const portableAssets = await this.collectPortableAssets(payload.objects);
1360
+ if (Object.keys(portableAssets).length > 0) {
1361
+ payload.assets = portableAssets;
1362
+ }
1363
+ }
1364
+ else {
1365
+ delete payload.assets;
1366
+ }
1367
+ return JSON.stringify(payload, null, 2);
1351
1368
  }
1352
1369
  /**
1353
1370
  * Imports a workspace from a JSON string into a new workspace.
@@ -1361,22 +1378,15 @@ export class KritzelEngine {
1361
1378
  if (!data.__class__ || data.__class__ !== 'KritzelWorkspace') {
1362
1379
  throw new Error('Invalid workspace data: missing or incorrect __class__ identifier');
1363
1380
  }
1381
+ await this.core.initializeAssetStorage();
1382
+ await this.restorePortableAssets(data);
1364
1383
  if (data.version && data.version !== WORKSPACE_EXPORT_VERSION) {
1365
1384
  console.warn(`Workspace version mismatch: expected ${WORKSPACE_EXPORT_VERSION}, got ${data.version}`);
1366
1385
  }
1367
1386
  // Create a new workspace with a fresh ID but use the imported name
1368
1387
  const newWorkspaceId = ObjectHelper.generateUUID();
1369
- const importedName = data.name || 'Imported Workspace';
1370
- let importedViewport = data.viewport || { centerWorldX: 0, centerWorldY: 0, scale: 1 };
1371
- // Backward compatibility: convert legacy translateX/translateY to centerWorldX/centerWorldY
1372
- if ('translateX' in importedViewport && !('centerWorldX' in importedViewport)) {
1373
- const scale = importedViewport.scale ?? 1;
1374
- importedViewport = {
1375
- centerWorldX: -(importedViewport.translateX ?? 0) / scale,
1376
- centerWorldY: -(importedViewport.translateY ?? 0) / scale,
1377
- scale,
1378
- };
1379
- }
1388
+ const importedName = this.getImportedWorkspaceName(data.name);
1389
+ const importedViewport = this.getImportedWorkspaceViewport(data.viewport);
1380
1390
  const newWorkspace = new KritzelWorkspace(newWorkspaceId, importedName, importedViewport);
1381
1391
  // Save the new workspace
1382
1392
  this.core.createWorkspace(newWorkspace);
@@ -1415,6 +1425,8 @@ export class KritzelEngine {
1415
1425
  if (!data.__class__ || data.__class__ !== 'KritzelWorkspace') {
1416
1426
  throw new Error('Invalid workspace data: missing or incorrect __class__ identifier');
1417
1427
  }
1428
+ await this.core.initializeAssetStorage();
1429
+ await this.restorePortableAssets(data);
1418
1430
  if (data.version && data.version !== WORKSPACE_EXPORT_VERSION) {
1419
1431
  console.warn(`Workspace version mismatch: expected ${WORKSPACE_EXPORT_VERSION}, got ${data.version}`);
1420
1432
  }
@@ -1441,6 +1453,98 @@ export class KritzelEngine {
1441
1453
  this.core.rerender();
1442
1454
  return loadedCount;
1443
1455
  }
1456
+ getWorkspaceExportMode() {
1457
+ return this.core.assetResolver.hasRemoteProvider ? 'lightweight' : 'portable';
1458
+ }
1459
+ async collectPortableAssets(serializedObjects) {
1460
+ if (!Array.isArray(serializedObjects) || serializedObjects.length === 0) {
1461
+ return {};
1462
+ }
1463
+ const assetIds = new Set();
1464
+ for (const serializedObject of serializedObjects) {
1465
+ if (!serializedObject || typeof serializedObject !== 'object') {
1466
+ continue;
1467
+ }
1468
+ const maybeImage = serializedObject;
1469
+ if (maybeImage.__class__ === 'KritzelImage' && typeof maybeImage.assetId === 'string' && maybeImage.assetId.length > 0) {
1470
+ assetIds.add(maybeImage.assetId);
1471
+ }
1472
+ }
1473
+ const assets = {};
1474
+ for (const assetId of assetIds) {
1475
+ try {
1476
+ const blob = await this.core.assetResolver.fetchBlob(assetId);
1477
+ assets[assetId] = await this.blobToDataUrl(blob);
1478
+ }
1479
+ catch (error) {
1480
+ console.warn(`[Kritzel] Failed to embed asset ${assetId} in portable workspace export:`, error);
1481
+ }
1482
+ }
1483
+ return assets;
1484
+ }
1485
+ async restorePortableAssets(data) {
1486
+ const assets = data.assets;
1487
+ if (!assets || typeof assets !== 'object') {
1488
+ return;
1489
+ }
1490
+ for (const [assetId, dataUrl] of Object.entries(assets)) {
1491
+ if (!assetId || typeof dataUrl !== 'string' || !dataUrl.startsWith('data:')) {
1492
+ continue;
1493
+ }
1494
+ try {
1495
+ const blob = await this.dataUrlToBlob(dataUrl);
1496
+ await this.core.assetResolver.put(blob, {
1497
+ id: assetId,
1498
+ mimeType: blob.type || 'application/octet-stream',
1499
+ kind: 'image',
1500
+ });
1501
+ }
1502
+ catch (error) {
1503
+ console.warn(`[Kritzel] Failed to restore embedded asset ${assetId} from portable workspace import:`, error);
1504
+ }
1505
+ }
1506
+ }
1507
+ blobToDataUrl(blob) {
1508
+ return new Promise((resolve, reject) => {
1509
+ const reader = new FileReader();
1510
+ reader.onload = () => resolve(reader.result);
1511
+ reader.onerror = () => reject(reader.error ?? new Error('Failed to read blob as data URL'));
1512
+ reader.readAsDataURL(blob);
1513
+ });
1514
+ }
1515
+ async dataUrlToBlob(dataUrl) {
1516
+ const response = await fetch(dataUrl);
1517
+ return response.blob();
1518
+ }
1519
+ getImportedWorkspaceName(rawName) {
1520
+ if (typeof rawName === 'string' && rawName.trim().length > 0) {
1521
+ return rawName;
1522
+ }
1523
+ return 'Imported Workspace';
1524
+ }
1525
+ getImportedWorkspaceViewport(rawViewport) {
1526
+ if (!rawViewport || typeof rawViewport !== 'object') {
1527
+ return { centerWorldX: 0, centerWorldY: 0, scale: 1 };
1528
+ }
1529
+ const viewport = rawViewport;
1530
+ if (typeof viewport.centerWorldX === 'number' && typeof viewport.centerWorldY === 'number') {
1531
+ const scale = typeof viewport.scale === 'number' && viewport.scale > 0 ? viewport.scale : 1;
1532
+ return {
1533
+ centerWorldX: viewport.centerWorldX,
1534
+ centerWorldY: viewport.centerWorldY,
1535
+ scale,
1536
+ };
1537
+ }
1538
+ if (typeof viewport.translateX === 'number' || typeof viewport.translateY === 'number') {
1539
+ const scale = typeof viewport.scale === 'number' && viewport.scale > 0 ? viewport.scale : 1;
1540
+ return {
1541
+ centerWorldX: -(typeof viewport.translateX === 'number' ? viewport.translateX : 0) / scale,
1542
+ centerWorldY: -(typeof viewport.translateY === 'number' ? viewport.translateY : 0) / scale,
1543
+ scale,
1544
+ };
1545
+ }
1546
+ return { centerWorldX: 0, centerWorldY: 0, scale: 1 };
1547
+ }
1444
1548
  /**
1445
1549
  * Exports the current workspace as a JSON file and triggers a browser download.
1446
1550
  * @param filename - Optional custom filename (without extension). Defaults to workspace name with timestamp.
@@ -5337,6 +5441,10 @@ export class KritzelEngine {
5337
5441
  "Promise": {
5338
5442
  "location": "global",
5339
5443
  "id": "global::Promise"
5444
+ },
5445
+ "WorkspaceJsonExportPayload": {
5446
+ "location": "global",
5447
+ "id": "global::WorkspaceJsonExportPayload"
5340
5448
  }
5341
5449
  },
5342
5450
  "return": "Promise<string>"
@@ -5362,6 +5470,10 @@ export class KritzelEngine {
5362
5470
  "location": "global",
5363
5471
  "id": "global::Promise"
5364
5472
  },
5473
+ "WorkspaceJsonExportPayload": {
5474
+ "location": "global",
5475
+ "id": "global::WorkspaceJsonExportPayload"
5476
+ },
5365
5477
  "KritzelBaseObject": {
5366
5478
  "location": "import",
5367
5479
  "path": "../../../classes/objects/base-object.class",
@@ -5395,6 +5507,10 @@ export class KritzelEngine {
5395
5507
  "location": "global",
5396
5508
  "id": "global::Promise"
5397
5509
  },
5510
+ "WorkspaceJsonExportPayload": {
5511
+ "location": "global",
5512
+ "id": "global::WorkspaceJsonExportPayload"
5513
+ },
5398
5514
  "KritzelBaseObject": {
5399
5515
  "location": "import",
5400
5516
  "path": "../../../classes/objects/base-object.class",
@@ -3,4 +3,4 @@
3
3
  * This file is auto-generated by the version bump scripts.
4
4
  * Do not modify manually.
5
5
  */
6
- export const KRITZEL_VERSION = '0.4.1';
6
+ export const KRITZEL_VERSION = '0.4.2';
@@ -1 +1 @@
1
- export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-B43upypT.js";export{K as KritzelBaseObject,b as KritzelLine,a as KritzelPath}from"./p-Ka7OWbnk.js";export{u as APP_STATE_MIGRATIONS,A as AssetNotFoundError,D as DE_LOCALE,E as EN_LOCALE,F as FR_LOCALE,I as IndexedDBAssetProvider,s as KritzelAlignment,o as KritzelAnchorManager,n as KritzelAssetResolver,e as KritzelBaseTool,f as KritzelBrushTool,l as KritzelCursorHelper,d as KritzelCustomElement,r as KritzelCustomElementRendererRegistry,h as KritzelEraserTool,b as KritzelGroup,a as KritzelImage,i as KritzelImageTool,q as KritzelLicenseManager,g as KritzelLineTool,p as KritzelLocalizationManager,m as KritzelSelectionTool,c as KritzelShape,k as KritzelShapeTool,K as KritzelText,j as KritzelTextTool,S as ShapeType,W as WORKSPACE_MIGRATIONS,t as runMigrations}from"./p-BH4oJ7yX.js";import*as z from"yjs";import{IndexeddbPersistence as y}from"y-indexeddb";import{WebsocketProvider as w}from"y-websocket";import{H as x,a as T}from"./kritzel-editor.js";export{d as DEFAULT_ASSET_STORAGE_CONFIG,D as DEFAULT_BRUSH_CONFIG,c as DEFAULT_LINE_TOOL_CONFIG,b as DEFAULT_TEXT_CONFIG,KritzelEditor,defineCustomElement as defineCustomElementKritzelEditor}from"./kritzel-editor.js";export{K as KritzelWorkspace,W as WORKSPACE_EXPORT_VERSION}from"./p-DhMlShij.js";export{K as KritzelThemeManager,d as darkTheme,l as lightTheme}from"./p-BmyTdQGy.js";export{K as KritzelFontRegistry}from"./p-DJkKlUyZ.js";export{C as CURRENT_APP_STATE_SCHEMA_VERSION,a as CURRENT_WORKSPACE_SCHEMA_VERSION}from"./p-CW-VyJgK.js";export{KritzelActiveUsers,defineCustomElement as defineCustomElementKritzelActiveUsers}from"./kritzel-active-users.js";export{KritzelAvatar,defineCustomElement as defineCustomElementKritzelAvatar}from"./kritzel-avatar.js";export{KritzelAwarenessCursors,defineCustomElement as defineCustomElementKritzelAwarenessCursors}from"./kritzel-awareness-cursors.js";export{KritzelBackToContent,defineCustomElement as defineCustomElementKritzelBackToContent}from"./kritzel-back-to-content.js";export{KritzelBrushStyle,defineCustomElement as defineCustomElementKritzelBrushStyle}from"./kritzel-brush-style.js";export{KritzelButton,defineCustomElement as defineCustomElementKritzelButton}from"./kritzel-button.js";export{KritzelColor,defineCustomElement as defineCustomElementKritzelColor}from"./kritzel-color.js";export{KritzelColorPalette,defineCustomElement as defineCustomElementKritzelColorPalette}from"./kritzel-color-palette.js";export{KritzelContextMenu,defineCustomElement as defineCustomElementKritzelContextMenu}from"./kritzel-context-menu.js";export{KritzelControls,defineCustomElement as defineCustomElementKritzelControls}from"./kritzel-controls.js";export{KritzelCurrentUser,defineCustomElement as defineCustomElementKritzelCurrentUser}from"./kritzel-current-user.js";export{KritzelCurrentUserDialog,defineCustomElement as defineCustomElementKritzelCurrentUserDialog}from"./kritzel-current-user-dialog.js";export{KritzelCursorTrail,defineCustomElement as defineCustomElementKritzelCursorTrail}from"./kritzel-cursor-trail.js";export{KritzelDialog,defineCustomElement as defineCustomElementKritzelDialog}from"./kritzel-dialog.js";export{KritzelDropdown,defineCustomElement as defineCustomElementKritzelDropdown}from"./kritzel-dropdown.js";export{KritzelEngine,defineCustomElement as defineCustomElementKritzelEngine}from"./kritzel-engine.js";export{KritzelExport,defineCustomElement as defineCustomElementKritzelExport}from"./kritzel-export.js";export{KritzelFont,defineCustomElement as defineCustomElementKritzelFont}from"./kritzel-font.js";export{KritzelFontFamily,defineCustomElement as defineCustomElementKritzelFontFamily}from"./kritzel-font-family.js";export{KritzelFontSize,defineCustomElement as defineCustomElementKritzelFontSize}from"./kritzel-font-size.js";export{KritzelIcon,defineCustomElement as defineCustomElementKritzelIcon}from"./kritzel-icon.js";export{KritzelInput,defineCustomElement as defineCustomElementKritzelInput}from"./kritzel-input.js";export{KritzelLineEndings,defineCustomElement as defineCustomElementKritzelLineEndings}from"./kritzel-line-endings.js";export{KritzelLoadingOverlay,defineCustomElement as defineCustomElementKritzelLoadingOverlay}from"./kritzel-loading-overlay.js";export{KritzelLoginDialog,defineCustomElement as defineCustomElementKritzelLoginDialog}from"./kritzel-login-dialog.js";export{KritzelMasterDetail,defineCustomElement as defineCustomElementKritzelMasterDetail}from"./kritzel-master-detail.js";export{KritzelMenu,defineCustomElement as defineCustomElementKritzelMenu}from"./kritzel-menu.js";export{KritzelMenuItem,defineCustomElement as defineCustomElementKritzelMenuItem}from"./kritzel-menu-item.js";export{KritzelMoreMenu,defineCustomElement as defineCustomElementKritzelMoreMenu}from"./kritzel-more-menu.js";export{KritzelNotificationCard,defineCustomElement as defineCustomElementKritzelNotificationCard}from"./kritzel-notification-card.js";export{KritzelNumericInput,defineCustomElement as defineCustomElementKritzelNumericInput}from"./kritzel-numeric-input.js";export{KritzelOpacitySlider,defineCustomElement as defineCustomElementKritzelOpacitySlider}from"./kritzel-opacity-slider.js";export{KritzelPillTabs,defineCustomElement as defineCustomElementKritzelPillTabs}from"./kritzel-pill-tabs.js";export{KritzelPortal,defineCustomElement as defineCustomElementKritzelPortal}from"./kritzel-portal.js";export{KritzelSettings,defineCustomElement as defineCustomElementKritzelSettings}from"./kritzel-settings.js";export{KritzelShapeFill,defineCustomElement as defineCustomElementKritzelShapeFill}from"./kritzel-shape-fill.js";export{KritzelShareDialog,defineCustomElement as defineCustomElementKritzelShareDialog}from"./kritzel-share-dialog.js";export{KritzelSlideToggle,defineCustomElement as defineCustomElementKritzelSlideToggle}from"./kritzel-slide-toggle.js";export{KritzelSplitButton,defineCustomElement as defineCustomElementKritzelSplitButton}from"./kritzel-split-button.js";export{KritzelStrokeSize,defineCustomElement as defineCustomElementKritzelStrokeSize}from"./kritzel-stroke-size.js";export{KritzelSyncIndicator,defineCustomElement as defineCustomElementKritzelSyncIndicator}from"./kritzel-sync-indicator.js";export{KritzelToolConfig,defineCustomElement as defineCustomElementKritzelToolConfig}from"./kritzel-tool-config.js";export{KritzelTooltip,defineCustomElement as defineCustomElementKritzelTooltip}from"./kritzel-tooltip.js";export{KritzelUtilityPanel,defineCustomElement as defineCustomElementKritzelUtilityPanel}from"./kritzel-utility-panel.js";export{KritzelWatermark,defineCustomElement as defineCustomElementKritzelWatermark}from"./kritzel-watermark.js";export{KritzelWorkspaceManager,defineCustomElement as defineCustomElementKritzelWorkspaceManager}from"./kritzel-workspace-manager.js";export{KritzelZoomPanel,defineCustomElement as defineCustomElementKritzelZoomPanel}from"./kritzel-zoom-panel.js";const P=Math.floor,v=127,U=Number.MAX_SAFE_INTEGER;class M{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const O=()=>new M,_=e=>{const t=new Uint8Array((e=>{let t=e.cpos;for(let s=0;s<e.bufs.length;s++)t+=e.bufs[s].length;return t})(e));let s=0;for(let i=0;i<e.bufs.length;i++){const n=e.bufs[i];t.set(n,s),s+=n.length}return t.set(new Uint8Array(e.cbuf.buffer,0,e.cpos),s),t},L=(e,t)=>{const s=e.cbuf.length;e.cpos===s&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(2*s),e.cpos=0),e.cbuf[e.cpos++]=t},R=(e,t)=>{for(;t>v;)L(e,128|v&t),t=P(t/128);L(e,v&t)},$=(e,t)=>{R(e,t.byteLength),((e,t)=>{const s=e.cbuf.length,i=e.cpos,n=((e,t)=>e<t?e:t)(s-i,t.length),o=t.length-n;e.cbuf.set(t.subarray(0,n),i),e.cpos+=n,o>0&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(((e,t)=>e>t?e:t)(2*s,o)),e.cbuf.set(t.subarray(n)),e.cpos=o)})(e,t)},B=e=>Error(e),H=B("Unexpected end of array"),N=B("Integer out of Range");class G{constructor(e){this.arr=e,this.pos=0}}const J=e=>((e,t)=>{const s=new Uint8Array(e.arr.buffer,e.pos+e.arr.byteOffset,t);return e.pos+=t,s})(e,V(e)),V=e=>{let t=0,s=1;const i=e.arr.length;for(;e.pos<i;){const i=e.arr[e.pos++];if(t+=(i&v)*s,s*=128,i<128)return t;if(t>U)throw N}throw H};class X{type="local";doc;channel;_synced=!1;constructor(e,t,s){this.doc=t,this.channel=new BroadcastChannel(e),this.channel.onmessage=e=>{this.handleMessage(e.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info("BroadcastChannel Provider initialized: "+e)}handleDocUpdate=(e,t)=>{if(t!==this){const t=O();R(t,0),$(t,e),this.channel.postMessage(_(t))}};handleMessage(e){const t=(e=>new G(e))(new Uint8Array(e));switch(V(t)){case 0:const e=J(t);z.applyUpdate(this.doc,e,this);break;case 1:this.broadcastSync();break;case 2:const s=J(t),i=z.encodeStateAsUpdate(this.doc,s);if(i.length>0){const e=O();R(e,0),$(e,i),this.channel.postMessage(_(e))}}}broadcastSync(){const e=O();R(e,2),$(e,z.encodeStateVector(this.doc)),this.channel.postMessage(_(e))}async connect(){if(!this._synced)return new Promise((e=>{const t=()=>{this._synced?e():setTimeout(t,50)};t()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}const Z=new Map;class Q{type="local";doc;cacheKey;isConnected=!1;constructor(e,t,s){this.doc=t,this.cacheKey=s?.name??e}handleUpdate=(e,t)=>{t!==this&&Z.set(this.cacheKey,z.encodeStateAsUpdate(this.doc))};async connect(){if(this.isConnected)return;const e=Z.get(this.cacheKey);e&&z.applyUpdate(this.doc,e,this),this.doc.on("update",this.handleUpdate),this.isConnected=!0}disconnect(){this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleUpdate),this.isConnected=!1}static clear(e){void 0!==e?Z.delete(e):Z.clear()}}class Y{type="local";provider;isConnected=!1;constructor(e,t,s){this.provider=new y(s?.name||e,t)}async connect(){if(!this.isConnected)return new Promise((e=>{this.provider.on("synced",(()=>{this.isConnected=!0,e()}))}))}disconnect(){this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class ee{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(e,t,s){const i=s?.url||"ws://localhost:1234",n=s?.roomName||e;this.provider=new w(i,n,t,{params:s?.params,protocols:s?.protocols,WebSocketPolyfill:s?.WebSocketPolyfill,awareness:s?.awareness,maxBackoffTime:s?.maxBackoffTime,disableBc:!0}),this._quiet=s?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${i}/${n}`)}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new ee(t,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:e})=>{"connected"===e?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===e&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(e=>{e&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((e,t)=>{const s=setTimeout((()=>{t(Error("WebSocket connection timeout"))}),1e4),i=({status:t})=>{"connected"===t&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class te{type="network";provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;connectionTimeoutMs;_connectionStatus="disconnected";visibilityHandler=null;onlineHandler=null;get awareness(){return this.provider.awareness}get connectionStatus(){return this._connectionStatus}static sharedWebSocketProvider=null;constructor(e,t,s){const i=s?.name||e,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const o=s?.websocketProvider||te.sharedWebSocketProvider,r={};void 0!==s?.delay&&(r.delay=s.delay),void 0!==s?.factor&&(r.factor=s.factor),void 0!==s?.maxAttempts&&(r.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(r.minDelay=s.minDelay),void 0!==s?.maxDelay&&(r.maxDelay=s.maxDelay);const l=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info("Hocuspocus connected: "+i),s?.onConnect&&s.onConnect())},a=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info("Hocuspocus disconnected: "+i),s?.onDisconnect&&s.onDisconnect())},c=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info("Hocuspocus synced: "+i),s?.onSynced&&s.onSynced())},m=e=>{this.isDestroyed||("connecting"===e.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(e))};if(o){this.usesSharedSocket=!0;const e={websocketProvider:o,name:i,document:t,token:s?.token||null,onStatus:m,onConnect:l,onDisconnect:a,onSynced:c,...r};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new x(e),this.provider.attach(),s?.quiet||console.info("Hocuspocus Provider initialized (multiplexed): "+i)}else{this.usesSharedSocket=!1;const e={url:n,name:i,document:t,token:s?.token||null,autoConnect:!1,onStatus:m,onConnect:l,onDisconnect:a,onSynced:c,...r};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(e.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new x(e),s?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}this.setupBrowserEventListeners()}setupBrowserEventListeners(){"undefined"!=typeof document&&(this.visibilityHandler=()=>{"visible"!==document.visibilityState||this.isConnected||this.isDestroyed||this.provider.connect()},document.addEventListener("visibilitychange",this.visibilityHandler)),"undefined"!=typeof window&&(this.onlineHandler=()=>{this.isConnected||this.isDestroyed||this.provider.connect()},window.addEventListener("online",this.onlineHandler))}removeBrowserEventListeners(){this.visibilityHandler&&"undefined"!=typeof document&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&"undefined"!=typeof window&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null)}static createSharedWebSocket(e){if(te.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),te.sharedWebSocketProvider;const t={url:e.url};return e.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),e.onConnect&&(t.onConnect=e.onConnect),e.onDisconnect&&(t.onDisconnect=e.onDisconnect),e.onStatus&&(t.onStatus=e.onStatus),te.sharedWebSocketProvider=new T(t),console.info("Shared Hocuspocus WebSocket created: "+e.url),te.sharedWebSocketProvider}static destroySharedWebSocket(){te.sharedWebSocketProvider&&(te.sharedWebSocketProvider.destroy(),te.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return te.sharedWebSocketProvider}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new te(t,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((e,t)=>{this.pendingConnectReject=t,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,t(Error("Hocuspocus connection timeout"))}),this.connectionTimeoutMs);const s=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),this.isDestroyed||e()};if(this.provider.on("synced",s),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),void e();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}async reconnect(){return this.disconnect(),this.connect()}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.removeBrowserEventListeners(),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}}class se{type="remote";name="HttpAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new se(e)}}async init(){this._options.quiet||console.info("HttpAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=t.id??this.generateUuid(),i={...t,id:s},n=await(this._options.headers?.())??{},o=await this._options.uploadUrl(i),r=this._options.upload??this.defaultUpload;return{id:(await r(o,e,i,n)).id??s,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.resolveUrl(e)}async fetch(e){const t=await this._options.resolveUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to fetch asset ${e}: ${i.status} ${i.statusText}`);return i.blob()}async delete(e){if(!this._options.deleteUrl)return;const t=await this._options.deleteUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{method:"DELETE",headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to delete asset ${e}: ${i.status} ${i.statusText}`);this._options.quiet||console.info("HttpAssetProvider: deleted asset "+e)}defaultUpload=async(e,t,s,i)=>{const n=new FormData;n.append("metadata",JSON.stringify(s)),n.append("file",t,s.originalFilename||`${s.id}.${this.extensionFromMime(s.mimeType)}`);const o=await fetch(e,{method:"POST",headers:i,body:n});if(!o.ok)throw Error(`[HttpAssetProvider] Upload failed: ${o.status} ${o.statusText}`);return(o.headers.get("content-type")||"").includes("application/json")?await o.json():{}};extensionFromMime(e){const t=e.indexOf("/");return t>=0?e.slice(t+1):"bin"}generateUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();const e=crypto.getRandomValues(new Uint8Array(16));e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e,(e=>e.toString(16).padStart(2,"0"))).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}}class ie{type="remote";name="PresignedAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new ie(e)}}async init(){this._options.quiet||console.info("PresignedAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=await this._options.getUploadDescriptor(t),i=s.method??"PUT",n={...s.headers??{}};let o;if(n["Content-Type"]||n["content-type"]||(n["Content-Type"]=t.mimeType),"POST"===i&&s.fields){const t=new FormData;for(const[e,i]of Object.entries(s.fields))t.append(e,i);t.append("file",e),o=t,delete n["Content-Type"],delete n["content-type"]}else o=e;const r=await fetch(s.url,{method:i,headers:n,body:o});if(!r.ok)throw Error(`[PresignedAssetProvider] Upload failed: ${r.status} ${r.statusText}`);return{id:s.id,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.getDownloadUrl(e)}async fetch(e){const t=await this._options.getDownloadUrl(e),s=await fetch(t);if(!s.ok)throw Error(`[PresignedAssetProvider] Failed to fetch asset ${e}: ${s.status} ${s.statusText}`);return s.blob()}async delete(e){this._options.deleteAsset&&(await this._options.deleteAsset(e),this._options.quiet||console.info("PresignedAssetProvider: deleted asset "+e))}}export{X as BroadcastSyncProvider,te as HocuspocusSyncProvider,se as HttpAssetProvider,Q as InMemorySyncProvider,Y as IndexedDBSyncProvider,ie as PresignedAssetProvider,ee as WebSocketSyncProvider}
1
+ export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-B43upypT.js";export{K as KritzelBaseObject,b as KritzelLine,a as KritzelPath}from"./p-Ka7OWbnk.js";export{u as APP_STATE_MIGRATIONS,A as AssetNotFoundError,D as DE_LOCALE,E as EN_LOCALE,F as FR_LOCALE,I as IndexedDBAssetProvider,s as KritzelAlignment,o as KritzelAnchorManager,n as KritzelAssetResolver,e as KritzelBaseTool,f as KritzelBrushTool,l as KritzelCursorHelper,d as KritzelCustomElement,r as KritzelCustomElementRendererRegistry,h as KritzelEraserTool,b as KritzelGroup,a as KritzelImage,i as KritzelImageTool,q as KritzelLicenseManager,g as KritzelLineTool,p as KritzelLocalizationManager,m as KritzelSelectionTool,c as KritzelShape,k as KritzelShapeTool,K as KritzelText,j as KritzelTextTool,S as ShapeType,W as WORKSPACE_MIGRATIONS,t as runMigrations}from"./p--Oazz-BP.js";import*as z from"yjs";import{IndexeddbPersistence as y}from"y-indexeddb";import{WebsocketProvider as w}from"y-websocket";import{H as x,a as T}from"./kritzel-editor.js";export{d as DEFAULT_ASSET_STORAGE_CONFIG,D as DEFAULT_BRUSH_CONFIG,c as DEFAULT_LINE_TOOL_CONFIG,b as DEFAULT_TEXT_CONFIG,KritzelEditor,defineCustomElement as defineCustomElementKritzelEditor}from"./kritzel-editor.js";export{K as KritzelWorkspace,W as WORKSPACE_EXPORT_VERSION}from"./p-DAwPPDMS.js";export{K as KritzelThemeManager,d as darkTheme,l as lightTheme}from"./p-BmyTdQGy.js";export{K as KritzelFontRegistry}from"./p-DJkKlUyZ.js";export{C as CURRENT_APP_STATE_SCHEMA_VERSION,a as CURRENT_WORKSPACE_SCHEMA_VERSION}from"./p-CW-VyJgK.js";export{KritzelActiveUsers,defineCustomElement as defineCustomElementKritzelActiveUsers}from"./kritzel-active-users.js";export{KritzelAvatar,defineCustomElement as defineCustomElementKritzelAvatar}from"./kritzel-avatar.js";export{KritzelAwarenessCursors,defineCustomElement as defineCustomElementKritzelAwarenessCursors}from"./kritzel-awareness-cursors.js";export{KritzelBackToContent,defineCustomElement as defineCustomElementKritzelBackToContent}from"./kritzel-back-to-content.js";export{KritzelBrushStyle,defineCustomElement as defineCustomElementKritzelBrushStyle}from"./kritzel-brush-style.js";export{KritzelButton,defineCustomElement as defineCustomElementKritzelButton}from"./kritzel-button.js";export{KritzelColor,defineCustomElement as defineCustomElementKritzelColor}from"./kritzel-color.js";export{KritzelColorPalette,defineCustomElement as defineCustomElementKritzelColorPalette}from"./kritzel-color-palette.js";export{KritzelContextMenu,defineCustomElement as defineCustomElementKritzelContextMenu}from"./kritzel-context-menu.js";export{KritzelControls,defineCustomElement as defineCustomElementKritzelControls}from"./kritzel-controls.js";export{KritzelCurrentUser,defineCustomElement as defineCustomElementKritzelCurrentUser}from"./kritzel-current-user.js";export{KritzelCurrentUserDialog,defineCustomElement as defineCustomElementKritzelCurrentUserDialog}from"./kritzel-current-user-dialog.js";export{KritzelCursorTrail,defineCustomElement as defineCustomElementKritzelCursorTrail}from"./kritzel-cursor-trail.js";export{KritzelDialog,defineCustomElement as defineCustomElementKritzelDialog}from"./kritzel-dialog.js";export{KritzelDropdown,defineCustomElement as defineCustomElementKritzelDropdown}from"./kritzel-dropdown.js";export{KritzelEngine,defineCustomElement as defineCustomElementKritzelEngine}from"./kritzel-engine.js";export{KritzelExport,defineCustomElement as defineCustomElementKritzelExport}from"./kritzel-export.js";export{KritzelFont,defineCustomElement as defineCustomElementKritzelFont}from"./kritzel-font.js";export{KritzelFontFamily,defineCustomElement as defineCustomElementKritzelFontFamily}from"./kritzel-font-family.js";export{KritzelFontSize,defineCustomElement as defineCustomElementKritzelFontSize}from"./kritzel-font-size.js";export{KritzelIcon,defineCustomElement as defineCustomElementKritzelIcon}from"./kritzel-icon.js";export{KritzelInput,defineCustomElement as defineCustomElementKritzelInput}from"./kritzel-input.js";export{KritzelLineEndings,defineCustomElement as defineCustomElementKritzelLineEndings}from"./kritzel-line-endings.js";export{KritzelLoadingOverlay,defineCustomElement as defineCustomElementKritzelLoadingOverlay}from"./kritzel-loading-overlay.js";export{KritzelLoginDialog,defineCustomElement as defineCustomElementKritzelLoginDialog}from"./kritzel-login-dialog.js";export{KritzelMasterDetail,defineCustomElement as defineCustomElementKritzelMasterDetail}from"./kritzel-master-detail.js";export{KritzelMenu,defineCustomElement as defineCustomElementKritzelMenu}from"./kritzel-menu.js";export{KritzelMenuItem,defineCustomElement as defineCustomElementKritzelMenuItem}from"./kritzel-menu-item.js";export{KritzelMoreMenu,defineCustomElement as defineCustomElementKritzelMoreMenu}from"./kritzel-more-menu.js";export{KritzelNotificationCard,defineCustomElement as defineCustomElementKritzelNotificationCard}from"./kritzel-notification-card.js";export{KritzelNumericInput,defineCustomElement as defineCustomElementKritzelNumericInput}from"./kritzel-numeric-input.js";export{KritzelOpacitySlider,defineCustomElement as defineCustomElementKritzelOpacitySlider}from"./kritzel-opacity-slider.js";export{KritzelPillTabs,defineCustomElement as defineCustomElementKritzelPillTabs}from"./kritzel-pill-tabs.js";export{KritzelPortal,defineCustomElement as defineCustomElementKritzelPortal}from"./kritzel-portal.js";export{KritzelSettings,defineCustomElement as defineCustomElementKritzelSettings}from"./kritzel-settings.js";export{KritzelShapeFill,defineCustomElement as defineCustomElementKritzelShapeFill}from"./kritzel-shape-fill.js";export{KritzelShareDialog,defineCustomElement as defineCustomElementKritzelShareDialog}from"./kritzel-share-dialog.js";export{KritzelSlideToggle,defineCustomElement as defineCustomElementKritzelSlideToggle}from"./kritzel-slide-toggle.js";export{KritzelSplitButton,defineCustomElement as defineCustomElementKritzelSplitButton}from"./kritzel-split-button.js";export{KritzelStrokeSize,defineCustomElement as defineCustomElementKritzelStrokeSize}from"./kritzel-stroke-size.js";export{KritzelSyncIndicator,defineCustomElement as defineCustomElementKritzelSyncIndicator}from"./kritzel-sync-indicator.js";export{KritzelToolConfig,defineCustomElement as defineCustomElementKritzelToolConfig}from"./kritzel-tool-config.js";export{KritzelTooltip,defineCustomElement as defineCustomElementKritzelTooltip}from"./kritzel-tooltip.js";export{KritzelUtilityPanel,defineCustomElement as defineCustomElementKritzelUtilityPanel}from"./kritzel-utility-panel.js";export{KritzelWatermark,defineCustomElement as defineCustomElementKritzelWatermark}from"./kritzel-watermark.js";export{KritzelWorkspaceManager,defineCustomElement as defineCustomElementKritzelWorkspaceManager}from"./kritzel-workspace-manager.js";export{KritzelZoomPanel,defineCustomElement as defineCustomElementKritzelZoomPanel}from"./kritzel-zoom-panel.js";const P=Math.floor,v=127,U=Number.MAX_SAFE_INTEGER;class M{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}}const O=()=>new M,_=e=>{const t=new Uint8Array((e=>{let t=e.cpos;for(let s=0;s<e.bufs.length;s++)t+=e.bufs[s].length;return t})(e));let s=0;for(let i=0;i<e.bufs.length;i++){const n=e.bufs[i];t.set(n,s),s+=n.length}return t.set(new Uint8Array(e.cbuf.buffer,0,e.cpos),s),t},L=(e,t)=>{const s=e.cbuf.length;e.cpos===s&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(2*s),e.cpos=0),e.cbuf[e.cpos++]=t},R=(e,t)=>{for(;t>v;)L(e,128|v&t),t=P(t/128);L(e,v&t)},$=(e,t)=>{R(e,t.byteLength),((e,t)=>{const s=e.cbuf.length,i=e.cpos,n=((e,t)=>e<t?e:t)(s-i,t.length),o=t.length-n;e.cbuf.set(t.subarray(0,n),i),e.cpos+=n,o>0&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(((e,t)=>e>t?e:t)(2*s,o)),e.cbuf.set(t.subarray(n)),e.cpos=o)})(e,t)},B=e=>Error(e),H=B("Unexpected end of array"),N=B("Integer out of Range");class G{constructor(e){this.arr=e,this.pos=0}}const V=e=>((e,t)=>{const s=new Uint8Array(e.arr.buffer,e.pos+e.arr.byteOffset,t);return e.pos+=t,s})(e,J(e)),J=e=>{let t=0,s=1;const i=e.arr.length;for(;e.pos<i;){const i=e.arr[e.pos++];if(t+=(i&v)*s,s*=128,i<128)return t;if(t>U)throw N}throw H};class Z{type="local";doc;channel;_synced=!1;constructor(e,t,s){this.doc=t,this.channel=new BroadcastChannel(e),this.channel.onmessage=e=>{this.handleMessage(e.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),s?.quiet||console.info("BroadcastChannel Provider initialized: "+e)}handleDocUpdate=(e,t)=>{if(t!==this){const t=O();R(t,0),$(t,e),this.channel.postMessage(_(t))}};handleMessage(e){const t=(e=>new G(e))(new Uint8Array(e));switch(J(t)){case 0:const e=V(t);z.applyUpdate(this.doc,e,this);break;case 1:this.broadcastSync();break;case 2:const s=V(t),i=z.encodeStateAsUpdate(this.doc,s);if(i.length>0){const e=O();R(e,0),$(e,i),this.channel.postMessage(_(e))}}}broadcastSync(){const e=O();R(e,2),$(e,z.encodeStateVector(this.doc)),this.channel.postMessage(_(e))}async connect(){if(!this._synced)return new Promise((e=>{const t=()=>{this._synced?e():setTimeout(t,50)};t()}))}disconnect(){}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}const X=new Map;class Q{type="local";doc;cacheKey;isConnected=!1;constructor(e,t,s){this.doc=t,this.cacheKey=s?.name??e}handleUpdate=(e,t)=>{t!==this&&X.set(this.cacheKey,z.encodeStateAsUpdate(this.doc))};async connect(){if(this.isConnected)return;const e=X.get(this.cacheKey);e&&z.applyUpdate(this.doc,e,this),this.doc.on("update",this.handleUpdate),this.isConnected=!0}disconnect(){this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.doc.off("update",this.handleUpdate),this.isConnected=!1}static clear(e){void 0!==e?X.delete(e):X.clear()}}class Y{type="local";provider;isConnected=!1;constructor(e,t,s){this.provider=new y(s?.name||e,t)}async connect(){if(!this.isConnected)return new Promise((e=>{this.provider.on("synced",(()=>{this.isConnected=!0,e()}))}))}disconnect(){this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class ee{type="network";provider;isConnected=!1;_quiet=!1;get awareness(){return this.provider.awareness}constructor(e,t,s){const i=s?.url||"ws://localhost:1234",n=s?.roomName||e;this.provider=new w(i,n,t,{params:s?.params,protocols:s?.protocols,WebSocketPolyfill:s?.WebSocketPolyfill,awareness:s?.awareness,maxBackoffTime:s?.maxBackoffTime,disableBc:!0}),this._quiet=s?.quiet??!1,this.setupEventListeners(),this._quiet||console.info(`WebSocket Provider initialized: ${i}/${n}`)}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new ee(t,s,n)}}}setupEventListeners(){this.provider.on("status",(({status:e})=>{"connected"===e?(this.isConnected=!0,this._quiet||console.info("WebSocket connected")):"disconnected"===e&&(this.isConnected=!1,this._quiet||console.info("WebSocket disconnected"))})),this.provider.on("sync",(e=>{e&&!this._quiet&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((e,t)=>{const s=setTimeout((()=>{t(Error("WebSocket connection timeout"))}),1e4),i=({status:t})=>{"connected"===t&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(s),this.provider.off("status",i),this.isConnected=!0,e())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}async reconnect(){return this.disconnect(),this.connect()}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class te{type="network";provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;isDestroyed=!1;connectTimeout=null;pendingConnectReject=null;connectionTimeoutMs;_connectionStatus="disconnected";visibilityHandler=null;onlineHandler=null;get awareness(){return this.provider.awareness}get connectionStatus(){return this._connectionStatus}static sharedWebSocketProvider=null;constructor(e,t,s){const i=s?.name||e,n=s?.url||"ws://localhost:1234";this.connectionTimeoutMs=s?.connectionTimeout??1e4;const o=s?.websocketProvider||te.sharedWebSocketProvider,r={};void 0!==s?.delay&&(r.delay=s.delay),void 0!==s?.factor&&(r.factor=s.factor),void 0!==s?.maxAttempts&&(r.maxAttempts=s.maxAttempts),void 0!==s?.minDelay&&(r.minDelay=s.minDelay),void 0!==s?.maxDelay&&(r.maxDelay=s.maxDelay);const l=()=>{this.isDestroyed||(this.isConnected=!0,this._connectionStatus="connected",s?.quiet||console.info("Hocuspocus connected: "+i),s?.onConnect&&s.onConnect())},a=()=>{this.isDestroyed||(this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected",s?.quiet||console.info("Hocuspocus disconnected: "+i),s?.onDisconnect&&s.onDisconnect())},c=()=>{this.isDestroyed||(this.isSynced=!0,this._connectionStatus="synced",s?.quiet||console.info("Hocuspocus synced: "+i),s?.onSynced&&s.onSynced())},m=e=>{this.isDestroyed||("connecting"===e.status&&(this._connectionStatus="connecting"),s?.onStatus&&s.onStatus(e))};if(o){this.usesSharedSocket=!0;const e={websocketProvider:o,name:i,document:t,token:s?.token||null,onStatus:m,onConnect:l,onDisconnect:a,onSynced:c,...r};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),this.provider=new x(e),this.provider.attach(),s?.quiet||console.info("Hocuspocus Provider initialized (multiplexed): "+i)}else{this.usesSharedSocket=!1;const e={url:n,name:i,document:t,token:s?.token||null,autoConnect:!1,onStatus:m,onConnect:l,onDisconnect:a,onSynced:c,...r};void 0!==s?.forceSyncInterval&&(e.forceSyncInterval=s.forceSyncInterval),s?.onAuthenticationFailed&&(e.onAuthenticationFailed=s.onAuthenticationFailed),s?.WebSocketPolyfill&&(e.WebSocketPolyfill=s.WebSocketPolyfill),this.provider=new x(e),s?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}this.setupBrowserEventListeners()}setupBrowserEventListeners(){"undefined"!=typeof document&&(this.visibilityHandler=()=>{"visible"!==document.visibilityState||this.isConnected||this.isDestroyed||this.provider.connect()},document.addEventListener("visibilitychange",this.visibilityHandler)),"undefined"!=typeof window&&(this.onlineHandler=()=>{this.isConnected||this.isDestroyed||this.provider.connect()},window.addEventListener("online",this.onlineHandler))}removeBrowserEventListeners(){this.visibilityHandler&&"undefined"!=typeof document&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&"undefined"!=typeof window&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null)}static createSharedWebSocket(e){if(te.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),te.sharedWebSocketProvider;const t={url:e.url};return e.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),e.onConnect&&(t.onConnect=e.onConnect),e.onDisconnect&&(t.onDisconnect=e.onDisconnect),e.onStatus&&(t.onStatus=e.onStatus),te.sharedWebSocketProvider=new T(t),console.info("Shared Hocuspocus WebSocket created: "+e.url),te.sharedWebSocketProvider}static destroySharedWebSocket(){te.sharedWebSocketProvider&&(te.sharedWebSocketProvider.destroy(),te.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return te.sharedWebSocketProvider}static with(e){return{create:(t,s,i)=>{const n=i?{...e,...i}:e;return new te(t,s,n)}}}async connect(){if(!this.isSynced&&!this.isDestroyed)return this._connectionStatus="connecting",new Promise(((e,t)=>{this.pendingConnectReject=t,this.connectTimeout=setTimeout((()=>{this.pendingConnectReject=null,this.connectTimeout=null,t(Error("Hocuspocus connection timeout"))}),this.connectionTimeoutMs);const s=()=>{this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),this.isDestroyed||e()};if(this.provider.on("synced",s),this.provider.isSynced)return this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject=null,this.provider.off("synced",s),void e();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}async reconnect(){return this.disconnect(),this.connect()}disconnect(){this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}destroy(){this.isDestroyed=!0,this.connectTimeout&&(clearTimeout(this.connectTimeout),this.connectTimeout=null),this.pendingConnectReject&&(this.pendingConnectReject=null),this.removeBrowserEventListeners(),this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1,this._connectionStatus="disconnected"}}class se{type="remote";name="HttpAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new se(e)}}async init(){this._options.quiet||console.info("HttpAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=t.id??this.generateUuid(),i={...t,id:s},n=await(this._options.headers?.())??{},o=await this._options.uploadUrl(i),r=this._options.upload??this.defaultUpload;return{id:(await r(o,e,i,n)).id??s,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.resolveUrl(e)}async fetch(e){const t=await this._options.resolveUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to fetch asset ${e}: ${i.status} ${i.statusText}`);return i.blob()}async delete(e){if(!this._options.deleteUrl)return;const t=await this._options.deleteUrl(e),s=await(this._options.headers?.())??{},i=await fetch(t,{method:"DELETE",headers:s});if(!i.ok)throw Error(`[HttpAssetProvider] Failed to delete asset ${e}: ${i.status} ${i.statusText}`);this._options.quiet||console.info("HttpAssetProvider: deleted asset "+e)}defaultUpload=async(e,t,s,i)=>{const n=new FormData;n.append("metadata",JSON.stringify(s)),n.append("file",t,s.originalFilename||`${s.id}.${this.extensionFromMime(s.mimeType)}`);const o=await fetch(e,{method:"POST",headers:i,body:n});if(!o.ok)throw Error(`[HttpAssetProvider] Upload failed: ${o.status} ${o.statusText}`);return(o.headers.get("content-type")||"").includes("application/json")?await o.json():{}};extensionFromMime(e){const t=e.indexOf("/");return t>=0?e.slice(t+1):"bin"}generateUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();const e=crypto.getRandomValues(new Uint8Array(16));e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e,(e=>e.toString(16).padStart(2,"0"))).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}}class ie{type="remote";name="PresignedAssetProvider";_options;constructor(e){this._options=e}static with(e){return{create:()=>new ie(e)}}async init(){this._options.quiet||console.info("PresignedAssetProvider initialized")}destroy(){}canResolve(e){return!0}async put(e,t){const s=await this._options.getUploadDescriptor(t),i=s.method??"PUT",n={...s.headers??{}};let o;if(n["Content-Type"]||n["content-type"]||(n["Content-Type"]=t.mimeType),"POST"===i&&s.fields){const t=new FormData;for(const[e,i]of Object.entries(s.fields))t.append(e,i);t.append("file",e),o=t,delete n["Content-Type"],delete n["content-type"]}else o=e;const r=await fetch(s.url,{method:i,headers:n,body:o});if(!r.ok)throw Error(`[PresignedAssetProvider] Upload failed: ${r.status} ${r.statusText}`);return{id:s.id,kind:t.kind??"file",mimeType:t.mimeType,size:e.size,createdAt:Date.now(),width:t.width,height:t.height,durationMs:t.durationMs,originalFilename:t.originalFilename}}async resolve(e){return this._options.getDownloadUrl(e)}async fetch(e){const t=await this._options.getDownloadUrl(e),s=await fetch(t);if(!s.ok)throw Error(`[PresignedAssetProvider] Failed to fetch asset ${e}: ${s.status} ${s.statusText}`);return s.blob()}async delete(e){this._options.deleteAsset&&(await this._options.deleteAsset(e),this._options.quiet||console.info("PresignedAssetProvider: deleted asset "+e))}}export{Z as BroadcastSyncProvider,te as HocuspocusSyncProvider,se as HttpAssetProvider,Q as InMemorySyncProvider,Y as IndexedDBSyncProvider,ie as PresignedAssetProvider,ee as WebSocketSyncProvider}