dome-embedded-app-sdk 0.3.2 → 0.3.3
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.
- package/README.md +53 -36
- package/dist/card-sdk.d.ts +6 -89
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types/card-sdk.types.d.ts +236 -0
- package/dist/utils.d.ts +13 -0
- package/docs/card-sdk.md +160 -0
- package/docs/viewer-sdk.md +50 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,64 +1,81 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Dome Embedded App SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build Dome cards and document viewers with a single SDK. Cards let you extend a dome with custom functionality, while viewers let you render and edit documents inside Dome.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install dome-embedded-app-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## What you can build
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
### **Cards**
|
|
10
14
|
|
|
11
15
|
A "card" in Dome enables you to extend the functionality of a dome. Each "card" is like a mini website (webapp) that you can build as per your needs. Each dome is made up of cards. By adding your custom card to your dome, you can extend it's functionality.
|
|
12
16
|
|
|
13
17
|
Use this SDK to create your custom card that can do whatever you like: a simple todo list, snake & ladder game, to a complex project management tool, a 3D AR visualization, to anything else you can imagine! Anything you can build in React or Angular can be created into a card!
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
### **Document viewers**
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
Add view / edit capability for any document in Dome. For example, you can come up with your own spreadsheet and make it instantly available to all users of Dome. Alternatively, you can create your own viewer that views & (optionally) edits existing documents such as Excel files. The options a limitless!
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
> Note: We currently support React and Angular, with support for more frameworks planned in the future.
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
## Getting started
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
1. Register your card or viewer at [https://dome.so/developer](https://dome.so/developer).
|
|
28
|
+
2. Initialize the SDK in your app.
|
|
29
|
+
3. Handle lifecycle events and call SDK APIs.
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
### Cards quick start
|
|
26
32
|
|
|
27
33
|
```JavaScript
|
|
28
|
-
import { CardSdk } from "dome-embedded-app-sdk";
|
|
34
|
+
import { CardSdk, getKeyFromBlob } from "dome-embedded-app-sdk";
|
|
35
|
+
|
|
36
|
+
const my_card_decryption_blob = {...};
|
|
37
|
+
|
|
38
|
+
CardSdk.init(getKeyFromBlob(my_card_decryption_blob), {
|
|
39
|
+
onInit: (data) => {
|
|
40
|
+
console.log("Init payload", data);
|
|
41
|
+
},
|
|
42
|
+
onError: ({ error_code, message }) => {
|
|
43
|
+
console.error("Some Error", `${message} (${error_code})`);
|
|
44
|
+
}
|
|
45
|
+
}).then((sdk) => console.log("SDK Instance", sdk));
|
|
29
46
|
```
|
|
30
47
|
|
|
31
|
-
|
|
48
|
+
### Document viewer quick start
|
|
32
49
|
|
|
33
50
|
```JavaScript
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
51
|
+
import { ViewerSdk } from "dome-embedded-app-sdk";
|
|
52
|
+
|
|
53
|
+
ViewerSdk.init({
|
|
54
|
+
onInitialData: ({ doc, ui }) => {
|
|
55
|
+
console.log("Initial doc", doc, ui);
|
|
56
|
+
},
|
|
57
|
+
onDataChange: ({ doc }) => {
|
|
58
|
+
console.log("Doc updated", doc);
|
|
59
|
+
},
|
|
60
|
+
onCloseRequest: () => {
|
|
61
|
+
console.log("Close requested");
|
|
62
|
+
},
|
|
63
|
+
onSaveRequest: () => {
|
|
64
|
+
console.log("Save requested");
|
|
65
|
+
}
|
|
66
|
+
});
|
|
46
67
|
```
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
### Deploy
|
|
69
|
+
## Guides
|
|
51
70
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
## 2. Document Viewer
|
|
55
|
-
|
|
56
|
-
Add view / edit capability for any document in Dome. For example, you can come up with your own spreadsheet and make it instantly available to all users of Dome. Alternatively, you can create your own viewer that views & (optionally) edits existing documents such as Excel files. The options a limitless!
|
|
71
|
+
- Card SDK guide: `docs/card-sdk.md`
|
|
72
|
+
- Viewer SDK guide: `docs/viewer-sdk.md`
|
|
57
73
|
|
|
58
|
-
|
|
74
|
+
## Starter projects
|
|
59
75
|
|
|
60
|
-
|
|
76
|
+
- React card starter: <https://github.com/InTouchSO/card-react_starter>
|
|
77
|
+
- Angular card starter: <https://github.com/InTouchSO/card-angular_starter>
|
|
61
78
|
|
|
62
79
|
## Help
|
|
63
80
|
|
|
64
|
-
Join our developer community on Dome here: <url>. Hang out, get latest updates, ask questions,
|
|
81
|
+
Join our developer community on Dome here: <url>. Hang out, get latest updates, ask questions, and get support.
|
package/dist/card-sdk.d.ts
CHANGED
|
@@ -1,91 +1,9 @@
|
|
|
1
1
|
import { DomeEmbeddedAppSdk, CardClientMessageType } from "./dome-sdk";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
description?: string | null;
|
|
7
|
-
abbr?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface CardKeyBlobV1 {
|
|
10
|
-
v: number;
|
|
11
|
-
seed: number;
|
|
12
|
-
obf: number[];
|
|
13
|
-
}
|
|
14
|
-
export type CardKeyBlob = CardKeyBlobV1;
|
|
2
|
+
import { CardPermission } from "./types/card-sdk.types";
|
|
3
|
+
import type { CardEventHandler, CardFsCallback, CardFsListHandler, CardFsReadHandler, CardFsWriteUpdatePayload, CardKeyBlob, CardPermissionsMap, CardUser, CardUserRole } from "./types/card-sdk.types";
|
|
4
|
+
export { CardFsErrorCode, CardPermission, cardPermission } from "./types/card-sdk.types";
|
|
5
|
+
export type { CardEventHandler, CardFileChangePayload, CardFsCallback, CardFsErrorPayload, CardFsListHandler, CardFsListResult, CardFsReadHandler, CardFsReadResult, CardFsReadUpdatePayload, CardFsWriteUpdatePayload, CardInitData, CardInitErrorPayload, CardKeyBlob, CardKeyBlobV1, CardPermissionsMap, CardRefreshRequestPayload, CardUiProps, CardUser, CardUserCover, CardUserCoverPhoto, CardUserName, CardUserOrganization, CardUserPhoto, CardUserRole, } from "./types/card-sdk.types";
|
|
15
6
|
export declare function getKeyFromBlob(blob: CardKeyBlob): string;
|
|
16
|
-
export declare enum CardPermission {
|
|
17
|
-
READ = "r",
|
|
18
|
-
WRITE = "w",
|
|
19
|
-
FORWARD = "f",
|
|
20
|
-
SHARE = "s",
|
|
21
|
-
DOWNLOAD = "d"
|
|
22
|
-
}
|
|
23
|
-
export declare const cardPermission: typeof CardPermission;
|
|
24
|
-
export interface CardEventHandler {
|
|
25
|
-
onInit: (data: unknown) => void;
|
|
26
|
-
onInitError?: (data: unknown) => void;
|
|
27
|
-
onError?: (data: {
|
|
28
|
-
error_code: string | number;
|
|
29
|
-
message: string;
|
|
30
|
-
data: any;
|
|
31
|
-
}) => void;
|
|
32
|
-
onFileChange?: (data: unknown) => void;
|
|
33
|
-
onRefreshRequest?: (data: unknown) => void;
|
|
34
|
-
}
|
|
35
|
-
export type CardFsCallback<T = any> = (payload: T) => void;
|
|
36
|
-
export declare enum CardFsErrorCode {
|
|
37
|
-
NO_INTERNET = "NO_INTERNET",
|
|
38
|
-
NO_PERMISSION = "NO_PERMISSION",
|
|
39
|
-
NOT_FOUND = "NOT_FOUND",
|
|
40
|
-
SERVER_ERROR = "SERVER_ERROR",
|
|
41
|
-
TIMEOUT = "TIMEOUT",
|
|
42
|
-
INVALID_REQUEST = "INVALID_REQUEST",
|
|
43
|
-
UNKNOWN = "UNKNOWN"
|
|
44
|
-
}
|
|
45
|
-
export interface CardFsErrorPayload {
|
|
46
|
-
message: string;
|
|
47
|
-
code?: CardFsErrorCode;
|
|
48
|
-
}
|
|
49
|
-
export interface CardFsReadResult {
|
|
50
|
-
name?: string;
|
|
51
|
-
iuid?: string | null;
|
|
52
|
-
object?: any;
|
|
53
|
-
data?: any;
|
|
54
|
-
is_dirty?: boolean;
|
|
55
|
-
is_stale: boolean;
|
|
56
|
-
is_complete: boolean;
|
|
57
|
-
}
|
|
58
|
-
export interface CardFsWriteUpdatePayload {
|
|
59
|
-
status: "uploading" | "completed" | "unknown";
|
|
60
|
-
progress?: number;
|
|
61
|
-
uploaded_bytes?: number;
|
|
62
|
-
[key: string]: any;
|
|
63
|
-
}
|
|
64
|
-
export interface CardFsReadUpdatePayload {
|
|
65
|
-
status: "downloading" | "completed" | "unknown";
|
|
66
|
-
progress?: number;
|
|
67
|
-
downloaded_bytes?: number;
|
|
68
|
-
[key: string]: any;
|
|
69
|
-
}
|
|
70
|
-
export interface CardFsReadHandler {
|
|
71
|
-
next: CardFsCallback<CardFsReadResult>;
|
|
72
|
-
error?: CardFsCallback<CardFsErrorPayload>;
|
|
73
|
-
}
|
|
74
|
-
export interface CardFsListHandler {
|
|
75
|
-
next: CardFsCallback<CardFsListResult>;
|
|
76
|
-
error?: CardFsCallback<CardFsErrorPayload>;
|
|
77
|
-
}
|
|
78
|
-
export interface CardFsListResult {
|
|
79
|
-
documents: any[];
|
|
80
|
-
is_stale: boolean;
|
|
81
|
-
is_complete: boolean;
|
|
82
|
-
is_dirty: boolean;
|
|
83
|
-
folder_name?: string;
|
|
84
|
-
folder_iuid?: string;
|
|
85
|
-
last_index?: number | null;
|
|
86
|
-
last_page?: number | boolean | null;
|
|
87
|
-
[key: string]: any;
|
|
88
|
-
}
|
|
89
7
|
/**
|
|
90
8
|
* Use CardSdk to create webapp cards
|
|
91
9
|
*/
|
|
@@ -210,7 +128,6 @@ export declare class CardSdk extends DomeEmbeddedAppSdk {
|
|
|
210
128
|
private clearFsWriteRequest;
|
|
211
129
|
private failFsWriteRequest;
|
|
212
130
|
private handleFsWriteSuccess;
|
|
213
|
-
private handleFsWriteError;
|
|
214
131
|
private createCardFsError;
|
|
215
132
|
private toCardFsErrorPayload;
|
|
216
133
|
private cardFSReadFallback;
|
|
@@ -234,6 +151,6 @@ export declare class CardSdk extends DomeEmbeddedAppSdk {
|
|
|
234
151
|
iuid: string;
|
|
235
152
|
ts_m: number;
|
|
236
153
|
}): void;
|
|
237
|
-
getUsername(userObj:
|
|
154
|
+
getUsername(userObj: CardUser | null | undefined): string;
|
|
155
|
+
private attachUserFullName;
|
|
238
156
|
}
|
|
239
|
-
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export type { HostInfo, HostCapabilities, HostDetails } from "./dome-sdk";
|
|
|
3
3
|
export { ViewerSdk } from "./viewer-sdk";
|
|
4
4
|
export type { ViewerEventHandler, Document, UiProps } from "./viewer-sdk";
|
|
5
5
|
export { CardSdk, CardPermission, cardPermission, getKeyFromBlob, CardFsErrorCode } from "./card-sdk";
|
|
6
|
-
export type { CardEventHandler, CardFsErrorPayload, CardFsCallback, CardFsReadResult, CardFsReadHandler, CardKeyBlob, CardKeyBlobV1, } from "./card-sdk";
|
|
6
|
+
export type { CardEventHandler, CardFileChangePayload, CardFsErrorPayload, CardFsCallback, CardFsReadResult, CardFsReadHandler, CardInitData, CardInitErrorPayload, CardPermissionsMap, CardRefreshRequestPayload, CardUiProps, CardUser, CardUserCover, CardUserCoverPhoto, CardUserName, CardUserOrganization, CardUserPhoto, CardUserRole, CardKeyBlob, CardKeyBlobV1, } from "./card-sdk";
|
|
7
7
|
export { CryptoA01 } from "./crypto";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.domeSdk=t():e.domeSdk=t()}(this,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{CardClientMessageType:()=>d,CardFsErrorCode:()=>E,CardMessageType:()=>c,CardPermission:()=>p,CardSdk:()=>m,CommonClientMessageType:()=>n,CryptoA01:()=>h,DomeEmbeddedAppSdk:()=>l,ViewerClientMessageType:()=>o,ViewerMessageType:()=>a,ViewerSdk:()=>u,cardPermission:()=>_,getKeyFromBlob:()=>f});const r="0.3.2",s=new Set(["dome","intouchapp"]);var a,i,n,o,d,c;!function(e){e.CONNECTION_SUCCESS="CONNECTION_SUCCESS",e.INIT="INIT",e.REQUEST_SAVE="REQUEST_SAVE",e.REQUEST_CLOSE="REQUEST_CLOSE",e.REQUEST_INITIAL_DATA="REQUEST_INITIAL_DATA",e.SET_DIRTY="SET_DIRTY",e.SEND_CLOSE="SEND_CLOSE",e.SEND_EXCEPTION="SEND_EXCEPTION"}(a||(a={})),function(e){e.INIT_MESSAGE_CHANNEL="INIT_MESSAGE_CHANNEL"}(i||(i={})),function(e){e.CONNECT="CONNECT"}(n||(n={})),function(e){e.REQUEST_CLOSE="REQUEST_CLOSE",e.REQUEST_SAVE="REQUEST_SAVE",e.DATA_CHANGE="DATA_CHANGE",e.SAVE_ERROR="SAVE_ERROR",e.SAVE_SUCCESS="SAVE_SUCCESS",e.INIT_ACK="INIT_ACK"}(o||(o={})),function(e){e.DATA_CHANGE="DATA_CHANGE",e.CFS_ERROR="CFS_ERROR",e.CFS_WRITE_SUCCESS="CFS_WRITE_SUCCESS",e.CFS_FILE_DATA="CFS_FILE_DATA",e.CFS_WRITE_FILE_ACK="CFS_WRITE_FILE_ACK",e.CFS_READ_FILE_ACK="CFS_READ_FILE_ACK",e.CFS_DELETE_FILE_ACK="CFS_DELETE_FILE_ACK",e.CFS_LIST_FILES_ACK="CFS_LIST_FILES_ACK",e.INIT_ACK="INIT_ACK",e.INIT_ERROR="INIT_ERROR",e.AF1_DATA_TOKEN_ACK="AF1_DATA_TOKEN_ACK",e.ERROR="ERROR",e.REFRESH="REFRESH",e.LOGGING_ENABLE="LOGGING_ENABLE",e.LOGGING_DISABLE="LOGGING_DISABLE",e.LOGGING_CLEAR="LOGGING_CLEAR",e.LOGGING_GET="LOGGING_GET"}(d||(d={})),function(e){e.APP_READY="APP_READY",e.INIT="INIT",e.CFS_READ_FILE="CFS_READ_FILE",e.CFS_WRITE_FILE="CFS_WRITE_FILE",e.CFS_DELETE_FILE="CFS_DELETE_FILE",e.CFS_LIST_FILES="CFS_LIST_FILES",e.FILE_DIRTY="FILE_DIRTY",e.OPEN_DEEPLINK="OPEN_DEEPLINK",e.AF1_DATA_TOKEN="AF1_DATA_TOKEN",e.LOGGING_GET_RET="LOGGING_GET_RET"}(c||(c={}));class l{constructor(){this.targetOrigin="*",this.isAppReady=!1,this.port2=null,this.runtimeHost="unknown",this.parentHostDetails=null,this.parentCapabilities=null,this.handleDeepLinkClick=e=>{if("webapp"!==this.runtimeHost)return;if(!(e.target instanceof Element))return;const t=e.target.closest("a[href]");if(!t)return;const r=t.getAttribute("href")??"";this.emitDeepLink(r)&&e.preventDefault()},console.info(`Initializing Dome Embedded App SDK v${r}`),this.detectHost(),this.setupDeepLinkInterception()}detectHost(){void 0!==window.AndroidBridge?this.runtimeHost="android":void 0!==window.webkit?this.runtimeHost="ios":this.runtimeHost="webapp",this.runtimeHost}setupDeepLinkInterception(){"webapp"===this.runtimeHost&&"undefined"!=typeof document&&document.addEventListener("click",this.handleDeepLinkClick,!0)}emitDeepLink(e){if("string"!=typeof e||""===e.trim())return console.warn("emitDeepLink called without a valid href"),!1;const t=e.split(":")[0]?.toLowerCase();return!(!t||!s.has(t))&&(this.sendMessage(c.OPEN_DEEPLINK,{url:e}),!0)}updateParentContext(e,t){if(!e&&!t)return;const r={...this.parentHostDetails??{type:this.runtimeHost},...e??{}};r.type||(r.type=this.runtimeHost);const s=t??this.parentCapabilities??r.capabilities;t&&(this.parentCapabilities=t),s?r.capabilities=s:delete r.capabilities,this.parentHostDetails=r,this.parentCapabilities=s??null,s?console.info("Host capabilities detected",{host_type:r.type,capabilities:s}):console.info("Host capabilities not found",{hostType:r.type})}getHost(){return this.parentHostDetails??{type:this.runtimeHost}}sendMessage(e,t){const r={type:e,data:t??null};switch(this.runtimeHost){case"android":window.AndroidBridge?.sendMessage(JSON.stringify(r));break;case"ios":window?.webkit?.messageHandlers?window.webkit?.messageHandlers.appHandler.postMessage(JSON.stringify(r)):console.error("webkit.messageHandlers not found");break;case"webapp":this.port2?this.port2.postMessage(r):console.error("Web connection is not established.");break;default:console.error("Unsupported host, cannot send message.")}this.runtimeHost}sendAppInit(){this.isAppReady||(this.isAppReady=!0,this.sendMessage(a.INIT,{sdk:{ver:r}}))}safeInvoke(e,t,r){const s=t?.[e];"function"==typeof s?s(r):console.warn(`Handler for '${String(e)}' is not defined.`)}setupParentConnection(){return new Promise(((e,t)=>{switch(this.runtimeHost){case"android":window.receiveFromAndroid=e=>{this.handleMessage(e.type,e.data)},e();break;case"ios":window.receiveFromIOS=e=>{this.handleMessage(e.type,e.data)},e();break;case"webapp":if(this.port2)return console.warn("Connection already established. Skipping reinitialization."),void e();const s=t=>{const{type:r}=t.data||{};r===n.CONNECT&&t.ports&&t.ports.length>0&&(this.port2=t.ports[0],this.port2.onmessage=e=>this.handlePortMessage(e),window.removeEventListener("message",s),this.notifyConnectionSuccess(),e())};window.addEventListener("message",s),window.parent?window.parent.postMessage({type:i.INIT_MESSAGE_CHANNEL,data:{sdk:{ver:r}}},this.targetOrigin):console.error("Parent window not available to initialize message channel.");break;default:console.error("Unknown host."),t("Unknown host")}}))}notifyConnectionSuccess(){this.sendMessage(a.CONNECTION_SUCCESS)}handlePortMessage(e){const{type:t,data:r}=e.data||{};t&&this.handleMessage(t,r)}handleMessage(e,t){throw new Error("Subclasses must implement handleMessage.")}}class u extends l{constructor(){super(),this.handler=null,this.pendingRequests=new Map,this.pendingInitAck=null}static init(e){return u.initialized?(console.warn("ViewerSdk is already initialized. Skipping initialization."),u.instance):(u.instance||(u.instance=new u,u.instance.setupParentConnection().then((()=>{try{u.instance.initializeViewerSdk()}catch(e){console.error("Error in initializeViewerSdk:",e)}})).catch((e=>{console.error("init: Error setting up parent connection!",e),console.trace("called from:")}))),e&&u.instance.setHandler(e),u.initialized=!0,u.instance)}setHandler(e){this.handler=e,this.pendingInitAck&&(this.safeInvoke("onInitialData",this.handler,this.pendingInitAck),this.pendingInitAck=null)}canRead(e){return!!e?.includes("r")}canWrite(e){return!!e?.includes("w")||!!e?.includes("*")}initializeViewerSdk(){this.sendAppInit()}requestInitialData(){this.sendMessage(a.REQUEST_INITIAL_DATA)}requestSave(e,t){const r=function(){if("undefined"!=typeof window&&window.crypto&&window.crypto.randomUUID)return window.crypto.randomUUID();if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();throw new Error("UUID generation is not supported in this environment")}();return this.sendMessage(a.REQUEST_SAVE,{doc:e,isDataDirty:t,requestId:r}),new Promise(((e,t)=>{this.pendingRequests.set(r,e),this.pendingRequests.set(r+"_reject",t),setTimeout((()=>{this.pendingRequests.has(r)&&(this.pendingRequests.delete(r),this.pendingRequests.delete(r+"_reject"))}),3e4)}))}handleOnSave(e){const{requestId:t,status:r,message:s}=e,a=this.pendingRequests.get(t),i=this.pendingRequests.get(t+"_reject");a&&("error"===r?i?.({status:r,message:s}):a({status:r,message:s}),this.pendingRequests.delete(t),this.pendingRequests.delete(t+"_reject"))}setDirty(e){this.sendMessage(a.SET_DIRTY,e)}sendClose(e,t){this.sendMessage(a.SEND_CLOSE,{doc:e,isDataDirty:t})}sendException(e){this.sendMessage(a.SEND_EXCEPTION,e)}handleMessage(e,t){if(e===o.INIT_ACK&&this.updateParentContext(t?.host,t?.capabilities),this.handler)switch(e){case o.INIT_ACK:this.safeInvoke("onInitialData",this.handler,t);break;case o.DATA_CHANGE:this.safeInvoke("onDataChange",this.handler,t);break;case o.REQUEST_CLOSE:this.safeInvoke("onCloseRequest",this.handler);break;case o.REQUEST_SAVE:this.safeInvoke("onSaveRequest",this.handler);break;case o.SAVE_SUCCESS:case o.SAVE_ERROR:this.handleOnSave(t);break;default:console.warn(`No handler found for message type: ${e}`)}else e===o.INIT_ACK?(console.warn("Handler not set. Storing INIT_ACK message for later processing."),this.pendingInitAck=t):console.error("Message handler not found for type:",e)}}u.initialized=!1;class h{constructor(){if(this.subtleCrypto=window.crypto?.subtle,!this.subtleCrypto)throw new Error("SubtleCrypto API is not available in this environment.")}async decrypt(e,t,r){try{if(!e)throw new Error("Invalid token");const s=this.base64UrlDecode(e);if(128!==s[0])throw new Error("Invalid version");s.slice(1,9);const a=s.slice(9,25),i=s.slice(25,-32),n=s.slice(-32),o=await this.deriveKey(t,r),{hmacKey:d,aesKey:c}=await this.splitKey(o),l=s.slice(0,-32);if(!new Uint8Array(await this.subtleCrypto.sign("HMAC",d,l)).every(((e,t)=>e===n[t])))throw new Error("Invalid HMAC. Token has been tampered with!");const u=await this.subtleCrypto.decrypt({name:"AES-CBC",iv:a},c,i);return(new TextDecoder).decode(u)}catch(e){throw console.log("Error in decrypt:",e),e}}async deriveKey(e,t,r=1e4){const s=new TextEncoder,a=await this.subtleCrypto.importKey("raw",s.encode(e),"PBKDF2",!1,["deriveKey"]);return this.subtleCrypto.deriveKey({name:"PBKDF2",hash:"SHA-256",salt:s.encode(t),iterations:r},a,{name:"AES-CBC",length:256},!0,["encrypt","decrypt"])}async splitKey(e){const t=new Uint8Array(await this.subtleCrypto.exportKey("raw",e));return{hmacKey:await this.subtleCrypto.importKey("raw",t.slice(0,16),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"]),aesKey:await this.subtleCrypto.importKey("raw",t.slice(16),{name:"AES-CBC"},!1,["encrypt","decrypt"])}}base64UrlDecode(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),r=atob(t);return new Uint8Array([...r].map((e=>e.charCodeAt(0))))}}function f(e){let t;if(1!==e.v)throw new Error(`Unsupported key blob version: ${e.v}`);return t=function(e){const{seed:t,obf:r}=e,s=new Uint8Array(r.length);for(let e=0;e<r.length;e++)s[e]=r[e]^t+17*e&255;return s}(e),function(e){if("undefined"!=typeof TextDecoder)return(new TextDecoder).decode(e);let t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return t}(t)}var p;!function(e){e.READ="r",e.WRITE="w",e.FORWARD="f",e.SHARE="s",e.DOWNLOAD="d"}(p||(p={}));const _=p;var E;!function(e){e.NO_INTERNET="NO_INTERNET",e.NO_PERMISSION="NO_PERMISSION",e.NOT_FOUND="NOT_FOUND",e.SERVER_ERROR="SERVER_ERROR",e.TIMEOUT="TIMEOUT",e.INVALID_REQUEST="INVALID_REQUEST",e.UNKNOWN="UNKNOWN"}(E||(E={}));class S{constructor(e,t){this.cardIuid=e,this.containerIuid=t,this.openPromise=null}isSupported(){return"undefined"!=typeof indexedDB}async openDb(){return this.isSupported()?(this.openPromise||(this.openPromise=new Promise((e=>{this.openWithVersion(S.DB_VERSION,e)}))),this.openPromise):null}openWithVersion(e,t){let r="ensure";const s=indexedDB.open(this.cardIuid,e);s.onupgradeneeded=e=>{r=0===(e.oldVersion||0)?"create":"ensure",this.configureStores(s.result)},s.onsuccess=()=>{const e=s.result;if(!this.hasRequiredStores(e)){const r=e.version+1;return e.close(),void this.openWithVersion(r,t)}this.updateStoresMetadata(e,"ensure"===r).catch((()=>{})).finally((()=>t(e)))},s.onerror=()=>t(null)}configureStores(e){e.objectStoreNames.contains(S.DATA_STORE)||e.createObjectStore(S.DATA_STORE),e.objectStoreNames.contains(S.NAME_LOOKUP_STORE)||e.createObjectStore(S.NAME_LOOKUP_STORE),e.objectStoreNames.contains(S.INFO_STORE)||e.createObjectStore(S.INFO_STORE),e.objectStoreNames.contains(S.FOLDER_LISTING_STORE)||e.createObjectStore(S.FOLDER_LISTING_STORE)}hasRequiredStores(e){const t=e.objectStoreNames;return t.contains(S.DATA_STORE)&&t.contains(S.NAME_LOOKUP_STORE)&&t.contains(S.INFO_STORE)&&t.contains(S.FOLDER_LISTING_STORE)}static nowMicros(){return Math.trunc(1e3*Date.now())}updateStoresMetadata(e,t){return Promise.all([this.ensureStoreVersion(e,S.DATA_STORE),this.ensureStoreVersion(e,S.NAME_LOOKUP_STORE),this.ensureStoreVersion(e,S.FOLDER_LISTING_STORE),this.updateCardInfo(e,t)]).then((()=>{}))}ensureStoreVersion(e,t){return e.objectStoreNames.contains(t)?new Promise((r=>{try{const s=e.transaction(t,"readwrite"),a=s.objectStore(t),i=()=>r();s.oncomplete=i,s.onerror=i,s.onabort=i,a.put("1.0.0",S.STORE_VERSION_KEY)}catch{r()}})):Promise.resolve()}async updateCardInfo(e,t){if(!e.objectStoreNames.contains(S.INFO_STORE))return;const r=await this.readInfoValue(e,"container_iuid"),s=t?await this.readInfoValue(e,"ts_c"):void 0,a=this.containerIuid??r??null,i=t&&s?s:S.nowMicros();await Promise.all([this.writeInfoValue(e,"container_iuid",a),this.writeInfoValue(e,"ts_c",i)]).catch((()=>{}))}readInfoValue(e,t){return new Promise((r=>{try{const s=e.transaction(S.INFO_STORE,"readonly"),a=s.objectStore(S.INFO_STORE).get(t);a.onsuccess=()=>r(a.result),a.onerror=()=>r(void 0)}catch{r(void 0)}}))}writeInfoValue(e,t,r){return new Promise((s=>{try{const a=e.transaction(S.INFO_STORE,"readwrite"),i=a.objectStore(S.INFO_STORE),n=()=>s();a.oncomplete=n,a.onerror=n,a.onabort=n,i.put(r,t)}catch{s()}}))}keyFor(e){return e}static normalizeFolderName(e){if("string"!=typeof e)return"/";let t=e.trim();return t?(t=t.replace(/^\/+/,""),t?(t.endsWith("/")||(t+="/"),t):"/"):"/"}folderListingKey(e){return S.normalizeFolderName(e)}static normalizeName(e){if("string"!=typeof e)return null;const t=e.trim();return t||null}async put(e,t){const r=await this.openDb();r&&await new Promise((s=>{const a=r.transaction(S.DATA_STORE,"readwrite");a.objectStore(S.DATA_STORE).put(t,e).onsuccess=()=>s(),a.oncomplete=()=>s(),a.onerror=()=>s(),a.onabort=()=>s()}))}async get(e){const t=await this.openDb();if(t)return new Promise((r=>{const s=t.transaction(S.DATA_STORE,"readonly").objectStore(S.DATA_STORE).get(e);s.onsuccess=()=>r(s.result),s.onerror=()=>r(void 0)}))}async delete(e){const t=await this.openDb();t&&await new Promise((r=>{const s=t.transaction(S.DATA_STORE,"readwrite");s.objectStore(S.DATA_STORE).delete(e).onsuccess=()=>r(),s.oncomplete=()=>r(),s.onerror=()=>r(),s.onabort=()=>r()}))}static async hashName(e){const t="undefined"!=typeof globalThis?globalThis.crypto:void 0;if(!t?.subtle?.digest)throw new Error("CardFS name hashing requires SubtleCrypto support");const r=S.encodeText(e),s=await t.subtle.digest("SHA-256",r);return S.bufferToBase64(s)}static encodeText(e){if("undefined"!=typeof TextEncoder)return(new TextEncoder).encode(e).buffer;const t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t.buffer}static bufferToBase64(e){let t="";const r=new Uint8Array(e);for(let e=0;e<r.length;e++)t+=String.fromCharCode(r[e]);return btoa(t)}async getIuidForName(e){const t=S.normalizeName(e);if(!t)return;const r=await this.openDb();if(!r)return;const s=await S.hashName(t);return new Promise((e=>{const t=r.transaction(S.NAME_LOOKUP_STORE,"readonly").objectStore(S.NAME_LOOKUP_STORE).get(s);t.onsuccess=()=>e(t.result),t.onerror=()=>e(void 0)}))}async upsertNameLookup(e,t){const r=S.normalizeName(e);if(!r)return;const s=await this.openDb();if(!s)return;const a=await S.hashName(r);await new Promise((e=>{const r=s.transaction(S.NAME_LOOKUP_STORE,"readwrite"),i=r.objectStore(S.NAME_LOOKUP_STORE);i.put(t,a);i.openCursor().onsuccess=e=>{const r=e.target.result;r&&(r.key!==a&&r.value===t&&r.delete(),r.continue())},r.oncomplete=()=>e(),r.onerror=()=>e(),r.onabort=()=>e()}))}async deleteNameLookupByName(e){const t=S.normalizeName(e);if(!t)return;const r=await this.openDb();if(!r)return;const s=await S.hashName(t);await new Promise((e=>{const t=r.transaction(S.NAME_LOOKUP_STORE,"readwrite");t.objectStore(S.NAME_LOOKUP_STORE).delete(s),t.oncomplete=()=>e(),t.onerror=()=>e(),t.onabort=()=>e()}))}async deleteNameLookupByIuid(e){if(!e)return;const t=await this.openDb();t&&await new Promise((r=>{const s=t.transaction(S.NAME_LOOKUP_STORE,"readwrite");s.objectStore(S.NAME_LOOKUP_STORE).openCursor().onsuccess=t=>{const r=t.target.result;r&&(r.value===e&&r.delete(),r.continue())},s.oncomplete=()=>r(),s.onerror=()=>r(),s.onabort=()=>r()}))}static estimateSize(e){if(null==e)return 0;if("undefined"!=typeof Blob&&e instanceof Blob)return e.size;if(e instanceof ArrayBuffer)return e.byteLength;if(ArrayBuffer.isView(e))return e.byteLength;if("string"==typeof e)return new Blob([e]).size;try{return new Blob([JSON.stringify(e)]).size}catch{return 0}}async cacheDocument(e,t){if(!e?.iuid)return;await this.put(this.keyFor(`${e.iuid}_object`),e);const r=S.normalizeName(e.name);if(r&&await this.upsertNameLookup(r,e.iuid),void 0===t)return void await this.delete(this.keyFor(`${e.iuid}_data`));S.estimateSize(t)<=S.MAX_DATA_BYTES?await this.put(this.keyFor(`${e.iuid}_data`),t):await this.delete(this.keyFor(`${e.iuid}_data`))}async getByName(e){const t=S.normalizeName(e);if(!t)return null;const r=await this.getIuidForName(t);if(!r)return null;const s=await this.get(this.keyFor(`${r}_object`));if(!s)return null;return{iuid:r,object:s,data:await this.get(this.keyFor(`${r}_data`))}}async getByIuid(e){if(!e)return null;const t=await this.get(this.keyFor(`${e}_object`));if(!t)return null;return{iuid:e,object:t,data:await this.get(this.keyFor(`${e}_data`))}}async deleteByName(e){const t=await this.getByName(e);await this.deleteNameLookupByName(e),t&&(await this.delete(this.keyFor(`${t.iuid}_object`)),await this.delete(this.keyFor(`${t.iuid}_data`)))}async deleteByIuid(e,t){t&&await this.deleteNameLookupByName(t),await this.deleteNameLookupByIuid(e),await this.delete(this.keyFor(`${e}_object`)),await this.delete(this.keyFor(`${e}_data`))}async cacheFolderListing(e,t){const r=await this.openDb();if(!r)return;const s=this.folderListingKey(e??t.folder_name),a={folder_name:S.normalizeFolderName(t.folder_name??e),folder_iuid:t.folder_iuid,last_index:t.last_index??null,last_page:t.last_page??null,documents:Array.isArray(t.documents)?t.documents:[]};await new Promise((e=>{const t=r.transaction(S.FOLDER_LISTING_STORE,"readwrite");t.objectStore(S.FOLDER_LISTING_STORE).put(a,s).onsuccess=()=>e(),t.oncomplete=()=>e(),t.onerror=()=>e(),t.onabort=()=>e()}))}async getFolderListing(e){const t=await this.openDb();if(!t)return null;const r=this.folderListingKey(e);return new Promise((e=>{const s=t.transaction(S.FOLDER_LISTING_STORE,"readonly").objectStore(S.FOLDER_LISTING_STORE).get(r);s.onsuccess=()=>e(s.result),s.onerror=()=>e(null)}))}}S.DB_VERSION=3,S.DATA_STORE="cardfs",S.NAME_LOOKUP_STORE="cardfs_name_iuid_lookup",S.INFO_STORE="info",S.FOLDER_LISTING_STORE="cardfs_folder_listings",S.STORE_VERSION_KEY="ver",S.MAX_DATA_BYTES=5242880;class m extends l{buildCardFsMessagePayload(e,t){return{...e.name?{name:e.name}:{},...e.iuid?{iuid:e.iuid}:{},...t??{}}}formatFolderPath(e){if("string"!=typeof e)return;let t=e.trim();return t&&(t=t.replace(/^\/+/,""),t)?(t.endsWith("/")||(t+="/"),t):void 0}assertValidReadHandler(e){if(!e||"function"!=typeof e.next)throw new Error("cardFS.read requires a handler with a next() function");return e}assertValidListHandler(e){if(!e||"function"!=typeof e.next)throw new Error("cardFS.list requires a handler with a next() function");return e}invokeReadHandlerNext(e,t){try{e.next(t)}catch(e){console.error("cardFS.read handler next() threw",e)}}invokeReadHandlerError(e,t){if(e.error)try{e.error(t)}catch(e){console.error("cardFS.read handler error() threw",e)}}sanitizeReadData(e,t){if(null==e)return{value:e,stripped:!1};try{if(S.estimateSize(e)>S.MAX_DATA_BYTES){const e=t?` for ${t}`:"";return console.warn(`cardFS.read payload data exceeded ${S.MAX_DATA_BYTES} bytes${e}; omitting data`),{value:void 0,stripped:!0}}}catch(e){console.warn("cardFS.read payload size estimation failed",e)}return{value:e,stripped:!1}}getCardIuid(){return this.dataStore?.iuid||null}ensureCardFsCache(){if(!this.shouldUseCardFsFallback())return null;if(!this.cardFsCache){const e=this.getCardIuid();e&&(this.cardFsCache=new S(e,this.containerIuid))}return this.cardFsCache}supportsParentCardFs(){return!!this.parentCapabilities?.card_fs}shouldUseCardFsFallback(){return!this.supportsParentCardFs()}constructor(){super(),this.handler=null,this.accessToken="",this.devMode=!1,this.permission=null,this.userRole=null,this.fsReadRequests=new Map,this.fsWriteRequests=new Map,this.cardFsCache=null,this.pendingAcks=new Map,this.consoleCaptureInstalled=!1,this.consoleCaptureEnabled=!1,this.consoleCaptureMinLevel=null,this.consoleLogBuffer=new Array(m.MAX_CONSOLE_LOG_ENTRIES).fill(null),this.consoleLogWriteIndex=0,this.consoleLogSize=0,this.handleMessage=(e,t)=>{if(e===d.INIT_ACK&&this.updateParentContext(t?.host,t?.capabilities),e===d.CFS_ERROR){const e=t?.messageId,r=this.createCardFsError(t,"Unknown cardFS error");if(e&&this.pendingAcks.has(e)){const t=this.pendingAcks.get(e);clearTimeout(t.timeout),this.pendingAcks.delete(e),t.reject(r)}if(e){if(this.fsReadRequests.has(e))return void this.failFsReadRequest(e,r);if(this.fsWriteRequests.has(e))return void this.failFsWriteRequest(e,r)}return void console.warn("CardSdk: CFS_ERROR received but no matching fs request",t?.messageId??t?.name)}this.handleFsAckMessage(e,t);const r=t?.messageId;if(r&&this.pendingAcks.has(r)){const s=this.pendingAcks.get(r);if(s.ackType===e)return clearTimeout(s.timeout),this.pendingAcks.delete(r),void s.resolve(t)}if(r||!this.resolvePendingAckByType(e,t)){if(!this.handler)throw new Error("Message handler not found!");switch(e){case d.INIT_ACK:this.applyLoggingConfig(t?.logging),this.dataStore.kw1=t.key_wa1,this.dataStore.iuid=t.iuid,"boolean"==typeof t?.dev_mode&&(this.devMode=t.dev_mode,this.dataStore.dev_mode=t.dev_mode),t.iuid?this.shouldUseCardFsFallback()?this.cardFsCache=new S(t.iuid,this.containerIuid):this.cardFsCache=null:this.shouldUseCardFsFallback()||(this.cardFsCache=null);try{this.cryptoA01.decrypt(this.dataStore.denc,t.key_wa1+this.dataStore.kw2,t.iuid).then((e=>{const r=JSON.parse(e),s=r?.container?.iuid;s&&(this.containerIuid=s,this.shouldUseCardFsFallback()&&this.dataStore?.iuid&&(this.cardFsCache=new S(this.dataStore.iuid,this.containerIuid)));const a="string"==typeof r?.api_token?r.api_token.trim():"";a?this.accessToken=a:console.warn("CardSdk: INIT_ACK payload missing api_token; fallback APIs may fail without auth"),this.permission=r?.perms_v2??null,this.userRole=r?.role??null,this.handler&&this.safeInvoke("onInit",this.handler,{...r,ui:t.ui}),delete this.dataStore.denc})).catch((e=>{throw console.error("Final decrypt error",e),e}))}catch(e){console.error("Decryption failed!",e),this.sendEventError("dec2_failed",e.message)}break;case d.INIT_ERROR:this.safeInvoke("onInitError",this.handler,t);break;case d.CFS_FILE_DATA:{const e=t?.messageId;if(e&&this.fsReadRequests.has(e)){const{messageId:r,...s}=t||{};return void this.handleFsReadDataMessage(e,s)}console.warn("CardSdk: CFS_FILE_DATA received but no matching fsRead request",t?.messageId??t?.name);break}case d.DATA_CHANGE:this.safeInvoke("onFileChange",this.handler,t);case d.CFS_WRITE_SUCCESS:{const e=t?.messageId;if(e&&this.fsWriteRequests.has(e))return void this.handleFsWriteSuccess(e,t);console.warn("CardSdk: CFS_WRITE_SUCCESS received but no matching fsWrite request",t?.messageId??t?.name);break}case d.ERROR:this.safeInvoke("onError",this.handler,t);break;case d.REFRESH:this.safeInvoke("onRefreshRequest",this.handler,t);break;case d.AF1_DATA_TOKEN_ACK:break;case d.LOGGING_ENABLE:this.applyLoggingConfig({status:"enabled",level:t?.level??t?.logging?.level});break;case d.LOGGING_DISABLE:this.consoleCaptureEnabled=!1;break;case d.LOGGING_CLEAR:this.clearConsoleLogs();break;case d.LOGGING_GET:this.sendConsoleLogs();break;case d.CFS_READ_FILE_ACK:case d.CFS_WRITE_FILE_ACK:case d.CFS_DELETE_FILE_ACK:case d.CFS_LIST_FILES_ACK:break;default:console.warn(`No handler found for message type: ${e}`)}}},this.cryptoA01=new h,this.cardFS={read:(e,t,r=!0)=>{this.cardFSRead(e,t,r)},readById:(e,t,r=!0)=>{this.cardFSReadById(e,t,r)},write:(e,t,r)=>this.cardFSWrite(e,t,r),writeById:(e,t,r)=>this.cardFSWriteById(e,t,r),delete:(e,t)=>this.cardFSDelete(e,t),deleteById:(e,t)=>this.cardFSDeleteById(e,t),list:(e,t)=>this.cardFSList(e,t)}}static async init(e,t,r){try{return m.instance||(m.instance=new m,m.instance.setupParentConnection().then((()=>{m.instance.initializeCardSdk(e)})).catch((e=>{console.error(e)})),t&&m.instance.setHandler(t)),m.instance}catch(e){throw console.error("CardSdk: Unrecoverable error in init",e),e}}setHandler(e){this.handler=e}openDeepLink(e){this.emitDeepLink(e)||console.warn("openDeepLink ignored; provide a dome:// or intouchapp:// href")}hasPerm(e){if(!e)return!1;const t=this.userRole?.abbr;if(!t)return!0;if("o"===t)return!0;const r=this.permission?.[t];return"string"==typeof r?!!r.includes("*")||r.includes(e):m.DEFAULT_ROLE_PERMISSIONS.includes(e)}canRead(){return this.hasPerm(p.READ)}canWrite(){return this.hasPerm(p.WRITE)}deriveSecretSeed(e){const t=e.split("").reverse().join("").substring(4,25);if(!t)throw new Error("Cannot decrypt (1)");return t}getCardIuidEnc(e){try{const t=e.pathname.split("/wa/").filter(Boolean);if(t.length<2)return null;return(t[1]?.split("/")[0]??null)||null}catch(e){return console.warn("CardSdk: Failed to extract seed token",e),null}}async requestAf1DataFromParent(e){const t=await this.sendMessageWithAck(c.AF1_DATA_TOKEN,{sdk:{ver:r}},d.AF1_DATA_TOKEN_ACK),{messageId:s,...a}=t||{},{cie:i,ck:n,dev_token:o}=a;if(!i||!n||!o)throw new Error("Invalid AF1 data token payload");const l=await this.fetchAf1Data(i,n,o,e),u=l?.data_af1??l?.data?.data_af1;if(!u)throw new Error("AF1 data fetch returned empty payload");return window.IT_DATA_AF1=u,l?.ver&&(window.IT_VERSION=l.ver),l?.env&&(window.IT_ENV=l.env),{dataAf1:u,cie:i}}async fetchAf1Data(e,t,r,s){if(!(e&&t&&r&&s))throw new Error("Invalid AF1 data fetch parameters");const a=new URL(`https://dome.so/api/v1/cards/e/${encodeURIComponent(e)}/data_af1/`);a.searchParams.set("dt",r),a.searchParams.set("rt",s),a.searchParams.set("ck",t);const i=await fetch(a.toString(),{method:"GET"});if(!i.ok){const e=await i.text().catch((()=>i.statusText));throw new Error(`AF1 data fetch failed: ${i.status} ${e}`)}return i.json()}async initializeCardSdk(e){let t="CardSdk::initializeCardSdk:";try{if(!e)throw new Error("Invalid secret");const r=window.location.href,s=new URL(r),a=s.searchParams.get("rt");if(!a)throw new Error("Missing request token");let i=this.getCardIuidEnc(s),n=window.IT_DATA_AF1;if(!n){const{dataAf1:e,cie:t}=await this.requestAf1DataFromParent(a);n=e,i=t||i}if(!n)throw console.error(t,"No data"),new Error("No data");if(!i)throw new Error("Cannot decrypt (missing seed)");const o=this.deriveSecretSeed(i),d=await this.cryptoA01.decrypt(n,e,o);try{const e=JSON.parse(d);if(!e.ite)throw new Error("Invalid data");this.dataStore={denc:e.d,kw2:e.kw2},m.instance.sendInit(e.ite)}catch(e){throw console.error("Initial Decryption failed (2):",e),e}}catch(e){console.error(t,"Init failed:",e),this.sendEventError("init_failed",e.message)}}async sendInit(e){const t={token:e,sdk:{ver:r}},s=this.getWebappDetails();s&&(t.wa=s),this.sendMessage(c.INIT,t)}getWebappDetails(){if("undefined"==typeof window)return null;let e={};const t=window.IT_VERSION,r=window.IT_ENV;return t&&(e.ver=String(t)),r&&(e.env=String(r)),Object.keys(e).length?e:null}sendMessageWithAck(e,t,r,s=15e3,a){const i=crypto.randomUUID();if(a)try{a(i)}catch(e){return Promise.reject(e)}return new Promise(((a,n)=>{const o=setTimeout((()=>{this.pendingAcks.delete(i);const e=new Error(`${r} not received in time`);this.isCardFsAckType(r)&&(e.code=E.TIMEOUT),n(e)}),s);this.pendingAcks.set(i,{resolve:a,reject:n,timeout:o,ackType:r}),this.sendMessage(e,{...t,messageId:i})}))}resolvePendingAckByType(e,t){for(const[r,s]of this.pendingAcks.entries())if(s.ackType===e)return clearTimeout(s.timeout),this.pendingAcks.delete(r),s.resolve(t),!0;return!1}cardFSRead(e,t,r=!0){const s={name:e},a=this.assertValidReadHandler(t);this.cardFSReadInternal(s,a,r,"read")}cardFSReadById(e,t,r=!0){const s={iuid:e},a=this.assertValidReadHandler(t);this.cardFSReadInternal(s,a,r,"readById")}cardFSReadInternal(e,t,r,s){if(this.shouldUseCardFsFallback())return void this.cardFSReadFallback(e,void 0,t,r).catch((e=>{const r=e instanceof Error?e:new Error(String(e));this.invokeReadHandlerError(t,this.toCardFsErrorPayload(r))}));let a=null;const i=e.name?`"${e.name}"`:e.iuid?`iuid ${e.iuid}`:"document";this.sendMessageWithAck(c.CFS_READ_FILE,this.buildCardFsMessagePayload(e,{allow_stale:r}),d.CFS_READ_FILE_ACK,m.CARD_FS_ACK_TIMEOUT_MS,(e=>{a=e;const n={name:i,handler:t,allowStale:r,timeoutMessage:`cardFS.${s} timed out for ${i}`};this.fsReadRequests.set(e,n)})).catch((e=>{const r=e instanceof Error?e:new Error(String(e));a?this.failFsReadRequest(a,r):this.invokeReadHandlerError(t,this.toCardFsErrorPayload(r))}))}isCardFsAckType(e){return e===d.CFS_READ_FILE_ACK||e===d.CFS_WRITE_FILE_ACK||e===d.CFS_DELETE_FILE_ACK||e===d.CFS_LIST_FILES_ACK}cardFSWrite(e,t,r){const s={name:e};return this.cardFSWriteInternal(s,t,r,"write")}cardFSWriteById(e,t,r){const s={iuid:e};return this.cardFSWriteInternal(s,t,r,"writeById")}cardFSWriteInternal(e,t,r,s){return this.shouldUseCardFsFallback()?this.cardFSWriteFallback(e,t).catch((e=>{throw this.toCardFsErrorPayload(e)})):new Promise(((a,i)=>{let n=null;const o=e.name?`"${e.name}"`:e.iuid?`iuid ${e.iuid}`:"document";this.sendMessageWithAck(c.CFS_WRITE_FILE,this.buildCardFsMessagePayload(e,{data:t}),d.CFS_WRITE_FILE_ACK,m.CARD_FS_ACK_TIMEOUT_MS,(e=>{n=e;const t={name:o,onUpdate:r,resolve:a,reject:i,timeoutMessage:`cardFS.${s} timed out for ${o}`};this.fsWriteRequests.set(e,t)})).catch((e=>{const t=e instanceof Error?e:new Error(String(e));n?this.failFsWriteRequest(n,t):i(this.toCardFsErrorPayload(t))}))}))}cardFSDelete(e,t){const r={name:e};return this.cardFSDeleteInternal(r,t,"delete")}cardFSDeleteById(e,t){const r={iuid:e};return this.cardFSDeleteInternal(r,t,"deleteById")}cardFSDeleteInternal(e,t,r){return this.shouldUseCardFsFallback()?this.cardFSDeleteFallback(e).then((e=>{try{t?.(e)}catch(e){console.error(`cardFS.${r} fallback callback threw`,e)}return e})).catch((e=>{throw this.toCardFsErrorPayload(e)})):new Promise(((r,s)=>{this.sendMessageWithAck(c.CFS_DELETE_FILE,this.buildCardFsMessagePayload(e),d.CFS_DELETE_FILE_ACK,m.CARD_FS_ACK_TIMEOUT_MS).then((e=>{const{messageId:s,...a}=e||{};t?.(a),r(a)})).catch((e=>{s(this.toCardFsErrorPayload(e))}))}))}cardFSList(e,t){const r=this.assertValidListHandler(t),s=this.formatFolderPath(e);if(this.shouldUseCardFsFallback())return void this.cardFSListFallback(s).then((e=>{r.next(this.normalizeListResult(e))})).catch((e=>{r.error?.(this.toCardFsErrorPayload(e))}));const a=s?{name:s}:{};this.sendMessageWithAck(c.CFS_LIST_FILES,a,d.CFS_LIST_FILES_ACK,m.CARD_FS_ACK_TIMEOUT_MS).then((e=>{const{messageId:t,...s}=e||{};r.next(this.normalizeListResult(s))})).catch((e=>{r.error?.(this.toCardFsErrorPayload(e))}))}resetFsReadProgressTimeout(e){const t=this.fsReadRequests.get(e);t&&(t.progressTimeout&&clearTimeout(t.progressTimeout),t.progressTimeout=setTimeout((()=>{this.failFsReadRequest(e,{code:E.TIMEOUT,message:t.timeoutMessage})}),m.FS_RESPONSE_TIMEOUT_MS))}resetFsWriteProgressTimeout(e){const t=this.fsWriteRequests.get(e);t&&(t.progressTimeout&&clearTimeout(t.progressTimeout),t.progressTimeout=setTimeout((()=>{this.failFsWriteRequest(e,{code:E.TIMEOUT,message:t.timeoutMessage})}),m.FS_RESPONSE_TIMEOUT_MS))}handleFsReadDataMessage(e,t){const r=this.fsReadRequests.get(e);if(!r)return;const s=this.sanitizeReadData(t?.data,r.name),a=Boolean(t?.from_cache??t?.is_stale),i={name:t?.name,iuid:t?.iuid??null,object:t?.object,data:s.value,is_dirty:"boolean"==typeof t?.is_dirty?t.is_dirty:void 0,is_stale:Boolean(t?.is_stale??t?.from_cache),is_complete:"boolean"==typeof t?.is_complete?t.is_complete:!r.allowStale||!a};this.invokeReadHandlerNext(r.handler,i),i.is_complete&&r.progressTimeout&&(clearTimeout(r.progressTimeout),r.progressTimeout=void 0),r.cleanupTimeout&&clearTimeout(r.cleanupTimeout),r.cleanupTimeout=setTimeout((()=>{this.clearFsReadRequest(e)}),m.FS_READ_RETENTION_MS)}handleFsAckMessage(e,t){const r=t?.messageId;if(!r)return!1;if(e===d.CFS_READ_FILE_ACK){const e=this.fsReadRequests.get(r);return!!e&&(this.resetFsReadProgressTimeout(r),e.cleanupTimeout&&clearTimeout(e.cleanupTimeout),e.cleanupTimeout=setTimeout((()=>{this.clearFsReadRequest(r)}),m.FS_READ_RETENTION_MS),!0)}if(e===d.CFS_WRITE_FILE_ACK){const e=this.fsWriteRequests.get(r);if(!e)return!1;const{messageId:s,...a}=t||{};if("function"==typeof e.onUpdate)try{e.onUpdate(a)}catch(e){console.error("cardFS.write onUpdate callback threw",e)}return this.resetFsWriteProgressTimeout(r),!0}return!1}clearFsReadRequest(e){const t=this.fsReadRequests.get(e);if(t)return t.progressTimeout&&clearTimeout(t.progressTimeout),t.cleanupTimeout&&clearTimeout(t.cleanupTimeout),this.fsReadRequests.delete(e),t}sendConsoleLogs(){const e={logs:this.getConsoleLogs().map((e=>({l:e.level,ts:e.timestamp,args:e.args}))),ver:"1.0.0",sdk:{ver:r}};this.sendMessage(c.LOGGING_GET_RET,e)}setupConsoleCapture(){if(this.consoleCaptureInstalled||"undefined"==typeof console)return;["log","info","warn","error","debug"].forEach((e=>{const t=console[e];if("function"!=typeof t)return;const r=t.bind(console);console[e]=(...t)=>{try{this.recordConsoleEntry(e,t)}catch{}r(...t)}})),this.consoleCaptureInstalled=!0}applyLoggingConfig(e){if(!e)return;"enabled"===e.status?(this.consoleCaptureEnabled=!0,this.setupConsoleCapture()):"disabled"===e.status&&(this.consoleCaptureEnabled=!1);const t="string"==typeof e.level?e.level.toLowerCase():null;t&&this.isConsoleLogLevel(t)&&(this.consoleCaptureMinLevel=t)}isConsoleLogLevel(e){return"log"===e||"info"===e||"warn"===e||"error"===e||"debug"===e}shouldCaptureLevel(e){if(!this.consoleCaptureEnabled)return!1;if(!this.consoleCaptureMinLevel)return!0;const t=["debug","log","info","warn","error"];return t.indexOf(e)>=t.indexOf(this.consoleCaptureMinLevel)}recordConsoleEntry(e,t){if(!this.shouldCaptureLevel(e))return;const r={level:e,timestamp:(new Date).toISOString(),args:t.map((e=>this.serializeConsoleArg(e)))};this.consoleLogBuffer[this.consoleLogWriteIndex]=r,this.consoleLogWriteIndex=(this.consoleLogWriteIndex+1)%m.MAX_CONSOLE_LOG_ENTRIES,this.consoleLogSize=Math.min(this.consoleLogSize+1,m.MAX_CONSOLE_LOG_ENTRIES)}clearConsoleLogs(){this.consoleLogBuffer.fill(null),this.consoleLogWriteIndex=0,this.consoleLogSize=0}getConsoleLogs(){if(0===this.consoleLogSize)return[];if(this.consoleLogSize<m.MAX_CONSOLE_LOG_ENTRIES)return this.consoleLogBuffer.slice(0,this.consoleLogSize).filter((e=>null!==e));const e=[];for(let t=0;t<m.MAX_CONSOLE_LOG_ENTRIES;t+=1){const r=(this.consoleLogWriteIndex+t)%m.MAX_CONSOLE_LOG_ENTRIES,s=this.consoleLogBuffer[r];s&&e.push(s)}return e}serializeConsoleArg(e){if(null===e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e)return this.truncateSerializedArg(e);if(void 0===e)return this.truncateSerializedArg({type:"undefined"});if("bigint"==typeof e)return this.truncateSerializedArg({type:"bigint",value:e.toString()});if("symbol"==typeof e)return this.truncateSerializedArg({type:"symbol",value:e.toString()});if("function"==typeof e)return this.truncateSerializedArg({type:"function",name:e.name||null});if(e instanceof Error)return this.truncateSerializedArg({type:"error",name:e.name,message:e.message,stack:e.stack??null});try{return this.truncateSerializedArg(JSON.parse(JSON.stringify(e)))}catch{try{return this.truncateSerializedArg({type:"object",value:String(e)})}catch{return this.truncateSerializedArg({type:"object",value:"[unserializable]"})}}}truncateSerializedArg(e){try{if("string"==typeof e)return e.length>m.MAX_CONSOLE_ARG_CHARS?{type:"truncated",preview:e.slice(0,m.MAX_CONSOLE_ARG_CHARS),original_length:e.length}:e;const t=JSON.stringify(e);if("string"==typeof t&&t.length>m.MAX_CONSOLE_ARG_CHARS)return{type:"truncated",preview:t.slice(0,m.MAX_CONSOLE_ARG_CHARS),original_length:t.length}}catch{}return e}failFsReadRequest(e,t){const r=this.clearFsReadRequest(e);r&&this.invokeReadHandlerError(r.handler,this.toCardFsErrorPayload(t))}clearFsWriteRequest(e){const t=this.fsWriteRequests.get(e);if(t)return t.progressTimeout&&clearTimeout(t.progressTimeout),this.fsWriteRequests.delete(e),t}failFsWriteRequest(e,t){const r=this.clearFsWriteRequest(e);r&&r.reject(this.toCardFsErrorPayload(t))}handleFsWriteSuccess(e,t){const r=this.clearFsWriteRequest(e);if(!r)return;const{messageId:s,...a}=t||{};r.resolve(a)}handleFsWriteError(e,t){const r=this.clearFsWriteRequest(e);if(!r)return;const s=t instanceof Error?t:this.createCardFsError(t,"Unknown write error");r.reject(this.toCardFsErrorPayload(s))}createCardFsError(e,t){const r=new Error(e?.message||t),s=e?.error_code;return s&&Object.values(E).includes(s)&&(r.code=s),r}toCardFsErrorPayload(e,t="Unknown cardFS error"){const r="string"==typeof e?.message?e.message:"string"==typeof e?e:t,s=e?.code??e?.error_code;return s&&Object.values(E).includes(s)?{code:s,message:r}:{message:r}}async cardFSReadFallback(e,t,r,s=!0){if(!this.shouldUseCardFsFallback())throw new Error("cardFS.read fallback is disabled because parent supports card_fs");const a=this.getCardIuid();if(!a)throw new Error("cardFS.read fallback failed: card not initialized");const i=this.ensureCardFsCache();let n=null;const o=e.name?`"${e.name}"`:e.iuid?`iuid ${e.iuid}`:"document",d=(s,a,i,o,d,c)=>{if(!s)return null;const l=d??e.name??s?.name??e.iuid??"document",u=c??s?.iuid??e.iuid??null,{value:h}=this.sanitizeReadData(a,l),f={name:l,iuid:u,object:s,data:h,is_dirty:!i,is_stale:i,is_complete:o};return t&&this.fsReadRequests.has(t)?this.handleFsReadDataMessage(t,f):this.invokeReadHandlerNext(r,f),n||(n=f),f};let c=null;if(i)try{if(s){let t=null;e.iuid&&(t=await i.getByIuid(e.iuid)),!t&&e.name&&(t=await i.getByName(e.name)),t?.object&&(c=d(t.object,t.data,!0,!1,t.object?.name??e.name,t.iuid))}}catch(e){console.warn("cardFS.read cache lookup failed",e)}try{const t=await this.fetchDocumentPayload(a,e);t?(await(i?.cacheDocument(t.object,t.data)),d(t.object,t.data,!1,!0,t.object?.name,t.object?.iuid)):s&&c&&d(c.object,c.data,!0,!0,c.name,c.iuid??void 0)}catch(e){if(!n){throw e instanceof Error?e:new Error(String(e))}console.warn("cardFS.read fresh fetch failed",e),s&&c&&d(c.object,c.data,!0,!0,c.name,c.iuid??void 0)}if(!n)throw new Error(`cardFS.read fallback could not locate ${o}`)}async cardFSWriteFallback(e,t,r){if(!this.shouldUseCardFsFallback())throw new Error("cardFS.write fallback is disabled because parent supports card_fs");const s=this.getCardIuid();if(!s)throw new Error("cardFS.write fallback failed: card not initialized");await this.upsertDocumentViaApi(s,e,t);const a=await this.fetchDocumentPayload(s,e);await(this.ensureCardFsCache()?.cacheDocument(a.object,a.data));const i={name:a.object?.name??e.name??null,iuid:a.object?.iuid??e.iuid??null,object:a.object,data:a.data};return r&&this.fsWriteRequests.has(r)&&this.handleFsWriteSuccess(r,i),i}async cardFSDeleteFallback(e){if(!this.shouldUseCardFsFallback())throw new Error("cardFS.delete fallback is disabled because parent supports card_fs");const t=this.getCardIuid();if(!t)throw new Error("cardFS.delete fallback failed: card not initialized");const r=this.ensureCardFsCache(),s=await this.fetchDocumentMetadataByTarget(t,e).catch((()=>null)),a=s?.iuid??e.iuid??null,i=s?.name??e.name??null;if(!a)return e.name&&await(r?.deleteByName(e.name)),{name:i,iuid:null,deleted:!1};const n=await fetch(`/api/v1/documents/${a}/`,{method:"DELETE",headers:this.authHeader()});if(!n.ok&&404!==n.status){const e=await n.text().catch((()=>"delete failed"));throw new Error(`cardFS.delete fallback failed: ${e}`)}await(r?.deleteByIuid(a,i??void 0));return{name:i??a,iuid:a,deleted:404!==n.status}}async cardFSListFallback(e){if(!this.shouldUseCardFsFallback())throw new Error("cardFS.list fallback is disabled because parent supports card_fs");const t=this.getCardIuid();if(!t)throw new Error("cardFS.list fallback failed: card not initialized");const r=this.ensureCardFsCache(),s=this.formatFolderPath(e),a=s??"/";try{const e=await this.fetchFolderListing(t,s);return r&&(await r.cacheFolderListing(s,{folder_name:e.folder_name??a,folder_iuid:e.folder_iuid,last_index:e.last_index??null,last_page:e.last_page??null,documents:e.documents}),await Promise.all(e.documents.map((e=>r.cacheDocument(e,void 0))))),{documents:e.documents,folder_name:e.folder_name??a,folder_iuid:e.folder_iuid,last_index:e.last_index??null,last_page:e.last_page??null,is_dirty:!0,is_complete:!0}}catch(e){const t=await(r?.getFolderListing(s));if(t)return{documents:t.documents??[],folder_name:t.folder_name??a,folder_iuid:t.folder_iuid??void 0,last_index:t.last_index??null,last_page:t.last_page??null,from_cache:!0,is_dirty:!0,is_complete:!0};throw e}}authHeader(){return this.accessToken?{Authorization:`Bearer ${this.accessToken}`}:{}}async fetchDocumentMetadataByTarget(e,t){return t.iuid?this.fetchDocumentMetadataByIuid(t.iuid):t.name?this.fetchDocumentMetadataByName(e,t.name):null}async fetchDocumentMetadataByIuid(e){const t=await fetch(`/api/v1/documents/${e}/`,{method:"GET",headers:this.authHeader()});if(404===t.status)return null;if(!t.ok){const e=await t.text().catch((()=>"metadata lookup failed"));throw new Error(`cardFS metadata fetch failed: ${e}`)}return t.json().catch((()=>null))}normalizeDocumentsResponse(e){return Array.isArray(e?.results)?e.results:Array.isArray(e)?e:e?[e]:[]}normalizeListResult(e){const t=Array.isArray(e?.documents)?e.documents:[],r=Boolean(e?.from_cache??e?.is_stale),s="boolean"==typeof e?.is_complete?e.is_complete:!r,a="boolean"!=typeof e?.is_dirty||e.is_dirty;return{...e,documents:t,is_stale:r,is_complete:s,is_dirty:a}}async fetchDocumentMetadataByName(e,t){if(!t)return null;const r=await fetch(`/api/v1/documents/with_card/${e}/?name=${encodeURIComponent(t)}`,{method:"GET",headers:this.authHeader()});if(!r.ok){if(404===r.status)return null;const e=await r.text().catch((()=>"metadata lookup failed"));throw new Error(`cardFS metadata fetch failed: ${e}`)}const s=await r.json().catch((()=>null)),a=this.normalizeDocumentsResponse(s);return a.find((e=>e?.name===t))??a[0]??null}async fetchFolderListing(e,t){const r=t?`?name=${encodeURIComponent(t)}`:"",s=await fetch(`/api/v1/documents/with_card/${e}/${r}`,{method:"GET",headers:this.authHeader()});if(!s.ok){const e=await s.text().catch((()=>"list failed"));throw new Error(`cardFS.list failed: ${e}`)}const a=await s.json().catch((()=>null));return{documents:this.normalizeDocumentsResponse(a),folder_name:t,folder_iuid:void 0,last_index:a?.last_index??a?.last_page??null,last_page:a?.last_page??null}}async fetchDocumentPayload(e,t){const r="string"==typeof t?{name:t}:t,s=await this.fetchDocumentMetadataByTarget(e,r);if(!s){const e=r.name?`"${r.name}"`:r.iuid?`iuid ${r.iuid}`:"document";throw new Error(`cardFS document not found: ${e}`)}return{object:s,data:await this.fetchDocumentData(s)}}async fetchDocumentData(e){if(void 0!==e?.data)return e.data;const t=e?.orig?.url||e?.url?.original||e?.url;if(!t||"string"!=typeof t)return null;const r=await fetch(t);if(!r.ok){const e=await r.text().catch((()=>"download failed"));throw new Error(`cardFS data fetch failed: ${e}`)}const s=r.headers.get("Content-Type")||"";return s.includes("application/json")?r.json():s.startsWith("text/")?r.text():r.arrayBuffer()}async buildFileFormData(e,t){let r;const s=e=>{if(e instanceof ArrayBuffer)return new Blob([e.slice(0)],{type:"application/octet-stream"});if("undefined"!=typeof SharedArrayBuffer&&e instanceof SharedArrayBuffer){const t=new Uint8Array(e),r=new Uint8Array(t.length);return r.set(t),new Blob([r.buffer],{type:"application/octet-stream"})}if(ArrayBuffer.isView(e)){const t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),r=new Uint8Array(t.length);return r.set(t),new Blob([r.buffer],{type:"application/octet-stream"})}const t=new Uint8Array(e),r=new Uint8Array(t.length);return r.set(t),new Blob([r.buffer],{type:"application/octet-stream"})};if(t instanceof File)r=t;else if("undefined"!=typeof Blob&&t instanceof Blob)r=new File([t],e,{type:t.type||"application/octet-stream"});else if("undefined"!=typeof SharedArrayBuffer&&t instanceof SharedArrayBuffer){const a=s(t);r=new File([a],e,{type:a.type})}else if(t instanceof ArrayBuffer){const a=s(t);r=new File([a],e,{type:a.type})}else if(ArrayBuffer.isView(t)){const a=s(t);r=new File([a],e,{type:a.type})}else if("string"==typeof t){const s=new Blob([t],{type:"text/plain"});r=new File([s],e,{type:s.type})}else{const s=JSON.stringify(t??{}),a=new Blob([s],{type:"application/json"});r=new File([a],e,{type:a.type})}const a=new FormData;return a.append("file",r),a}async upsertDocumentViaApi(e,t,r){const s=await this.buildFileFormData(t.name??t.iuid??"document",r);if(t.iuid){const e=await fetch(`/api/v1/documents/${t.iuid}/`,{method:"PUT",headers:this.authHeader(),body:s});if(!e.ok){const t=await e.text().catch((()=>"update failed"));throw new Error(`cardFS.write update failed: ${t}`)}return}const a=t.name?await this.fetchDocumentMetadataByName(e,t.name).catch((()=>null)):null;if(a?.iuid){const e=await fetch(`/api/v1/documents/${a.iuid}/`,{method:"PUT",headers:this.authHeader(),body:s});if(!e.ok){const t=await e.text().catch((()=>"update failed"));throw new Error(`cardFS.write update failed: ${t}`)}return}if(s.append("parent_iuid",e),s.append("attached_to_iuid",e),!t.name)throw new Error('cardFS.write failed: "name" missing');s.append("filename",t.name);const i=await fetch("/api/v1/documents/",{method:"POST",headers:this.authHeader(),body:s});if(!i.ok){const e=await i.text().catch((()=>"upload failed"));throw new Error(`cardFS.write upload failed: ${e}`)}}formatErrorMessage(e){if("string"==typeof e&&e.trim())return e;if(e instanceof Error)return e.message||e.toString();if(e&&"object"==typeof e){if("string"==typeof e.message)return e.message;try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}}return null!=e?String(e):"Unknown error"}sendEventError(e,t,r=void 0){const s={message:this.formatErrorMessage(t),error_code:e,data:r??null};this.handler&&this.safeInvoke("onError",this.handler,s)}setFileDirty(e){this.sendMessage(c.FILE_DIRTY,e)}getUsername(e){const t=e?.name;return t&&Object.values(t).some((e=>e))?function(e){const{prefix:t="",given:r="",middle:s="",family:a="",suffix:i=""}=e||{};return[t,r,s,a,i].filter((e=>e)).join(" ").trim()}(t):""}}return m.FS_RESPONSE_TIMEOUT_MS=3e4,m.FS_READ_RETENTION_MS=15e3,m.CARD_FS_ACK_TIMEOUT_MS=15e3,m.MAX_CONSOLE_ARG_CHARS=1e3,m.MAX_CONSOLE_LOG_ENTRIES=100,m.DEFAULT_ROLE_PERMISSIONS="r",t})()));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.domeSdk=t():e.domeSdk=t()}(this,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{CardClientMessageType:()=>d,CardFsErrorCode:()=>E,CardMessageType:()=>c,CardPermission:()=>l,CardSdk:()=>w,CommonClientMessageType:()=>n,CryptoA01:()=>p,DomeEmbeddedAppSdk:()=>u,ViewerClientMessageType:()=>o,ViewerMessageType:()=>a,ViewerSdk:()=>f,cardPermission:()=>_,getKeyFromBlob:()=>S});const r="0.3.3",s=new Set(["dome","intouchapp"]);var a,i,n,o,d,c,l;!function(e){e.CONNECTION_SUCCESS="CONNECTION_SUCCESS",e.INIT="INIT",e.REQUEST_SAVE="REQUEST_SAVE",e.REQUEST_CLOSE="REQUEST_CLOSE",e.REQUEST_INITIAL_DATA="REQUEST_INITIAL_DATA",e.SET_DIRTY="SET_DIRTY",e.SEND_CLOSE="SEND_CLOSE",e.SEND_EXCEPTION="SEND_EXCEPTION"}(a||(a={})),function(e){e.INIT_MESSAGE_CHANNEL="INIT_MESSAGE_CHANNEL"}(i||(i={})),function(e){e.CONNECT="CONNECT"}(n||(n={})),function(e){e.REQUEST_CLOSE="REQUEST_CLOSE",e.REQUEST_SAVE="REQUEST_SAVE",e.DATA_CHANGE="DATA_CHANGE",e.SAVE_ERROR="SAVE_ERROR",e.SAVE_SUCCESS="SAVE_SUCCESS",e.INIT_ACK="INIT_ACK"}(o||(o={})),function(e){e.DATA_CHANGE="DATA_CHANGE",e.CFS_ERROR="CFS_ERROR",e.CFS_WRITE_SUCCESS="CFS_WRITE_SUCCESS",e.CFS_FILE_DATA="CFS_FILE_DATA",e.CFS_WRITE_FILE_ACK="CFS_WRITE_FILE_ACK",e.CFS_READ_FILE_ACK="CFS_READ_FILE_ACK",e.CFS_DELETE_FILE_ACK="CFS_DELETE_FILE_ACK",e.CFS_LIST_FILES_ACK="CFS_LIST_FILES_ACK",e.INIT_ACK="INIT_ACK",e.INIT_ERROR="INIT_ERROR",e.AF1_DATA_TOKEN_ACK="AF1_DATA_TOKEN_ACK",e.ERROR="ERROR",e.REFRESH="REFRESH",e.LOGGING_ENABLE="LOGGING_ENABLE",e.LOGGING_DISABLE="LOGGING_DISABLE",e.LOGGING_CLEAR="LOGGING_CLEAR",e.LOGGING_GET="LOGGING_GET"}(d||(d={})),function(e){e.APP_READY="APP_READY",e.INIT="INIT",e.CFS_READ_FILE="CFS_READ_FILE",e.CFS_WRITE_FILE="CFS_WRITE_FILE",e.CFS_DELETE_FILE="CFS_DELETE_FILE",e.CFS_LIST_FILES="CFS_LIST_FILES",e.FILE_DIRTY="FILE_DIRTY",e.OPEN_DEEPLINK="OPEN_DEEPLINK",e.AF1_DATA_TOKEN="AF1_DATA_TOKEN",e.LOGGING_GET_RET="LOGGING_GET_RET"}(c||(c={}));class u{constructor(){this.targetOrigin="*",this.isAppReady=!1,this.port2=null,this.runtimeHost="unknown",this.parentHostDetails=null,this.parentCapabilities=null,this.handleDeepLinkClick=e=>{if("webapp"!==this.runtimeHost)return;if(!(e.target instanceof Element))return;const t=e.target.closest("a[href]");if(!t)return;const r=t.getAttribute("href")??"";this.emitDeepLink(r)&&e.preventDefault()},console.info(`Initializing Dome Embedded App SDK v${r}`),this.detectHost(),this.setupDeepLinkInterception()}detectHost(){void 0!==window.AndroidBridge?this.runtimeHost="android":void 0!==window.webkit?this.runtimeHost="ios":this.runtimeHost="webapp",this.runtimeHost}setupDeepLinkInterception(){"webapp"===this.runtimeHost&&"undefined"!=typeof document&&document.addEventListener("click",this.handleDeepLinkClick,!0)}emitDeepLink(e){if("string"!=typeof e||""===e.trim())return console.warn("emitDeepLink called without a valid href"),!1;const t=e.split(":")[0]?.toLowerCase();return!(!t||!s.has(t))&&(this.sendMessage(c.OPEN_DEEPLINK,{url:e}),!0)}updateParentContext(e,t){if(!e&&!t)return;const r={...this.parentHostDetails??{type:this.runtimeHost},...e??{}};r.type||(r.type=this.runtimeHost);const s=t??this.parentCapabilities??r.capabilities;t&&(this.parentCapabilities=t),s?r.capabilities=s:delete r.capabilities,this.parentHostDetails=r,this.parentCapabilities=s??null,s?console.info("Host capabilities detected",{host_type:r.type,capabilities:s}):console.info("Host capabilities not found",{hostType:r.type})}getHost(){return this.parentHostDetails??{type:this.runtimeHost}}sendMessage(e,t){const r={type:e,data:t??null};switch(this.runtimeHost){case"android":window.AndroidBridge?.sendMessage(JSON.stringify(r));break;case"ios":window?.webkit?.messageHandlers?window.webkit?.messageHandlers.appHandler.postMessage(JSON.stringify(r)):console.error("webkit.messageHandlers not found");break;case"webapp":this.port2?this.port2.postMessage(r):console.error("Web connection is not established.");break;default:console.error("Unsupported host, cannot send message.")}this.runtimeHost}sendAppInit(){this.isAppReady||(this.isAppReady=!0,this.sendMessage(a.INIT,{sdk:{ver:r}}))}safeInvoke(e,t,r){const s=t?.[e];"function"==typeof s?s(r):console.warn(`Handler for '${String(e)}' is not defined.`)}setupParentConnection(){return new Promise(((e,t)=>{switch(this.runtimeHost){case"android":window.receiveFromAndroid=e=>{this.handleMessage(e.type,e.data)},e();break;case"ios":window.receiveFromIOS=e=>{this.handleMessage(e.type,e.data)},e();break;case"webapp":if(this.port2)return console.warn("Connection already established. Skipping reinitialization."),void e();const s=t=>{const{type:r}=t.data||{};r===n.CONNECT&&t.ports&&t.ports.length>0&&(this.port2=t.ports[0],this.port2.onmessage=e=>this.handlePortMessage(e),window.removeEventListener("message",s),this.notifyConnectionSuccess(),e())};window.addEventListener("message",s),window.parent?window.parent.postMessage({type:i.INIT_MESSAGE_CHANNEL,data:{sdk:{ver:r}}},this.targetOrigin):console.error("Parent window not available to initialize message channel.");break;default:console.error("Unknown host."),t("Unknown host")}}))}notifyConnectionSuccess(){this.sendMessage(a.CONNECTION_SUCCESS)}handlePortMessage(e){const{type:t,data:r}=e.data||{};t&&this.handleMessage(t,r)}handleMessage(e,t){throw new Error("Subclasses must implement handleMessage.")}}function h(e){const{prefix:t="",given:r="",middle:s="",family:a="",suffix:i=""}=e||{};return[t,r,s,a,i].filter((e=>e)).join(" ").trim()}class f extends u{constructor(){super(),this.handler=null,this.pendingRequests=new Map,this.pendingInitAck=null}static init(e){return f.initialized?(console.warn("ViewerSdk is already initialized. Skipping initialization."),f.instance):(f.instance||(f.instance=new f,f.instance.setupParentConnection().then((()=>{try{f.instance.initializeViewerSdk()}catch(e){console.error("Error in initializeViewerSdk:",e)}})).catch((e=>{console.error("init: Error setting up parent connection!",e),console.trace("called from:")}))),e&&f.instance.setHandler(e),f.initialized=!0,f.instance)}setHandler(e){this.handler=e,this.pendingInitAck&&(this.safeInvoke("onInitialData",this.handler,this.pendingInitAck),this.pendingInitAck=null)}canRead(e){return!!e?.includes("r")}canWrite(e){return!!e?.includes("w")||!!e?.includes("*")}initializeViewerSdk(){this.sendAppInit()}requestInitialData(){this.sendMessage(a.REQUEST_INITIAL_DATA)}requestSave(e,t){const r=function(){if("undefined"!=typeof window&&window.crypto&&window.crypto.randomUUID)return window.crypto.randomUUID();if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();throw new Error("UUID generation is not supported in this environment")}();return this.sendMessage(a.REQUEST_SAVE,{doc:e,isDataDirty:t,requestId:r}),new Promise(((e,t)=>{this.pendingRequests.set(r,e),this.pendingRequests.set(r+"_reject",t),setTimeout((()=>{this.pendingRequests.has(r)&&(this.pendingRequests.delete(r),this.pendingRequests.delete(r+"_reject"))}),3e4)}))}handleOnSave(e){const{requestId:t,status:r,message:s}=e,a=this.pendingRequests.get(t),i=this.pendingRequests.get(t+"_reject");a&&("error"===r?i?.({status:r,message:s}):a({status:r,message:s}),this.pendingRequests.delete(t),this.pendingRequests.delete(t+"_reject"))}setDirty(e){this.sendMessage(a.SET_DIRTY,e)}sendClose(e,t){this.sendMessage(a.SEND_CLOSE,{doc:e,isDataDirty:t})}sendException(e){this.sendMessage(a.SEND_EXCEPTION,e)}handleMessage(e,t){if(e===o.INIT_ACK&&this.updateParentContext(t?.host,t?.capabilities),this.handler)switch(e){case o.INIT_ACK:this.safeInvoke("onInitialData",this.handler,t);break;case o.DATA_CHANGE:this.safeInvoke("onDataChange",this.handler,t);break;case o.REQUEST_CLOSE:this.safeInvoke("onCloseRequest",this.handler);break;case o.REQUEST_SAVE:this.safeInvoke("onSaveRequest",this.handler);break;case o.SAVE_SUCCESS:case o.SAVE_ERROR:this.handleOnSave(t);break;default:console.warn(`No handler found for message type: ${e}`)}else e===o.INIT_ACK?(console.warn("Handler not set. Storing INIT_ACK message for later processing."),this.pendingInitAck=t):console.error("Message handler not found for type:",e)}}f.initialized=!1;class p{constructor(){if(this.subtleCrypto=window.crypto?.subtle,!this.subtleCrypto)throw new Error("SubtleCrypto API is not available in this environment.")}async decrypt(e,t,r){try{if(!e)throw new Error("Invalid token");const s=this.base64UrlDecode(e);if(128!==s[0])throw new Error("Invalid version");s.slice(1,9);const a=s.slice(9,25),i=s.slice(25,-32),n=s.slice(-32),o=await this.deriveKey(t,r),{hmacKey:d,aesKey:c}=await this.splitKey(o),l=s.slice(0,-32);if(!new Uint8Array(await this.subtleCrypto.sign("HMAC",d,l)).every(((e,t)=>e===n[t])))throw new Error("Invalid HMAC. Token has been tampered with!");const u=await this.subtleCrypto.decrypt({name:"AES-CBC",iv:a},c,i);return(new TextDecoder).decode(u)}catch(e){throw console.log("Error in decrypt:",e),e}}async deriveKey(e,t,r=1e4){const s=new TextEncoder,a=await this.subtleCrypto.importKey("raw",s.encode(e),"PBKDF2",!1,["deriveKey"]);return this.subtleCrypto.deriveKey({name:"PBKDF2",hash:"SHA-256",salt:s.encode(t),iterations:r},a,{name:"AES-CBC",length:256},!0,["encrypt","decrypt"])}async splitKey(e){const t=new Uint8Array(await this.subtleCrypto.exportKey("raw",e));return{hmacKey:await this.subtleCrypto.importKey("raw",t.slice(0,16),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"]),aesKey:await this.subtleCrypto.importKey("raw",t.slice(16),{name:"AES-CBC"},!1,["encrypt","decrypt"])}}base64UrlDecode(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),r=atob(t);return new Uint8Array([...r].map((e=>e.charCodeAt(0))))}}!function(e){e.READ="r",e.WRITE="w",e.FORWARD="f",e.SHARE="s",e.DOWNLOAD="d"}(l||(l={}));const _=l;var E;!function(e){e.NO_INTERNET="NO_INTERNET",e.NO_PERMISSION="NO_PERMISSION",e.NOT_FOUND="NOT_FOUND",e.SERVER_ERROR="SERVER_ERROR",e.TIMEOUT="TIMEOUT",e.INVALID_REQUEST="INVALID_REQUEST",e.UNKNOWN="UNKNOWN"}(E||(E={}));function S(e){let t;if(1!==e.v)throw new Error(`Unsupported key blob version: ${e.v}`);return t=function(e){const{seed:t,obf:r}=e,s=new Uint8Array(r.length);for(let e=0;e<r.length;e++)s[e]=r[e]^t+17*e&255;return s}(e),function(e){if("undefined"!=typeof TextDecoder)return(new TextDecoder).decode(e);let t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return t}(t)}class m{constructor(e,t){this.cardIuid=e,this.containerIuid=t,this.openPromise=null}isSupported(){return"undefined"!=typeof indexedDB}async openDb(){return this.isSupported()?(this.openPromise||(this.openPromise=new Promise((e=>{this.openWithVersion(m.DB_VERSION,e)}))),this.openPromise):null}openWithVersion(e,t){let r="ensure";const s=indexedDB.open(this.cardIuid,e);s.onupgradeneeded=e=>{r=0===(e.oldVersion||0)?"create":"ensure",this.configureStores(s.result)},s.onsuccess=()=>{const e=s.result;if(!this.hasRequiredStores(e)){const r=e.version+1;return e.close(),void this.openWithVersion(r,t)}this.updateStoresMetadata(e,"ensure"===r).catch((()=>{})).finally((()=>t(e)))},s.onerror=()=>t(null)}configureStores(e){e.objectStoreNames.contains(m.DATA_STORE)||e.createObjectStore(m.DATA_STORE),e.objectStoreNames.contains(m.NAME_LOOKUP_STORE)||e.createObjectStore(m.NAME_LOOKUP_STORE),e.objectStoreNames.contains(m.INFO_STORE)||e.createObjectStore(m.INFO_STORE),e.objectStoreNames.contains(m.FOLDER_LISTING_STORE)||e.createObjectStore(m.FOLDER_LISTING_STORE)}hasRequiredStores(e){const t=e.objectStoreNames;return t.contains(m.DATA_STORE)&&t.contains(m.NAME_LOOKUP_STORE)&&t.contains(m.INFO_STORE)&&t.contains(m.FOLDER_LISTING_STORE)}static nowMicros(){return Math.trunc(1e3*Date.now())}updateStoresMetadata(e,t){return Promise.all([this.ensureStoreVersion(e,m.DATA_STORE),this.ensureStoreVersion(e,m.NAME_LOOKUP_STORE),this.ensureStoreVersion(e,m.FOLDER_LISTING_STORE),this.updateCardInfo(e,t)]).then((()=>{}))}ensureStoreVersion(e,t){return e.objectStoreNames.contains(t)?new Promise((r=>{try{const s=e.transaction(t,"readwrite"),a=s.objectStore(t),i=()=>r();s.oncomplete=i,s.onerror=i,s.onabort=i,a.put("1.0.0",m.STORE_VERSION_KEY)}catch{r()}})):Promise.resolve()}async updateCardInfo(e,t){if(!e.objectStoreNames.contains(m.INFO_STORE))return;const r=await this.readInfoValue(e,"container_iuid"),s=t?await this.readInfoValue(e,"ts_c"):void 0,a=this.containerIuid??r??null,i=t&&s?s:m.nowMicros();await Promise.all([this.writeInfoValue(e,"container_iuid",a),this.writeInfoValue(e,"ts_c",i)]).catch((()=>{}))}readInfoValue(e,t){return new Promise((r=>{try{const s=e.transaction(m.INFO_STORE,"readonly"),a=s.objectStore(m.INFO_STORE).get(t);a.onsuccess=()=>r(a.result),a.onerror=()=>r(void 0)}catch{r(void 0)}}))}writeInfoValue(e,t,r){return new Promise((s=>{try{const a=e.transaction(m.INFO_STORE,"readwrite"),i=a.objectStore(m.INFO_STORE),n=()=>s();a.oncomplete=n,a.onerror=n,a.onabort=n,i.put(r,t)}catch{s()}}))}keyFor(e){return e}static normalizeFolderName(e){if("string"!=typeof e)return"/";let t=e.trim();return t?(t=t.replace(/^\/+/,""),t?(t.endsWith("/")||(t+="/"),t):"/"):"/"}folderListingKey(e){return m.normalizeFolderName(e)}static normalizeName(e){if("string"!=typeof e)return null;const t=e.trim();return t||null}async put(e,t){const r=await this.openDb();r&&await new Promise((s=>{const a=r.transaction(m.DATA_STORE,"readwrite");a.objectStore(m.DATA_STORE).put(t,e).onsuccess=()=>s(),a.oncomplete=()=>s(),a.onerror=()=>s(),a.onabort=()=>s()}))}async get(e){const t=await this.openDb();if(t)return new Promise((r=>{const s=t.transaction(m.DATA_STORE,"readonly").objectStore(m.DATA_STORE).get(e);s.onsuccess=()=>r(s.result),s.onerror=()=>r(void 0)}))}async delete(e){const t=await this.openDb();t&&await new Promise((r=>{const s=t.transaction(m.DATA_STORE,"readwrite");s.objectStore(m.DATA_STORE).delete(e).onsuccess=()=>r(),s.oncomplete=()=>r(),s.onerror=()=>r(),s.onabort=()=>r()}))}static async hashName(e){const t="undefined"!=typeof globalThis?globalThis.crypto:void 0;if(!t?.subtle?.digest)throw new Error("CardFS name hashing requires SubtleCrypto support");const r=m.encodeText(e),s=await t.subtle.digest("SHA-256",r);return m.bufferToBase64(s)}static encodeText(e){if("undefined"!=typeof TextEncoder)return(new TextEncoder).encode(e).buffer;const t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t.buffer}static bufferToBase64(e){let t="";const r=new Uint8Array(e);for(let e=0;e<r.length;e++)t+=String.fromCharCode(r[e]);return btoa(t)}async getIuidForName(e){const t=m.normalizeName(e);if(!t)return;const r=await this.openDb();if(!r)return;const s=await m.hashName(t);return new Promise((e=>{const t=r.transaction(m.NAME_LOOKUP_STORE,"readonly").objectStore(m.NAME_LOOKUP_STORE).get(s);t.onsuccess=()=>e(t.result),t.onerror=()=>e(void 0)}))}async upsertNameLookup(e,t){const r=m.normalizeName(e);if(!r)return;const s=await this.openDb();if(!s)return;const a=await m.hashName(r);await new Promise((e=>{const r=s.transaction(m.NAME_LOOKUP_STORE,"readwrite"),i=r.objectStore(m.NAME_LOOKUP_STORE);i.put(t,a);i.openCursor().onsuccess=e=>{const r=e.target.result;r&&(r.key!==a&&r.value===t&&r.delete(),r.continue())},r.oncomplete=()=>e(),r.onerror=()=>e(),r.onabort=()=>e()}))}async deleteNameLookupByName(e){const t=m.normalizeName(e);if(!t)return;const r=await this.openDb();if(!r)return;const s=await m.hashName(t);await new Promise((e=>{const t=r.transaction(m.NAME_LOOKUP_STORE,"readwrite");t.objectStore(m.NAME_LOOKUP_STORE).delete(s),t.oncomplete=()=>e(),t.onerror=()=>e(),t.onabort=()=>e()}))}async deleteNameLookupByIuid(e){if(!e)return;const t=await this.openDb();t&&await new Promise((r=>{const s=t.transaction(m.NAME_LOOKUP_STORE,"readwrite");s.objectStore(m.NAME_LOOKUP_STORE).openCursor().onsuccess=t=>{const r=t.target.result;r&&(r.value===e&&r.delete(),r.continue())},s.oncomplete=()=>r(),s.onerror=()=>r(),s.onabort=()=>r()}))}static estimateSize(e){if(null==e)return 0;if("undefined"!=typeof Blob&&e instanceof Blob)return e.size;if(e instanceof ArrayBuffer)return e.byteLength;if(ArrayBuffer.isView(e))return e.byteLength;if("string"==typeof e)return new Blob([e]).size;try{return new Blob([JSON.stringify(e)]).size}catch{return 0}}async cacheDocument(e,t){if(!e?.iuid)return;await this.put(this.keyFor(`${e.iuid}_object`),e);const r=m.normalizeName(e.name);if(r&&await this.upsertNameLookup(r,e.iuid),void 0===t)return void await this.delete(this.keyFor(`${e.iuid}_data`));m.estimateSize(t)<=m.MAX_DATA_BYTES?await this.put(this.keyFor(`${e.iuid}_data`),t):await this.delete(this.keyFor(`${e.iuid}_data`))}async getByName(e){const t=m.normalizeName(e);if(!t)return null;const r=await this.getIuidForName(t);if(!r)return null;const s=await this.get(this.keyFor(`${r}_object`));if(!s)return null;return{iuid:r,object:s,data:await this.get(this.keyFor(`${r}_data`))}}async getByIuid(e){if(!e)return null;const t=await this.get(this.keyFor(`${e}_object`));if(!t)return null;return{iuid:e,object:t,data:await this.get(this.keyFor(`${e}_data`))}}async deleteByName(e){const t=await this.getByName(e);await this.deleteNameLookupByName(e),t&&(await this.delete(this.keyFor(`${t.iuid}_object`)),await this.delete(this.keyFor(`${t.iuid}_data`)))}async deleteByIuid(e,t){t&&await this.deleteNameLookupByName(t),await this.deleteNameLookupByIuid(e),await this.delete(this.keyFor(`${e}_object`)),await this.delete(this.keyFor(`${e}_data`))}async cacheFolderListing(e,t){const r=await this.openDb();if(!r)return;const s=this.folderListingKey(e??t.folder_name),a={folder_name:m.normalizeFolderName(t.folder_name??e),folder_iuid:t.folder_iuid,last_index:t.last_index??null,last_page:t.last_page??null,documents:Array.isArray(t.documents)?t.documents:[]};await new Promise((e=>{const t=r.transaction(m.FOLDER_LISTING_STORE,"readwrite");t.objectStore(m.FOLDER_LISTING_STORE).put(a,s).onsuccess=()=>e(),t.oncomplete=()=>e(),t.onerror=()=>e(),t.onabort=()=>e()}))}async getFolderListing(e){const t=await this.openDb();if(!t)return null;const r=this.folderListingKey(e);return new Promise((e=>{const s=t.transaction(m.FOLDER_LISTING_STORE,"readonly").objectStore(m.FOLDER_LISTING_STORE).get(r);s.onsuccess=()=>e(s.result),s.onerror=()=>e(null)}))}}m.DB_VERSION=3,m.DATA_STORE="cardfs",m.NAME_LOOKUP_STORE="cardfs_name_iuid_lookup",m.INFO_STORE="info",m.FOLDER_LISTING_STORE="cardfs_folder_listings",m.STORE_VERSION_KEY="ver",m.MAX_DATA_BYTES=5242880;class w extends u{buildCardFsMessagePayload(e,t){return{...e.name?{name:e.name}:{},...e.iuid?{iuid:e.iuid}:{},...t??{}}}formatFolderPath(e){if("string"!=typeof e)return;let t=e.trim();return t&&(t=t.replace(/^\/+/,""),t)?(t.endsWith("/")||(t+="/"),t):void 0}assertValidReadHandler(e){if(!e||"function"!=typeof e.next)throw new Error("cardFS.read requires a handler with a next() function");return e}assertValidListHandler(e){if(!e||"function"!=typeof e.next)throw new Error("cardFS.list requires a handler with a next() function");return e}invokeReadHandlerNext(e,t){try{e.next(t)}catch(e){console.error("cardFS.read handler next() threw",e)}}invokeReadHandlerError(e,t){if(e.error)try{e.error(t)}catch(e){console.error("cardFS.read handler error() threw",e)}}sanitizeReadData(e,t){if(null==e)return{value:e,stripped:!1};try{if(m.estimateSize(e)>m.MAX_DATA_BYTES){const e=t?` for ${t}`:"";return console.warn(`cardFS.read payload data exceeded ${m.MAX_DATA_BYTES} bytes${e}; omitting data`),{value:void 0,stripped:!0}}}catch(e){console.warn("cardFS.read payload size estimation failed",e)}return{value:e,stripped:!1}}getCardIuid(){return this.dataStore?.iuid||null}ensureCardFsCache(){if(!this.shouldUseCardFsFallback())return null;if(!this.cardFsCache){const e=this.getCardIuid();e&&(this.cardFsCache=new m(e,this.containerIuid))}return this.cardFsCache}supportsParentCardFs(){return!!this.parentCapabilities?.card_fs}shouldUseCardFsFallback(){return!this.supportsParentCardFs()}constructor(){super(),this.handler=null,this.accessToken="",this.devMode=!1,this.permission=null,this.userRole=null,this.fsReadRequests=new Map,this.fsWriteRequests=new Map,this.cardFsCache=null,this.pendingAcks=new Map,this.consoleCaptureInstalled=!1,this.consoleCaptureEnabled=!1,this.consoleCaptureMinLevel=null,this.consoleLogBuffer=new Array(w.MAX_CONSOLE_LOG_ENTRIES).fill(null),this.consoleLogWriteIndex=0,this.consoleLogSize=0,this.handleMessage=(e,t)=>{if(e===d.INIT_ACK&&this.updateParentContext(t?.host,t?.capabilities),e===d.CFS_ERROR){const e=t?.messageId,r=this.createCardFsError(t,"Unknown cardFS error");if(e&&this.pendingAcks.has(e)){const t=this.pendingAcks.get(e);clearTimeout(t.timeout),this.pendingAcks.delete(e),t.reject(r)}if(e){if(this.fsReadRequests.has(e))return void this.failFsReadRequest(e,r);if(this.fsWriteRequests.has(e))return void this.failFsWriteRequest(e,r)}return void console.warn("CardSdk: CFS_ERROR received but no matching fs request",t?.messageId??t?.name)}this.handleFsAckMessage(e,t);const r=t?.messageId;if(r&&this.pendingAcks.has(r)){const s=this.pendingAcks.get(r);if(s.ackType===e)return clearTimeout(s.timeout),this.pendingAcks.delete(r),void s.resolve(t)}if(r||!this.resolvePendingAckByType(e,t)){if(!this.handler)throw new Error("Message handler not found!");switch(e){case d.INIT_ACK:this.applyLoggingConfig(t?.logging),this.dataStore.kw1=t.key_wa1,this.dataStore.iuid=t.iuid,"boolean"==typeof t?.dev_mode&&(this.devMode=t.dev_mode,this.dataStore.dev_mode=t.dev_mode),t.iuid?this.shouldUseCardFsFallback()?this.cardFsCache=new m(t.iuid,this.containerIuid):this.cardFsCache=null:this.shouldUseCardFsFallback()||(this.cardFsCache=null);try{this.cryptoA01.decrypt(this.dataStore.denc,t.key_wa1+this.dataStore.kw2,t.iuid).then((e=>{const r=JSON.parse(e),s=r?.container?.iuid;s&&(this.containerIuid=s,this.shouldUseCardFsFallback()&&this.dataStore?.iuid&&(this.cardFsCache=new m(this.dataStore.iuid,this.containerIuid)));const a="string"==typeof r?.api_token?r.api_token.trim():"";a?this.accessToken=a:console.warn("CardSdk: INIT_ACK payload missing api_token; fallback APIs may fail without auth"),this.permission=r?.perms_v2??null,this.userRole=r?.role??null;const i=this.attachUserFullName(r?.user);this.handler&&this.safeInvoke("onInit",this.handler,{...r,user:i,ui:t.ui}),delete this.dataStore.denc})).catch((e=>{throw console.error("Final decrypt error",e),e}))}catch(e){console.error("Decryption failed!",e),this.sendEventError("dec2_failed",e.message)}break;case d.INIT_ERROR:this.safeInvoke("onInitError",this.handler,t);break;case d.CFS_FILE_DATA:{const e=t?.messageId;if(e&&this.fsReadRequests.has(e)){const{messageId:r,...s}=t||{};return void this.handleFsReadDataMessage(e,s)}console.warn("CardSdk: CFS_FILE_DATA received but no matching fsRead request",t?.messageId??t?.name);break}case d.DATA_CHANGE:this.safeInvoke("onFileChange",this.handler,t);case d.CFS_WRITE_SUCCESS:{const e=t?.messageId;if(e&&this.fsWriteRequests.has(e))return void this.handleFsWriteSuccess(e,t);console.warn("CardSdk: CFS_WRITE_SUCCESS received but no matching fsWrite request",t?.messageId??t?.name);break}case d.ERROR:this.safeInvoke("onError",this.handler,t);break;case d.REFRESH:this.safeInvoke("onRefreshRequest",this.handler,t);break;case d.AF1_DATA_TOKEN_ACK:break;case d.LOGGING_ENABLE:this.applyLoggingConfig({status:"enabled",level:t?.level??t?.logging?.level});break;case d.LOGGING_DISABLE:this.consoleCaptureEnabled=!1;break;case d.LOGGING_CLEAR:this.clearConsoleLogs();break;case d.LOGGING_GET:this.sendConsoleLogs();break;case d.CFS_READ_FILE_ACK:case d.CFS_WRITE_FILE_ACK:case d.CFS_DELETE_FILE_ACK:case d.CFS_LIST_FILES_ACK:break;default:console.warn(`No handler found for message type: ${e}`)}}},this.cryptoA01=new p,this.cardFS={read:(e,t,r=!0)=>{this.cardFSRead(e,t,r)},readById:(e,t,r=!0)=>{this.cardFSReadById(e,t,r)},write:(e,t,r)=>this.cardFSWrite(e,t,r),writeById:(e,t,r)=>this.cardFSWriteById(e,t,r),delete:(e,t)=>this.cardFSDelete(e,t),deleteById:(e,t)=>this.cardFSDeleteById(e,t),list:(e,t)=>this.cardFSList(e,t)}}static async init(e,t,r){try{return w.instance||(w.instance=new w,w.instance.setupParentConnection().then((()=>{w.instance.initializeCardSdk(e)})).catch((e=>{console.error(e)})),t&&w.instance.setHandler(t)),w.instance}catch(e){throw console.error("CardSdk: Unrecoverable error in init",e),e}}setHandler(e){this.handler=e}openDeepLink(e){this.emitDeepLink(e)||console.warn("openDeepLink ignored; provide a dome:// or intouchapp:// href")}hasPerm(e){if(!e)return!1;const t=this.userRole?.abbr;if(!t)return!0;if("o"===t)return!0;const r=this.permission?.[t];return"string"==typeof r?!!r.includes("*")||r.includes(e):w.DEFAULT_ROLE_PERMISSIONS.includes(e)}canRead(){return this.hasPerm(l.READ)}canWrite(){return this.hasPerm(l.WRITE)}deriveSecretSeed(e){const t=e.split("").reverse().join("").substring(4,25);if(!t)throw new Error("Cannot decrypt (1)");return t}getCardIuidEnc(e){try{const t=e.pathname.split("/wa/").filter(Boolean);if(t.length<2)return null;return(t[1]?.split("/")[0]??null)||null}catch(e){return console.warn("CardSdk: Failed to extract seed token",e),null}}async requestAf1DataFromParent(e){const t=await this.sendMessageWithAck(c.AF1_DATA_TOKEN,{sdk:{ver:r}},d.AF1_DATA_TOKEN_ACK),{messageId:s,...a}=t||{},{cie:i,ck:n,dev_token:o}=a;if(!i||!n||!o)throw new Error("Invalid AF1 data token payload");const l=await this.fetchAf1Data(i,n,o,e),u=l?.data_af1??l?.data?.data_af1;if(!u)throw new Error("AF1 data fetch returned empty payload");return window.IT_DATA_AF1=u,l?.ver&&(window.IT_VERSION=l.ver),l?.env&&(window.IT_ENV=l.env),{dataAf1:u,cie:i}}async fetchAf1Data(e,t,r,s){if(!(e&&t&&r&&s))throw new Error("Invalid AF1 data fetch parameters");const a=new URL(`https://dome.so/api/v1/cards/e/${encodeURIComponent(e)}/data_af1/`);a.searchParams.set("dt",r),a.searchParams.set("rt",s),a.searchParams.set("ck",t);const i=await fetch(a.toString(),{method:"GET"});if(!i.ok){const e=await i.text().catch((()=>i.statusText));throw new Error(`AF1 data fetch failed: ${i.status} ${e}`)}return i.json()}async initializeCardSdk(e){let t="CardSdk::initializeCardSdk:";try{if(!e)throw new Error("Invalid secret");const r=window.location.href,s=new URL(r),a=s.searchParams.get("rt");if(!a)throw new Error("Missing request token");let i=this.getCardIuidEnc(s),n=window.IT_DATA_AF1;if(!n){const{dataAf1:e,cie:t}=await this.requestAf1DataFromParent(a);n=e,i=t||i}if(!n)throw console.error(t,"No data"),new Error("No data");if(!i)throw new Error("Cannot decrypt (missing seed)");const o=this.deriveSecretSeed(i),d=await this.cryptoA01.decrypt(n,e,o);try{const e=JSON.parse(d);if(!e.ite)throw new Error("Invalid data");this.dataStore={denc:e.d,kw2:e.kw2},w.instance.sendInit(e.ite)}catch(e){throw console.error("Initial Decryption failed (2):",e),e}}catch(e){console.error(t,"Init failed:",e),this.sendEventError("init_failed",e.message)}}async sendInit(e){const t={token:e,sdk:{ver:r}},s=this.getWebappDetails();s&&(t.wa=s),this.sendMessage(c.INIT,t)}getWebappDetails(){if("undefined"==typeof window)return null;let e={};const t=window.IT_VERSION,r=window.IT_ENV;return t&&(e.ver=String(t)),r&&(e.env=String(r)),Object.keys(e).length?e:null}sendMessageWithAck(e,t,r,s=15e3,a){const i=crypto.randomUUID();if(a)try{a(i)}catch(e){return Promise.reject(e)}return new Promise(((a,n)=>{const o=setTimeout((()=>{this.pendingAcks.delete(i);const e=new Error(`${r} not received in time`);this.isCardFsAckType(r)&&(e.code=E.TIMEOUT),n(e)}),s);this.pendingAcks.set(i,{resolve:a,reject:n,timeout:o,ackType:r}),this.sendMessage(e,{...t,messageId:i})}))}resolvePendingAckByType(e,t){for(const[r,s]of this.pendingAcks.entries())if(s.ackType===e)return clearTimeout(s.timeout),this.pendingAcks.delete(r),s.resolve(t),!0;return!1}cardFSRead(e,t,r=!0){const s={name:e},a=this.assertValidReadHandler(t);this.cardFSReadInternal(s,a,r,"read")}cardFSReadById(e,t,r=!0){const s={iuid:e},a=this.assertValidReadHandler(t);this.cardFSReadInternal(s,a,r,"readById")}cardFSReadInternal(e,t,r,s){if(this.shouldUseCardFsFallback())return void this.cardFSReadFallback(e,void 0,t,r).catch((e=>{const r=e instanceof Error?e:new Error(String(e));this.invokeReadHandlerError(t,this.toCardFsErrorPayload(r))}));let a=null;const i=e.name?`"${e.name}"`:e.iuid?`iuid ${e.iuid}`:"document";this.sendMessageWithAck(c.CFS_READ_FILE,this.buildCardFsMessagePayload(e,{allow_stale:r}),d.CFS_READ_FILE_ACK,w.CARD_FS_ACK_TIMEOUT_MS,(e=>{a=e;const n={name:i,handler:t,allowStale:r,timeoutMessage:`cardFS.${s} timed out for ${i}`};this.fsReadRequests.set(e,n)})).catch((e=>{const r=e instanceof Error?e:new Error(String(e));a?this.failFsReadRequest(a,r):this.invokeReadHandlerError(t,this.toCardFsErrorPayload(r))}))}isCardFsAckType(e){return e===d.CFS_READ_FILE_ACK||e===d.CFS_WRITE_FILE_ACK||e===d.CFS_DELETE_FILE_ACK||e===d.CFS_LIST_FILES_ACK}cardFSWrite(e,t,r){const s={name:e};return this.cardFSWriteInternal(s,t,r,"write")}cardFSWriteById(e,t,r){const s={iuid:e};return this.cardFSWriteInternal(s,t,r,"writeById")}cardFSWriteInternal(e,t,r,s){return this.shouldUseCardFsFallback()?this.cardFSWriteFallback(e,t).catch((e=>{throw this.toCardFsErrorPayload(e)})):new Promise(((a,i)=>{let n=null;const o=e.name?`"${e.name}"`:e.iuid?`iuid ${e.iuid}`:"document";this.sendMessageWithAck(c.CFS_WRITE_FILE,this.buildCardFsMessagePayload(e,{data:t}),d.CFS_WRITE_FILE_ACK,w.CARD_FS_ACK_TIMEOUT_MS,(e=>{n=e;const t={name:o,onUpdate:r,resolve:a,reject:i,timeoutMessage:`cardFS.${s} timed out for ${o}`};this.fsWriteRequests.set(e,t)})).catch((e=>{const t=e instanceof Error?e:new Error(String(e));n?this.failFsWriteRequest(n,t):i(this.toCardFsErrorPayload(t))}))}))}cardFSDelete(e,t){const r={name:e};return this.cardFSDeleteInternal(r,t,"delete")}cardFSDeleteById(e,t){const r={iuid:e};return this.cardFSDeleteInternal(r,t,"deleteById")}cardFSDeleteInternal(e,t,r){return this.shouldUseCardFsFallback()?this.cardFSDeleteFallback(e).then((e=>{try{t?.(e)}catch(e){console.error(`cardFS.${r} fallback callback threw`,e)}return e})).catch((e=>{throw this.toCardFsErrorPayload(e)})):new Promise(((r,s)=>{this.sendMessageWithAck(c.CFS_DELETE_FILE,this.buildCardFsMessagePayload(e),d.CFS_DELETE_FILE_ACK,w.CARD_FS_ACK_TIMEOUT_MS).then((e=>{const{messageId:s,...a}=e||{};t?.(a),r(a)})).catch((e=>{s(this.toCardFsErrorPayload(e))}))}))}cardFSList(e,t){const r=this.assertValidListHandler(t),s=this.formatFolderPath(e);if(this.shouldUseCardFsFallback())return void this.cardFSListFallback(s).then((e=>{r.next(this.normalizeListResult(e))})).catch((e=>{r.error?.(this.toCardFsErrorPayload(e))}));const a=s?{name:s}:{};this.sendMessageWithAck(c.CFS_LIST_FILES,a,d.CFS_LIST_FILES_ACK,w.CARD_FS_ACK_TIMEOUT_MS).then((e=>{const{messageId:t,...s}=e||{};r.next(this.normalizeListResult(s))})).catch((e=>{r.error?.(this.toCardFsErrorPayload(e))}))}resetFsReadProgressTimeout(e){const t=this.fsReadRequests.get(e);t&&(t.progressTimeout&&clearTimeout(t.progressTimeout),t.progressTimeout=setTimeout((()=>{this.failFsReadRequest(e,{code:E.TIMEOUT,message:t.timeoutMessage})}),w.FS_RESPONSE_TIMEOUT_MS))}resetFsWriteProgressTimeout(e){const t=this.fsWriteRequests.get(e);t&&(t.progressTimeout&&clearTimeout(t.progressTimeout),t.progressTimeout=setTimeout((()=>{this.failFsWriteRequest(e,{code:E.TIMEOUT,message:t.timeoutMessage})}),w.FS_RESPONSE_TIMEOUT_MS))}handleFsReadDataMessage(e,t){const r=this.fsReadRequests.get(e);if(!r)return;const s=this.sanitizeReadData(t?.data,r.name),a=Boolean(t?.from_cache??t?.is_stale),i={name:t?.name,iuid:t?.iuid??null,object:t?.object,data:s.value,is_dirty:"boolean"==typeof t?.is_dirty?t.is_dirty:void 0,is_stale:Boolean(t?.is_stale??t?.from_cache),is_complete:"boolean"==typeof t?.is_complete?t.is_complete:!r.allowStale||!a};this.invokeReadHandlerNext(r.handler,i),i.is_complete&&r.progressTimeout&&(clearTimeout(r.progressTimeout),r.progressTimeout=void 0),r.cleanupTimeout&&clearTimeout(r.cleanupTimeout),r.cleanupTimeout=setTimeout((()=>{this.clearFsReadRequest(e)}),w.FS_READ_RETENTION_MS)}handleFsAckMessage(e,t){const r=t?.messageId;if(!r)return!1;if(e===d.CFS_READ_FILE_ACK){const e=this.fsReadRequests.get(r);return!!e&&(this.resetFsReadProgressTimeout(r),e.cleanupTimeout&&clearTimeout(e.cleanupTimeout),e.cleanupTimeout=setTimeout((()=>{this.clearFsReadRequest(r)}),w.FS_READ_RETENTION_MS),!0)}if(e===d.CFS_WRITE_FILE_ACK){const e=this.fsWriteRequests.get(r);if(!e)return!1;const{messageId:s,...a}=t||{};if("function"==typeof e.onUpdate)try{e.onUpdate(a)}catch(e){console.error("cardFS.write onUpdate callback threw",e)}return this.resetFsWriteProgressTimeout(r),!0}return!1}clearFsReadRequest(e){const t=this.fsReadRequests.get(e);if(t)return t.progressTimeout&&clearTimeout(t.progressTimeout),t.cleanupTimeout&&clearTimeout(t.cleanupTimeout),this.fsReadRequests.delete(e),t}sendConsoleLogs(){const e={logs:this.getConsoleLogs().map((e=>({l:e.level,ts:e.timestamp,args:e.args}))),ver:"1.0.0",sdk:{ver:r}};this.sendMessage(c.LOGGING_GET_RET,e)}setupConsoleCapture(){if(this.consoleCaptureInstalled||"undefined"==typeof console)return;["log","info","warn","error","debug"].forEach((e=>{const t=console[e];if("function"!=typeof t)return;const r=t.bind(console);console[e]=(...t)=>{try{this.recordConsoleEntry(e,t)}catch{}r(...t)}})),this.consoleCaptureInstalled=!0}applyLoggingConfig(e){if(!e)return;"enabled"===e.status?(this.consoleCaptureEnabled=!0,this.setupConsoleCapture()):"disabled"===e.status&&(this.consoleCaptureEnabled=!1);const t="string"==typeof e.level?e.level.toLowerCase():null;t&&this.isConsoleLogLevel(t)&&(this.consoleCaptureMinLevel=t)}isConsoleLogLevel(e){return"log"===e||"info"===e||"warn"===e||"error"===e||"debug"===e}shouldCaptureLevel(e){if(!this.consoleCaptureEnabled)return!1;if(!this.consoleCaptureMinLevel)return!0;const t=["debug","log","info","warn","error"];return t.indexOf(e)>=t.indexOf(this.consoleCaptureMinLevel)}recordConsoleEntry(e,t){if(!this.shouldCaptureLevel(e))return;const r={level:e,timestamp:(new Date).toISOString(),args:t.map((e=>this.serializeConsoleArg(e)))};this.consoleLogBuffer[this.consoleLogWriteIndex]=r,this.consoleLogWriteIndex=(this.consoleLogWriteIndex+1)%w.MAX_CONSOLE_LOG_ENTRIES,this.consoleLogSize=Math.min(this.consoleLogSize+1,w.MAX_CONSOLE_LOG_ENTRIES)}clearConsoleLogs(){this.consoleLogBuffer.fill(null),this.consoleLogWriteIndex=0,this.consoleLogSize=0}getConsoleLogs(){if(0===this.consoleLogSize)return[];if(this.consoleLogSize<w.MAX_CONSOLE_LOG_ENTRIES)return this.consoleLogBuffer.slice(0,this.consoleLogSize).filter((e=>null!==e));const e=[];for(let t=0;t<w.MAX_CONSOLE_LOG_ENTRIES;t+=1){const r=(this.consoleLogWriteIndex+t)%w.MAX_CONSOLE_LOG_ENTRIES,s=this.consoleLogBuffer[r];s&&e.push(s)}return e}serializeConsoleArg(e){if(null===e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e)return this.truncateSerializedArg(e);if(void 0===e)return this.truncateSerializedArg({type:"undefined"});if("bigint"==typeof e)return this.truncateSerializedArg({type:"bigint",value:e.toString()});if("symbol"==typeof e)return this.truncateSerializedArg({type:"symbol",value:e.toString()});if("function"==typeof e)return this.truncateSerializedArg({type:"function",name:e.name||null});if(e instanceof Error)return this.truncateSerializedArg({type:"error",name:e.name,message:e.message,stack:e.stack??null});try{return this.truncateSerializedArg(JSON.parse(JSON.stringify(e)))}catch{try{return this.truncateSerializedArg({type:"object",value:String(e)})}catch{return this.truncateSerializedArg({type:"object",value:"[unserializable]"})}}}truncateSerializedArg(e){try{if("string"==typeof e)return e.length>w.MAX_CONSOLE_ARG_CHARS?{type:"truncated",preview:e.slice(0,w.MAX_CONSOLE_ARG_CHARS),original_length:e.length}:e;const t=JSON.stringify(e);if("string"==typeof t&&t.length>w.MAX_CONSOLE_ARG_CHARS)return{type:"truncated",preview:t.slice(0,w.MAX_CONSOLE_ARG_CHARS),original_length:t.length}}catch{}return e}failFsReadRequest(e,t){const r=this.clearFsReadRequest(e);r&&this.invokeReadHandlerError(r.handler,this.toCardFsErrorPayload(t))}clearFsWriteRequest(e){const t=this.fsWriteRequests.get(e);if(t)return t.progressTimeout&&clearTimeout(t.progressTimeout),this.fsWriteRequests.delete(e),t}failFsWriteRequest(e,t){const r=this.clearFsWriteRequest(e);r&&r.reject(this.toCardFsErrorPayload(t))}handleFsWriteSuccess(e,t){const r=this.clearFsWriteRequest(e);if(!r)return;const{messageId:s,...a}=t||{};r.resolve(a)}createCardFsError(e,t){const r=new Error(e?.message||t),s=e?.error_code;return s&&Object.values(E).includes(s)&&(r.code=s),r}toCardFsErrorPayload(e,t="Unknown cardFS error"){const r="string"==typeof e?.message?e.message:"string"==typeof e?e:t,s=e?.code??e?.error_code;return s&&Object.values(E).includes(s)?{code:s,message:r}:{message:r}}async cardFSReadFallback(e,t,r,s=!0){if(!this.shouldUseCardFsFallback())throw new Error("cardFS.read fallback is disabled because parent supports card_fs");const a=this.getCardIuid();if(!a)throw new Error("cardFS.read fallback failed: card not initialized");const i=this.ensureCardFsCache();let n=null;const o=e.name?`"${e.name}"`:e.iuid?`iuid ${e.iuid}`:"document",d=(s,a,i,o,d,c)=>{if(!s)return null;const l=d??e.name??s?.name??e.iuid??"document",u=c??s?.iuid??e.iuid??null,{value:h}=this.sanitizeReadData(a,l),f={name:l,iuid:u,object:s,data:h,is_dirty:!i,is_stale:i,is_complete:o};return t&&this.fsReadRequests.has(t)?this.handleFsReadDataMessage(t,f):this.invokeReadHandlerNext(r,f),n||(n=f),f};let c=null;if(i)try{if(s){let t=null;e.iuid&&(t=await i.getByIuid(e.iuid)),!t&&e.name&&(t=await i.getByName(e.name)),t?.object&&(c=d(t.object,t.data,!0,!1,t.object?.name??e.name,t.iuid))}}catch(e){console.warn("cardFS.read cache lookup failed",e)}try{const t=await this.fetchDocumentPayload(a,e);t?(await(i?.cacheDocument(t.object,t.data)),d(t.object,t.data,!1,!0,t.object?.name,t.object?.iuid)):s&&c&&d(c.object,c.data,!0,!0,c.name,c.iuid??void 0)}catch(e){if(!n){throw e instanceof Error?e:new Error(String(e))}console.warn("cardFS.read fresh fetch failed",e),s&&c&&d(c.object,c.data,!0,!0,c.name,c.iuid??void 0)}if(!n)throw new Error(`cardFS.read fallback could not locate ${o}`)}async cardFSWriteFallback(e,t,r){if(!this.shouldUseCardFsFallback())throw new Error("cardFS.write fallback is disabled because parent supports card_fs");const s=this.getCardIuid();if(!s)throw new Error("cardFS.write fallback failed: card not initialized");await this.upsertDocumentViaApi(s,e,t);const a=await this.fetchDocumentPayload(s,e);await(this.ensureCardFsCache()?.cacheDocument(a.object,a.data));const i={name:a.object?.name??e.name??null,iuid:a.object?.iuid??e.iuid??null,object:a.object,data:a.data};return r&&this.fsWriteRequests.has(r)&&this.handleFsWriteSuccess(r,i),i}async cardFSDeleteFallback(e){if(!this.shouldUseCardFsFallback())throw new Error("cardFS.delete fallback is disabled because parent supports card_fs");const t=this.getCardIuid();if(!t)throw new Error("cardFS.delete fallback failed: card not initialized");const r=this.ensureCardFsCache(),s=await this.fetchDocumentMetadataByTarget(t,e).catch((()=>null)),a=s?.iuid??e.iuid??null,i=s?.name??e.name??null;if(!a)return e.name&&await(r?.deleteByName(e.name)),{name:i,iuid:null,deleted:!1};const n=await fetch(`/api/v1/documents/${a}/`,{method:"DELETE",headers:this.authHeader()});if(!n.ok&&404!==n.status){const e=await n.text().catch((()=>"delete failed"));throw new Error(`cardFS.delete fallback failed: ${e}`)}await(r?.deleteByIuid(a,i??void 0));return{name:i??a,iuid:a,deleted:404!==n.status}}async cardFSListFallback(e){if(!this.shouldUseCardFsFallback())throw new Error("cardFS.list fallback is disabled because parent supports card_fs");const t=this.getCardIuid();if(!t)throw new Error("cardFS.list fallback failed: card not initialized");const r=this.ensureCardFsCache(),s=this.formatFolderPath(e),a=s??"/";try{const e=await this.fetchFolderListing(t,s);return r&&(await r.cacheFolderListing(s,{folder_name:e.folder_name??a,folder_iuid:e.folder_iuid,last_index:e.last_index??null,last_page:e.last_page??null,documents:e.documents}),await Promise.all(e.documents.map((e=>r.cacheDocument(e,void 0))))),{documents:e.documents,folder_name:e.folder_name??a,folder_iuid:e.folder_iuid,last_index:e.last_index??null,last_page:e.last_page??null,is_dirty:!0,is_complete:!0}}catch(e){const t=await(r?.getFolderListing(s));if(t)return{documents:t.documents??[],folder_name:t.folder_name??a,folder_iuid:t.folder_iuid??void 0,last_index:t.last_index??null,last_page:t.last_page??null,from_cache:!0,is_dirty:!0,is_complete:!0};throw e}}authHeader(){return this.accessToken?{Authorization:`Bearer ${this.accessToken}`}:{}}async fetchDocumentMetadataByTarget(e,t){return t.iuid?this.fetchDocumentMetadataByIuid(t.iuid):t.name?this.fetchDocumentMetadataByName(e,t.name):null}async fetchDocumentMetadataByIuid(e){const t=await fetch(`/api/v1/documents/${e}/`,{method:"GET",headers:this.authHeader()});if(404===t.status)return null;if(!t.ok){const e=await t.text().catch((()=>"metadata lookup failed"));throw new Error(`cardFS metadata fetch failed: ${e}`)}return t.json().catch((()=>null))}normalizeDocumentsResponse(e){return Array.isArray(e?.results)?e.results:Array.isArray(e)?e:e?[e]:[]}normalizeListResult(e){const t=Array.isArray(e?.documents)?e.documents:[],r=Boolean(e?.from_cache??e?.is_stale),s="boolean"==typeof e?.is_complete?e.is_complete:!r,a="boolean"!=typeof e?.is_dirty||e.is_dirty;return{...e,documents:t,is_stale:r,is_complete:s,is_dirty:a}}async fetchDocumentMetadataByName(e,t){if(!t)return null;const r=await fetch(`/api/v1/documents/with_card/${e}/?name=${encodeURIComponent(t)}`,{method:"GET",headers:this.authHeader()});if(!r.ok){if(404===r.status)return null;const e=await r.text().catch((()=>"metadata lookup failed"));throw new Error(`cardFS metadata fetch failed: ${e}`)}const s=await r.json().catch((()=>null)),a=this.normalizeDocumentsResponse(s);return a.find((e=>e?.name===t))??a[0]??null}async fetchFolderListing(e,t){const r=t?`?name=${encodeURIComponent(t)}`:"",s=await fetch(`/api/v1/documents/with_card/${e}/${r}`,{method:"GET",headers:this.authHeader()});if(!s.ok){const e=await s.text().catch((()=>"list failed"));throw new Error(`cardFS.list failed: ${e}`)}const a=await s.json().catch((()=>null));return{documents:this.normalizeDocumentsResponse(a),folder_name:t,folder_iuid:void 0,last_index:a?.last_index??a?.last_page??null,last_page:a?.last_page??null}}async fetchDocumentPayload(e,t){const r="string"==typeof t?{name:t}:t,s=await this.fetchDocumentMetadataByTarget(e,r);if(!s){const e=r.name?`"${r.name}"`:r.iuid?`iuid ${r.iuid}`:"document";throw new Error(`cardFS document not found: ${e}`)}return{object:s,data:await this.fetchDocumentData(s)}}async fetchDocumentData(e){if(void 0!==e?.data)return e.data;const t=e?.orig?.url||e?.url?.original||e?.url;if(!t||"string"!=typeof t)return null;const r=await fetch(t);if(!r.ok){const e=await r.text().catch((()=>"download failed"));throw new Error(`cardFS data fetch failed: ${e}`)}const s=r.headers.get("Content-Type")||"";return s.includes("application/json")?r.json():s.startsWith("text/")?r.text():r.arrayBuffer()}async buildFileFormData(e,t){let r;const s=e=>{if(e instanceof ArrayBuffer)return new Blob([e.slice(0)],{type:"application/octet-stream"});if("undefined"!=typeof SharedArrayBuffer&&e instanceof SharedArrayBuffer){const t=new Uint8Array(e),r=new Uint8Array(t.length);return r.set(t),new Blob([r.buffer],{type:"application/octet-stream"})}if(ArrayBuffer.isView(e)){const t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),r=new Uint8Array(t.length);return r.set(t),new Blob([r.buffer],{type:"application/octet-stream"})}const t=new Uint8Array(e),r=new Uint8Array(t.length);return r.set(t),new Blob([r.buffer],{type:"application/octet-stream"})};if(t instanceof File)r=t;else if("undefined"!=typeof Blob&&t instanceof Blob)r=new File([t],e,{type:t.type||"application/octet-stream"});else if("undefined"!=typeof SharedArrayBuffer&&t instanceof SharedArrayBuffer){const a=s(t);r=new File([a],e,{type:a.type})}else if(t instanceof ArrayBuffer){const a=s(t);r=new File([a],e,{type:a.type})}else if(ArrayBuffer.isView(t)){const a=s(t);r=new File([a],e,{type:a.type})}else if("string"==typeof t){const s=new Blob([t],{type:"text/plain"});r=new File([s],e,{type:s.type})}else{const s=JSON.stringify(t??{}),a=new Blob([s],{type:"application/json"});r=new File([a],e,{type:a.type})}const a=new FormData;return a.append("file",r),a}async upsertDocumentViaApi(e,t,r){const s=await this.buildFileFormData(t.name??t.iuid??"document",r);if(t.iuid){const e=await fetch(`/api/v1/documents/${t.iuid}/`,{method:"PUT",headers:this.authHeader(),body:s});if(!e.ok){const t=await e.text().catch((()=>"update failed"));throw new Error(`cardFS.write update failed: ${t}`)}return}const a=t.name?await this.fetchDocumentMetadataByName(e,t.name).catch((()=>null)):null;if(a?.iuid){const e=await fetch(`/api/v1/documents/${a.iuid}/`,{method:"PUT",headers:this.authHeader(),body:s});if(!e.ok){const t=await e.text().catch((()=>"update failed"));throw new Error(`cardFS.write update failed: ${t}`)}return}if(s.append("parent_iuid",e),s.append("attached_to_iuid",e),!t.name)throw new Error('cardFS.write failed: "name" missing');s.append("filename",t.name);const i=await fetch("/api/v1/documents/",{method:"POST",headers:this.authHeader(),body:s});if(!i.ok){const e=await i.text().catch((()=>"upload failed"));throw new Error(`cardFS.write upload failed: ${e}`)}}formatErrorMessage(e){if("string"==typeof e&&e.trim())return e;if(e instanceof Error)return e.message||e.toString();if(e&&"object"==typeof e){if("string"==typeof e.message)return e.message;try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}}return null!=e?String(e):"Unknown error"}sendEventError(e,t,r=void 0){const s={message:this.formatErrorMessage(t),error_code:e,data:r??null};this.handler&&this.safeInvoke("onError",this.handler,s)}setFileDirty(e){this.sendMessage(c.FILE_DIRTY,e)}getUsername(e){const t=e?.name;return t&&Object.values(t).some((e=>e))?h(t):""}attachUserFullName(e){return e&&"object"==typeof e?{...e,getFullName(){return h(this?.name)}}:e}}return w.FS_RESPONSE_TIMEOUT_MS=3e4,w.FS_READ_RETENTION_MS=15e3,w.CARD_FS_ACK_TIMEOUT_MS=15e3,w.MAX_CONSOLE_ARG_CHARS=1e3,w.MAX_CONSOLE_LOG_ENTRIES=100,w.DEFAULT_ROLE_PERMISSIONS="r",t})()));
|
|
2
2
|
//# sourceMappingURL=index.js.map
|