@netless/fastboard 0.0.11 → 0.2.1
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/LICENSE.txt +1 -1
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +7 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +24 -85
- package/src/index.ts +2 -49
- package/README.md +0 -136
- package/dist/index.cjs.js +0 -14
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.es.js +0 -2804
- package/dist/index.es.js.map +0 -1
- package/dist/svelte.cjs.js +0 -2
- package/dist/svelte.cjs.js.map +0 -1
- package/dist/svelte.es.js +0 -32
- package/dist/svelte.es.js.map +0 -1
- package/dist/vue.cjs.js +0 -2
- package/dist/vue.cjs.js.map +0 -1
- package/dist/vue.es.js +0 -43
- package/dist/vue.es.js.map +0 -1
- package/src/WhiteboardApp.ts +0 -146
- package/src/behaviors/register-apps.ts +0 -39
- package/src/behaviors/style.ts +0 -17
- package/src/components/PageControl/PageControl.scss +0 -80
- package/src/components/PageControl/PageControl.tsx +0 -110
- package/src/components/PageControl/hooks.ts +0 -70
- package/src/components/PageControl/index.ts +0 -2
- package/src/components/PlayerControl/PlayerControl.scss +0 -145
- package/src/components/PlayerControl/PlayerControl.tsx +0 -157
- package/src/components/PlayerControl/components/Button.tsx +0 -55
- package/src/components/PlayerControl/hooks.ts +0 -88
- package/src/components/PlayerControl/icons/Loading.tsx +0 -13
- package/src/components/PlayerControl/icons/Pause.tsx +0 -13
- package/src/components/PlayerControl/icons/Play.tsx +0 -13
- package/src/components/PlayerControl/icons/index.ts +0 -10
- package/src/components/PlayerControl/index.ts +0 -2
- package/src/components/RedoUndo/RedoUndo.scss +0 -56
- package/src/components/RedoUndo/RedoUndo.tsx +0 -79
- package/src/components/RedoUndo/hooks.ts +0 -50
- package/src/components/RedoUndo/index.ts +0 -2
- package/src/components/Root.scss +0 -55
- package/src/components/Root.tsx +0 -65
- package/src/components/Toolbar/Content.tsx +0 -94
- package/src/components/Toolbar/Toolbar.scss +0 -281
- package/src/components/Toolbar/Toolbar.tsx +0 -132
- package/src/components/Toolbar/components/ApplianceButtons.tsx +0 -132
- package/src/components/Toolbar/components/AppsButton.tsx +0 -106
- package/src/components/Toolbar/components/Button.tsx +0 -54
- package/src/components/Toolbar/components/ColorBox.tsx +0 -56
- package/src/components/Toolbar/components/CutLine.tsx +0 -8
- package/src/components/Toolbar/components/Mask.tsx +0 -44
- package/src/components/Toolbar/components/PencilButton.tsx +0 -70
- package/src/components/Toolbar/components/ShapesButton.tsx +0 -143
- package/src/components/Toolbar/components/Slider.tsx +0 -27
- package/src/components/Toolbar/components/TextButton.tsx +0 -66
- package/src/components/Toolbar/components/UpDownButtons.tsx +0 -49
- package/src/components/Toolbar/components/assets/cocos.png +0 -0
- package/src/components/Toolbar/components/assets/collapsed.png +0 -0
- package/src/components/Toolbar/components/assets/countdown.png +0 -0
- package/src/components/Toolbar/components/assets/expanded.png +0 -0
- package/src/components/Toolbar/components/assets/geogebra.png +0 -0
- package/src/components/Toolbar/components/assets/vscode.png +0 -0
- package/src/components/Toolbar/const.ts +0 -32
- package/src/components/Toolbar/hooks.ts +0 -112
- package/src/components/Toolbar/icons/Apps.tsx +0 -16
- package/src/components/Toolbar/icons/Arrow.tsx +0 -16
- package/src/components/Toolbar/icons/Circle.tsx +0 -21
- package/src/components/Toolbar/icons/Clean.tsx +0 -16
- package/src/components/Toolbar/icons/Clicker.tsx +0 -19
- package/src/components/Toolbar/icons/Collapse.tsx +0 -17
- package/src/components/Toolbar/icons/Diamond.tsx +0 -17
- package/src/components/Toolbar/icons/Down.tsx +0 -17
- package/src/components/Toolbar/icons/Eraser.tsx +0 -16
- package/src/components/Toolbar/icons/Expand.tsx +0 -17
- package/src/components/Toolbar/icons/Line.tsx +0 -13
- package/src/components/Toolbar/icons/Pencil.tsx +0 -16
- package/src/components/Toolbar/icons/Rectangle.tsx +0 -13
- package/src/components/Toolbar/icons/Selector.tsx +0 -16
- package/src/components/Toolbar/icons/SpeechBalloon.tsx +0 -17
- package/src/components/Toolbar/icons/Star.tsx +0 -17
- package/src/components/Toolbar/icons/Text.tsx +0 -16
- package/src/components/Toolbar/icons/Triangle.tsx +0 -17
- package/src/components/Toolbar/icons/Up.tsx +0 -17
- package/src/components/Toolbar/icons/index.ts +0 -42
- package/src/components/Toolbar/index.ts +0 -2
- package/src/components/ZoomControl/ZoomControl.scss +0 -80
- package/src/components/ZoomControl/ZoomControl.tsx +0 -109
- package/src/components/ZoomControl/hooks.ts +0 -111
- package/src/components/ZoomControl/index.ts +0 -2
- package/src/components/hooks.ts +0 -80
- package/src/i18n/en.json +0 -31
- package/src/i18n/index.ts +0 -22
- package/src/i18n/zh-CN.json +0 -32
- package/src/icons/ChevronLeft.tsx +0 -21
- package/src/icons/ChevronRight.tsx +0 -21
- package/src/icons/FilePlus.tsx +0 -18
- package/src/icons/Minus.tsx +0 -21
- package/src/icons/Plus.tsx +0 -21
- package/src/icons/Redo.tsx +0 -24
- package/src/icons/Reset.tsx +0 -23
- package/src/icons/Undo.tsx +0 -24
- package/src/icons/index.tsx +0 -11
- package/src/internal/Instance.tsx +0 -275
- package/src/internal/helpers.ts +0 -86
- package/src/internal/hooks.ts +0 -9
- package/src/internal/index.ts +0 -3
- package/src/internal/mount-whiteboard.ts +0 -90
- package/src/react.tsx +0 -52
- package/src/style.scss +0 -35
- package/src/svelte.ts +0 -45
- package/src/theme/index.ts +0 -36
- package/src/types/index.ts +0 -22
- package/src/vue.ts +0 -74
package/dist/index.es.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/behaviors/register-apps.ts","../src/internal/helpers.ts","../src/i18n/index.ts","../src/internal/mount-whiteboard.ts","../src/components/hooks.ts","../src/components/Toolbar/hooks.ts","../node_modules/.pnpm/object-assign@4.1.1/node_modules/object-assign/index.js","../node_modules/.pnpm/react@17.0.2/node_modules/react/cjs/react-jsx-runtime.production.min.js","../node_modules/.pnpm/react@17.0.2/node_modules/react/jsx-runtime.js","../react/jsx-runtime","../src/icons/index.tsx","../src/theme/index.ts","../src/components/Toolbar/icons/Apps.tsx","../src/components/Toolbar/icons/Arrow.tsx","../src/components/Toolbar/icons/Circle.tsx","../src/components/Toolbar/icons/Clean.tsx","../src/components/Toolbar/icons/Clicker.tsx","../src/components/Toolbar/icons/Collapse.tsx","../src/components/Toolbar/icons/Diamond.tsx","../src/components/Toolbar/icons/Down.tsx","../src/components/Toolbar/icons/Eraser.tsx","../src/components/Toolbar/icons/Expand.tsx","../src/components/Toolbar/icons/Line.tsx","../src/components/Toolbar/icons/Pencil.tsx","../src/components/Toolbar/icons/Rectangle.tsx","../src/components/Toolbar/icons/Selector.tsx","../src/components/Toolbar/icons/SpeechBalloon.tsx","../src/components/Toolbar/icons/Star.tsx","../src/components/Toolbar/icons/Text.tsx","../src/components/Toolbar/icons/Triangle.tsx","../src/components/Toolbar/icons/Up.tsx","../src/components/Toolbar/icons/index.ts","../src/components/Toolbar/const.ts","../src/components/Toolbar/components/Button.tsx","../src/components/Toolbar/components/CutLine.tsx","../src/components/Toolbar/components/UpDownButtons.tsx","../src/components/Toolbar/components/ApplianceButtons.tsx","../src/components/Toolbar/components/assets/vscode.png","../src/components/Toolbar/components/assets/geogebra.png","../src/components/Toolbar/components/assets/countdown.png","../src/components/Toolbar/components/AppsButton.tsx","../src/components/Toolbar/components/ColorBox.tsx","../src/components/Toolbar/components/Slider.tsx","../src/components/Toolbar/components/PencilButton.tsx","../src/components/Toolbar/components/TextButton.tsx","../src/components/Toolbar/components/ShapesButton.tsx","../src/components/Toolbar/Content.tsx","../src/components/Toolbar/components/assets/collapsed.png","../src/components/Toolbar/components/assets/expanded.png","../src/components/Toolbar/components/Mask.tsx","../src/components/Toolbar/Toolbar.tsx","../src/components/RedoUndo/hooks.ts","../src/icons/Undo.tsx","../src/icons/Redo.tsx","../src/components/RedoUndo/RedoUndo.tsx","../src/components/ZoomControl/hooks.ts","../src/icons/Minus.tsx","../src/icons/Plus.tsx","../src/icons/Reset.tsx","../src/components/ZoomControl/ZoomControl.tsx","../src/components/PageControl/hooks.ts","../src/icons/FilePlus.tsx","../src/icons/ChevronLeft.tsx","../src/icons/ChevronRight.tsx","../src/components/PageControl/PageControl.tsx","../src/components/Root.tsx","../src/internal/Instance.tsx","../src/behaviors/style.ts","../src/WhiteboardApp.ts","../src/internal/hooks.ts","../src/components/PlayerControl/hooks.ts","../src/components/PlayerControl/components/Button.tsx","../src/components/PlayerControl/icons/Loading.tsx","../src/components/PlayerControl/icons/Pause.tsx","../src/components/PlayerControl/icons/Play.tsx","../src/components/PlayerControl/icons/index.ts","../src/components/PlayerControl/PlayerControl.tsx","../src/react.tsx","../src/index.ts"],"sourcesContent":["import { WindowManager } from \"@netless/window-manager\";\n\nWindowManager.register({\n kind: \"Slide\",\n appOptions: {\n // turn on to show debug controller\n debug: false,\n },\n src: async () => {\n const app = await import(\"@netless/app-slide\");\n return app.default ?? app;\n },\n});\n\nWindowManager.register({\n kind: \"Monaco\",\n src: async () => {\n const app = await import(\"@netless/app-monaco\");\n return app.default ?? app;\n },\n});\nWindowManager.register({\n kind: \"Countdown\",\n src: async () => {\n const app = await import(\"@netless/app-countdown\");\n return app.default ?? app;\n },\n});\nWindowManager.register({\n kind: \"GeoGebra\",\n src: async () => {\n const app = await import(\"@netless/app-geogebra\");\n return app.default ?? app;\n },\n appOptions: {\n HTML5Codebase:\n \"https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d\",\n },\n});\n","import type { SceneDefinition } from \"white-web-sdk\";\n\nexport function noop() {\n return;\n}\n\nexport function applyStyles(css: string) {\n const el = document.createElement(\"style\");\n el.appendChild(document.createTextNode(css));\n document.head.appendChild(el);\n return el;\n}\n\nexport function clamp(value: number, min: number, max: number) {\n return value < min ? min : value > max ? max : value;\n}\n\nexport function isEqualArray<T>(a: T[], b: T[]) {\n return a.length === b.length && a.every((e, i) => e === b[i]);\n}\n\nexport type TaskFn = () => Promise<void> | void;\n\nexport class Lock {\n running = false;\n private nextFn: TaskFn | null = null;\n schedule(fn: TaskFn) {\n if (this.running) {\n this.nextFn = fn;\n } else {\n this.running = true;\n Promise.resolve(fn()).then(this.step);\n }\n }\n private step = () => {\n if (this.nextFn) {\n const fn = this.nextFn;\n this.nextFn = null;\n Promise.resolve(fn()).then(this.step);\n } else {\n this.running = false;\n }\n };\n}\n\n// Copy from https://github.com/crimx/side-effect-manager/blob/main/src/gen-uid.ts\nconst SOUP =\n \"!#%()*+,-./:;=?@[]^_`{|}~\" +\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst SOUP_LEN = SOUP.length;\nconst ID_LEN = 20;\nconst reusedIdCarrier = Array(ID_LEN);\n\nexport const genUID = (): string => {\n for (let i = 0; i < ID_LEN; i++) {\n reusedIdCarrier[i] = SOUP.charAt(Math.random() * SOUP_LEN);\n }\n return reusedIdCarrier.join(\"\");\n};\n\nexport function makeSlideParams(scenes: SceneDefinition[]) {\n const scenesWithoutPPT: SceneDefinition[] = [];\n let taskId = \"\";\n let url = \"\";\n\n // e.g. \"ppt(x)://cdn/prefix/dynamicConvert/{taskId}/1.slide\"\n const pptSrcRE = /^pptx?(?<prefix>:\\/\\/\\S+?dynamicConvert)\\/(?<taskId>\\w+)\\//;\n\n for (const { name, ppt } of scenes) {\n // make sure scenesWithoutPPT.length === scenes.length\n scenesWithoutPPT.push({ name });\n\n if (!ppt || !ppt.src.startsWith(\"ppt\")) {\n continue;\n }\n const match = pptSrcRE.exec(ppt.src);\n if (!match || !match.groups) {\n continue;\n }\n taskId = match.groups.taskId;\n url = \"https\" + match.groups.prefix;\n break;\n }\n\n return { scenesWithoutPPT, taskId, url };\n}\n","import i18next from \"i18next\";\nimport en from \"./en.json\";\nimport zhCN from \"./zh-CN.json\";\n\nexport type CreateI18nParams = {\n language?: string;\n};\n\nexport const createI18n = async (params: CreateI18nParams) => {\n const defaultLang = navigator.language || \"zh-CN\";\n const lng = params.language || defaultLang;\n\n await i18next.init({\n lng,\n resources: {\n en: en,\n \"zh-CN\": zhCN,\n },\n });\n\n return i18next;\n};\n","import type { MountParams } from \"@netless/window-manager\";\nimport type {\n JoinRoomParams,\n RoomCallbacks,\n WhiteWebSdkConfiguration,\n} from \"white-web-sdk\";\nimport type { Essentials, Language } from \"./Instance\";\n\nimport { WindowManager } from \"@netless/window-manager\";\nimport { DefaultHotKeys, WhiteWebSdk } from \"white-web-sdk\";\nimport { createI18n } from \"../i18n\";\n\nexport type SdkConfig = Omit<\n WhiteWebSdkConfiguration,\n \"useMobXState\" | \"disableNewPencil\" | \"disableMagixEventDispatchLimit\"\n>;\nexport type JoinRoom = Omit<\n JoinRoomParams,\n \"useMultiViews\" | \"disableMagixEventDispatchLimit\"\n> & { callbacks?: Partial<RoomCallbacks> };\nexport type ManagerConfig = Omit<MountParams, \"room\">;\n\nfunction ensureWindowManager(joinRoom: JoinRoom) {\n if (\n !joinRoom.invisiblePlugins ||\n !joinRoom.invisiblePlugins.includes(WindowManager)\n ) {\n joinRoom.invisiblePlugins = [\n ...(joinRoom.invisiblePlugins || []),\n WindowManager,\n ];\n }\n}\n\nexport const defaultHotKeys = {\n changeToSelector: \"s\",\n changeToLaserPointer: \"z\",\n changeToPencil: \"p\",\n changeToRectangle: \"r\",\n changeToEllipse: \"c\",\n changeToEraser: \"e\",\n changeToText: \"t\",\n changeToStraight: \"l\",\n changeToArrow: \"a\",\n changeToHand: \"h\",\n};\n\nexport async function mountWhiteboard(\n sdkConfig: SdkConfig,\n joinRoom: JoinRoom,\n managerConfig: ManagerConfig,\n language: Language\n): Promise<Essentials> {\n const sdk = new WhiteWebSdk({\n ...sdkConfig,\n useMobXState: true,\n });\n\n ensureWindowManager(joinRoom);\n joinRoom = { ...joinRoom };\n const callbacks = joinRoom.callbacks;\n delete joinRoom.callbacks;\n const joinRoomParams: JoinRoomParams = {\n floatBar: true,\n hotKeys: {\n ...DefaultHotKeys,\n ...defaultHotKeys,\n },\n ...joinRoom,\n useMultiViews: true,\n disableNewPencil: false,\n disableMagixEventDispatchLimit: true,\n };\n const room = await sdk.joinRoom(joinRoomParams, callbacks);\n\n const manager = await WindowManager.mount({\n cursor: true,\n debug: import.meta.env.DEV,\n ...managerConfig,\n room,\n });\n\n const i18n = await createI18n({ language });\n\n if (import.meta.env.DEV) {\n Object.assign(window, { sdk, room, manager });\n }\n\n return { sdk, room, manager, i18n };\n}\n","import type { Room, WindowManager } from \"@netless/window-manager\";\nimport { BuiltinApps } from \"@netless/window-manager\";\nimport { useEffect, useState } from \"react\";\n\nexport function useWritable(room?: Room | null) {\n const [writable, setWritable] = useState(false);\n\n useEffect(() => {\n if (room) {\n setWritable(room.isWritable);\n room.isWritable && (room.disableSerialization = false);\n\n const updateWritable = () => setWritable(room.isWritable);\n room.callbacks.on(\"onEnableWriteNowChanged\", updateWritable);\n\n return () => {\n room.callbacks.off(\"onEnableWriteNowChanged\", updateWritable);\n };\n }\n }, [room]);\n\n return writable;\n}\n\nexport type BoxState = \"normal\" | \"minimized\" | \"maximized\";\n\nexport function useBoxState(manager?: WindowManager | null) {\n const [boxState, setBoxState] = useState<BoxState | undefined>();\n\n useEffect(() => {\n if (manager) {\n setBoxState(manager.boxState);\n\n manager.emitter.on(\"boxStateChange\", setBoxState);\n\n return () => {\n manager.emitter.off(\"boxStateChange\", setBoxState);\n };\n }\n }, [manager]);\n\n return boxState;\n}\n\nexport function useFocusedApp(manager?: WindowManager | null) {\n const [focused, setFocused] = useState<string | undefined>();\n\n useEffect(() => {\n if (manager) {\n setFocused(manager.focused);\n\n manager.emitter.on(\"focusedChange\", setFocused);\n\n return () => {\n manager.emitter.off(\"focusedChange\", setFocused);\n };\n }\n }, [manager]);\n\n return focused;\n}\n\nexport function useMaximized(manager?: WindowManager | null) {\n return useBoxState(manager) === \"maximized\";\n}\n\nexport function useHideControls(manager?: WindowManager | null) {\n const maximized = useMaximized(manager);\n const focusedApp = useFocusedApp(manager);\n\n if (maximized) {\n if (Object.values(BuiltinApps).some(kind => focusedApp?.includes(kind))) {\n return \"toolbar-only\";\n } else {\n return true;\n }\n }\n\n return false;\n}\n","import type {\n ApplianceNames,\n Color,\n MemberState,\n Room,\n RoomState,\n ShapeType,\n} from \"white-web-sdk\";\nimport type { WindowManager } from \"@netless/window-manager\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport { noop } from \"../../internal\";\nimport { useWritable } from \"../hooks\";\n\nexport function useRoomState(room?: Room | null) {\n const [memberState, setMemberState] = useState<MemberState | undefined>(\n undefined\n );\n\n useEffect(() => {\n if (room) {\n setMemberState(room.state.memberState);\n const onRoomStateChanged = (diff: Partial<RoomState>) => {\n if (diff.memberState) setMemberState(diff.memberState);\n };\n room.callbacks.on(\"onRoomStateChanged\", onRoomStateChanged);\n return () => room.callbacks.off(\"onRoomStateChanged\", onRoomStateChanged);\n }\n }, [room]);\n\n return { memberState };\n}\n\nexport interface ToolbarHook {\n readonly writable: boolean;\n readonly memberState: MemberState | undefined;\n cleanCurrentScene(): void;\n setAppliance(appliance: ApplianceNames, shape?: ShapeType): void;\n setStrokeWidth(width: number): void;\n setStrokeColor(color: Color): void;\n}\n\nexport function useToolbar(\n room?: Room | null,\n manager?: WindowManager | null\n): ToolbarHook {\n const writable = useWritable(room);\n const { memberState } = useRoomState(room);\n\n const cleanCurrentScene = useCallback(() => {\n if (manager) {\n manager.mainView.cleanCurrentScene();\n } else if (room) {\n room.cleanCurrentScene();\n }\n }, [manager, room]);\n\n const setAppliance = useCallback(\n (appliance: ApplianceNames, shape?: ShapeType) => {\n const memberState = {\n currentApplianceName: appliance,\n shapeType: shape,\n };\n if (manager) {\n manager.mainView.setMemberState(memberState);\n } else if (room) {\n room.setMemberState(memberState);\n }\n },\n [manager, room]\n );\n\n const setStrokeWidth = useCallback(\n (strokeWidth: number) => {\n if (manager) {\n manager.mainView.setMemberState({ strokeWidth });\n } else if (room) {\n room.setMemberState({ strokeWidth });\n }\n },\n [manager, room]\n );\n\n const setStrokeColor = useCallback(\n (strokeColor: Color) => {\n if (manager) {\n manager.mainView.setMemberState({ strokeColor });\n } else if (room) {\n room.setMemberState({ strokeColor });\n }\n },\n [manager, room]\n );\n\n return {\n writable,\n memberState,\n cleanCurrentScene,\n setAppliance,\n setStrokeWidth,\n setStrokeColor,\n };\n}\n\nexport const EmptyToolbarHook: ToolbarHook = {\n writable: false,\n memberState: undefined,\n cleanCurrentScene: noop,\n setAppliance: noop,\n setStrokeWidth: noop,\n setStrokeColor: noop,\n};\n","/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n","/** @license React v17.0.2\n * react-jsx-runtime.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';require(\"object-assign\");var f=require(\"react\"),g=60103;exports.Fragment=60107;if(\"function\"===typeof Symbol&&Symbol.for){var h=Symbol.for;g=h(\"react.element\");exports.Fragment=h(\"react.fragment\")}var m=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,n=Object.prototype.hasOwnProperty,p={key:!0,ref:!0,__self:!0,__source:!0};\nfunction q(c,a,k){var b,d={},e=null,l=null;void 0!==k&&(e=\"\"+k);void 0!==a.key&&(e=\"\"+a.key);void 0!==a.ref&&(l=a.ref);for(b in a)n.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:g,type:c,key:e,ref:l,props:d,_owner:m.current}}exports.jsx=q;exports.jsxs=q;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.min.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","import * as jsxRuntime from \"/home/runner/work/fastboard/fastboard/node_modules/react/jsx-runtime.js\"\nexport const jsx = jsxRuntime.jsx\nexport const jsxs = jsxRuntime.jsxs\nexport const Fragment = jsxRuntime.Fragment","import React from \"react\";\n\nexport interface IconPropsWithFallback {\n fallback: React.ReactElement;\n src?: string;\n alt?: string;\n}\n\nexport function Icon({ fallback, src, alt = \"[icon]\" }: IconPropsWithFallback) {\n return src ? <img src={src} alt={alt} title={alt} /> : fallback;\n}\n","import type { IconProps } from \"../types\";\n\nexport interface ThemeConfig {\n color: string;\n activeColor: string;\n backgroundColor: string;\n hoverBackgroundColor: string;\n}\n\nexport const light: ThemeConfig = {\n color: \"#5D5D5D\",\n activeColor: \"#3381FF\",\n backgroundColor: \"#fff\",\n hoverBackgroundColor: \"rgba(51, 129, 255, 0.1)\",\n};\n\nexport const dark: ThemeConfig = {\n ...light,\n color: \"#eee\",\n backgroundColor: \"#111\",\n};\n\nexport const themes = { light, dark };\n\nexport const getStroke = (props: IconProps) => {\n let config;\n if (props.theme) {\n config = themes[props.theme];\n } else {\n config = themes.light;\n }\n return props.active ? config.activeColor : config.color;\n};\n\nexport const TopOffset = [0, 11] as [number, number];\nexport const RightOffset = [0, 11] as [number, number];\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Apps = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <g fill={stroke}>\n <path d=\"M17.667 4.5h-3.334c-1.012 0-1.833.82-1.833 1.833V11.5h5.167c1.012 0 1.833-.82 1.833-1.833V6.333c0-1.012-.82-1.833-1.833-1.833Zm-3.334 1h3.334c.46 0 .833.373.833.833v3.334l-.006.104a.833.833 0 0 1-.827.729H13.5V6.333c0-.46.373-.833.833-.833Z\" />\n <path d=\"M6.333 19.5A1.833 1.833 0 0 1 4.5 17.667v-3.334c0-.525.221-1 .576-1.334a1.822 1.822 0 0 1-.576-1.332V8.333c0-1.012.82-1.833 1.833-1.833H10A1.5 1.5 0 0 1 11.5 8v4.5h4.167c.962 0 1.75.74 1.827 1.683l.006.15v3.334c0 1.012-.82 1.833-1.833 1.833Zm4.167-6H6.333a.833.833 0 0 0-.827.729l-.006.104v3.334c0 .46.373.833.833.833H10.5v-5Zm5.167 0H11.5v5h4.167c.46 0 .833-.373.833-.833v-3.334a.833.833 0 0 0-.833-.833ZM10 7.5H6.333a.833.833 0 0 0-.833.833v3.334c0 .46.373.833.833.833H10.5V8a.5.5 0 0 0-.41-.492L10 7.5Z\" />\n </g>\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Arrow = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill={stroke}\n d=\"M19 5v6l-2.647-2.646L5.99 18.718l-.708-.708L15.645 7.646 13 5h6Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Circle = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <rect\n width=\"15\"\n height=\"15\"\n x=\"4.5\"\n y=\"4.5\"\n fill=\"none\"\n stroke={stroke}\n rx=\"7.5\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Clean = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill={stroke}\n d=\"M9.754 11.99c0 1.856-.711 3.62-1.96 4.951l-.151.155h1.403l.855-.853h.707l.853.853h2.635l.094-.064a6.237 6.237 0 0 0 2.559-4.781l.005-.26h1a7.237 7.237 0 0 1-2.994 5.862l-.229.16-.277.083h-3l-.353-.146-.647-.647-.646.647-.354.146h-3l-.286-.91.214-.148a6.237 6.237 0 0 0 2.567-4.787l.005-.26h1Zm4.772-6.502v2l.35.039a2.98 2.98 0 0 1 2.644 2.78l.006.181h-8a2.98 2.98 0 0 1 2.65-2.961l.35-.039v-2h2Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Clicker = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <g fill=\"none\">\n <path d=\"M0 0h24v24H0z\" />\n <path\n fill={stroke}\n d=\"m7 5.072 10.33 7.892-4.879.549 3.232 5.598-.866.5-3.233-5.597-2.914 3.95L7 5.072Z\"\n />\n </g>\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Collapse = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n d=\"m8 10-2 2 2 2m10-8H6m12 12H6m12-4h-8m8-4h-8\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Diamond = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n d=\"M4.222 12 12 4.222 19.778 12 12 19.778z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Down = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n d=\"m16 13-2 2-2 2-2-2-2-2m8-6-2 2-2 2-2-2-2-2\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Eraser = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill={stroke}\n d=\"m14.333 5.183.165.007c.494.037.978.245 1.356.623l2.333 2.333a2.15 2.15 0 0 1 0 3.04l-5.833 5.834a3.8 3.8 0 0 1-5.374 0l-1.167-1.166a2.15 2.15 0 0 1 0-3.04l7-7c.42-.42.97-.63 1.52-.63ZM11.52 8.52l-4.999 5a1.15 1.15 0 0 0 0 1.626l1.167 1.167a2.8 2.8 0 0 0 3.96 0l3.832-3.833-3.96-3.96Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Expand = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n d=\"m16 10 2 2-2 2M6 6h12M6 18h12M6 14h8m-8-4h8\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Line = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path fill={stroke} d=\"m18.01 5.282.708.708L5.99 18.718l-.708-.708z\" />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Pencil = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill={stroke}\n d=\"m17.497 4.84.116.105 1.442 1.442a1.52 1.52 0 0 1 .104 2.034l-.104.116L8.733 18.858l-4.347.756.756-4.347L15.463 4.945a1.52 1.52 0 0 1 2.034-.104ZM5.967 16.349l-.353 2.037 2.037-.354-1.683-1.683Zm8.407-8.901-7.946 7.946 2.178 2.178 7.946-7.946-2.178-2.178Zm-.728 2.2.708.707-5 5-.708-.708 5-5Zm2.596-4.055-.072.06-1.09 1.088 2.179 2.178 1.089-1.088a.52.52 0 0 0 .105-.584l-.045-.08-.06-.072-1.442-1.442a.52.52 0 0 0-.664-.06Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Rectangle = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path fill=\"none\" stroke={stroke} d=\"M5.5 5.5h13v13h-13z\" />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Selector = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill={stroke}\n d=\"m12 12 8 2.667-3.556 1.777L14.667 20 12 12Zm3-8v7.5h-1V5H5v9h6.5v1H4V4h11Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const SpeechBalloon = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n d=\"M17 4.5c.414 0 .79.168 1.06.44.272.27.44.646.44 1.06v9c0 .414-.168.79-.44 1.06a1.49 1.49 0 0 1-1.06.44h-4.207l-2.715 2.715-1.81-2.715H7a1.49 1.49 0 0 1-1.06-.44A1.495 1.495 0 0 1 5.5 15V6c0-.414.168-.79.44-1.06A1.49 1.49 0 0 1 7 4.5Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Star = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n d=\"m12 3.523 1.993 5.734 6.07.123-4.838 3.668 1.758 5.81L12 15.391l-4.983 3.467 1.758-5.81L3.938 9.38l6.069-.123L12 3.523Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Text = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill={stroke}\n d=\"M18.5 5.5V8h-1V6.5H13v11h2v1H9v-1h2v-11H6.5V8h-1V5.5h13Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Triangle = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n d=\"M12 6.008 19.138 18.5H4.862L12 6.008Z\"\n />\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Up = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n d=\"m16 11-2-2-2-2-2 2-2 2m8 6-2-2-2-2-2 2-2 2\"\n />\n </svg>\n );\n};\n","import { memo } from \"react\";\nimport { Apps } from \"./Apps\";\nimport { Arrow } from \"./Arrow\";\nimport { Circle } from \"./Circle\";\nimport { Clean } from \"./Clean\";\nimport { Clicker } from \"./Clicker\";\nimport { Collapse } from \"./Collapse\";\nimport { Diamond } from \"./Diamond\";\nimport { Down } from \"./Down\";\nimport { Eraser } from \"./Eraser\";\nimport { Expand } from \"./Expand\";\nimport { Line } from \"./Line\";\nimport { Pencil } from \"./Pencil\";\nimport { Rectangle } from \"./Rectangle\";\nimport { Selector } from \"./Selector\";\nimport { SpeechBalloon } from \"./SpeechBalloon\";\nimport { Star } from \"./Star\";\nimport { Text } from \"./Text\";\nimport { Triangle } from \"./Triangle\";\nimport { Up } from \"./Up\";\n\nexport const Icons = {\n Clicker: memo(Clicker),\n Collapse: memo(Collapse),\n Eraser: memo(Eraser),\n Expand: memo(Expand),\n Pencil: memo(Pencil),\n Selector: memo(Selector),\n Rectangle: memo(Rectangle),\n Text: memo(Text),\n Apps: memo(Apps),\n Clean: memo(Clean),\n Circle: memo(Circle),\n Line: memo(Line),\n Arrow: memo(Arrow),\n Star: memo(Star),\n Diamond: memo(Diamond),\n SpeechBalloon: memo(SpeechBalloon),\n Triangle: memo(Triangle),\n Up: memo(Up),\n Down: memo(Down),\n};\n","import { ApplianceNames, ShapeType } from \"white-web-sdk\";\nimport { Icons } from \"./icons\";\n\nexport const ShapesMap = {\n [ApplianceNames.rectangle]: Icons.Rectangle,\n [ApplianceNames.ellipse]: Icons.Circle,\n [ApplianceNames.straight]: Icons.Line,\n [ApplianceNames.arrow]: Icons.Arrow,\n [ShapeType.Pentagram]: Icons.Star,\n [ShapeType.Rhombus]: Icons.Diamond,\n [ShapeType.Triangle]: Icons.Triangle,\n [ShapeType.SpeechBalloon]: Icons.SpeechBalloon,\n} as const;\n\nexport const ApplianceShapes = [\n ApplianceNames.rectangle,\n ApplianceNames.ellipse,\n ApplianceNames.straight,\n ApplianceNames.arrow,\n] as const;\n\nexport const Shapes = [\n ShapeType.Pentagram,\n ShapeType.Rhombus,\n ShapeType.Triangle,\n ShapeType.SpeechBalloon,\n] as const;\n\nexport const ItemHeight = 32 + 4;\nexport const ItemsCount = 8;\nexport const MaxHeight = ItemHeight * ItemsCount - 4;\nexport const MinHeight = ItemHeight * 2 - 4;\n","import type { Placement } from \"tippy.js\";\n\nimport clsx from \"clsx\";\nimport React, { forwardRef, useContext, type PropsWithChildren } from \"react\";\nimport Tippy from \"@tippyjs/react\";\n\nimport { RightOffset } from \"../../../theme\";\nimport { ToolbarContext } from \"../Toolbar\";\n\ntype ButtonProps = PropsWithChildren<{\n content: React.ReactNode;\n disabled?: boolean;\n active?: boolean;\n onClick?: () => void;\n interactive?: boolean;\n placement?: Placement;\n}>;\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (props, ref) => {\n const {\n content,\n disabled,\n active,\n onClick,\n interactive,\n placement = \"right\",\n children,\n } = props;\n const { writable, theme } = useContext(ToolbarContext);\n\n return (\n <Tippy\n className=\"fastboard-tip\"\n content={content}\n interactive={interactive}\n theme={theme}\n disabled={disabled || !writable}\n placement={placement}\n offset={placement.includes(\"right\") ? RightOffset : undefined}\n duration={300}\n >\n <button\n ref={ref}\n className={clsx(\"fastboard-toolbar-btn\", theme, { active })}\n onClick={onClick}\n disabled={disabled || !writable}\n >\n {children}\n </button>\n </Tippy>\n );\n }\n);\n","import clsx from \"clsx\";\nimport React, { useContext } from \"react\";\nimport { ToolbarContext, name } from \"../Toolbar\";\n\nexport function CutLine() {\n const { theme } = useContext(ToolbarContext);\n return <span className={clsx(`${name}-cut-line`, theme)} />;\n}\n","import React, { useCallback, useContext } from \"react\";\n\nimport { Icon } from \"../../../icons\";\nimport { Icons } from \"../icons\";\nimport { Button } from \"./Button\";\nimport { CutLine } from \"./CutLine\";\nimport { ToolbarContext } from \"../Toolbar\";\nimport { ItemHeight } from \"../const\";\n\nexport interface UpButtonProps {\n disabled: boolean;\n scrollTo: (height: number) => void;\n}\n\nexport function UpButton({ disabled, scrollTo }: UpButtonProps) {\n const { theme, icons } = useContext(ToolbarContext);\n const scrollUp = useCallback(() => scrollTo(-ItemHeight), [scrollTo]);\n\n return (\n <>\n <Button content=\"Up\" disabled={disabled} onClick={scrollUp}>\n <Icon\n fallback={<Icons.Up theme={theme} />}\n src={disabled ? icons?.upIconDisable : icons?.upIcon}\n alt=\"[up]\"\n />\n </Button>\n <CutLine />\n </>\n );\n}\n\nexport function DownButton({ disabled, scrollTo }: UpButtonProps) {\n const { theme, icons } = useContext(ToolbarContext);\n const scrollDown = useCallback(() => scrollTo(ItemHeight), [scrollTo]);\n\n return (\n <>\n <CutLine />\n <Button content=\"Down\" disabled={disabled} onClick={scrollDown}>\n <Icon\n fallback={<Icons.Down theme={theme} />}\n src={disabled ? icons?.downIconDisable : icons?.downIcon}\n alt=\"[down]\"\n />\n </Button>\n </>\n );\n}\n","import type { HotKey } from \"white-web-sdk\";\n\nimport React, { useCallback, useContext } from \"react\";\nimport { ApplianceNames } from \"white-web-sdk\";\n\nimport { defaultHotKeys, useInstance } from \"../../../internal\";\nimport { Icon } from \"../../../icons\";\nimport { Icons } from \"../icons\";\nimport { ToolbarContext } from \"../Toolbar\";\nimport { Button } from \"./Button\";\n\nexport function renderToolTip(text: string | undefined, hotkey?: HotKey) {\n if (!(typeof hotkey === \"string\")) return text;\n return (\n <span className=\"fastboard-toolbar-tooltip\">\n <span>{text}</span>\n <span className=\"fastboard-toolbar-hotkey\">{hotkey.toUpperCase()}</span>\n </span>\n );\n}\n\nexport function ClickerButton() {\n const app = useInstance();\n\n const { theme, icons, writable, setAppliance, memberState, i18n } =\n useContext(ToolbarContext);\n\n const changeAppliance = useCallback(\n () => setAppliance(ApplianceNames.clicker),\n [setAppliance]\n );\n\n const shortcut = app?.config.joinRoom.hotKeys?.changeToClick;\n const appliance = memberState?.currentApplianceName;\n const active = appliance === ApplianceNames.clicker;\n const disabled = !writable;\n\n return (\n <Button\n content={renderToolTip(i18n?.t(\"clicker\"), shortcut)}\n onClick={changeAppliance}\n active={active}\n >\n <Icon\n fallback={<Icons.Clicker theme={theme} active={active} />}\n src={disabled ? icons?.clickerIconDisable : icons?.clickerIcon}\n alt=\"[clicker]\"\n />\n </Button>\n );\n}\n\nexport function SelectorButton() {\n const app = useInstance();\n\n const { theme, icons, writable, setAppliance, memberState, i18n } =\n useContext(ToolbarContext);\n\n const changeAppliance = useCallback(\n () => setAppliance(ApplianceNames.selector),\n [setAppliance]\n );\n\n const appliance = memberState?.currentApplianceName;\n const active = appliance === ApplianceNames.selector;\n const disabled = !writable;\n const shortcut = (app?.config.joinRoom.hotKeys || defaultHotKeys)\n .changeToSelector;\n\n return (\n <Button\n content={renderToolTip(i18n?.t(\"selector\"), shortcut)}\n onClick={changeAppliance}\n active={active}\n >\n <Icon\n fallback={<Icons.Selector theme={theme} active={active} />}\n src={disabled ? icons?.selectorIconDisable : icons?.selectorIcon}\n alt=\"[selector]\"\n />\n </Button>\n );\n}\n\nexport function EraserButton() {\n const app = useInstance();\n\n const { theme, icons, writable, setAppliance, memberState, i18n } =\n useContext(ToolbarContext);\n\n const changeAppliance = useCallback(\n () => setAppliance(ApplianceNames.eraser),\n [setAppliance]\n );\n\n const appliance = memberState?.currentApplianceName;\n const active = appliance === ApplianceNames.eraser;\n const disabled = !writable;\n const shortcut = (app?.config.joinRoom.hotKeys || defaultHotKeys)\n .changeToEraser;\n\n return (\n <Button\n content={renderToolTip(i18n?.t(\"eraser\"), shortcut)}\n onClick={changeAppliance}\n active={active}\n >\n <Icon\n fallback={<Icons.Eraser theme={theme} active={active} />}\n src={disabled ? icons?.eraserIconDisable : icons?.eraserIcon}\n alt=\"[eraser]\"\n />\n </Button>\n );\n}\n\nexport function CleanButton() {\n const { theme, icons, writable, cleanCurrentScene, i18n } =\n useContext(ToolbarContext);\n\n const disabled = !writable;\n\n return (\n <Button content={i18n?.t(\"clean\")} onClick={cleanCurrentScene}>\n <Icon\n fallback={<Icons.Clean theme={theme} />}\n src={disabled ? icons?.cleanIconDisable : icons?.cleanIcon}\n alt=\"[clean]\"\n />\n </Button>\n );\n}\n","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAB+5JREFUaN7tWglIVWkUdsMtC5OcRFMKoaZ0yLGNaSYl0honUlscSspkMrUwM0dsk7ByKdRSxKUUhqksMttwyRYqpwxpZ1qo0LSMkzk6YloWmc7/HeeV9/nue8/Kp80kHHjbvff//rN95/vV6+zspP+C6X0B8n8Acv/+fUpNTaU1a9bQtm3b6MqVK/T27dvPB8jLly8pPDycjIyMyMDAiIYOHSFem5K+vj4tXLiQ6uvrBz6Qjo4OCgwMFIs2IHf3FRQfX0lpac2UlFRLPj5bydDQhDw9PamtrW1gAykvLxeLNSQvr/W0e3cn7dr13vA+ICCH9PT0KCoqio4fP05nzpyhq1ev0uPHj6m9vX3gAFmxYgWZm1sJLzRJQCgsK6udHBwmkI2NDYWGhlJISAgbrgO4nJwcunnzJr169ar/gFRXV5Orqys5On7fwxsKy8nppKlTfxFgzSk4OFilAdi6deuouLiYXrx4oTsgtbW1lJmZyTvs4OBAdnbOskDw+YQJP9PgwYP593JgFLZx40a6detW3wJpbW2lffv20apVq949eMqUKSJHjCkm5qpKICkpdRx6vr6+dOHCBc4ThFNMTMy7UFMGg7A7dOiQVjnUayC3b9/m3VJ+aEBAAJmZmXEebN9eI/FMWtrf5OT0I1lYWHAeKFe7J0+ecDjFxsaq9E52dja9fv360wDBA0tLS2nlypUqdw4htmfPHl6shYU1eXisoSVLcmn27BgaNmwU95asrCy1z0Cinz59miIiIiT3X758udic7fz869evqyzhWgGBa/fv369yt1JSUqiysvLdb69du0bz5s3jXEC5NTU1pRkzZtCpU6e09vrTp08pMTGR7z99+nTRWIfyvRTm6OjIYYnN1RoIqMXevXt7xDA6+MmTJ1XGLx7Q1NREjx49ooaGhg+iJ8jDuXPn8sLt7b8VzfZ3Wru2nIKC8gSQH5gtbNmyRT2Qmpoa3kEkJZJaGcSGDRskXugLQy4h51xdF1BGRqukcGRmtolSHsjhikbcA8i9e/do1qxZZGJiwjsB1Hjt4uJCy5YtYxCbN2+mxsbGPmezyBNT08GUnEwqq2BqaqPIxWHk5+cnBXLjxg2ysrISsW1N3t6bKTr6DxE+JTRp0iLmT3Z2dgzi+fPnOqHl4GWjRn1Hubmq+xI+Hzt2Jo0ZM4ZDmYGgtGHXLS1tKS6uUlI6u3hSLoPpHpN9bSgQyAV1QJycvGj06NGcgwzkxIkTHEohIfky9KKDnJ29GD2SUBdA0CQHDbLiEFK1pvT0Ft74OXPmvA+trVu3krGxmSilT1VeBFu8OJtzBrxKF0AuXbrEbNrNLVQ0xHal9bylmTOjeD3oLe+AbNq0SSSWBe3YUS8LJDDwN/ZaVVWVzsIL1RHPHDdulpg2T4tps0Yw5TJRyebz56BIil7CQAoKCvgL/FiOuU6e7C/quT01NzfrDAh6FBqutbW1pCGikkZHR0toi56i+YC9jhgxvkdMItmjos7zyLp69ep+ERaweSjHbm5u3B6WLl1Kd+7cUU1RwHFAJ4YP/1pwmzwxqlYJEvcncyUTk0HCveN00j/kLD4+XtKUMVnKci0QsyFDhvzbDA255HaNr15UV1fXbyBAJjFFdiepEDpkgWRkZAguEyTEAh92I+IT0k53ctYfhkrZfRgDoVTmbxIgCQkJkrETfwNBfDt48KAkrDBsqaXxcXFxEiBgrv0NAoUIQp9iXfDM3bt31QMZiB45evSoxBugSW/evFEPBFNe94sw1vYnCCiTKPnd13Tx4kXNo+6xY8ckF+F9f4HArqPYdF8PQl+VN3oAgfzS/UJwMF1ULIwGhYWFHDZJSUk8LIFtKGteysKFLBAM9ZGRkZLE6utJ8MiRI2Rra8sE0MjITFjXUAdagqFJsRaM271SUfLy8iQ7gWMBOXd+rOXn5/O4CoUyIqJU0KMmnggDA3PFkOfAo66/vz9HhnID1AgEgkFYWJgEDNyOMgjtCd1/586dTLM1aU3qrKWlhadOe3sXMVs09+B3sbG3edR1cnKiZ8+efZhAd+DAAQkQb29vGjlyJLvcwKCLuuD1tGnTVNZ0bQxzRBcVL5QdHTw9I1kr1qaf6ckd2GA+BwjwLAMDzOzfiIcWC280iIQkIb7tEvP9V4JkDmcNuLdAkkUMYUN27PhLFkhYWBHnTkVFxYdLppCEQJ2hHNrYjBPx29DD/TEx14X7h3Ac97ZKoahgkYmJNbJAgoL28yZCGPko7ffw4cPs/tDQAlmF3dPzV05KTe7HTIHymZubyxs0f37XlOfnlyKr4I8f78Me1+bMRC0QJDV2LTm5TnbXwsO7hAuEYklJCZ0/f57Kysro7NmzTC8gQKM/QJlUPk5A2UVCr19frgSmgxYtShP31efi8tHHChCdcbOEhGpZICEhXV6D3qtoXArTdAaCkLS0tGThw80thO8FadTZ+Sd+LqZBTWVXKyAIBSxywYJkle7HZxACMFkqlEhNpjhuA0FFEqNQYAaCUI2eYmxszNoAZo7eHJzqaeI77u7uIgcshfsrZIW7iRMnqvUAvsOEl56ezmVXeUxV5BCODEBUP6Q/aVTjHz58yD3E2Nicj52Dg/PZ/S4uvtxTPDw86MGDB3T58mUWvkE0kRtFRUV07tw59iqOCfrqWLpX5yNwP5QLlGKFJINExcmVrrTgT3r0hjMP7DC6ubZJ+OWfar4A+cztHyyv+3VOTz+jAAAAAElFTkSuQmCC\"","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAAXNSR0IArs4c6QAADAhJREFUWMOtmYlXk1cWwPkr5pyZM2faOTPOjFu1omyyKdICyqoFpBAFFAggQQgJqChUW0dFhEERFNmXLAREqcqmgFbErW60CLIlAglhSSAhybcxN3whfllQoL7zzjtfPt57+eW+e++792IxZ9iENTl9F8LVXJaGy4aR7BoemxyxW2cI2ejcp1r/u3cNd+68/f03xcw0gaFzy28WRp+V73u7zoRNlcSTHCSQAVnDeWJm/CM7Dg4OpKelFRcV37179213t1gslsumlIoZgsBXjjVHENLHt3szD6g4SXppUcWmJWvKIpSyxXasq7uekpxcWlLS0tLS1tb26tWrd7290IWDg9iSJWdh+orA8ZHG8pG8aD2HXlQLnYU0ZRMqhdkdm5sak5jM7Kyspqamlvl27969Vm1rGx0eXjmWlgxDh6qzporjjQ6RcposrDWfQFSma2WyqcyMc8ePpRZcudrQ0NDc0kzCwZkODvT/ISxomEoxWJI2XZ5gLDDuBz70QRGBIaZrlUplZkbG6Z9OZ2dlFxUWcjlcHpfHqaqanJyYw1FcLiY0syvEgqaZFPddPqyoSNSLykjJtHr2mDtnojHT0/If0tMKC4vut7ffvHGjmsfjc7lDgwMEjmHPBNj1VPTWWXysb4VY2t8t6u7PoSsrmRqKYZIjwmMpOSxREbNdUFLGr72QV3g+tyArv7CUKyir4qaeSOPzq1+/fPnubTc+32A3fOApKjhC7oPcPEUoJleIRRDEdNfDvqwocBl6mSE8tqgokXcyhn0ocg/toHdI5O790bv30/32kT3aJyTSNyQyMp6dk38NbHBBLVAwYar1oPcLCVSzEiztTxS/na1JVZTHqTlM0HRFVRInPSYk7KAPjb57H31X0AEX3yB7Dz8bV08rl13WOzzt3H2dvQPdA0MBDnpwdALver1KpSJkI2jtcQMd4CdjXc0rwcJ772O1yRpuPNnFxQms2IN+NLofLcp1TwhwrLdx+vcmm39ttN7itMPe1WOLk+u/NlrBm/U2jltcdm7z2QvcPiFRzBM/yXqeIfwUIwVFr5/Apf3Lw8KFLxA+U88EXV7ByDoS6x4QarVj11or+69sHKMTWIK6m+/6+8VjY1LpuFgy9q6vv/ZGfUwCa721A8wBOBe/YK/gCHpMrLBIK28jMqThAqFWLBWLUE0jdcepTGSfrWLkMoPXbdmakJL6c0MzgqKgf0ZrKwV1r7p+A77DyUfXbLbbYO/i4OkPYjsQFjZakqihXLjwgPDZ2NNq+MIlYaFvbpsykV3FYfRUndLMKvOKyh92PjFaODs5kRp1CFyXdhMUrb/TYOXkut7W2d7Tf+fe8KToMNBOIxcN5omLe5aEpWnIWAxL15uyx4eFg0Mio4UtR47wVq3GVCq9LT/79YWdi9sGhx0OngFugWFV6dFUz0yO6O1zxKz801jjvFPy4mg152NkirofcbWBv0YUMwUbLB+G0MBxUt8/fPR4nZW95XYPJ+9A76D9I8WJRhcaOB3sYak+CrJYTLFUj7jj+VGTVyPVHMZiWGO54VPtXOrCvsbGgj//bYhTZbon+3j66s12djv3uOwOzkuJ+OApuLoLA61Oxnvuz81rqhksXNKL1v8Ek2DqdHGcNO+AqsoMmaoyTpQZMnqFQVX5O4x4/t9XqSQSgw1xvH9Q2PbgoZWz6ybnbx28Ar77nqasSqJGmiQifiONmBw2g4WPD6J1aZQYhj1TGi+5FK4sP2SIxQBc0flgUc4BfMFTq+SyaxssHwQFzyoUMzMzcrl8ar4JRaLE1JO/v+1NOnp8jZU96L6zz97nl+L1xkg9TW0wh6oNsOAz1phpdPfBqKxIADJpXvh0cbSiLHamJEZ6OVzLdP770eJkYr4hCNJVW1vwp7/+XlwMHmxM68Z0DZ4nxsfh4VZj09otW23cfB29AgpTI418mP5mg+vfAAt//xrOTv8jqOJVVSWN5UYIM76HgxMCEDxosYKVPU/UavXk5KRkaKj2u4Drq9eN9PRIF2l9/f3gLDZv94BzPBYThvDMRnJs5G6uARb6mI/w2EaypY6TnBMjhSzhuSDh2cCRa0zZqzY4IxDLSM/bDg/PtjUbGzdtGX7bvRgWTHZ29/ra8RvAigyjoTyDdOFDUP6myQBruqNWXhSn4pqRLblmlsNSdj1ApycQ+fjM1IR0/mhg7CkrvfPFqp+/WHXzL192l5XBK7NYoG1uPnu+dnQFLBotGDWRFtlx0SsLahCDjXRPlSRK8+mzVUnGQd+88OQljJGCJHRWIZPJqNoz0NZW/+U/67+A/o+B9tbFpDUtl+/w9COxQveFoHy2aVCO8pMJuXgBC8fwl/VIdYrW9MoOS3KjlBWJapPQT3wpUphBG+t+bvR9gNhbW/M4Lr6ntoaKa9RGR0dtt39ruc0dsBKjQhEey1RPkJpjEIhb6C6I35oRCruyggkEsiKGmvPhp8iLGaILYaIMmuRNp3Q5bXx8/F77g18edXZ0Pt5o52Tl6glYF5IOaLhmdAtruQixtRYLl42iNceMZoDpgcxGcg6OX4meuBoryY3UMl0IG8iOEgsHlocllT559mt2fmFG1sX/bLLdunMPYDWciTXK2slOPBeAmLRYxJtGhGfscMkH6ZWY/vNh7y/ouuh/kQ3FOe+Hh6XLbxKJxGN34Iat2x28/Lf7BI6VJhlpCKlYeO8DnZdXPq6bLo03ZdK6Ky6rkB2aERtSyaZlRvi03hRMTEysgAnOsYLLX2Npa/2NN2Cx6aGkLzXyjpgghZgY0mHhCtlEAWOiIJZqqDr/XsnsOhu6wzfQdpf/Orvtnv5BAwODK8AaHBpydvP6ym4bMMHl05EVZ1YKSG3q3HwKaaFL7x9VTF07NJZPV827Bj0ZKJYwMyw5Ihj2svPYDSEA/TBTJBItiwnmxyaw1mzZauvuB/sk0ferOCwjAyQ7Dpn6fGyjcxDE1Ah2I11RliC+FDFZGKcoT1CUJ4L8SDXvy2N47N4LegpGtNrSNjya0T8wsGDz4o7OJ6Yo18qqOjqfwgPMDI+Og1U23/rADh579ooKtXGzqbKDfoOTMgxsoMzTcx/8m7IyUXwxAlDeZ4XDKMwMHcujwy53M2KdvAPgCLRkm+3c/QJaWlsnJybaf+k4lZFN3sTU9vT5i6sllc33Wt19A2A+pCTA5OQVAPtQU0Xqg1axhruMw0BtJv76NngvUHN5Sbw0jz52OWqqMI6sKMHKmlPRgAW727r7Qh4GaQ+dwSyt5Lx4+Qr4xhcaPIPR3WlqDo9hrLdxgJkQMjh4B0DUIDhJ13DNHJ/uKqxNJWZlZqJTEBn26w3S11OrIPrLm/sDfZtPIJDZe35n6bJzrbXDemt7ux3u+yJjjqadTD999mjaqf2RMXYu7uus7ddaO27evhNmwnxY1XgmVmOi49RCC95+ZW7RoBnQhC+Rmz+qTcoh82SsN5fjI8Jo8wcKcP6gMZuc3TZsdQGprLN2hBE8k6Wzm42bDwkEM2H+69x4jYlrNLBBSMu6mj5V35qVoZ1cjeCoTtqG3kVZxao/HbOfFuLiq4Vb6P4kKPnR0TvAxTdw/76QW/+NmY+PzVx/VDJUkIJPDi8tqx7rR1qvaPgpppEa6Qyf5jAup0REhdO8AoLAxNz37IXRyz8oKowG759fZJjWeUx9lU7fW3IgNl5yaQSinTcNGj7b7P2lS6Sq2eCHJCVMsHxxCVPF0b5BKMU604q10VbaTQxrJJ+u2EDMg3WUI/zkT/5iamKiWeSSNatbiOAoMS1ZJhaITDOLtxeYki32NYvRmIXWuoa7uXOG5XGLJdZYIaHFO8pIso8ch4FGL+TyptMMCv01x/AFL7psLF269kspulCj+qRszN56ph2tSydmpCvHmifTYC/rUcExsxpmFtGs8zSovFWnQB7/h7B0l9RoN9aYRZb29BUEs8f6EYl+8FjVKVjfoz+MpT/Qvk7s3mVUcFRtkugtxWD1f4KIFHt+/fNgfciXVNOQm+tNYTHBUP/bYJoYY235nxWLZJNL4HZf7P8J5l0J1+BP+J1zoBqfGQu8Gnb7jGnlwjhG4JqLSsibpy6NUM98bixUg9+7ZJqzf8QpGCgflw21U8ikqXv+H7p3tGfM9Tp+AAAAAElFTkSuQmCC\"","import Tippy from \"@tippyjs/react\";\nimport React, { useContext } from \"react\";\n\nimport vscodePNG from \"./assets/vscode.png\";\nimport geogebraPNG from \"./assets/geogebra.png\";\nimport countdownPNG from \"./assets/countdown.png\";\n\nimport { useInstance } from \"../../../internal\";\nimport { Icon } from \"../../../icons\";\nimport { RightOffset } from \"../../../theme\";\nimport { Icons } from \"../icons\";\nimport { ToolbarContext } from \"../Toolbar\";\nimport { Button } from \"./Button\";\n\nexport interface AppsButtonProps {\n content?: React.ReactNode;\n onClick?: () => void;\n}\n\nexport function AppsButton({ content, onClick }: AppsButtonProps) {\n const { theme, icons, writable } = useContext(ToolbarContext);\n\n const disabled = !writable;\n\n const button = (\n <Button content=\"Apps\" onClick={onClick}>\n <Icon\n fallback={<Icons.Apps theme={theme} />}\n src={disabled ? icons?.appsIconDisable : icons?.appsIcon}\n alt=\"[apps]\"\n />\n </Button>\n );\n\n return content === false ? (\n button\n ) : (\n <span className=\"fastboard-toolbar-btn-interactive\">\n <Tippy\n className=\"fastboard-tip\"\n content={renderAppsButtonContent(content)}\n theme={theme}\n placement=\"right-end\"\n trigger=\"click\"\n offset={RightOffset}\n arrow={false}\n interactive\n >\n {button}\n </Tippy>\n </span>\n );\n}\n\nfunction renderAppsButtonContent(content?: React.ReactNode) {\n return (\n <div className=\"fastboard-toolbar-panel apps\">\n <div className=\"fastboard-toolbar-apps\">{content || <DefaultApps />}</div>\n </div>\n );\n}\n\nfunction DefaultApps() {\n const app = useInstance();\n\n return (\n <>\n <AppIcon\n title=\"Code Editor\"\n src={vscodePNG}\n alt=\"[code editor]\"\n onClick={app?.insertCodeEditor.bind(app)}\n />\n <AppIcon\n title=\"GeoGebra\"\n src={geogebraPNG}\n alt=\"[geogebra]\"\n onClick={app?.insertGeoGebra.bind(app)}\n />\n <AppIcon\n title=\"Countdown\"\n src={countdownPNG}\n alt=\"[countdown]\"\n onClick={app?.insertCountdown.bind(app)}\n />\n </>\n );\n}\n\ninterface AppIconProps {\n title: string;\n src: string;\n alt: string;\n onClick?: () => void;\n}\n\nfunction AppIcon({ title, src, alt, onClick }: AppIconProps) {\n return (\n <span className=\"fastboard-toolbar-app-icon\">\n <Button placement=\"top\" content={title} onClick={onClick}>\n <img src={src} alt={alt} title={title} />\n </Button>\n <span className=\"fastboard-toolbar-app-icon-text\">{title}</span>\n </span>\n );\n}\n","import type { Color } from \"white-web-sdk\";\n\nimport clsx from \"clsx\";\nimport React, { useContext } from \"react\";\n\nimport { isEqualArray } from \"../../../internal\";\nimport { ToolbarContext } from \"../Toolbar\";\n\nconst colors: Record<string, Color> = {\n \"#E02020\": [224, 32, 32],\n \"#F7B500\": [247, 181, 0],\n \"#6DD400\": [109, 212, 0],\n \"#32C5FF\": [50, 197, 255],\n \"#0091FF\": [0, 145, 255],\n \"#6236FF\": [98, 54, 255],\n \"#B620E0\": [182, 32, 224],\n \"#6D7278\": [109, 114, 120],\n};\n\nconst colorKeys = Object.keys(colors);\n\nexport function ColorBox() {\n const { theme, memberState, setStrokeColor, writable } =\n useContext(ToolbarContext);\n\n const strokeColor = memberState?.strokeColor;\n const disabled = !writable;\n\n return (\n <div className={clsx(\"fastboard-toolbar-color-box\", theme)}>\n {colorKeys.map((key: string) => (\n <div\n key={key}\n className={clsx(\"fastboard-toolbar-color-item\", theme)}\n onClick={() => setStrokeColor(colors[key])}\n >\n <div\n className={clsx(\"fastboard-toolbar-color-border\", theme, {\n active: strokeColor && isEqualArray(strokeColor, colors[key]),\n })}\n >\n <button\n className={clsx(\"fastboard-toolbar-color-btn\")}\n style={{ background: key }}\n disabled={disabled}\n onClick={ev => {\n ev.stopPropagation();\n setStrokeColor(colors[key]);\n }}\n />\n </div>\n </div>\n ))}\n </div>\n );\n}\n","import clsx from \"clsx\";\nimport RcSlider from \"rc-slider\";\nimport React, { useContext } from \"react\";\n\nimport { themes } from \"../../../theme\";\nimport { ToolbarContext } from \"../Toolbar\";\n\nexport function Slider() {\n const { theme, writable, memberState, setStrokeWidth } =\n useContext(ToolbarContext);\n const { activeColor } = themes[theme];\n\n const strokeWidth = memberState?.strokeWidth || 0;\n\n return (\n <RcSlider\n disabled={!writable}\n className={clsx(\"fastboard-toolbar-slider\", theme)}\n trackStyle={{ background: activeColor }}\n handleStyle={{ border: `1px solid ${activeColor}` }}\n value={strokeWidth}\n onChange={setStrokeWidth}\n min={1}\n max={32}\n />\n );\n}\n","import Tippy from \"@tippyjs/react\";\nimport React, { useCallback } from \"react\";\nimport { useContext } from \"react\";\nimport { ApplianceNames } from \"white-web-sdk\";\n\nimport { defaultHotKeys, useInstance } from \"../../../internal\";\nimport { Icon } from \"../../../icons\";\nimport { RightOffset } from \"../../../theme\";\nimport { Icons } from \"../icons\";\nimport { ToolbarContext } from \"../Toolbar\";\nimport { Button } from \"./Button\";\nimport { ColorBox } from \"./ColorBox\";\nimport { CutLine } from \"./CutLine\";\nimport { Slider } from \"./Slider\";\nimport { renderToolTip } from \"./ApplianceButtons\";\n\nexport function PencilButton() {\n const app = useInstance();\n\n const { theme, icons, writable, setAppliance, memberState, i18n } =\n useContext(ToolbarContext);\n\n const changeAppliance = useCallback(() => {\n setAppliance(ApplianceNames.pencil);\n }, [setAppliance]);\n\n const appliance = memberState?.currentApplianceName;\n const active = appliance === ApplianceNames.pencil;\n const disabled = !writable;\n const shortcut = (app?.config.joinRoom.hotKeys || defaultHotKeys)\n .changeToPencil;\n\n return (\n <span className=\"fastboard-toolbar-btn-interactive\">\n <Tippy\n className=\"fastboard-tip\"\n content={renderPencilButtonContent()}\n theme={theme}\n placement=\"right-start\"\n trigger=\"click\"\n offset={RightOffset}\n arrow={false}\n interactive\n >\n <Button\n content={renderToolTip(i18n?.t(\"pencil\"), shortcut)}\n active={active}\n onClick={changeAppliance}\n >\n <Icon\n fallback={<Icons.Pencil theme={theme} active={active} />}\n src={disabled ? icons?.pencilIconDisable : icons?.pencilIcon}\n alt=\"[pencil]\"\n />\n <span className=\"fastboard-toolbar-triangle\" />\n </Button>\n </Tippy>\n </span>\n );\n}\n\nfunction renderPencilButtonContent() {\n return (\n <div className=\"fastboard-toolbar-panel pencil\">\n <Slider />\n <CutLine />\n <ColorBox />\n </div>\n );\n}\n","import Tippy from \"@tippyjs/react\";\nimport React, { useCallback } from \"react\";\nimport { useContext } from \"react\";\nimport { ApplianceNames } from \"white-web-sdk\";\n\nimport { defaultHotKeys, useInstance } from \"../../../internal\";\nimport { Icon } from \"../../../icons\";\nimport { RightOffset } from \"../../../theme\";\nimport { Icons } from \"../icons\";\nimport { ToolbarContext } from \"../Toolbar\";\nimport { Button } from \"./Button\";\nimport { ColorBox } from \"./ColorBox\";\nimport { renderToolTip } from \"./ApplianceButtons\";\n\nexport function TextButton() {\n const app = useInstance();\n\n const { theme, icons, writable, setAppliance, memberState, i18n } =\n useContext(ToolbarContext);\n\n const changeAppliance = useCallback(() => {\n setAppliance(ApplianceNames.text);\n }, [setAppliance]);\n\n const appliance = memberState?.currentApplianceName;\n const active = appliance === ApplianceNames.text;\n const disabled = !writable;\n const shortcut = (app?.config.joinRoom.hotKeys || defaultHotKeys)\n .changeToText;\n\n return (\n <span className=\"fastboard-toolbar-btn-interactive\">\n <Tippy\n className=\"fastboard-tip\"\n content={renderTextButtonContent()}\n theme={theme}\n placement=\"right-start\"\n trigger=\"click\"\n offset={RightOffset}\n arrow={false}\n interactive\n >\n <Button\n content={renderToolTip(i18n?.t(\"text\"), shortcut)}\n active={active}\n onClick={changeAppliance}\n >\n <Icon\n fallback={<Icons.Text theme={theme} active={active} />}\n src={disabled ? icons?.textIconDisable : icons?.textIcon}\n alt=\"[text]\"\n />\n <span className=\"fastboard-toolbar-triangle\" />\n </Button>\n </Tippy>\n </span>\n );\n}\n\nfunction renderTextButtonContent() {\n return (\n <div className=\"fastboard-toolbar-panel text\">\n <ColorBox />\n </div>\n );\n}\n","import type { IconProps } from \"../../../types\";\n\nimport Tippy from \"@tippyjs/react\";\nimport React, { useContext } from \"react\";\nimport type { ShapeType } from \"white-web-sdk\";\nimport { ApplianceNames } from \"white-web-sdk\";\n\nimport { RightOffset } from \"../../../theme\";\nimport { ApplianceShapes, Shapes, ShapesMap } from \"../const\";\nimport { Icons } from \"../icons\";\nimport { ToolbarContext } from \"../Toolbar\";\nimport { Button } from \"./Button\";\nimport { CutLine } from \"./CutLine\";\nimport { Slider } from \"./Slider\";\nimport { ColorBox } from \"./ColorBox\";\n\nconst ShapeTypes = new Set([...ApplianceShapes, ...Shapes]);\n\nexport function ShapesButton() {\n const { theme, memberState, i18n } = useContext(ToolbarContext);\n\n const appliance = memberState?.currentApplianceName;\n const shape = memberState?.shapeType;\n\n const key = (\n appliance === ApplianceNames.shape ? shape : appliance\n ) as keyof typeof ShapesMap;\n\n const active = ShapeTypes.has(key);\n\n const CurrentIcon = ShapesMap[key] || Icons.Rectangle;\n\n return (\n <span className=\"fastboard-toolbar-btn-interactive\">\n <Tippy\n className=\"fastboard-tip\"\n content={renderShapesButtonContent()}\n theme={theme}\n placement=\"right-start\"\n trigger=\"click\"\n offset={RightOffset}\n arrow={false}\n interactive\n >\n <Button content={i18n?.t(\"shape\")} active={active}>\n <CurrentIcon theme={theme} active={active} />\n <span className=\"fastboard-toolbar-triangle\" />\n </Button>\n </Tippy>\n </span>\n );\n}\n\nfunction renderShapesButtonContent() {\n return (\n <div className=\"fastboard-toolbar-panel shapes\">\n <ShapesBox />\n <CutLine />\n <Slider />\n <CutLine />\n <ColorBox />\n </div>\n );\n}\n\nexport function ShapesBox() {\n const { i18n } = useContext(ToolbarContext);\n return (\n <div className=\"fastboard-toolbar-shapes\">\n {ApplianceShapes.map(Appliance => (\n <ApplianceShapeButton\n key={Appliance}\n content={i18n?.t(Appliance)}\n Appliance={Appliance}\n Icon={ShapesMap[Appliance]}\n />\n ))}\n {Shapes.map(shape => (\n <ShapeShapeButton\n key={shape}\n content={i18n?.t(shape)}\n shape={shape}\n Icon={ShapesMap[shape]}\n />\n ))}\n </div>\n );\n}\n\ninterface ApplianceShapeButtonProps {\n content?: string;\n Appliance: ApplianceNames;\n Icon: React.ComponentType<IconProps>;\n}\n\nfunction ApplianceShapeButton({\n content,\n Appliance,\n Icon,\n}: ApplianceShapeButtonProps) {\n const { theme, writable, setAppliance, memberState } =\n useContext(ToolbarContext);\n\n const current = memberState?.currentApplianceName;\n const disabled = !writable;\n\n return (\n <Button\n content={content}\n disabled={disabled}\n placement=\"top\"\n onClick={() => setAppliance(Appliance)}\n >\n <Icon theme={theme} active={current === Appliance} />\n </Button>\n );\n}\n\ninterface ShapeShapeButtonProps {\n content?: string;\n shape: ShapeType;\n Icon: React.ComponentType<IconProps>;\n}\n\nfunction ShapeShapeButton({ content, shape, Icon }: ShapeShapeButtonProps) {\n const { theme, writable, setAppliance, memberState } =\n useContext(ToolbarContext);\n\n const appliance = memberState?.currentApplianceName;\n const current = appliance === ApplianceNames.shape && memberState?.shapeType;\n const disabled = !writable;\n\n return (\n <Button\n content={content}\n disabled={disabled}\n placement=\"top\"\n onClick={() => setAppliance(ApplianceNames.shape, shape)}\n >\n <Icon theme={theme} active={current === shape} />\n </Button>\n );\n}\n","import React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useInstance, clamp } from \"../../internal\";\nimport { name } from \"./Toolbar\";\nimport { ItemHeight, ItemsCount, MaxHeight, MinHeight } from \"./const\";\nimport { DownButton, UpButton } from \"./components/UpDownButtons\";\nimport {\n CleanButton,\n ClickerButton,\n EraserButton,\n SelectorButton,\n} from \"./components/ApplianceButtons\";\nimport { AppsButton } from \"./components/AppsButton\";\nimport { PencilButton } from \"./components/PencilButton\";\nimport { TextButton } from \"./components/TextButton\";\nimport { ShapesButton } from \"./components/ShapesButton\";\nimport clsx from \"clsx\";\n\nexport const Content = React.memo(() => {\n const app = useInstance();\n const ref = useRef<HTMLDivElement>(null);\n const [scrollTop, setScrollTop] = useState(0);\n const [parentHeight, setParentHeight] = useState(0);\n\n const hasAppButton = app?.config.toolbar?.apps?.enable ?? true;\n const needScroll = parentHeight < ItemHeight * ItemsCount + 48;\n const sectionHeight = clamp(\n parentHeight - 48 * (needScroll ? 3 : 1),\n MinHeight,\n MaxHeight\n );\n const scrollBuffer = Math.max(parentHeight - sectionHeight - 1, 0);\n const disableScrollUp = scrollTop === 0;\n const disableScrollDown = scrollTop === scrollBuffer;\n\n const scrollTo = useCallback(\n (height: number) => {\n setScrollTop(clamp(scrollTop + height, 0, scrollBuffer));\n },\n [scrollBuffer, scrollTop]\n );\n\n useEffect(() => {\n if (ref.current) {\n ref.current.scrollTop = scrollTop;\n }\n }, [scrollTop]);\n\n useEffect(() => {\n const container = ref.current?.parentElement?.parentElement;\n if (container) {\n const { paddingTop, paddingBottom } = getComputedStyle(container);\n const padding = parseInt(paddingTop) + parseInt(paddingBottom) || 0;\n const resizeObserver = new ResizeObserver(() => {\n setParentHeight(container.getBoundingClientRect().height - padding);\n });\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }\n }, []);\n\n return (\n <>\n {needScroll && (\n <UpButton scrollTo={scrollTo} disabled={disableScrollUp} />\n )}\n <div\n ref={ref}\n className={clsx(`${name}-section`)}\n style={{\n height: `${sectionHeight}px`,\n overflow: needScroll ? \"hidden\" : \"visible\",\n }}\n >\n <ClickerButton />\n <SelectorButton />\n <PencilButton />\n <TextButton />\n <ShapesButton />\n <EraserButton />\n <CleanButton />\n {hasAppButton && (\n <AppsButton\n content={app?.config.toolbar?.apps?.content}\n onClick={app?.config.toolbar?.apps?.onClick}\n />\n )}\n </div>\n {needScroll && (\n <DownButton scrollTo={scrollTo} disabled={disableScrollDown} />\n )}\n </>\n );\n});\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAB8CAYAAAAMw2JFAAAAAXNSR0IArs4c6QAAA49JREFUeF7tnLFv00AUh5/TFVYkxIDEnKFjJ/gb2CIqpUPagYXNEV2LRGk7tAiRSA0bWcC0QzowwQKuVDnCLE2KTZCMSNLkHCLalCpBkdFVMTKh8TXO+c4S16XDSb0vv/vyfE3fqwQR+ZIA4AoAdADgJ08mSVXVV9ls9nE+nzcBAAFAnweQ1Gg06gihrmEYubm5OeX4+LgBAD9Yw0iO49S63S7U6/VYq9UyCoXC2tLS0kcAwEA9VkBnIO5m7XYbJwTVanVLluWcruvfAOA7ADhhA/0Fgjfr9/tweHgYs20baZq2sbCw8HaQTqgy/wPivvKTkxN8XFPNZvMdC5lHgmAgx3EAISQhhHqGYWyGKbMviJsOC5kvBOIjcxUAWjRkHgtkSGZb07R1WjKPDeIj82cAaAatzIFBhmU2TTOXTCZfBq3ME4HQlJkKCA2ZqYJMIjN1kKAyhwYyrsyhgpwns6IoyysrK/rgQfrnqc4ExCtzrVb7tbe39yCVSr0GAFyZz2CYguANT09PwbIsaWdn5146nX4zuO+wB8EwnU5HqlQqdiKRuHNwcFDC1Zh5Iu4xWZYVU1V1eXZ29jlOhRvI0dGRVC6XP8zMzNwFgK/cQHq9HpTLZXt6evo2AFS4geDbX6lUisXj8VsA8IkbCHZlf39/Kh6P3xQg7jtHJDL826JIRCRC+gRBOCIcEY6QEhCOkBISdUQ4IhwhJSAcISUk6kjojjxaXbt0Py3jP1DCtes3ruLvVetLnenRYIgnT7OX3Y25gLgQ3gSYg3ghuIEMQ3ABOQ+COcgoCKYgfhD/Jwh+1ZE4GrdKRkJWPxhulTUSBe28ZLglMgzDHcR9N3G/BpDuHH7r4qoY+lUx6PGIoxFHQ3JHOCIcEY6QEhCOkBISdUQ4IhwhJSAcISUk6ohwxM+RyLR/RaYhLjItgpFomoxEG2kkGmvxRBPXVmPPWIypKMpD5s3X3kEh0zSfJZPJF6NmK0JrI3VHpxBCaiaTWc/n877TJtRBPMNkdrFY3Jifn8ed3njUzneYjCqIZ7xue3FxMadpGh6vu9BEEhUQr4yFQmE1yMDhRCDjyEi6JAUGGVdG6iBBZaQK4pVRluVNXdfZjsfRkHGiRGjKGBjEI+P7TCazQaqMpI1I635jtmNVRtJGpPVRg8fbtGW8EAiL6VUiyGA4vUd6TJN+0KTr0u7u7hYLGUmg0fkHBiRSVuu/AWpfZNft9vFDAAAAAElFTkSuQmCC\"","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAB8CAYAAAAMw2JFAAAAAXNSR0IArs4c6QAAA5xJREFUeF7tnL9v00AUx5/TlRkJMSAxZ+jYCf4GtopK6dB2qBBsjshaJErboWVJpYaNLGDaIR2YYAFXqlxhlvzAJkhGJGlyDhVNSpWgyOiqBJnQ+urznW2Jy1JVVnKffv3x8yV9LxLE5CEBwFUA6ALAzyiZJFVVX21ubj7N5/MmACAAGEQBJDWbzQZCqGcYRm52dlbpdDpNAPgRNozkOE691+tBo9FItNtto1AorC0tLX0EAAzUDwvoDGS02NHREU4IarXatizLOV3XvwHAdwBweAP9BYIXGwwGcHh4mLBtG2matrGwsPB2mA5Xmf8BGf3lJycn+HRNtFqtd2HIfCEIBnIcBxBCEkKobxjGFk+ZPUFG6YQh86VAPGSuAUCbhcy+QMZktjVNW2cls28QD5k/A0CLtjJTg4zLbJpmLpVKvaStzIFAWMrMBISFzExBgsjMHIRWZm4gfmXmCnKezIqiLK+srOjDG+mfu3ooIG6Z6/X6r/39/Udzc3OvAQBX5jOYUEHwgqenp2BZlrS7u/sgnU6/Ge53wgfBMN1uV6pWq/b09PTdSqVSwtU49ERGp8myrISqqsszMzPPcSqRgRwfH0vlcvnD1NTUIgB8jQyk3+9DuVy2Jycn7wBANTIQvPsrlUqJZDJ5GwA+RQaCXSkWixPJZPKWABldOSKR8XeLIhGRCOkTBOGIcEQ4QkpAOEJKSNQR4YhwhJSAcISUkKgjTBy5fuPmNfxCNetLA/98srp25WFaxv+UpH5QnZpxEPz7/XuLnSAwzEBwFEFgmIIEgWEOQgvDBYQGhhuIXxiuIH5g/g8QP5czt0T8QFB/mHdeZXXXdr8QXEBoIJiD0EIwBQkCwQwksm0A9abD44lUl68A4ZEAkz0rDzDhiDg1JK+EI8IR4QgpAeEIKSFRR4QjwhFSAsIRUkKijsTSkdi0f8WmIS42LYKxaJqMRRtpLBpr8URTpK3GrrEYU1GUx6E3X7sHhUzTfJZKpV5cNFvBrY10NDqFEFKz2ex6Pp/3nDZhDuIaJrMPDg425ufncac3HrXzHCZjCuIar9vJZDI5TdPweN2lJpKYgLhlLBQKqzQDh4FA/MhI2ptQg/iVkTkIrYxMQdwyyrK8pet6uONxLGQMlAhLGalBXDK+z2azG6TKSFqIdNxrzNZXZSQtRDp+0eDxDmsZLwUSxvQqEWQ4nN4n3aZJLxT0uLS3t7cdhowk0Ph8gQGJNKzjvwGKWUjXcvHclAAAAABJRU5ErkJggg==\"","import React, { useState, useEffect } from \"react\";\nimport ReactDOM from \"react-dom\";\n\ntype MaskProps = {\n toolbar: HTMLDivElement | null;\n children: React.ReactNode;\n};\n\nexport const Mask = React.memo(({ toolbar, children }: MaskProps) => {\n const [rootElement] = useState<HTMLDivElement | null>(() => {\n const element = document.createElement(\"div\");\n element.style.position = \"absolute\";\n return element;\n });\n\n useEffect(() => {\n if (toolbar && rootElement) {\n toolbar.appendChild(rootElement);\n }\n }, [rootElement, toolbar]);\n\n useEffect(() => {\n if (rootElement && toolbar) {\n toolbar.appendChild(rootElement);\n\n const toolbarRect = toolbar.getBoundingClientRect();\n const halfHeight = toolbarRect.height / 2 - 31;\n rootElement.style.top = halfHeight + \"px\";\n rootElement.style.left = \"41px\";\n rootElement.style.width = \"17px\";\n rootElement.style.height = \"62px\";\n\n return () => {\n toolbar.removeChild(rootElement);\n };\n }\n }, [rootElement, toolbar]);\n\n if (rootElement) {\n return ReactDOM.createPortal(children, rootElement);\n } else {\n return null;\n }\n});\n","import type { i18n } from \"i18next\";\nimport type { CommonProps, GenericIcon, Theme } from \"../../types\";\nimport { AnimatePresence, motion } from \"framer-motion\";\n\nimport React, { createContext, useCallback, useState } from \"react\";\n\nimport { Icon } from \"../../icons\";\nimport { EmptyToolbarHook, useToolbar, type ToolbarHook } from \"./hooks\";\nimport { Content } from \"./Content\";\n\nimport collapsePNG from \"./components/assets/collapsed.png\";\nimport expandPNG from \"./components/assets/expanded.png\";\n\nimport clsx from \"clsx\";\nimport { Mask } from \"./components/Mask\";\n\nexport type ToolbarProps = CommonProps & {\n icons?: GenericIcon<\n | \"clicker\"\n | \"selector\"\n | \"pencil\"\n | \"eraser\"\n | \"clean\"\n | \"expand\"\n | \"collapse\"\n | \"up\"\n | \"down\"\n | \"text\"\n | \"apps\"\n >;\n};\n\ntype ToolbarContextType = ToolbarHook & {\n theme: Theme;\n icons?: ToolbarProps[\"icons\"];\n i18n?: i18n | null;\n};\n\nexport const ToolbarContext = createContext<ToolbarContextType>({\n theme: \"light\",\n ...EmptyToolbarHook,\n});\n\nexport const name = \"fastboard-toolbar\";\n\nexport const Toolbar = ({\n theme = \"light\",\n icons,\n room,\n manager,\n i18n,\n}: ToolbarProps) => {\n const [expanded, setExpanded] = useState(true);\n const hook = useToolbar(room, manager);\n const [toolbar, toolbarRef] = useState<HTMLDivElement | null>(null);\n const [onHover, setOnHover] = useState<boolean>(false);\n const [pointEvents, setPointEvents] = useState(true);\n const disabled = !hook.writable;\n\n const toggle = useCallback(() => {\n setExpanded(e => !e);\n }, []);\n\n return (\n <ToolbarContext.Provider value={{ theme, icons, ...hook, i18n }}>\n <AnimatePresence>\n {expanded ? (\n <motion.div\n initial={{ x: -100 }}\n animate={{\n x: 0,\n transition: { duration: 0.5 },\n }}\n key=\"toolbar\"\n ref={toolbarRef}\n className={clsx(name, theme)}\n onPointerEnter={() => {\n if (expanded) {\n setOnHover(true);\n }\n }}\n onMouseLeave={() => setOnHover(false)}\n exit={{\n x: -100,\n transition: { duration: 0.5 },\n }}\n onAnimationStart={() => setPointEvents(false)}\n onAnimationComplete={() => setPointEvents(true)}\n style={{ pointerEvents: pointEvents ? \"auto\" : \"none\" }}\n >\n <Content />\n {expanded && onHover && (\n <Mask toolbar={toolbar}>\n <div onClick={toggle}>\n <img\n draggable={false}\n className={clsx(`${name}-mask-btn`, theme)}\n src={collapsePNG}\n />\n </div>\n </Mask>\n )}\n </motion.div>\n ) : (\n <motion.div\n className={clsx(`${name}-expand-btn`, theme)}\n key=\"expand\"\n onClick={toggle}\n initial={{ x: -100 }}\n animate={{\n x: 0,\n transition: { duration: 0.5 },\n }}\n >\n {!expanded && (\n <Icon\n fallback={\n <img\n draggable={false}\n src={expandPNG}\n className={clsx(`${name}-mask-btn`, theme)}\n />\n }\n src={disabled ? icons?.expandIconDisable : icons?.expandIcon}\n />\n )}\n </motion.div>\n )}\n </AnimatePresence>\n </ToolbarContext.Provider>\n );\n};\n","import type { WindowManager, Room } from \"@netless/window-manager\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nexport function useRedoUndo(\n room?: Room | null,\n manager?: WindowManager | null\n) {\n const [undoSteps, setUndoSteps] = useState(0);\n const [redoSteps, setRedoSteps] = useState(0);\n\n useEffect(() => {\n if (manager) {\n manager.mainView.callbacks.on(\"onCanUndoStepsUpdate\", setUndoSteps);\n manager.mainView.callbacks.on(\"onCanRedoStepsUpdate\", setRedoSteps);\n\n return () => {\n manager.mainView.callbacks.off(\"onCanUndoStepsUpdate\", setUndoSteps);\n manager.mainView.callbacks.off(\"onCanRedoStepsUpdate\", setRedoSteps);\n };\n }\n\n if (room) {\n room.callbacks.on(\"onCanUndoStepsUpdate\", setUndoSteps);\n room.callbacks.on(\"onCanRedoStepsUpdate\", setRedoSteps);\n\n return () => {\n room.callbacks.off(\"onCanUndoStepsUpdate\", setUndoSteps);\n room.callbacks.off(\"onCanRedoStepsUpdate\", setRedoSteps);\n };\n }\n }, [room, manager]);\n\n const undo = useCallback(() => {\n if (manager) {\n manager.mainView.undo();\n } else if (room) {\n room.undo();\n }\n }, [manager, room]);\n\n const redo = useCallback(() => {\n if (manager) {\n manager.mainView.redo();\n } else if (room) {\n room.redo();\n }\n }, [manager, room]);\n\n return { redoSteps, undoSteps, redo, undo };\n}\n","import type { IconProps } from \"../types\";\n\nimport React from \"react\";\nimport { themes } from \"../theme\";\n\nexport function Undo({ theme = \"light\", active }: IconProps) {\n const config = themes[theme];\n const stroke = active ? config.activeColor : config.color;\n\n return (\n <svg viewBox=\"0 0 24 24\">\n <g\n fill=\"none\"\n fillRule=\"evenodd\"\n stroke={stroke}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M10 14H6v-4\" />\n <path d=\"m6 14 .788-.9A7.005 7.005 0 0 1 18 14h0\" />\n </g>\n </svg>\n );\n}\n","import type { IconProps } from \"../types\";\n\nimport React from \"react\";\nimport { themes } from \"../theme\";\n\nexport function Redo({ theme = \"light\", active }: IconProps) {\n const config = themes[theme];\n const stroke = active ? config.activeColor : config.color;\n\n return (\n <svg viewBox=\"0 0 24 24\">\n <g\n fill=\"none\"\n fillRule=\"evenodd\"\n stroke={stroke}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M14 14h4v-4\" />\n <path d=\"m18 14-.788-.9A7.005 7.005 0 0 0 6 14h0\" />\n </g>\n </svg>\n );\n}\n","import type { CommonProps, GenericIcon } from \"../../types\";\n\nimport clsx from \"clsx\";\nimport React from \"react\";\nimport Tippy from \"@tippyjs/react\";\n\nimport { Icon } from \"../../icons\";\nimport { Undo } from \"../../icons/Undo\";\nimport { Redo } from \"../../icons/Redo\";\nimport { TopOffset } from \"../../theme\";\nimport { useWritable } from \"../hooks\";\nimport { useRedoUndo } from \"./hooks\";\n\nexport const name = \"fastboard-redo-undo\";\n\nexport type RedoUndoProps = CommonProps & GenericIcon<\"undo\" | \"redo\">;\n\nexport function RedoUndo({\n room,\n manager,\n theme = \"light\",\n undoIcon,\n undoIconDisable,\n redoIcon,\n redoIconDisable,\n i18n,\n}: RedoUndoProps) {\n const writable = useWritable(room);\n const { redoSteps, undoSteps, redo, undo } = useRedoUndo(room, manager);\n\n const disabled = !writable;\n\n return (\n <div className={clsx(name, theme)}>\n <Tippy\n className=\"fastboard-tip\"\n content={i18n?.t(\"undo\")}\n theme={theme}\n disabled={disabled}\n placement=\"top\"\n duration={300}\n offset={TopOffset}\n >\n <button\n className={clsx(`${name}-btn`, \"undo\", theme)}\n disabled={disabled || undoSteps === 0}\n onClick={undo}\n >\n <Icon\n fallback={<Undo theme={theme} />}\n src={undoSteps === 0 ? undoIconDisable : undoIcon}\n alt=\"[undo]\"\n />\n </button>\n </Tippy>\n <Tippy\n className=\"fastboard-tip\"\n content={i18n?.t(\"redo\")}\n theme={theme}\n disabled={disabled}\n placement=\"top\"\n duration={300}\n offset={TopOffset}\n >\n <button\n className={clsx(`${name}-btn`, \"redo\", theme)}\n disabled={disabled || redoSteps === 0}\n onClick={redo}\n >\n <Icon\n fallback={<Redo theme={theme} />}\n src={redoSteps === 0 ? redoIconDisable : redoIcon}\n alt=\"[redo]\"\n />\n </button>\n </Tippy>\n </div>\n );\n}\n","import type { Room, RoomState } from \"white-web-sdk\";\nimport type { WindowManager } from \"@netless/window-manager\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { clamp } from \"../../internal\";\n\nexport const ScalePoints: readonly number[] = [\n 0.10737418240000011, 0.13421772800000012, 0.16777216000000014,\n 0.20971520000000016, 0.26214400000000015, 0.3276800000000002,\n 0.4096000000000002, 0.5120000000000001, 0.6400000000000001, 0.8, 1, 1.26,\n 1.5876000000000001, 2.000376, 2.5204737600000002, 3.1757969376000004,\n 4.001504141376, 5.041895218133761, 6.352787974848539, 8.00451284830916, 10,\n];\n\nfunction nextScale(scale: number, delta: 1 | -1) {\n const { length } = ScalePoints;\n const last = length - 1;\n if (scale < ScalePoints[0]) return ScalePoints[0];\n if (scale > ScalePoints[last]) return ScalePoints[last];\n for (let i = 0; i < length; ++i) {\n const curr = ScalePoints[i];\n const prev = i === 0 ? -Infinity : (ScalePoints[i - 1] + curr) / 2;\n const next = i === last ? Infinity : (ScalePoints[i + 1] + curr) / 2;\n if (prev <= scale && scale <= next)\n return ScalePoints[clamp(i + delta, 0, last)];\n }\n return 1;\n}\n\nexport function useZoomControl(\n room?: Room | null,\n manager?: WindowManager | null\n) {\n const [scale, setScale] = useState(1);\n\n const resetCamera = useCallback(() => {\n if (manager) {\n manager.mainView.moveCamera({ scale: 1, centerX: 0, centerY: 0 });\n } else if (room) {\n const { scenes, index } = room.state.sceneState;\n if (scenes[index].ppt) {\n room.scalePptToFit();\n } else {\n room.moveCamera({ scale: 1, centerX: 0, centerY: 0 });\n }\n }\n }, [room, manager]);\n\n const zoomIn = useCallback(() => {\n if (manager) {\n manager.mainView.moveCamera({\n scale: nextScale(scale, 1),\n centerX: 0,\n centerY: 0,\n });\n } else if (room) {\n room.moveCamera({\n scale: nextScale(scale, 1),\n centerX: 0,\n centerY: 0,\n });\n }\n }, [room, manager, scale]);\n\n const zoomOut = useCallback(() => {\n if (manager) {\n manager.mainView.moveCamera({\n scale: nextScale(scale, -1),\n centerX: 0,\n centerY: 0,\n });\n } else if (room) {\n room.moveCamera({\n scale: nextScale(scale, -1),\n centerX: 0,\n centerY: 0,\n });\n }\n }, [room, manager, scale]);\n\n useEffect(() => {\n if (manager) {\n setScale(manager.mainView.camera.scale);\n\n const onCameraUpdated = ({ scale }: { scale: number }) => setScale(scale);\n\n manager.mainView.callbacks.on(\"onCameraUpdated\", onCameraUpdated);\n\n return () => {\n manager.mainView.callbacks.off(\"onCameraUpdated\", onCameraUpdated);\n };\n }\n\n if (room) {\n setScale(room.state.cameraState.scale);\n\n const onRoomStateChanged = (modifyState: Partial<RoomState>) => {\n if (modifyState.cameraState) {\n setScale(modifyState.cameraState.scale);\n }\n };\n\n room.callbacks.on(\"onRoomStateChanged\", onRoomStateChanged);\n\n return () => {\n room.callbacks.off(\"onRoomStateChanged\", onRoomStateChanged);\n };\n }\n }, [room, manager]);\n\n return { scale, resetCamera, zoomIn, zoomOut };\n}\n","import type { IconProps } from \"../types\";\n\nimport React from \"react\";\nimport { themes } from \"../theme\";\n\nexport function Minus({ theme = \"light\", active }: IconProps) {\n const config = themes[theme];\n const stroke = active ? config.activeColor : config.color;\n\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M7 12h10\"\n />\n </svg>\n );\n}\n","import type { IconProps } from \"../types\";\n\nimport React from \"react\";\nimport { themes } from \"../theme\";\n\nexport function Plus({ theme = \"light\", active }: IconProps) {\n const config = themes[theme];\n const stroke = active ? config.activeColor : config.color;\n\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 7v10m-5-5h10\"\n />\n </svg>\n );\n}\n","import type { IconProps } from \"../types\";\n\nimport React from \"react\";\nimport { themes } from \"../theme\";\n\nexport function Reset({ theme = \"light\", active }: IconProps) {\n const config = themes[theme];\n const stroke = active ? config.activeColor : config.color;\n\n return (\n <svg viewBox=\"0 0 24 24\">\n <g fill=\"none\" fillRule=\"evenodd\" transform=\"translate(-176 -684)\">\n <path\n stroke={stroke}\n strokeLinejoin=\"round\"\n d=\"M188 688v4m0 8v4m8-8h-4m-8 0h-4\"\n />\n <circle cx=\"188\" cy=\"696\" r=\"6\" stroke={stroke} />\n <circle cx=\"188\" cy=\"696\" r=\"1\" fill={stroke} />\n </g>\n </svg>\n );\n}\n","import type { CommonProps, GenericIcon } from \"../../types\";\n\nimport clsx from \"clsx\";\nimport React from \"react\";\nimport Tippy from \"@tippyjs/react\";\n\nimport { TopOffset } from \"../../theme\";\nimport { Icon } from \"../../icons\";\nimport { Minus } from \"../../icons/Minus\";\nimport { Plus } from \"../../icons/Plus\";\nimport { Reset } from \"../../icons/Reset\";\nimport { useWritable } from \"../hooks\";\nimport { useZoomControl } from \"./hooks\";\n\nexport const name = \"fastboard-zoom-control\";\n\nexport type ZoomControlProps = CommonProps &\n GenericIcon<\"reset\" | \"minus\" | \"plus\">;\n\nexport function ZoomControl({\n room,\n manager,\n theme = \"light\",\n resetIcon,\n resetIconDisable,\n minusIcon,\n minusIconDisable,\n plusIcon,\n plusIconDisable,\n i18n,\n}: ZoomControlProps) {\n const writable = useWritable(room);\n const { scale, resetCamera, zoomIn, zoomOut } = useZoomControl(room, manager);\n\n const disabled = !writable;\n\n return (\n <div className={clsx(name, theme)}>\n {/* <span className={clsx(`${name}-cut-line`, theme)} /> */}\n <Tippy\n className=\"fastboard-tip\"\n content={i18n?.t(\"zoomOut\")}\n theme={theme}\n disabled={disabled}\n placement=\"top\"\n duration={300}\n offset={TopOffset}\n >\n <button\n className={clsx(`${name}-btn`, \"minus\", theme)}\n disabled={disabled}\n onClick={zoomOut}\n >\n <Icon\n fallback={<Minus theme={theme} />}\n src={disabled ? minusIconDisable : minusIcon}\n alt=\"[minus]\"\n />\n </button>\n </Tippy>\n <span className={clsx(`${name}-scale`, theme)}>\n {Math.ceil(scale * 100)}\n </span>\n <span className={clsx(`${name}-percent`, theme)}>%</span>\n <Tippy\n className=\"fastboard-tip\"\n content={i18n?.t(\"zoomIn\")}\n theme={theme}\n disabled={disabled}\n placement=\"top\"\n duration={300}\n offset={TopOffset}\n >\n <button\n className={clsx(`${name}-btn`, \"plus\", theme)}\n disabled={disabled}\n onClick={zoomIn}\n >\n <Icon\n fallback={<Plus theme={theme} />}\n src={disabled ? plusIconDisable : plusIcon}\n alt=\"[plus]\"\n />\n </button>\n </Tippy>\n <Tippy\n className=\"fastboard-tip\"\n content={i18n?.t(\"reset\")}\n theme={theme}\n disabled={disabled}\n placement=\"top\"\n duration={300}\n offset={TopOffset}\n >\n <button\n className={clsx(`${name}-btn`, \"reset\", theme)}\n disabled={disabled}\n onClick={resetCamera}\n >\n <Icon\n fallback={<Reset theme={theme} />}\n src={disabled ? resetIconDisable : resetIcon}\n alt=\"[reset]\"\n />\n </button>\n </Tippy>\n </div>\n );\n}\n","import type { Room, RoomState } from \"white-web-sdk\";\nimport type { WindowManager } from \"@netless/window-manager\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nexport function usePageControl(\n room?: Room | null,\n manager?: WindowManager | null\n) {\n const [pageIndex, setPageIndex] = useState(0);\n const [pageCount, setPageCount] = useState(0);\n\n const addPage = useCallback(async () => {\n if (manager && room) {\n await manager.switchMainViewToWriter();\n const path = room.state.sceneState.contextPath;\n room.putScenes(path, [{}], pageIndex + 1);\n await manager.setMainViewSceneIndex(pageIndex + 1);\n } else if (!manager && room) {\n const path = room.state.sceneState.contextPath;\n room.putScenes(path, [{}], pageIndex + 1);\n room.setSceneIndex(pageIndex + 1);\n }\n }, [room, manager, pageIndex]);\n\n const prevPage = useCallback(() => {\n if (manager) {\n manager.setMainViewSceneIndex(pageIndex - 1);\n } else if (room) {\n room.pptPreviousStep();\n }\n }, [room, manager, pageIndex]);\n\n const nextPage = useCallback(() => {\n if (manager) {\n manager.setMainViewSceneIndex(pageIndex + 1);\n } else if (room) {\n room.pptNextStep();\n }\n }, [room, manager, pageIndex]);\n\n useEffect(() => {\n if (room) {\n setPageIndex(room.state.sceneState.index);\n setPageCount(room.state.sceneState.scenes.length);\n\n if (manager) {\n manager.emitter.on(\"mainViewSceneIndexChange\", setPageIndex);\n\n return () => {\n manager.emitter.off(\"mainViewSceneIndexChange\", setPageIndex);\n };\n } else {\n const onRoomStateChanged = (modifyState: Partial<RoomState>) => {\n if (modifyState.sceneState) {\n setPageIndex(modifyState.sceneState.index);\n setPageCount(modifyState.sceneState.scenes.length);\n }\n };\n\n room.callbacks.on(\"onRoomStateChanged\", onRoomStateChanged);\n\n return () => {\n room.callbacks.off(\"onRoomStateChanged\", onRoomStateChanged);\n };\n }\n }\n }, [room, manager]);\n\n return { pageIndex, pageCount, prevPage, nextPage, addPage };\n}\n","import type { IconProps } from \"../types\";\n\nimport React from \"react\";\nimport { themes } from \"../theme\";\n\nexport function FilePlus({ theme = \"light\", active }: IconProps) {\n const config = themes[theme];\n const stroke = active ? config.activeColor : config.color;\n\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill={stroke}\n d=\"M12 7.5a.5.5 0 0 1 .09.992L12 8.5H8a1.5 1.5 0 0 0-1.493 1.356L6.5 10v6a1.5 1.5 0 0 0 1.356 1.493L8 17.5h6a1.5 1.5 0 0 0 1.493-1.356L15.5 16v-4a.5.5 0 0 1 .992-.09l.008.09v4a2.5 2.5 0 0 1-2.336 2.495L14 18.5H8a2.5 2.5 0 0 1-2.495-2.336L5.5 16v-6a2.5 2.5 0 0 1 2.336-2.495L8 7.5h4Zm4-2a.5.5 0 0 1 .492.41L16.5 6v1.5H18a.5.5 0 0 1 .09.992L18 8.5h-1.5V10a.5.5 0 0 1-.992.09L15.5 10V8.5H14a.5.5 0 0 1-.09-.992L14 7.5h1.5V6a.5.5 0 0 1 .5-.5Z\"\n />\n </svg>\n );\n}\n","import type { IconProps } from \"../types\";\n\nimport React from \"react\";\nimport { themes } from \"../theme\";\n\nexport function ChevronLeft({ theme = \"light\", active }: IconProps) {\n const config = themes[theme];\n const stroke = active ? config.activeColor : config.color;\n\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m14 16-2-2-2-2 2-2 2-2\"\n />\n </svg>\n );\n}\n","import type { IconProps } from \"../types\";\n\nimport React from \"react\";\nimport { themes } from \"../theme\";\n\nexport function ChevronRight({ theme = \"light\", active }: IconProps) {\n const config = themes[theme];\n const stroke = active ? config.activeColor : config.color;\n\n return (\n <svg viewBox=\"0 0 24 24\">\n <path\n fill=\"none\"\n stroke={stroke}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m10 16 2-2 2-2-2-2-2-2\"\n />\n </svg>\n );\n}\n","import type { CommonProps, GenericIcon } from \"../../types\";\n\nimport clsx from \"clsx\";\nimport React from \"react\";\nimport Tippy from \"@tippyjs/react\";\n\nimport { TopOffset } from \"../../theme\";\nimport { Icon } from \"../../icons\";\nimport { FilePlus } from \"../../icons/FilePlus\";\nimport { ChevronLeft } from \"../../icons/ChevronLeft\";\nimport { ChevronRight } from \"../../icons/ChevronRight\";\nimport { useWritable } from \"../hooks\";\nimport { usePageControl } from \"./hooks\";\n\nexport const name = \"fastboard-page-control\";\n\nexport type PageControlProps = CommonProps &\n GenericIcon<\"add\" | \"prev\" | \"next\">;\n\nexport function PageControl({\n room,\n manager,\n theme = \"light\",\n addIcon,\n addIconDisable,\n prevIcon,\n prevIconDisable,\n nextIcon,\n nextIconDisable,\n i18n,\n}: PageControlProps) {\n const writable = useWritable(room);\n const { pageIndex, pageCount, ...actions } = usePageControl(room, manager);\n\n const disabled = !writable;\n\n return (\n <div className={clsx(name, theme)}>\n {/* <span className={clsx(`${name}-cut-line`, theme)} />{\" \"} */}\n <Tippy\n className=\"fastboard-tip\"\n content={i18n?.t(\"prevPage\")}\n theme={theme}\n disabled={disabled}\n placement=\"top\"\n duration={300}\n offset={TopOffset}\n >\n <button\n className={clsx(`${name}-btn`, \"prev\", theme)}\n disabled={disabled || pageIndex === 0}\n onClick={actions.prevPage}\n >\n <Icon\n fallback={<ChevronLeft theme={theme} />}\n src={disabled ? prevIconDisable : prevIcon}\n alt=\"[prev]\"\n />\n </button>\n </Tippy>\n <span className={clsx(`${name}-page`, theme)}>\n {pageCount === 0 ? \"\\u2026\" : pageIndex + 1}\n </span>\n <span className={clsx(`${name}-slash`, theme)}>/</span>\n <span className={clsx(`${name}-page-count`, theme)}>{pageCount}</span>\n <Tippy\n className=\"fastboard-tip\"\n content={i18n?.t(\"nextPage\")}\n theme={theme}\n disabled={disabled}\n placement=\"top\"\n duration={300}\n offset={TopOffset}\n >\n <button\n className={clsx(`${name}-btn`, \"next\", theme)}\n disabled={disabled || pageIndex === pageCount - 1}\n onClick={actions.nextPage}\n >\n <Icon\n fallback={<ChevronRight theme={theme} />}\n src={disabled ? nextIconDisable : nextIcon}\n alt=\"[next]\"\n />\n </button>\n </Tippy>\n <Tippy\n className=\"fastboard-tip\"\n content={i18n?.t(\"addPage\")}\n theme={theme}\n disabled={disabled}\n placement=\"top\"\n duration={300}\n offset={TopOffset}\n >\n <button\n className={clsx(`${name}-btn`, \"add\", theme)}\n disabled={disabled}\n onClick={actions.addPage}\n >\n <Icon\n fallback={<FilePlus theme={theme} />}\n src={disabled ? addIconDisable : addIcon}\n alt=\"[add]\"\n />\n </button>\n </Tippy>\n </div>\n );\n}\n","import React, { useCallback, useState } from \"react\";\n\nimport { Lock, Instance } from \"../internal\";\nimport { Toolbar } from \"./Toolbar\";\nimport { RedoUndo } from \"./RedoUndo\";\nimport { ZoomControl } from \"./ZoomControl\";\nimport { PageControl } from \"./PageControl\";\nimport { useHideControls } from \"./hooks\";\n\nexport interface RootProps {\n instance: Instance;\n}\n\nexport function Root({ instance: app }: RootProps) {\n const [mux] = useState(() => new Lock());\n\n const useWhiteboard = useCallback(\n (container: HTMLDivElement | null) =>\n mux.schedule(\n container ? () => app.mount(container) : () => app.unmount()\n ),\n [app, mux]\n );\n\n const hideControls = useHideControls(app.manager);\n const showControls = !hideControls;\n\n const props = {\n room: app.room,\n manager: app.manager,\n i18n: app.i18n,\n };\n\n const {\n Toolbar: toolbar = showControls || hideControls === \"toolbar-only\",\n RedoUndo: redo_undo = showControls,\n ZoomControl: zoom_control = showControls,\n PageControl: page_control = showControls,\n } = app.config.layout || {};\n\n return (\n <Instance.Context.Provider value={app}>\n <div className=\"fastboard-root\">\n {!app.room && <div className=\"fastboard-loading\">Loading…</div>}\n <div className=\"fastboard-view\" ref={useWhiteboard} />\n {toolbar && (\n <div className=\"fastboard-left\">\n <Toolbar {...props} />\n </div>\n )}\n {(redo_undo || zoom_control) && (\n <div className=\"fastboard-bottom-left\">\n {redo_undo && <RedoUndo {...props} />}\n {zoom_control && <ZoomControl {...props} />}\n </div>\n )}\n {page_control && (\n <div className=\"fastboard-bottom-right\">\n <PageControl {...props} />\n </div>\n )}\n </div>\n </Instance.Context.Provider>\n );\n}\n","import type { Mutable } from \"type-fest\";\nimport type { WindowManager } from \"@netless/window-manager\";\nimport type { Room, SceneDefinition, WhiteWebSdk } from \"white-web-sdk\";\nimport type { JoinRoom, ManagerConfig, SdkConfig } from \"./mount-whiteboard\";\nimport type { i18n } from \"i18next\";\n\nimport React, { createContext, useContext } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { BuiltinApps } from \"@netless/window-manager\";\n\nimport { Root } from \"../components/Root\";\nimport { mountWhiteboard } from \"./mount-whiteboard\";\nimport { noop } from \"./helpers\";\n\nexport interface AcceptParams {\n readonly sdk: WhiteWebSdk;\n readonly room: Room;\n readonly manager: WindowManager;\n readonly i18n: i18n;\n}\n\nexport interface InsertMediaParams {\n title: string;\n src: string;\n}\n\nexport interface InsertDocsStatic {\n readonly fileType: \"pdf\" | \"ppt\";\n readonly scenePath: string;\n readonly scenes: SceneDefinition[];\n readonly title?: string;\n}\n\nexport interface InsertDocsDynamic {\n readonly fileType: \"pptx\";\n readonly scenePath: string;\n readonly taskId: string;\n readonly title?: string;\n readonly url?: string;\n readonly scenes?: SceneDefinition[];\n}\n\nexport type InsertDocsParams = InsertDocsStatic | InsertDocsDynamic;\n\nexport type Language = \"zh-CN\" | \"en-US\";\n\nexport interface Layout {\n Toolbar?: boolean;\n PageControl?: boolean;\n RedoUndo?: boolean;\n ZoomControl?: boolean;\n}\n\nexport interface WhiteboardAppConfig {\n readonly sdkConfig: SdkConfig;\n readonly joinRoom: JoinRoom;\n readonly managerConfig?: Omit<ManagerConfig, \"container\">;\n readonly layout?: Layout;\n readonly toolbar?: {\n apps?: {\n enable?: boolean;\n content?: React.ReactNode;\n onClick?: () => void;\n };\n };\n readonly language?: Language;\n}\n\nexport interface Essentials {\n readonly sdk: WhiteWebSdk;\n readonly room: Room;\n readonly manager: WindowManager;\n readonly i18n: i18n;\n}\n\nexport class Instance {\n static readonly Context = createContext<Instance | null>(null);\n\n config: Mutable<WhiteboardAppConfig>;\n\n sdk: WhiteWebSdk | null = null;\n room: Room | null = null;\n manager: WindowManager | null = null;\n i18n: i18n | null = null;\n\n ready = false;\n resolveReady!: () => void;\n readyPromise!: Promise<void>;\n\n refreshReadyPromise() {\n this.readyPromise = new Promise<void>(resolve => {\n this.resolveReady = () => {\n this.resolveReady = noop;\n this.ready = true;\n resolve();\n };\n });\n }\n\n constructor(config: WhiteboardAppConfig) {\n this.config = { ...config };\n this.refreshReadyPromise();\n this.initialize();\n }\n\n async initialize() {\n const essentials = await mountWhiteboard(\n this.config.sdkConfig,\n this.config.joinRoom,\n this.config.managerConfig || {},\n this.config.language || \"en-US\"\n );\n this.accept(essentials);\n this.resolveReady();\n }\n\n target: HTMLElement | null = null;\n collector: HTMLElement | null = null;\n\n bindElement(target: HTMLElement | null) {\n if (this.target && this.target !== target) {\n ReactDOM.unmountComponentAtNode(this.target);\n }\n this.target = target;\n this.forceUpdate();\n }\n\n bindCollector(collector: HTMLElement | null) {\n this.collector = collector;\n if (this.manager && collector) {\n this.manager.bindCollectorContainer(collector);\n }\n }\n\n updateLayout(layout: Layout | undefined) {\n this.config.layout = layout;\n this.forceUpdate();\n }\n\n async forceUpdate() {\n await this.readyPromise;\n if (this.target) {\n ReactDOM.render(<Root instance={this} />, this.target);\n }\n }\n\n accept({ sdk, room, manager, i18n }: AcceptParams) {\n this.sdk = sdk;\n this.room = room;\n this.manager = manager;\n this.i18n = i18n;\n this.forceUpdate();\n }\n\n async dispose() {\n if (this.room) {\n await this.unmount();\n }\n if (this.target) {\n ReactDOM.unmountComponentAtNode(this.target);\n this.sdk = this.room = this.manager = this.target = null;\n }\n }\n\n async mount(node: HTMLElement) {\n await this.readyPromise;\n if (!this.manager) {\n throw new Error(`[WhiteboardApp] mounted, but not found window manager`);\n }\n this.manager.bindContainer(node);\n if (this.collector) {\n this.manager.bindCollectorContainer(this.collector);\n }\n }\n\n async unmount() {\n if (this.manager) {\n this.manager.destroy();\n this.manager = null;\n }\n if (this.room) {\n try {\n await this.room.disconnect();\n } catch {\n // ignore any error on disconnecting\n }\n this.room = null;\n }\n this.refreshReadyPromise();\n }\n\n insertDocs(params: InsertDocsParams) {\n if (!this.manager) {\n throw new Error(`[WhiteboardApp] cannot insert doc before mounted`);\n }\n switch (params.fileType) {\n case \"pdf\":\n case \"ppt\":\n return this.manager.addApp({\n kind: \"DocsViewer\",\n options: {\n scenePath: params.scenePath,\n title: params.title,\n scenes: params.scenes,\n },\n });\n case \"pptx\":\n return this.manager.addApp({\n kind: \"Slide\",\n options: {\n scenePath: params.scenePath,\n title: params.title,\n scenes: params.scenes,\n },\n attributes: {\n taskId: params.taskId,\n url: params.url,\n },\n });\n }\n }\n\n insertCodeEditor() {\n if (!this.manager) {\n throw new Error(`[WhiteboardApp] cannot insert app before mounted`);\n }\n return this.manager.addApp({\n kind: \"Monaco\",\n options: { title: \"Code Editor\" },\n });\n }\n\n insertGeoGebra() {\n if (!this.manager) {\n throw new Error(`[WhiteboardApp] cannot insert app before mounted`);\n }\n return this.manager.addApp({\n kind: \"GeoGebra\",\n options: { title: \"GeoGebra\" },\n });\n }\n\n insertCountdown() {\n if (!this.manager) {\n throw new Error(`[WhiteboardApp] cannot insert app before mounted`);\n }\n return this.manager.addApp({\n kind: \"Countdown\",\n options: { title: \"Countdown\" },\n });\n }\n\n insertMedia({ title, src }: InsertMediaParams) {\n if (!this.manager) {\n throw new Error(`[WhiteboardApp] cannot insert app before mounted`);\n }\n return this.manager.addApp({\n kind: BuiltinApps.MediaPlayer,\n options: { title },\n attributes: { src },\n });\n }\n\n async changeLanguage(language: Language) {\n try {\n await this.i18n?.changeLanguage(language);\n } finally {\n await this.forceUpdate();\n }\n }\n}\n\nexport function useInstance() {\n return useContext(Instance.Context);\n}\n","import { applyStyles } from \"../internal\";\nimport style from \"../style.scss?inline\";\n\nconst newEl = applyStyles(style);\n\nif (import.meta.hot) {\n import.meta.hot.dispose(data => {\n data.el = newEl;\n });\n import.meta.hot.accept(() => {\n const oldEl = import.meta.hot?.data.el;\n if (oldEl) {\n oldEl.innerText = newEl.innerText;\n newEl.remove();\n }\n });\n}\n","import type { ConversionResponse, SceneDefinition } from \"white-web-sdk\";\nimport type {\n InsertDocsParams,\n InsertMediaParams,\n Language,\n Layout,\n WhiteboardAppConfig,\n} from \"./internal\";\nimport { genUID, Instance, makeSlideParams } from \"./internal\";\n\nexport type {\n Language,\n Layout,\n WhiteboardAppConfig,\n InsertMediaParams,\n InsertDocsParams,\n};\n\nexport class WhiteboardApp {\n private readonly _instance: Instance;\n\n public constructor(readonly config: WhiteboardAppConfig) {\n this._instance = new Instance(config);\n }\n\n public get room() {\n return this._instance.room;\n }\n\n public get manager() {\n return this._instance.manager;\n }\n\n public get sdk() {\n return this._instance.sdk;\n }\n\n public get i18n() {\n return this._instance.i18n;\n }\n\n public get target(): HTMLElement | null {\n return this._instance.target;\n }\n\n public get collector(): HTMLElement | null {\n return this._instance.collector;\n }\n\n public bindElement(target?: HTMLElement | null) {\n this._instance.bindElement(target || null);\n }\n\n public bindCollector(collector?: HTMLElement | null) {\n this._instance.bindCollector(collector || null);\n }\n\n public get layout() {\n return this._instance.config.layout;\n }\n\n public updateLayout(layout?: Layout | undefined) {\n this._instance.updateLayout(layout);\n }\n\n public insertMedia(params: InsertMediaParams) {\n this._instance.insertMedia(params);\n }\n\n /**\n * Insert PDF/PPTX from conversion result.\n * @param status https://developer.netless.link/server-en/home/server-conversion#get-query-task-conversion-progress\n */\n public insertDocs(\n filename: string,\n status: ConversionResponse\n ): Promise<string | undefined>;\n\n /**\n * Manual way.\n */\n public insertDocs(params: InsertDocsParams): Promise<string | undefined>;\n\n public insertDocs(\n arg1: string | InsertDocsParams,\n arg2?: ConversionResponse\n ) {\n if (typeof arg1 === \"object\" && \"fileType\" in arg1) {\n return this._instance.insertDocs(arg1);\n } else if (arg2 && arg2.status !== \"Finished\") {\n throw new Error(\"[WhiteboardApp] cannot insert a converting doc\");\n } else if (arg2 && arg2.progress) {\n const scenes: SceneDefinition[] = arg2.progress.convertedFileList.map(\n (f, i) => ({\n name: String(i + 1),\n ppt: {\n src: f.conversionFileUrl,\n width: f.width,\n height: f.height,\n previewURL: f.preview,\n },\n })\n );\n const uid = genUID();\n const scenePath = `/${arg2.uuid}/${uid}`;\n const { scenesWithoutPPT, taskId, url } = makeSlideParams(scenes);\n if (taskId && url) {\n return this._instance.insertDocs({\n fileType: \"pptx\",\n scenePath,\n taskId,\n title: arg1,\n url,\n scenes: scenesWithoutPPT,\n });\n } else {\n return this._instance.insertDocs({\n fileType: \"pdf\",\n scenePath,\n scenes,\n title: arg1,\n });\n }\n }\n }\n\n public insertCodeEditor() {\n return this._instance.insertCodeEditor();\n }\n\n public insertGeoGebra() {\n return this._instance.insertGeoGebra();\n }\n\n public insertCountdown() {\n return this._instance.insertCountdown();\n }\n\n public changeLanguage(language: Language) {\n return this._instance.changeLanguage(language);\n }\n\n public dispose() {\n return this._instance.dispose();\n }\n}\n","import { useEffect, useRef } from \"react\";\n\nexport function useLastValue<T>(value: T) {\n const ref = useRef<T>(value);\n useEffect(() => {\n ref.current = value;\n }, [value]);\n return ref.current;\n}\n","import type { DependencyList } from \"react\";\nimport type { Player } from \"white-web-sdk\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { PlayerPhase } from \"white-web-sdk\";\nimport { useLastValue } from \"../../internal/hooks\";\n\nconst EMPTY_ARRAY: DependencyList = [];\n\nfunction useForceUpdate() {\n const [, forceUpdate_] = useState({});\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useCallback(() => forceUpdate_({}), EMPTY_ARRAY);\n}\n\nexport function usePlayerControl(player?: Player | null) {\n const togglePlay = useCallback(() => {\n if (player) {\n switch (player.phase) {\n case PlayerPhase.WaitingFirstFrame:\n case PlayerPhase.Pause:\n case PlayerPhase.Ended: {\n player.play();\n break;\n }\n case PlayerPhase.Playing: {\n player.pause();\n break;\n }\n }\n }\n }, [player]);\n\n const seekToProgressTime = useCallback(\n (time: number) => {\n if (player) {\n player.seekToProgressTime(time);\n }\n },\n [player]\n );\n\n const lastPlayer = useLastValue(player);\n\n const forceUpdate = useForceUpdate();\n\n const setSpeed = useCallback(\n (speed: number) => {\n if (player) {\n player.playbackSpeed = speed;\n forceUpdate();\n }\n },\n [forceUpdate, player]\n );\n\n useEffect(() => {\n if (!lastPlayer && player) {\n forceUpdate();\n }\n }, [forceUpdate, lastPlayer, player]);\n\n useEffect(() => {\n if (player) {\n player.callbacks.on(\"onPhaseChanged\", forceUpdate);\n player.callbacks.on(\"onProgressTimeChanged\", forceUpdate);\n return () => {\n player.callbacks.off(\"onPhaseChanged\", forceUpdate);\n player.callbacks.off(\"onProgressTimeChanged\", forceUpdate);\n };\n }\n }, [forceUpdate, player]);\n\n const phase = player ? player.phase : PlayerPhase.WaitingFirstFrame;\n const currentTime = player ? player.progressTime : 0;\n const totalTime = player ? player.timeDuration : 0;\n const speed = player ? player.playbackSpeed : 1;\n\n return {\n phase,\n currentTime,\n totalTime,\n speed,\n setSpeed,\n togglePlay,\n seekToProgressTime,\n };\n}\n","import type { Placement } from \"tippy.js\";\nimport type { Theme } from \"../../../types\";\n\nimport clsx from \"clsx\";\nimport React, { forwardRef, type PropsWithChildren } from \"react\";\nimport Tippy from \"@tippyjs/react\";\n\nimport { TopOffset } from \"../../../theme\";\n\ntype ButtonProps = PropsWithChildren<{\n theme: Theme;\n content: React.ReactNode;\n disabled?: boolean;\n active?: boolean;\n onClick?: () => void;\n interactive?: boolean;\n placement?: Placement;\n}>;\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (props, ref) => {\n const {\n theme,\n content,\n disabled,\n active,\n onClick,\n interactive,\n placement = \"top\",\n children,\n } = props;\n\n return (\n <Tippy\n className=\"fastboard-tip\"\n content={content}\n interactive={interactive}\n theme={theme}\n disabled={disabled}\n placement={placement}\n offset={TopOffset}\n duration={300}\n >\n <button\n ref={ref}\n className={clsx(\"fastboard-player-control-btn\", theme, { active })}\n onClick={onClick}\n disabled={disabled}\n >\n {children}\n </button>\n </Tippy>\n );\n }\n);\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Loading = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8z\" fill={stroke}></path>\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Pause = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M14 19h4V5h-4M6 19h4V5H6v14z\" fill={stroke}></path>\n </svg>\n );\n};\n","import type { IconProps } from \"../../../types\";\n\nimport React from \"react\";\nimport { getStroke } from \"../../../theme\";\n\nexport const Play = (props: IconProps) => {\n const stroke = getStroke(props);\n return (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M8 5.14v14l11-7l-11-7z\" fill={stroke}></path>\n </svg>\n );\n};\n","import { memo } from \"react\";\nimport { Loading } from \"./Loading\";\nimport { Pause } from \"./Pause\";\nimport { Play } from \"./Play\";\n\nexport const Icons = {\n Play: memo(Play),\n Pause: memo(Pause),\n Loading: memo(Loading),\n};\n","import type { CommonProps, GenericIcon } from \"../../types\";\nimport Tippy from \"@tippyjs/react\";\nimport clsx from \"clsx\";\nimport RcSlider from \"rc-slider\";\nimport React, { useEffect, useState } from \"react\";\nimport { PlayerPhase, type Player } from \"white-web-sdk\";\n\nimport { Icon } from \"../../icons\";\nimport { themes, TopOffset } from \"../../theme\";\nimport { Button } from \"./components/Button\";\nimport { Icons } from \"./icons\";\nimport { usePlayerControl } from \"./hooks\";\n\nexport type PlayerControlProps = {\n autoHide?: boolean;\n player?: Player;\n} & Omit<CommonProps, \"room\"> &\n GenericIcon<\"play\" | \"pause\" | \"loading\">;\n\nexport const name = \"fastboard-player-control\";\n\nexport function PlayerControl({\n autoHide = false,\n player: player_,\n theme = \"light\",\n i18n,\n ...icons\n}: PlayerControlProps) {\n const [currentTime, setCurrentTime] = useState(0);\n const player = usePlayerControl(player_);\n\n useEffect(() => {\n setCurrentTime(player.currentTime);\n }, [player.currentTime]);\n\n useEffect(() => {\n if (player.currentTime !== currentTime) {\n player.seekToProgressTime(currentTime);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentTime]);\n\n const isLoading =\n player.phase === PlayerPhase.WaitingFirstFrame ||\n player.phase === PlayerPhase.Buffering;\n const isPlaying = player.phase === PlayerPhase.Playing;\n\n const { activeColor } = themes[theme];\n\n return (\n <div className={clsx(name, theme, { \"auto-hide\": autoHide })}>\n <button\n className={clsx(\n `${name}-btn`,\n isLoading ? \"loading\" : isPlaying ? \"pause\" : \"play\",\n theme\n )}\n disabled={isLoading}\n onClick={player.togglePlay}\n >\n <Icon\n fallback={\n isLoading ? (\n <Icons.Loading theme={theme} />\n ) : isPlaying ? (\n <Icons.Pause theme={theme} />\n ) : (\n <Icons.Play theme={theme} />\n )\n }\n src={\n isLoading\n ? icons.loadingIcon\n : isPlaying\n ? icons.pauseIcon\n : icons.playIcon\n }\n alt={isLoading ? \"[loading]\" : isPlaying ? \"[pause]\" : \"[play]\"}\n />\n </button>\n <span className={clsx(`${name}-slider`, { loading: isLoading }, theme)}>\n <RcSlider\n disabled={isLoading}\n trackStyle={{ background: activeColor }}\n handleStyle={{ border: `1px solid ${activeColor}` }}\n value={currentTime}\n onChange={setCurrentTime}\n min={0}\n max={player.totalTime}\n step={100}\n />\n </span>\n <span className={clsx(`${name}-current`, theme)}>\n {renderTime(player.currentTime)}\n </span>\n <span className={clsx(`${name}-slash`, theme)}>/</span>\n <span className={clsx(`${name}-total`, theme)}>\n {renderTime(player.totalTime)}\n </span>\n <span className={`${name}-btn-interactive`}>\n <Tippy\n className=\"fastboard-tip\"\n content={renderSpeeds(player)}\n theme={theme}\n placement=\"top-end\"\n trigger=\"click\"\n offset={TopOffset}\n arrow={false}\n interactive\n >\n <Button content={i18n?.t(\"speed\")} theme={theme} disabled={isLoading}>\n <span className={clsx(`${name}-speed-text`, theme)}>\n {player.speed}x\n </span>\n </Button>\n </Tippy>\n </span>\n </div>\n );\n}\n\nfunction renderTime(ms: number) {\n let seconds = ms / 1000;\n const minutes = Math.floor(seconds / 60);\n seconds = Math.floor(seconds) % 60;\n\n return (\n `${String(minutes).padStart(2, \"0\")}` +\n `:${String(seconds).padStart(2, \"0\")}`\n );\n}\n\nconst Speeds = [2.0, 1.5, 1.25, 1.0, 0.75, 0.5];\n\nfunction renderSpeeds({\n speed: current,\n setSpeed,\n}: {\n speed: number;\n setSpeed: (speed: number) => void;\n}) {\n return (\n <div className={clsx(`${name}-panel`, \"speed\")}>\n {Speeds.map(speed => (\n <button\n className={clsx(`${name}-btn`, \"speed\", {\n active: speed === current,\n })}\n key={speed}\n onClick={() => setSpeed(speed)}\n >\n {speed}x\n </button>\n ))}\n </div>\n );\n}\n","import type { WhiteboardApp } from \"./index\";\n\nimport React, { forwardRef, useEffect, useRef } from \"react\";\nimport { useLastValue } from \"./internal/hooks\";\n\n// https://itnext.io/reusing-the-ref-from-forwardref-with-react-hooks-4ce9df693dd\nfunction useCombinedRefs<T>(...refs: React.Ref<T>[]) {\n const targetRef = useRef<T | null>(null);\n\n useEffect(() => {\n for (const ref of refs) {\n if (!ref) continue;\n\n if (typeof ref === \"function\") {\n ref(targetRef.current);\n } else {\n (ref as typeof targetRef).current = targetRef.current;\n }\n }\n }, [refs]);\n\n return targetRef;\n}\n\n/**\n * @example\n * let app = await createWhiteboardApp(config)\n * <Fastboard app={app} />\n * await app.dispose()\n */\nexport const Fastboard = forwardRef<\n HTMLDivElement,\n { app?: WhiteboardApp | null } & React.DetailedHTMLProps<\n React.HTMLAttributes<HTMLDivElement>,\n HTMLDivElement\n >\n>(({ app, ...restProps }, outerRef) => {\n const innerRef = useRef<HTMLDivElement>(null);\n const ref = useCombinedRefs(outerRef, innerRef);\n const previous = useLastValue(app);\n\n useEffect(() => {\n if (previous && previous !== app) {\n previous.bindElement(null);\n }\n if (app) {\n app.bindElement(ref.current);\n }\n }, [app, previous, ref]);\n\n return <div className=\"fastboard\" {...restProps} ref={ref} />;\n});\n","import { WindowManager } from \"@netless/window-manager\";\n\nimport \"./behaviors/register-apps\";\nimport \"./behaviors/style\";\n\nimport { WhiteboardApp, type WhiteboardAppConfig } from \"./WhiteboardApp\";\n\nexport { version } from \"../package.json\";\nexport {\n PageControl,\n usePageControl,\n type PageControlProps,\n} from \"./components/PageControl\";\nexport {\n RedoUndo,\n useRedoUndo,\n type RedoUndoProps,\n} from \"./components/RedoUndo\";\nexport { Toolbar, useToolbar, type ToolbarProps } from \"./components/Toolbar\";\nexport {\n ZoomControl,\n useZoomControl,\n type ZoomControlProps,\n} from \"./components/ZoomControl\";\nexport {\n PlayerControl,\n usePlayerControl,\n type PlayerControlProps,\n} from \"./components/PlayerControl\";\nexport {};\n\nexport * from \"./WhiteboardApp\";\nexport * from \"./react\";\n\nexport const register = WindowManager.register.bind(WindowManager);\n\n/**\n * @example\n * let app = await createWhiteboardApp(config)\n * app.bindElement(el)\n */\nexport async function createWhiteboardApp(\n config: WhiteboardAppConfig\n): Promise<WhiteboardApp> {\n const app = new WhiteboardApp(config);\n // @ts-expect-error // eslint-disable-line\n await app._instance.readyPromise;\n return app;\n}\n"],"names":["require$$0","jsxRuntimeModule","jsxRuntime.jsx","jsxRuntime.jsxs","jsxRuntime.Fragment","fallback","src","alt","Apps","props","stroke","getStroke","Arrow","Circle","Clean","Clicker","Collapse","Diamond","Down","Eraser","Expand","Line","Pencil","Rectangle","Selector","SpeechBalloon","Star","Text","Triangle","Up","Icons","Button","forwardRef","ref","content","disabled","active","onClick","interactive","placement","children","writable","theme","useContext","ToolbarContext","includes","RightOffset","undefined","clsx","name","scrollTo","icons","scrollUp","useCallback","ItemHeight","upIconDisable","upIcon","scrollDown","downIconDisable","downIcon","text","hotkey","toUpperCase","app","useInstance","setAppliance","memberState","i18n","changeAppliance","ApplianceNames","clicker","shortcut","config","joinRoom","hotKeys","changeToClick","appliance","currentApplianceName","renderToolTip","t","clickerIconDisable","clickerIcon","selector","defaultHotKeys","changeToSelector","selectorIconDisable","selectorIcon","eraser","changeToEraser","eraserIconDisable","eraserIcon","cleanCurrentScene","cleanIconDisable","cleanIcon","button","appsIconDisable","appsIcon","renderAppsButtonContent","vscodePNG","insertCodeEditor","bind","geogebraPNG","insertGeoGebra","countdownPNG","insertCountdown","title","colors","colorKeys","Object","keys","setStrokeColor","strokeColor","map","key","isEqualArray","background","ev","stopPropagation","setStrokeWidth","activeColor","themes","strokeWidth","border","pencil","changeToPencil","renderPencilButtonContent","pencilIconDisable","pencilIcon","changeToText","renderTextButtonContent","textIconDisable","textIcon","ShapeTypes","Set","ApplianceShapes","Shapes","shape","shapeType","has","CurrentIcon","ShapesMap","renderShapesButtonContent","Appliance","Icon","current","Content","React","memo","useRef","scrollTop","setScrollTop","useState","parentHeight","setParentHeight","hasAppButton","toolbar","apps","enable","needScroll","ItemsCount","sectionHeight","clamp","MinHeight","MaxHeight","scrollBuffer","Math","max","disableScrollUp","disableScrollDown","height","container","parentElement","paddingTop","paddingBottom","getComputedStyle","padding","parseInt","resizeObserver","ResizeObserver","getBoundingClientRect","observe","disconnect","overflow","Mask","rootElement","element","document","createElement","style","position","appendChild","toolbarRect","halfHeight","top","left","width","removeChild","ReactDOM","createPortal","createContext","EmptyToolbarHook","Toolbar","room","manager","expanded","setExpanded","hook","useToolbar","toolbarRef","onHover","setOnHover","pointEvents","setPointEvents","toggle","e","x","transition","duration","pointerEvents","collapsePNG","expandPNG","expandIconDisable","expandIcon","color","undoIcon","undoIconDisable","redoIcon","redoIconDisable","useWritable","redoSteps","undoSteps","redo","undo","useRedoUndo","TopOffset","resetIcon","resetIconDisable","minusIcon","minusIconDisable","plusIcon","plusIconDisable","scale","resetCamera","zoomIn","zoomOut","useZoomControl","ceil","addIcon","addIconDisable","prevIcon","prevIconDisable","nextIcon","nextIconDisable","usePageControl","pageIndex","pageCount","actions","prevPage","nextPage","addPage","instance","mux","Lock","useWhiteboard","schedule","mount","unmount","hideControls","useHideControls","showControls","RedoUndo","redo_undo","ZoomControl","zoom_control","PageControl","page_control","layout","constructor","sdk","ready","resolveReady","readyPromise","target","collector","refreshReadyPromise","initialize","Promise","resolve","noop","essentials","mountWhiteboard","sdkConfig","managerConfig","language","accept","bindElement","unmountComponentAtNode","forceUpdate","bindCollector","bindCollectorContainer","updateLayout","render","dispose","node","Error","bindContainer","destroy","insertDocs","params","fileType","addApp","kind","options","scenePath","scenes","attributes","taskId","url","insertMedia","BuiltinApps","MediaPlayer","changeLanguage","Context","Instance","Loading","Pause","Play","autoHide","player","player_","currentTime","setCurrentTime","usePlayerControl","seekToProgressTime","isLoading","phase","PlayerPhase","WaitingFirstFrame","Buffering","isPlaying","Playing","togglePlay","loadingIcon","pauseIcon","playIcon","loading","totalTime","renderTime","renderSpeeds","speed","ms","seconds","minutes","floor","String","padStart","Speeds","setSpeed","refs","targetRef","Fastboard","outerRef","restProps","innerRef","useCombinedRefs","previous","useLastValue"],"mappings":"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"}
|
package/dist/svelte.cjs.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports[Symbol.toStringTag]="Module";var a=require("svelte/store"),n=require("./index.cjs.js");require("@netless/window-manager");require("white-web-sdk");require("i18next");require("react");require("react-dom");require("framer-motion");require("clsx");require("@tippyjs/react");require("rc-slider");function o(i,t){return a.readable(null,s=>{let e=null;n.createWhiteboardApp(t).then(r=>{s(e=r)});const u=i.subscribe(r=>{r&&e&&e.bindElement(r)});return()=>{u(),e&&e.dispose()}})}exports.useFastboard=o;
|
|
2
|
-
//# sourceMappingURL=svelte.cjs.js.map
|
package/dist/svelte.cjs.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"svelte.cjs.js","sources":["../src/svelte.ts"],"sourcesContent":["import { readable, type Readable } from \"svelte/store\";\nimport { createWhiteboardApp } from \"./index\";\n\nimport type { WhiteboardApp, WhiteboardAppConfig } from \"./WhiteboardApp\";\n\nexport type FastBoardConfig = WhiteboardAppConfig;\n\n/**\n * @example\n * ```svelte\n * <script>\n * let ref = writable(null)\n * let app = useFastboard(ref, { sdkConfig, joinRoom })\n * if (app) {\n * app.insertDocs({...})\n * }\n * </script>\n * <div style=\"width: 100%; height: 100%\" bind:this={$ref} />\n * ```\n */\nexport function useFastboard(\n ref: Readable<HTMLElement | null>,\n config: FastBoardConfig\n): Readable<WhiteboardApp | null> {\n return readable<WhiteboardApp | null>(null, set => {\n let app_: WhiteboardApp | null = null;\n\n createWhiteboardApp(config).then(app => {\n set((app_ = app));\n });\n\n const dispose = ref.subscribe(div => {\n if (div && app_) {\n app_.bindElement(div);\n }\n });\n\n return () => {\n dispose();\n if (app_) {\n app_.dispose();\n }\n };\n });\n}\n"],"names":["readable"],"mappings":"2XAqBE,EACA,EACgC,OACzBA,YAA+B,KAAM,GAAO,IAC7C,GAA6B,2BAEb,GAAQ,KAAK,GAAO,GACjC,EAAO,UAGR,GAAU,EAAI,UAAU,GAAO,CAC/B,GAAO,KACJ,YAAY,WAId,IAAM,KAEP,KACG"}
|
package/dist/svelte.es.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { readable } from "svelte/store";
|
|
2
|
-
import { createWhiteboardApp } from "./index.es.js";
|
|
3
|
-
import "@netless/window-manager";
|
|
4
|
-
import "white-web-sdk";
|
|
5
|
-
import "i18next";
|
|
6
|
-
import "react";
|
|
7
|
-
import "react-dom";
|
|
8
|
-
import "framer-motion";
|
|
9
|
-
import "clsx";
|
|
10
|
-
import "@tippyjs/react";
|
|
11
|
-
import "rc-slider";
|
|
12
|
-
function useFastboard(ref, config) {
|
|
13
|
-
return readable(null, (set) => {
|
|
14
|
-
let app_ = null;
|
|
15
|
-
createWhiteboardApp(config).then((app) => {
|
|
16
|
-
set(app_ = app);
|
|
17
|
-
});
|
|
18
|
-
const dispose = ref.subscribe((div) => {
|
|
19
|
-
if (div && app_) {
|
|
20
|
-
app_.bindElement(div);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
return () => {
|
|
24
|
-
dispose();
|
|
25
|
-
if (app_) {
|
|
26
|
-
app_.dispose();
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
export { useFastboard };
|
|
32
|
-
//# sourceMappingURL=svelte.es.js.map
|
package/dist/svelte.es.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"svelte.es.js","sources":["../src/svelte.ts"],"sourcesContent":["import { readable, type Readable } from \"svelte/store\";\nimport { createWhiteboardApp } from \"./index\";\n\nimport type { WhiteboardApp, WhiteboardAppConfig } from \"./WhiteboardApp\";\n\nexport type FastBoardConfig = WhiteboardAppConfig;\n\n/**\n * @example\n * ```svelte\n * <script>\n * let ref = writable(null)\n * let app = useFastboard(ref, { sdkConfig, joinRoom })\n * if (app) {\n * app.insertDocs({...})\n * }\n * </script>\n * <div style=\"width: 100%; height: 100%\" bind:this={$ref} />\n * ```\n */\nexport function useFastboard(\n ref: Readable<HTMLElement | null>,\n config: FastBoardConfig\n): Readable<WhiteboardApp | null> {\n return readable<WhiteboardApp | null>(null, set => {\n let app_: WhiteboardApp | null = null;\n\n createWhiteboardApp(config).then(app => {\n set((app_ = app));\n });\n\n const dispose = ref.subscribe(div => {\n if (div && app_) {\n app_.bindElement(div);\n }\n });\n\n return () => {\n dispose();\n if (app_) {\n app_.dispose();\n }\n };\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;;sBAqBE,KACA,QACgC;SACzB,SAA+B,MAAM,SAAO;QAC7C,OAA6B;wBAEb,QAAQ,KAAK,SAAO;UACjC,OAAO;AAAA;UAGR,UAAU,IAAI,UAAU,SAAO;UAC/B,OAAO,MAAM;aACV,YAAY;AAAA;AAAA;WAId,MAAM;;UAEP,MAAM;aACH;AAAA;AAAA;AAAA;AAAA;;"}
|
package/dist/vue.cjs.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports[Symbol.toStringTag]="Module";var t=require("vue-demi"),o=require("./index.cjs.js");require("@netless/window-manager");require("white-web-sdk");require("i18next");require("react");require("react-dom");require("framer-motion");require("clsx");require("@tippyjs/react");require("rc-slider");function n(u){var e;const r=t.unref(u);return(e=r==null?void 0:r.$el)!=null?e:r}function s(u){return t.getCurrentScope()?(t.onScopeDispose(u),!0):!1}function l(u,r){const e=t.shallowRef(null),i=t.computed(()=>n(u));return o.createWhiteboardApp(r).then(a=>{e.value=a}),t.watchEffect(()=>{i.value&&e.value&&e.value.bindElement(i.value)}),s(()=>{e.value&&e.value.dispose()}),e}exports.unrefElement=n;exports.useFastboard=l;
|
|
2
|
-
//# sourceMappingURL=vue.cjs.js.map
|
package/dist/vue.cjs.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vue.cjs.js","sources":["../src/vue.ts"],"sourcesContent":["import type { ComponentPublicInstance, Ref } from \"vue-demi\";\nimport {\n computed,\n getCurrentScope,\n onScopeDispose,\n shallowRef,\n unref,\n watchEffect,\n} from \"vue-demi\";\nimport { createWhiteboardApp } from \"./index\";\n\nimport type { WhiteboardApp, WhiteboardAppConfig } from \"./WhiteboardApp\";\n\nexport type FastBoardConfig = WhiteboardAppConfig;\n\nexport type MaybeRef<T> = T | Ref<T>;\nexport type VueInstance = ComponentPublicInstance;\nexport type MaybeElementRef = MaybeRef<\n HTMLElement | SVGElement | VueInstance | undefined | null\n>;\n\n/**\n * Get the dom element of a ref of element or Vue component instance\n */\nexport function unrefElement(elRef: MaybeElementRef) {\n const plain = unref(elRef);\n return (plain as VueInstance)?.$el ?? plain;\n}\n\nfunction tryOnScopeDispose(fn: () => void) {\n if (getCurrentScope()) {\n onScopeDispose(fn);\n return true;\n }\n return false;\n}\n\n/**\n * @example\n * ```vue\n * <script setup>\n * const el = ref(null)\n * const app = useFastboard(el, { sdkConfig, joinRoom })\n * if (app.value) {\n * app.value.insertDocs({...})\n * }\n * </script>\n * <template>\n * <div style=\"width: 100%; height: 100%\" ref=\"el\"></div>\n * </template>\n * ```\n */\nexport function useFastboard(el: MaybeElementRef, config: FastBoardConfig) {\n const app = shallowRef<WhiteboardApp | null>(null);\n const target = computed(() => unrefElement(el));\n\n createWhiteboardApp(config).then(app_ => {\n app.value = app_;\n });\n\n watchEffect(() => {\n if (target.value && app.value) {\n app.value.bindElement(target.value);\n }\n });\n\n tryOnScopeDispose(() => {\n if (app.value) {\n app.value.dispose();\n }\n });\n\n return app;\n}\n"],"names":["unref","getCurrentScope","shallowRef","computed"],"mappings":"uXAwB6B,EAAwB,YAC7C,GAAQA,QAAM,SACZ,oBAAuB,MAAvB,OAA8B,EAGxC,WAA2B,EAAgB,OACrCC,uCACa,GACR,IAEF,cAkBoB,EAAqB,EAAyB,MACnE,GAAMC,aAAiC,MACvC,EAASC,WAAS,IAAM,EAAa,iCAEvB,GAAQ,KAAK,GAAQ,GACnC,MAAQ,kBAGF,IAAM,CACZ,EAAO,OAAS,EAAI,SAClB,MAAM,YAAY,EAAO,WAIf,IAAM,CAClB,EAAI,SACF,MAAM,YAIP"}
|
package/dist/vue.es.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { unref, shallowRef, computed, watchEffect, getCurrentScope, onScopeDispose } from "vue-demi";
|
|
2
|
-
import { createWhiteboardApp } from "./index.es.js";
|
|
3
|
-
import "@netless/window-manager";
|
|
4
|
-
import "white-web-sdk";
|
|
5
|
-
import "i18next";
|
|
6
|
-
import "react";
|
|
7
|
-
import "react-dom";
|
|
8
|
-
import "framer-motion";
|
|
9
|
-
import "clsx";
|
|
10
|
-
import "@tippyjs/react";
|
|
11
|
-
import "rc-slider";
|
|
12
|
-
function unrefElement(elRef) {
|
|
13
|
-
var _a;
|
|
14
|
-
const plain = unref(elRef);
|
|
15
|
-
return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
|
|
16
|
-
}
|
|
17
|
-
function tryOnScopeDispose(fn) {
|
|
18
|
-
if (getCurrentScope()) {
|
|
19
|
-
onScopeDispose(fn);
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
function useFastboard(el, config) {
|
|
25
|
-
const app = shallowRef(null);
|
|
26
|
-
const target = computed(() => unrefElement(el));
|
|
27
|
-
createWhiteboardApp(config).then((app_) => {
|
|
28
|
-
app.value = app_;
|
|
29
|
-
});
|
|
30
|
-
watchEffect(() => {
|
|
31
|
-
if (target.value && app.value) {
|
|
32
|
-
app.value.bindElement(target.value);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
tryOnScopeDispose(() => {
|
|
36
|
-
if (app.value) {
|
|
37
|
-
app.value.dispose();
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
return app;
|
|
41
|
-
}
|
|
42
|
-
export { unrefElement, useFastboard };
|
|
43
|
-
//# sourceMappingURL=vue.es.js.map
|
package/dist/vue.es.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vue.es.js","sources":["../src/vue.ts"],"sourcesContent":["import type { ComponentPublicInstance, Ref } from \"vue-demi\";\nimport {\n computed,\n getCurrentScope,\n onScopeDispose,\n shallowRef,\n unref,\n watchEffect,\n} from \"vue-demi\";\nimport { createWhiteboardApp } from \"./index\";\n\nimport type { WhiteboardApp, WhiteboardAppConfig } from \"./WhiteboardApp\";\n\nexport type FastBoardConfig = WhiteboardAppConfig;\n\nexport type MaybeRef<T> = T | Ref<T>;\nexport type VueInstance = ComponentPublicInstance;\nexport type MaybeElementRef = MaybeRef<\n HTMLElement | SVGElement | VueInstance | undefined | null\n>;\n\n/**\n * Get the dom element of a ref of element or Vue component instance\n */\nexport function unrefElement(elRef: MaybeElementRef) {\n const plain = unref(elRef);\n return (plain as VueInstance)?.$el ?? plain;\n}\n\nfunction tryOnScopeDispose(fn: () => void) {\n if (getCurrentScope()) {\n onScopeDispose(fn);\n return true;\n }\n return false;\n}\n\n/**\n * @example\n * ```vue\n * <script setup>\n * const el = ref(null)\n * const app = useFastboard(el, { sdkConfig, joinRoom })\n * if (app.value) {\n * app.value.insertDocs({...})\n * }\n * </script>\n * <template>\n * <div style=\"width: 100%; height: 100%\" ref=\"el\"></div>\n * </template>\n * ```\n */\nexport function useFastboard(el: MaybeElementRef, config: FastBoardConfig) {\n const app = shallowRef<WhiteboardApp | null>(null);\n const target = computed(() => unrefElement(el));\n\n createWhiteboardApp(config).then(app_ => {\n app.value = app_;\n });\n\n watchEffect(() => {\n if (target.value && app.value) {\n app.value.bindElement(target.value);\n }\n });\n\n tryOnScopeDispose(() => {\n if (app.value) {\n app.value.dispose();\n }\n });\n\n return app;\n}\n"],"names":[],"mappings":";;;;;;;;;;;sBAwB6B,OAAwB;;QAC7C,QAAQ,MAAM;SACZ,qCAAuB,QAAvB,YAA8B;AAAA;AAGxC,2BAA2B,IAAgB;MACrC,mBAAmB;mBACN;WACR;AAAA;SAEF;AAAA;sBAkBoB,IAAqB,QAAyB;QACnE,MAAM,WAAiC;QACvC,SAAS,SAAS,MAAM,aAAa;sBAEvB,QAAQ,KAAK,UAAQ;QACnC,QAAQ;AAAA;cAGF,MAAM;QACZ,OAAO,SAAS,IAAI,OAAO;UACzB,MAAM,YAAY,OAAO;AAAA;AAAA;oBAIf,MAAM;QAClB,IAAI,OAAO;UACT,MAAM;AAAA;AAAA;SAIP;AAAA;;"}
|