{"version":3,"mappings":"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","names":["isPublicShare","loadState","getSharingToken","logger","args","callMobileMessage","messageName","attributes","message","attributesString","App","lazy","__vitePreload","n","ReadOnlyViewer","normalizeVersionSource","source","resolved","matchesComparisonRequest","versionSource","fileVersion","compareInfo","normalizedSource","compareSource","compareVersion","shouldRenderComparison","props","context","renderWhiteboardView","rootElement","root","createRoot","isComparisonView","componentProps","comparisonMode","ComponentToRender","React","StrictMode","Suspense","linkTo","VIEWER_REGISTRATION_ATTEMPTS","VIEWER_REGISTRATION_DELAY_MS","bootstrapWhiteboardRuntime","runtime","detectRuntime","runRecordingRuntime","runPublicShareRuntime","runDirectEditingRuntime","runDefaultViewerRuntime","fileId","normalizeNumericState","collabBackendUrl","runWhenDomReady","primeRecordingJwt","whiteboardElement","createWhiteboardElement","viewerContext","hasOpenedInViewer","isWhiteboardPublicShare","mimetypeElmt","ensurePublicShareLayout","openInViewer","viewerApi","getViewerApi","error","openEmbeddedFallback","previewHost","registerViewerHandler","createWhiteboardComponent","unmountWhiteboardRoot","component","options","createElement","isVue2Render","renderElement","h","attrs","event","normalizedFileId","isEmbedded","rawVersionSource","rawFileVersion","isVersionsDavSource","shouldUseVersionPreview","fileName","generateWhiteboardElementId","attempt","afterRegister","callback","handler","jwt","useJWTStore","payload","state","value","normalized","id","element"],"ignoreList":[0],"sources":["../node_modules/@nextcloud/sharing/dist/public.js","../src/utils/logger.ts","../src/utils/mobileInterface.ts","../src/utils/renderWhiteboardView.tsx","../src/main.ts"],"sourcesContent":["/*!\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n/**\n * @module public\n */\nimport { loadState } from '@nextcloud/initial-state';\n/**\n * Check if the current page is on a public share\n */\nexport function isPublicShare() {\n    // check both the new initial state version and fallback to legacy input\n    return (loadState('files_sharing', 'isPublic', null)\n        ?? document.querySelector('input#isPublic[type=\"hidden\"][name=\"isPublic\"][value=\"1\"]') !== null);\n}\n/**\n * Get the sharing token for the current public share\n */\nexport function getSharingToken() {\n    return (loadState('files_sharing', 'sharingToken', null)\n        ?? document.querySelector('input#sharingToken[type=\"hidden\"]')?.value\n        ?? null);\n}\n","/**\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\n/* eslint-disable no-console */\n\n/**\n * Centralized logging utility for Nextcloud Whiteboard\n * Only logs in development mode to avoid performance impact and noise in production\n */\n\nconst isDevelopment = process.env.NODE_ENV === 'development' || import.meta.env?.DEV === true\n\ntype LogArgs = unknown[]\n\nconst logger = {\n\t/**\n\t * Log debug information - only in development\n\t * @param {unknown[]} args - Arguments to log\n\t */\n\tdebug: (...args: LogArgs) => {\n\t\tif (isDevelopment) {\n\t\t\tconsole.log(...args)\n\t\t}\n\t},\n\n\t/**\n\t * Log warnings - always enabled as they indicate potential issues\n\t * @param {unknown[]} args - Arguments to log\n\t */\n\twarn: (...args: LogArgs) => {\n\t\tconsole.warn(...args)\n\t},\n\n\t/**\n\t * Log errors - always enabled as they need to be tracked\n\t * @param {unknown[]} args - Arguments to log\n\t */\n\terror: (...args: LogArgs) => {\n\t\tconsole.error(...args)\n\t},\n\n\t/**\n\t * Log info - only in development\n\t * @param {unknown[]} args - Arguments to log\n\t */\n\tinfo: (...args: LogArgs) => {\n\t\tif (isDevelopment) {\n\t\t\tconsole.info(...args)\n\t\t}\n\t},\n\n\t/**\n\t * Silent no-op function for completely removing logs\n\t */\n\tnoop: () => {},\n}\n\nexport default logger\n","/**\n * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\ndeclare global {\n\tinterface Window {\n\t\tDirectEditingMobileInterface?: {\n\t\t\t[key: string]: (arg?: string) => void\n\t\t}\n\t\twebkit?: {\n\t\t\tmessageHandlers?: {\n\t\t\t\tDirectEditingMobileInterface?: {\n\t\t\t\t\tpostMessage: (message: unknown) => void\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function callMobileMessage(messageName: string, attributes?: unknown): void {\n\tlet message: unknown = messageName\n\tif (typeof attributes !== 'undefined') {\n\t\tmessage = {\n\t\t\tMessageName: messageName,\n\t\t\tValues: attributes,\n\t\t}\n\t}\n\n\tlet attributesString: string | null = null\n\ttry {\n\t\tattributesString = JSON.stringify(attributes)\n\t} catch {\n\t\tattributesString = null\n\t}\n\n\tif (window.DirectEditingMobileInterface\n\t\t&& typeof window.DirectEditingMobileInterface[messageName] === 'function') {\n\t\tif (attributesString === null || typeof attributesString === 'undefined') {\n\t\t\twindow.DirectEditingMobileInterface[messageName]()\n\t\t} else {\n\t\t\twindow.DirectEditingMobileInterface[messageName](attributesString)\n\t\t}\n\t}\n\n\tif (window.webkit?.messageHandlers?.DirectEditingMobileInterface) {\n\t\twindow.webkit.messageHandlers.DirectEditingMobileInterface.postMessage(message)\n\t}\n\n\twindow.postMessage(message)\n}\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { StrictMode, Suspense, lazy } from 'react'\nimport { createRoot } from 'react-dom'\n\nimport type { WhiteboardAppProps } from '../App'\n\nconst App = lazy(() => import('../App'))\nconst ReadOnlyViewer = lazy(() => import('../components/ReadOnlyViewer'))\n\ntype ViewerFileInfo = {\n    source?: string\n    fileVersion?: string | null\n}\n\ntype ComparisonMatchContext = {\n    isViewerContext: boolean\n}\n\nconst normalizeVersionSource = (source: string | null): string | null => {\n\tif (!source) {\n\t\treturn null\n\t}\n\ttry {\n\t\tconst resolved = new URL(source, window.location.origin)\n\t\treturn resolved.pathname + resolved.search\n\t} catch {\n\t\treturn source\n\t}\n}\n\nexport const matchesComparisonRequest = (versionSource: string | null, fileVersion: string | null): boolean => {\n\tconst compareInfo = window?.OCA?.Viewer?.compareFileInfo as ViewerFileInfo | undefined\n\tif (!compareInfo || typeof compareInfo !== 'object') {\n\t\treturn false\n\t}\n\n\tconst normalizedSource = normalizeVersionSource(versionSource)\n\tconst compareSource = normalizeVersionSource(compareInfo.source ?? null)\n\tif (normalizedSource && compareSource && normalizedSource === compareSource) {\n\t\treturn true\n\t}\n\n\tconst compareVersion = compareInfo.fileVersion ?? null\n\tif (\n\t\tfileVersion\n        && compareVersion\n        && String(compareVersion) === String(fileVersion)\n\t) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nexport type RenderWhiteboardViewOptions = WhiteboardAppProps & {\n    isComparisonView?: boolean\n}\n\nexport type WhiteboardRootHandle = {\n    unmount: () => void\n}\n\nconst shouldRenderComparison = (\n\tprops: Pick<RenderWhiteboardViewOptions, 'isComparisonView' | 'versionSource' | 'fileVersion'>,\n\tcontext: ComparisonMatchContext,\n): boolean => {\n\tif (props.isComparisonView) {\n\t\treturn true\n\t}\n\tif (!context.isViewerContext) {\n\t\treturn false\n\t}\n\treturn matchesComparisonRequest(props.versionSource, props.fileVersion ?? null)\n}\n\nexport const renderWhiteboardView = (rootElement: HTMLElement, props: RenderWhiteboardViewOptions): WhiteboardRootHandle => {\n\tconst root = createRoot(rootElement)\n\tconst { isComparisonView, ...componentProps } = props\n\n\tconst comparisonMode = shouldRenderComparison(\n\t\t{\n\t\t\tisComparisonView,\n\t\t\tversionSource: componentProps.versionSource,\n\t\t\tfileVersion: componentProps.fileVersion ?? null,\n\t\t},\n\t\t{ isViewerContext: Boolean(rootElement.closest('.viewer__content')) },\n\t)\n\n\tconst ComponentToRender = (componentProps.isEmbedded || comparisonMode)\n\t\t? ReadOnlyViewer\n\t\t: App\n\n\troot.render(\n\t\t<StrictMode>\n\t\t\t<Suspense fallback={<div>Loading…</div>}>\n\t\t\t\t<ComponentToRender {...componentProps as WhiteboardAppProps} />\n\t\t\t</Suspense>\n\t\t</StrictMode>,\n\t)\n\n\treturn {\n\t\tunmount: () => root.unmount(),\n\t}\n}\n\ndeclare global {\n    interface Window {\n        OCA?: {\n            Viewer?: {\n                compareFileInfo?: ViewerFileInfo\n            }\n        }\n    }\n}\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { WhiteboardRootHandle } from './utils/renderWhiteboardView'\n\nimport { loadState } from '@nextcloud/initial-state'\nimport { linkTo } from '@nextcloud/router'\nimport { getSharingToken, isPublicShare } from '@nextcloud/sharing/public'\nimport { h } from 'vue'\nimport logger from './utils/logger'\nimport { callMobileMessage } from './utils/mobileInterface'\nimport {\n\tmatchesComparisonRequest,\n\trenderWhiteboardView,\n} from './utils/renderWhiteboardView'\n\nimport './styles/index.scss'\nimport '@nextcloud/dialogs/style.css'\n\ndeclare global {\n\tinterface Window {\n\t\tEXCALIDRAW_ASSET_PATH?: string | string[]\n\t}\n}\n\nwindow.EXCALIDRAW_ASSET_PATH = linkTo('whiteboard', 'dist/')\n\ntype RecordingContext = {\n\tfileId: number\n\tcollabBackendUrl: string\n\tjwt: string\n}\n\ntype PublicShareContext = {\n\tfileId: number\n\tcollabBackendUrl: string\n\tsharingToken: string | null\n}\n\ntype DirectEditingContext = {\n\tfileId: number\n\tcollabBackendUrl: string\n\tjwt: string\n}\n\ntype ViewerContext = {\n\tcollabBackendUrl: string\n\tresolveSharingToken: () => string | null\n}\n\ntype RuntimeDescriptor\n\t= | { type: 'recording', context: RecordingContext }\n\t\t| { type: 'public-share', context: PublicShareContext }\n\t\t| { type: 'direct-editing', context: DirectEditingContext }\n\t\t| { type: 'viewer', context: ViewerContext }\n\nconst VIEWER_REGISTRATION_ATTEMPTS = 3\nconst VIEWER_REGISTRATION_DELAY_MS = 250\n\nfunction bootstrapWhiteboardRuntime(): void {\n\tconst runtime = detectRuntime()\n\n\tswitch (runtime.type) {\n\t\tcase 'recording':\n\t\t\trunRecordingRuntime(runtime.context)\n\t\t\treturn\n\t\tcase 'public-share':\n\t\t\trunPublicShareRuntime(runtime.context)\n\t\t\treturn\n\t\tcase 'direct-editing':\n\t\t\trunDirectEditingRuntime(runtime.context)\n\t\t\treturn\n\t\tcase 'viewer':\n\t\tdefault:\n\t\t\trunDefaultViewerRuntime(runtime.context)\n\t}\n}\n\nfunction detectRuntime(): RuntimeDescriptor {\n\tconst fileId = normalizeNumericState(loadState('whiteboard', 'file_id', '0'))\n\tconst collabBackendUrl = loadState('whiteboard', 'collabBackendUrl', '')\n\n\tif (loadState('whiteboard', 'isRecording', false)) {\n\t\treturn {\n\t\t\ttype: 'recording',\n\t\t\tcontext: {\n\t\t\t\tfileId,\n\t\t\t\tcollabBackendUrl,\n\t\t\t\tjwt: loadState('whiteboard', 'jwt', ''),\n\t\t\t},\n\t\t}\n\t}\n\n\tif (loadState('whiteboard', 'directEditing', false)) {\n\t\treturn {\n\t\t\ttype: 'direct-editing',\n\t\t\tcontext: {\n\t\t\t\tfileId,\n\t\t\t\tcollabBackendUrl,\n\t\t\t\tjwt: loadState('whiteboard', 'jwt', ''),\n\t\t\t},\n\t\t}\n\t}\n\n\tif (isPublicShare()) {\n\t\treturn {\n\t\t\ttype: 'public-share',\n\t\t\tcontext: {\n\t\t\t\tfileId,\n\t\t\t\tcollabBackendUrl,\n\t\t\t\tsharingToken: getSharingToken(),\n\t\t\t},\n\t\t}\n\t}\n\n\treturn {\n\t\ttype: 'viewer',\n\t\tcontext: {\n\t\t\tcollabBackendUrl,\n\t\t\tresolveSharingToken: () => getSharingToken(),\n\t\t},\n\t}\n}\n\nfunction runRecordingRuntime(context: RecordingContext): void {\n\trunWhenDomReady(async () => {\n\t\tawait primeRecordingJwt(context.fileId, context.jwt)\n\n\t\tdocument.body.removeAttribute('id')\n\t\tdocument.body.innerHTML = ''\n\t\tconst whiteboardElement = createWhiteboardElement()\n\t\twhiteboardElement.classList.add('recording')\n\t\tdocument.body.appendChild(whiteboardElement)\n\n\t\trenderWhiteboardView(whiteboardElement, {\n\t\t\tfileId: context.fileId,\n\t\t\tisEmbedded: false,\n\t\t\tfileName: '',\n\t\t\tpublicSharingToken: null,\n\t\t\tcollabBackendUrl: context.collabBackendUrl,\n\t\t\tversionSource: null,\n\t\t\tfileVersion: null,\n\t\t})\n\t})\n}\n\nfunction runDirectEditingRuntime(context: DirectEditingContext): void {\n\trunWhenDomReady(async () => {\n\t\tawait primeRecordingJwt(context.fileId, context.jwt)\n\n\t\tconst whiteboardElement = document.getElementById('whiteboard-app')\n\t\tif (!whiteboardElement) {\n\t\t\tlogger.error('Direct editing mount element not found')\n\t\t\treturn\n\t\t}\n\n\t\tcallMobileMessage('loading')\n\n\t\trenderWhiteboardView(whiteboardElement, {\n\t\t\tfileId: context.fileId,\n\t\t\tisEmbedded: false,\n\t\t\tfileName: '',\n\t\t\tpublicSharingToken: null,\n\t\t\tcollabBackendUrl: context.collabBackendUrl,\n\t\t\tversionSource: null,\n\t\t\tfileVersion: null,\n\t\t})\n\t})\n}\n\nfunction runPublicShareRuntime(context: PublicShareContext): void {\n\tconst viewerContext: ViewerContext = {\n\t\tcollabBackendUrl: context.collabBackendUrl,\n\t\tresolveSharingToken: () => context.sharingToken,\n\t}\n\n\tlet hasOpenedInViewer = false\n\tconst isWhiteboardPublicShare = (): boolean => {\n\t\t// LoadViewer triggers whiteboard-main on all public shares; only continue if\n\t\t// this share was explicitly marked as a whiteboard file by the backend.\n\t\tif (!context.fileId) {\n\t\t\treturn false\n\t\t}\n\n\t\t// On NC29/30, there's a hidden input with id=\"mimetype\" that we can check.\n\t\t// On NC31+, this element doesn't exist, so we rely on the backend-provided\n\t\t// whiteboard file id check above.\n\t\tconst mimetypeElmt = document.getElementById('mimetype') as HTMLInputElement | null\n\t\tif (mimetypeElmt && mimetypeElmt.value !== 'application/vnd.excalidraw+json') {\n\t\t\treturn false\n\t\t}\n\n\t\treturn true\n\t}\n\n\tconst ensurePublicShareLayout = (): void => {\n\t\tdocument.body.classList.add('whiteboard-public-share')\n\t}\n\n\tconst openInViewer = (): void => {\n\t\tif (!isWhiteboardPublicShare()) {\n\t\t\thasOpenedInViewer = true\n\t\t\treturn\n\t\t}\n\n\t\tif (hasOpenedInViewer) {\n\t\t\treturn\n\t\t}\n\n\t\tensurePublicShareLayout()\n\n\t\tconst viewerApi = getViewerApi()\n\t\tif (!viewerApi) {\n\t\t\treturn\n\t\t}\n\n\t\tif (typeof viewerApi.openWith !== 'function' && typeof viewerApi.open !== 'function') {\n\t\t\treturn\n\t\t}\n\n\t\thasOpenedInViewer = true\n\n\t\ttry {\n\t\t\tviewerApi.setRootElement?.(null)\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\n\t\ttry {\n\t\t\tif (typeof viewerApi.openWith === 'function') {\n\t\t\t\tviewerApi.openWith('whiteboard', { path: '/', enableSidebar: false, canLoop: false })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tviewerApi.open?.({ path: '/', enableSidebar: false, canLoop: false })\n\t\t} catch (error) {\n\t\t\thasOpenedInViewer = false\n\t\t\tlogger.error('Could not open public share in viewer', { error })\n\t\t}\n\t}\n\n\tconst openEmbeddedFallback = (): void => {\n\t\tif (hasOpenedInViewer) {\n\t\t\treturn\n\t\t}\n\n\t\tif (!isWhiteboardPublicShare()) {\n\t\t\treturn\n\t\t}\n\n\t\tconst previewHost = document.getElementById('preview') || document.getElementById('imgframe')\n\t\tif (!previewHost) {\n\t\t\treturn\n\t\t}\n\n\t\tensurePublicShareLayout()\n\n\t\tpreviewHost.innerHTML = ''\n\n\t\tconst whiteboardElement = createWhiteboardElement()\n\t\tpreviewHost.appendChild(whiteboardElement)\n\n\t\trenderWhiteboardView(whiteboardElement, {\n\t\t\tfileId: context.fileId,\n\t\t\tisEmbedded: false,\n\t\t\tfileName: document.title,\n\t\t\tpublicSharingToken: context.sharingToken,\n\t\t\tcollabBackendUrl: context.collabBackendUrl,\n\t\t\tversionSource: null,\n\t\t\tfileVersion: null,\n\t\t})\n\t}\n\n\trunWhenDomReady(() => {\n\t\tregisterViewerHandler(createWhiteboardComponent(viewerContext), 0, openInViewer)\n\n\t\twindow.setTimeout(() => {\n\t\t\topenEmbeddedFallback()\n\t\t}, 2500)\n\t})\n}\n\nfunction runDefaultViewerRuntime(context: ViewerContext): void {\n\trunWhenDomReady(() => {\n\t\tregisterViewerHandler(createWhiteboardComponent(context))\n\t})\n}\n\ntype ViewerComponentOptions = {\n\tcollabBackendUrl: string\n\tresolveSharingToken: () => string | null\n}\n\ntype WhiteboardComponentData = {\n\tcontainerId: string\n\troot: WhiteboardRootHandle | null\n}\n\ntype LegacyCreateElement = (\n\ttag: string,\n\tdata?: Record<string, unknown>,\n\tchildren?: string,\n) => unknown\n\ntype WhiteboardComponentInstance = WhiteboardComponentData & {\n\t$el?: Element\n\t$emit: (event: string, ...args: unknown[]) => void\n\tfileid?: number | null\n\tfileId?: number | null\n\tfileVersion?: string | null\n\tsource?: string | null\n\tisEmbedded?: boolean\n\tisComparisonView?: boolean\n\tbasename?: string\n}\n\ntype ViewerComponentDefinition = {\n\tname: string\n\trender(this: WhiteboardComponentInstance, createElement?: LegacyCreateElement): unknown\n\tmounted(this: WhiteboardComponentInstance): void\n\tbeforeDestroy(this: WhiteboardComponentInstance): void\n\tbeforeUnmount(this: WhiteboardComponentInstance): void\n\tprops: Record<string, unknown>\n\tdata: () => WhiteboardComponentData\n}\n\ntype ViewerHandlerRegistration = {\n\tid: string\n\tmimes: string[]\n\tcomponent: ViewerComponentDefinition\n\tgroup: string | null\n\ttheme: string\n\tcanCompare: boolean\n}\n\ntype ViewerApi = {\n\tregisterHandler?: (handler: ViewerHandlerRegistration) => void\n\topen?: (options?: {\n\t\tpath?: string\n\t\tfileInfo?: unknown\n\t\tlist?: unknown[]\n\t\tenableSidebar?: boolean\n\t\tloadMore?: () => unknown[]\n\t\tcanLoop?: boolean\n\t\tonPrev?: () => void\n\t\tonNext?: () => void\n\t\tonClose?: () => void\n\t}) => void\n\topenWith?: (handlerId: string, options?: {\n\t\tpath?: string\n\t\tfileInfo?: unknown\n\t\tlist?: unknown[]\n\t\tenableSidebar?: boolean\n\t\tloadMore?: () => unknown[]\n\t\tcanLoop?: boolean\n\t\tonPrev?: () => void\n\t\tonNext?: () => void\n\t\tonClose?: () => void\n\t}) => void\n\tsetRootElement?: (el?: string | null) => void\n\tcompareFileInfo?: unknown\n}\n\ntype WindowWithViewer = Window & {\n\tOCA?: {\n\t\tViewer?: ViewerApi\n\t}\n}\n\nfunction unmountWhiteboardRoot(component: WhiteboardComponentInstance): void {\n\tcomponent.root?.unmount()\n\tcomponent.root = null\n}\n\nfunction createWhiteboardComponent(options: ViewerComponentOptions): ViewerComponentDefinition {\n\treturn {\n\t\tname: 'Whiteboard',\n\t\trender(\n\t\t\tthis: WhiteboardComponentInstance,\n\t\t\tcreateElement?: LegacyCreateElement,\n\t\t): unknown {\n\t\t\tconst isVue2Render = typeof createElement === 'function'\n\t\t\tconst renderElement = isVue2Render ? createElement : h\n\t\t\tconst attrs = isVue2Render\n\t\t\t\t? { attrs: { id: this.containerId } }\n\t\t\t\t: { id: this.containerId }\n\n\t\t\treturn renderElement(\n\t\t\t\t'div',\n\t\t\t\t{\n\t\t\t\t\t...attrs,\n\t\t\t\t\tclass: [\n\t\t\t\t\t\t'whiteboard',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t'whiteboard-viewer__embedding': Boolean(this.isEmbedded),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t'',\n\t\t\t)\n\t\t},\n\t\tmounted(this: WhiteboardComponentInstance) {\n\t\t\tthis.$emit('update:loaded', true)\n\n\t\t\tconst rootElement = (this.$el ?? document.getElementById(this.containerId)) as HTMLElement | null\n\t\t\tif (!rootElement) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\trootElement.addEventListener('keydown', (event) => {\n\t\t\t\tif (event.key === 'Escape') {\n\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst normalizedFileId\n\t\t\t\t= Number(this.fileid ?? this.fileId ?? 0) || 0\n\t\t\tconst isComparisonView = Boolean(this.isComparisonView)\n\t\t\tconst isEmbedded = Boolean(this.isEmbedded)\n\t\t\tconst rawVersionSource = this.source ?? null\n\t\t\tconst rawFileVersion = this.fileVersion ?? null\n\t\t\tconst isVersionsDavSource\n\t\t\t\t= rawVersionSource?.includes('/dav/versions/')\n\t\t\t\t\t|| rawVersionSource?.includes('/dav/trashbin/')\n\t\t\t\t\t|| false\n\t\t\tconst shouldUseVersionPreview\n\t\t\t\t= isComparisonView\n\t\t\t\t\t|| (rawFileVersion !== null && isVersionsDavSource)\n\t\t\t\t\t|| matchesComparisonRequest(\n\t\t\t\t\t\trawVersionSource,\n\t\t\t\t\t\trawFileVersion ?? null,\n\t\t\t\t\t)\n\t\t\tconst versionSource = isEmbedded\n\t\t\t\t? rawVersionSource\n\t\t\t\t: shouldUseVersionPreview\n\t\t\t\t\t? rawVersionSource\n\t\t\t\t\t: null\n\t\t\tconst fileVersion = isEmbedded\n\t\t\t\t? rawFileVersion\n\t\t\t\t: shouldUseVersionPreview\n\t\t\t\t\t? rawFileVersion\n\t\t\t\t\t: null\n\t\t\tconst fileName\n\t\t\t\t= typeof this.basename === 'string' ? this.basename : ''\n\n\t\t\tthis.root = renderWhiteboardView(rootElement, {\n\t\t\t\tfileId: normalizedFileId,\n\t\t\t\tisEmbedded,\n\t\t\t\tfileName,\n\t\t\t\tpublicSharingToken: options.resolveSharingToken(),\n\t\t\t\tcollabBackendUrl: options.collabBackendUrl,\n\t\t\t\tversionSource,\n\t\t\t\tfileVersion,\n\t\t\t\tisComparisonView,\n\t\t\t})\n\t\t},\n\t\tbeforeDestroy(this: WhiteboardComponentInstance) {\n\t\t\tunmountWhiteboardRoot(this)\n\t\t},\n\t\tbeforeUnmount(this: WhiteboardComponentInstance) {\n\t\t\tunmountWhiteboardRoot(this)\n\t\t},\n\t\tprops: {\n\t\t\tfilename: { type: String, default: null },\n\t\t\tfileid: { type: Number, default: null },\n\t\t\tfileId: { type: Number, default: null },\n\t\t\tfileVersion: { type: String, default: null },\n\t\t\tsource: { type: String, default: null },\n\t\t\tisEmbedded: { type: Boolean, default: false },\n\t\t\tisComparisonView: { type: Boolean, default: false },\n\t\t},\n\t\tdata: (): WhiteboardComponentData => ({\n\t\t\tcontainerId: generateWhiteboardElementId(),\n\t\t\troot: null,\n\t\t}),\n\t}\n}\n\nfunction registerViewerHandler(component: ViewerComponentDefinition, attempt = 0, afterRegister?: () => void): void {\n\tconst viewerApi = getViewerApi()\n\n\tif (viewerApi?.registerHandler) {\n\t\tviewerApi.registerHandler({\n\t\t\tid: 'whiteboard',\n\t\t\tmimes: ['application/vnd.excalidraw+json'],\n\t\t\tcomponent,\n\t\t\tgroup: null,\n\t\t\ttheme: 'default',\n\t\t\tcanCompare: true,\n\t\t})\n\t\tafterRegister?.()\n\t\treturn\n\t}\n\n\tif (attempt >= VIEWER_REGISTRATION_ATTEMPTS) {\n\t\tlogger.error('Could not register whiteboard handler for viewer')\n\t\treturn\n\t}\n\n\twindow.setTimeout(\n\t\t() => registerViewerHandler(component, attempt + 1, afterRegister),\n\t\tVIEWER_REGISTRATION_DELAY_MS,\n\t)\n}\n\nfunction getViewerApi(): ViewerApi | undefined {\n\treturn (window as WindowWithViewer).OCA?.Viewer\n}\n\nfunction runWhenDomReady(callback: () => void | Promise<void>): void {\n\tif (document.readyState === 'loading') {\n\t\tconst handler = () => {\n\t\t\tdocument.removeEventListener('DOMContentLoaded', handler)\n\t\t\tcallback()\n\t\t}\n\t\tdocument.addEventListener('DOMContentLoaded', handler)\n\t\treturn\n\t}\n\n\tcallback()\n}\n\nasync function primeRecordingJwt(fileId: number, jwt: string): Promise<void> {\n\tif (!jwt) {\n\t\treturn\n\t}\n\n\tconst { useJWTStore } = await import('./stores/useJwtStore')\n\tconst payload = useJWTStore.getState().parseJwt(jwt)\n\n\tif (!payload) {\n\t\treturn\n\t}\n\n\tuseJWTStore.setState((state) => ({\n\t\t...state,\n\t\ttokens: {\n\t\t\t...state.tokens,\n\t\t\t[fileId]: jwt,\n\t\t},\n\t\ttokenExpiries: {\n\t\t\t...state.tokenExpiries,\n\t\t\t[fileId]: payload.exp,\n\t\t},\n\t}))\n}\n\nfunction normalizeNumericState(value: unknown): number {\n\tconst normalized = Number(value)\n\treturn Number.isFinite(normalized) ? normalized : 0\n}\n\nfunction generateWhiteboardElementId() {\n\treturn `whiteboard-${Math.random()\n\t\t.toString(36)\n\t\t.replace(/[^a-z]+/g, '')\n\t\t.substr(2, 10)}`\n}\n\nfunction createWhiteboardElement(id = generateWhiteboardElementId()) {\n\tconst element = document.createElement('div')\n\telement.id = id\n\telement.className = 'whiteboard'\n\treturn element\n}\n\nbootstrapWhiteboardRuntime()\n"],"file":"whiteboard-main.mjs"}