@netless/fastboard-react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/LICENSE.txt +21 -0
  2. package/dist/behaviors/style.d.ts +1 -0
  3. package/dist/components/Fastboard.d.ts +15 -0
  4. package/dist/components/PageControl/PageControl.d.ts +5 -0
  5. package/dist/components/PageControl/hooks.d.ts +9 -0
  6. package/dist/components/PageControl/index.d.ts +2 -0
  7. package/dist/components/PlayerControl/PlayerControl.d.ts +9 -0
  8. package/dist/components/PlayerControl/hooks.d.ts +11 -0
  9. package/dist/components/PlayerControl/icons/Loading.d.ts +3 -0
  10. package/dist/components/PlayerControl/icons/Pause.d.ts +3 -0
  11. package/dist/components/PlayerControl/icons/Play.d.ts +3 -0
  12. package/dist/components/PlayerControl/icons/index.d.ts +6 -0
  13. package/dist/components/PlayerControl/index.d.ts +2 -0
  14. package/dist/components/RedoUndo/RedoUndo.d.ts +5 -0
  15. package/dist/components/RedoUndo/hooks.d.ts +6 -0
  16. package/dist/components/RedoUndo/index.d.ts +2 -0
  17. package/dist/components/Toolbar/Content.d.ts +2 -0
  18. package/dist/components/Toolbar/Toolbar.d.ts +14 -0
  19. package/dist/components/Toolbar/components/ApplianceButtons.d.ts +7 -0
  20. package/dist/components/Toolbar/components/AppsButton.d.ts +6 -0
  21. package/dist/components/Toolbar/components/ColorBox.d.ts +2 -0
  22. package/dist/components/Toolbar/components/CutLine.d.ts +2 -0
  23. package/dist/components/Toolbar/components/Mask.d.ts +7 -0
  24. package/dist/components/Toolbar/components/PencilButton.d.ts +2 -0
  25. package/dist/components/Toolbar/components/ShapesButton.d.ts +3 -0
  26. package/dist/components/Toolbar/components/Slider.d.ts +2 -0
  27. package/dist/components/Toolbar/components/TextButton.d.ts +2 -0
  28. package/dist/components/Toolbar/components/UpDownButtons.d.ts +7 -0
  29. package/dist/components/Toolbar/const.d.ts +18 -0
  30. package/dist/components/Toolbar/hooks.d.ts +12 -0
  31. package/dist/components/Toolbar/icons/Apps.d.ts +3 -0
  32. package/dist/components/Toolbar/icons/Arrow.d.ts +3 -0
  33. package/dist/components/Toolbar/icons/Circle.d.ts +3 -0
  34. package/dist/components/Toolbar/icons/Clean.d.ts +3 -0
  35. package/dist/components/Toolbar/icons/Clicker.d.ts +3 -0
  36. package/dist/components/Toolbar/icons/Collapse.d.ts +3 -0
  37. package/dist/components/Toolbar/icons/Diamond.d.ts +3 -0
  38. package/dist/components/Toolbar/icons/Down.d.ts +3 -0
  39. package/dist/components/Toolbar/icons/Eraser.d.ts +3 -0
  40. package/dist/components/Toolbar/icons/Expand.d.ts +3 -0
  41. package/dist/components/Toolbar/icons/Line.d.ts +3 -0
  42. package/dist/components/Toolbar/icons/Pencil.d.ts +3 -0
  43. package/dist/components/Toolbar/icons/Rectangle.d.ts +3 -0
  44. package/dist/components/Toolbar/icons/Selector.d.ts +3 -0
  45. package/dist/components/Toolbar/icons/SpeechBalloon.d.ts +3 -0
  46. package/dist/components/Toolbar/icons/Star.d.ts +3 -0
  47. package/dist/components/Toolbar/icons/Text.d.ts +3 -0
  48. package/dist/components/Toolbar/icons/Triangle.d.ts +3 -0
  49. package/dist/components/Toolbar/icons/Up.d.ts +3 -0
  50. package/dist/components/Toolbar/icons/index.d.ts +22 -0
  51. package/dist/components/Toolbar/index.d.ts +2 -0
  52. package/dist/components/ZoomControl/ZoomControl.d.ts +5 -0
  53. package/dist/components/ZoomControl/hooks.d.ts +7 -0
  54. package/dist/components/ZoomControl/index.d.ts +2 -0
  55. package/dist/components/hooks.d.ts +13 -0
  56. package/dist/i18n/index.d.ts +12 -0
  57. package/dist/icons/ChevronLeft.d.ts +3 -0
  58. package/dist/icons/ChevronRight.d.ts +3 -0
  59. package/dist/icons/FilePlus.d.ts +3 -0
  60. package/dist/icons/Minus.d.ts +3 -0
  61. package/dist/icons/Plus.d.ts +3 -0
  62. package/dist/icons/Redo.d.ts +3 -0
  63. package/dist/icons/Reset.d.ts +3 -0
  64. package/dist/icons/Undo.d.ts +3 -0
  65. package/dist/icons/index.d.ts +7 -0
  66. package/dist/index.d.ts +9 -0
  67. package/dist/index.js +2116 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/index.mjs +2083 -0
  70. package/dist/index.mjs.map +1 -0
  71. package/dist/internal/helpers.d.ts +16 -0
  72. package/dist/internal/hooks.d.ts +3 -0
  73. package/dist/internal/index.d.ts +2 -0
  74. package/dist/theme.d.ts +16 -0
  75. package/dist/typings.d.ts +10 -0
  76. package/package.json +41 -0
  77. package/src/behaviors/style.ts +4 -0
  78. package/src/components/Fastboard.scss +41 -0
  79. package/src/components/Fastboard.tsx +97 -0
  80. package/src/components/PageControl/PageControl.scss +80 -0
  81. package/src/components/PageControl/PageControl.tsx +105 -0
  82. package/src/components/PageControl/hooks.ts +67 -0
  83. package/src/components/PageControl/index.ts +2 -0
  84. package/src/components/PlayerControl/PlayerControl.scss +145 -0
  85. package/src/components/PlayerControl/PlayerControl.tsx +131 -0
  86. package/src/components/PlayerControl/components/Button.tsx +45 -0
  87. package/src/components/PlayerControl/hooks.ts +88 -0
  88. package/src/components/PlayerControl/icons/Loading.tsx +13 -0
  89. package/src/components/PlayerControl/icons/Pause.tsx +13 -0
  90. package/src/components/PlayerControl/icons/Play.tsx +13 -0
  91. package/src/components/PlayerControl/icons/index.ts +10 -0
  92. package/src/components/PlayerControl/index.ts +2 -0
  93. package/src/components/RedoUndo/RedoUndo.scss +56 -0
  94. package/src/components/RedoUndo/RedoUndo.tsx +76 -0
  95. package/src/components/RedoUndo/hooks.ts +18 -0
  96. package/src/components/RedoUndo/index.ts +2 -0
  97. package/src/components/Toolbar/Content.tsx +74 -0
  98. package/src/components/Toolbar/Toolbar.scss +281 -0
  99. package/src/components/Toolbar/Toolbar.tsx +116 -0
  100. package/src/components/Toolbar/components/ApplianceButtons.tsx +108 -0
  101. package/src/components/Toolbar/components/AppsButton.tsx +101 -0
  102. package/src/components/Toolbar/components/Button.tsx +46 -0
  103. package/src/components/Toolbar/components/ColorBox.tsx +55 -0
  104. package/src/components/Toolbar/components/CutLine.tsx +8 -0
  105. package/src/components/Toolbar/components/Mask.tsx +44 -0
  106. package/src/components/Toolbar/components/PencilButton.tsx +66 -0
  107. package/src/components/Toolbar/components/ShapesButton.tsx +128 -0
  108. package/src/components/Toolbar/components/Slider.tsx +26 -0
  109. package/src/components/Toolbar/components/TextButton.tsx +62 -0
  110. package/src/components/Toolbar/components/UpDownButtons.tsx +49 -0
  111. package/src/components/Toolbar/components/assets/cocos.png +0 -0
  112. package/src/components/Toolbar/components/assets/collapsed.png +0 -0
  113. package/src/components/Toolbar/components/assets/countdown.png +0 -0
  114. package/src/components/Toolbar/components/assets/expanded.png +0 -0
  115. package/src/components/Toolbar/components/assets/geogebra.png +0 -0
  116. package/src/components/Toolbar/components/assets/vscode.png +0 -0
  117. package/src/components/Toolbar/const.ts +32 -0
  118. package/src/components/Toolbar/hooks.ts +68 -0
  119. package/src/components/Toolbar/icons/Apps.tsx +16 -0
  120. package/src/components/Toolbar/icons/Arrow.tsx +13 -0
  121. package/src/components/Toolbar/icons/Circle.tsx +13 -0
  122. package/src/components/Toolbar/icons/Clean.tsx +16 -0
  123. package/src/components/Toolbar/icons/Clicker.tsx +19 -0
  124. package/src/components/Toolbar/icons/Collapse.tsx +13 -0
  125. package/src/components/Toolbar/icons/Diamond.tsx +13 -0
  126. package/src/components/Toolbar/icons/Down.tsx +13 -0
  127. package/src/components/Toolbar/icons/Eraser.tsx +16 -0
  128. package/src/components/Toolbar/icons/Expand.tsx +13 -0
  129. package/src/components/Toolbar/icons/Line.tsx +13 -0
  130. package/src/components/Toolbar/icons/Pencil.tsx +16 -0
  131. package/src/components/Toolbar/icons/Rectangle.tsx +13 -0
  132. package/src/components/Toolbar/icons/Selector.tsx +13 -0
  133. package/src/components/Toolbar/icons/SpeechBalloon.tsx +17 -0
  134. package/src/components/Toolbar/icons/Star.tsx +17 -0
  135. package/src/components/Toolbar/icons/Text.tsx +13 -0
  136. package/src/components/Toolbar/icons/Triangle.tsx +13 -0
  137. package/src/components/Toolbar/icons/Up.tsx +13 -0
  138. package/src/components/Toolbar/icons/index.ts +42 -0
  139. package/src/components/Toolbar/index.ts +2 -0
  140. package/src/components/ZoomControl/ZoomControl.scss +80 -0
  141. package/src/components/ZoomControl/ZoomControl.tsx +94 -0
  142. package/src/components/ZoomControl/hooks.ts +52 -0
  143. package/src/components/ZoomControl/index.ts +2 -0
  144. package/src/components/hooks.ts +59 -0
  145. package/src/i18n/en.json +31 -0
  146. package/src/i18n/index.ts +29 -0
  147. package/src/i18n/zh-CN.json +32 -0
  148. package/src/icons/ChevronLeft.tsx +21 -0
  149. package/src/icons/ChevronRight.tsx +21 -0
  150. package/src/icons/FilePlus.tsx +18 -0
  151. package/src/icons/Minus.tsx +15 -0
  152. package/src/icons/Plus.tsx +15 -0
  153. package/src/icons/Redo.tsx +18 -0
  154. package/src/icons/Reset.tsx +19 -0
  155. package/src/icons/Undo.tsx +18 -0
  156. package/src/icons/index.tsx +11 -0
  157. package/src/index.ts +10 -0
  158. package/src/internal/helpers.ts +31 -0
  159. package/src/internal/hooks.ts +23 -0
  160. package/src/internal/index.ts +2 -0
  161. package/src/style.scss +29 -0
  162. package/src/theme.ts +36 -0
  163. package/src/typings.ts +15 -0
package/dist/index.js ADDED
@@ -0,0 +1,2116 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+ var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
25
+ var __objRest = (source, exclude) => {
26
+ var target = {};
27
+ for (var prop in source)
28
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
29
+ target[prop] = source[prop];
30
+ if (source != null && __getOwnPropSymbols)
31
+ for (var prop of __getOwnPropSymbols(source)) {
32
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
33
+ target[prop] = source[prop];
34
+ }
35
+ return target;
36
+ };
37
+ var __export = (target, all) => {
38
+ for (var name6 in all)
39
+ __defProp(target, name6, { get: all[name6], enumerable: true });
40
+ };
41
+ var __reExport = (target, module2, copyDefault, desc) => {
42
+ if (module2 && typeof module2 === "object" || typeof module2 === "function") {
43
+ for (let key of __getOwnPropNames(module2))
44
+ if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
45
+ __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
46
+ }
47
+ return target;
48
+ };
49
+ var __toESM = (module2, isNodeMode) => {
50
+ return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
51
+ };
52
+ var __toCommonJS = /* @__PURE__ */ ((cache) => {
53
+ return (module2, temp) => {
54
+ return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
55
+ };
56
+ })(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
57
+
58
+ // src/index.ts
59
+ var src_exports = {};
60
+ __export(src_exports, {
61
+ EmptyToolbarHook: () => EmptyToolbarHook,
62
+ Fastboard: () => Fastboard,
63
+ FastboardAppContext: () => FastboardAppContext,
64
+ PageControl: () => PageControl,
65
+ PlayerControl: () => PlayerControl,
66
+ RedoUndo: () => RedoUndo,
67
+ ScalePoints: () => ScalePoints,
68
+ ThemeContext: () => ThemeContext,
69
+ Toolbar: () => Toolbar,
70
+ ZoomControl: () => ZoomControl,
71
+ useBoxState: () => useBoxState,
72
+ useFastboardApp: () => useFastboardApp,
73
+ useFastboardValue: () => useFastboardValue,
74
+ useFocusedApp: () => useFocusedApp,
75
+ useHideControls: () => useHideControls,
76
+ useMaximized: () => useMaximized,
77
+ usePageControl: () => usePageControl,
78
+ usePlayerControl: () => usePlayerControl,
79
+ useRedoUndo: () => useRedoUndo,
80
+ useRoomState: () => useRoomState,
81
+ useTheme: () => useTheme,
82
+ useToolbar: () => useToolbar,
83
+ useWritable: () => useWritable,
84
+ useZoomControl: () => useZoomControl
85
+ });
86
+
87
+ // ../../node_modules/.pnpm/tsup@5.11.11_typescript@4.5.4/node_modules/tsup/assets/cjs_shims.js
88
+ var getImportMetaUrl = () => typeof document === "undefined" ? new URL("file:" + __filename).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
89
+ var importMetaUrl = getImportMetaUrl();
90
+
91
+ // src/internal/helpers.ts
92
+ function noop() {
93
+ return;
94
+ }
95
+ function applyStyles(css) {
96
+ const el = document.createElement("style");
97
+ el.appendChild(document.createTextNode(css));
98
+ document.head.appendChild(el);
99
+ return el;
100
+ }
101
+ function clamp(value, min, max) {
102
+ return value < min ? min : value > max ? max : value;
103
+ }
104
+ function isEqualArray(a, b) {
105
+ return a.length === b.length && a.every((e, i) => e === b[i]);
106
+ }
107
+ var defaultHotKeys = {
108
+ changeToSelector: "s",
109
+ changeToLaserPointer: "z",
110
+ changeToPencil: "p",
111
+ changeToRectangle: "r",
112
+ changeToEllipse: "c",
113
+ changeToEraser: "e",
114
+ changeToText: "t",
115
+ changeToStraight: "l",
116
+ changeToArrow: "a",
117
+ changeToHand: "h"
118
+ };
119
+
120
+ // src/internal/hooks.ts
121
+ var import_react = require("react");
122
+ function useLastValue(value) {
123
+ const ref = (0, import_react.useRef)(value);
124
+ (0, import_react.useEffect)(() => {
125
+ ref.current = value;
126
+ }, [value]);
127
+ return ref.current;
128
+ }
129
+ function useAsyncValue(fn) {
130
+ const [value, setValue] = (0, import_react.useState)(null);
131
+ (0, import_react.useEffect)(() => {
132
+ fn().then(setValue);
133
+ }, []);
134
+ return value;
135
+ }
136
+ function useForceUpdate() {
137
+ const [, forceUpdate] = (0, import_react.useState)({});
138
+ return (0, import_react.useCallback)(() => forceUpdate({}), []);
139
+ }
140
+
141
+ // src/style.scss?inline
142
+ var style_default = '.page-renderer-pages-container{position:relative;overflow:hidden}.page-renderer-page{position:absolute;top:0;left:0;will-change:transform;background-position:center;background-size:cover;background-repeat:no-repeat}.page-renderer-page-img{display:block;width:100%;height:auto;user-select:none}.netless-app-docs-viewer-static-scrollbar{position:absolute;top:0;right:0;z-index:2147483647;width:8px;min-height:30px;margin:0;padding:0;border:none;outline:none;border-radius:4px;background:rgba(68,78,96,.4);box-shadow:1px 1px 8px #ffffffb3;opacity:0;transition:background .4s,opacity .4s 3s,transform .2s;will-change:transform,height;user-select:none}.netless-app-docs-viewer-static-scrollbar.netless-app-docs-viewer-static-scrollbar-dragging{background:rgba(68,78,96,.6);opacity:1;transition:background .4s,opacity .4s 3s!important}.netless-app-docs-viewer-static-scrollbar:hover,.netless-app-docs-viewer-static-scrollbar:focus{background:rgba(68,78,96,.5)}.netless-app-docs-viewer-static-scrollbar:active{background:rgba(68,78,96,.6)}.netless-app-docs-viewer-content:hover .netless-app-docs-viewer-static-scrollbar{opacity:1;transition:background .4s,opacity .4s,transform .2s}.netless-app-docs-viewer-readonly .netless-app-docs-viewer-static-scrollbar{display:none}.netless-app-docs-viewer-static-pages:hover .netless-app-docs-viewer-static-scrollbar{opacity:1;transition:background .4s,opacity .4s,transform .2s}.netless-window-manager-playground{width:100%;height:100%;position:relative;z-index:1;overflow:hidden;user-select:none}.netless-window-manager-sizer{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;overflow:hidden;display:flex}.netless-window-manager-sizer-horizontal{flex-direction:column}.netless-window-manager-sizer:before,.netless-window-manager-sizer:after{flex:1;content:"";display:block}.netless-window-manager-chess-sizer:before,.netless-window-manager-chess-sizer:after{background-image:linear-gradient(45deg,#b0b0b0 25%,transparent 25%),linear-gradient(-45deg,#b0b0b0 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#b0b0b0 75%),linear-gradient(-45deg,transparent 75%,#b0b0b0 75%);background-color:#fff;background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px}.netless-window-manager-wrapper{position:relative;z-index:1;width:100%;height:100%;overflow:hidden}.netless-window-manager-main-view{width:100%;height:100%}.netless-window-manager-cursor-pencil-image,.netless-window-manager-cursor-eraser-image{width:26px;height:26px}.netless-window-manager-cursor-selector-image{width:24px;height:24px}.netless-window-manager-cursor-selector-avatar{border-radius:50%;border-style:solid;border-width:2px;border-color:#fff;margin-bottom:2px}.netless-window-manager-cursor-selector-avatar img{width:12px}.netless-window-manager-cursor-inner{border-radius:4px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:4px;padding-right:4px;font-size:12px}.netless-window-manager-cursor-inner-mellow{height:32px;border-radius:16px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:16px;padding-right:16px}.netless-window-manager-cursor-tag-name{font-size:12px;margin-left:4px;padding:2px 8px;border-radius:4px}.netless-window-manager-cursor-mid{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:26px;height:26px;z-index:2147483647;left:0;top:0;will-change:transform;transition:transform .05s;transform-origin:0 0;user-select:none}.netless-window-manager-cursor-pencil-offset{margin-left:-20px}.netless-window-manager-cursor-selector-offset{margin-left:-22px;margin-top:56px}.netless-window-manager-cursor-text-offset{margin-left:-30px;margin-top:18px}.netless-window-manager-cursor-shape-offset{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:180px;height:64px;margin-left:-30px;margin-top:12px}.netless-window-manager-cursor-name{width:100%;height:48px;display:flex;align-items:center;justify-content:center;position:absolute;top:-40px}.cursor-image-wrapper{display:flex;justify-content:center}.telebox-collector{position:absolute;right:10px;bottom:15px}.tele-fancy-scrollbar{overscroll-behavior:contain;overflow:auto;overflow-y:scroll;overflow-y:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.tele-fancy-scrollbar::-webkit-scrollbar{height:8px;width:8px}.tele-fancy-scrollbar::-webkit-scrollbar-track{background-color:transparent}.tele-fancy-scrollbar::-webkit-scrollbar-thumb{background-color:#444e601a;background-color:transparent;border-radius:4px;transition:background-color .4s}.tele-fancy-scrollbar:hover::-webkit-scrollbar-thumb{background-color:#444e601a}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:hover{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:active{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:vertical{min-height:50px}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-box{position:absolute;top:0;left:0;z-index:100;will-change:transform;transition:width .4s cubic-bezier(.4,.9,.71,1.02),height .4s cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .4s ease}.telebox-box-main{position:relative;width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden;background:#f9f9fc;box-shadow:0 4px 10px #2f419226;border-radius:6px;border:1px solid #e3e3ec}.telebox-titlebar-wrap{flex-shrink:0;position:relative;z-index:1}.telebox-content-wrap{flex:1;width:100%;overflow:hidden;display:flex;justify-content:center;align-items:center}.telebox-content{width:100%;height:100%;position:relative}.telebox-footer-wrap{flex-shrink:0;display:flex;flex-direction:column}.telebox-footer-wrap:before{content:"";display:block;flex:1}.telebox-resize-handle{position:absolute;z-index:2147483647}.telebox-n{width:100%;height:5px;left:0;top:-5px;cursor:n-resize}.telebox-s{width:100%;height:5px;left:0;bottom:-5px;cursor:s-resize}.telebox-w{width:5px;height:100%;left:-5px;top:0;cursor:w-resize}.telebox-e{width:5px;height:100%;right:-5px;top:0;cursor:e-resize}.telebox-nw{width:15px;height:15px;top:-5px;left:-5px;cursor:nw-resize}.telebox-ne{width:15px;height:15px;top:-5px;right:-5px;cursor:ne-resize}.telebox-se{width:15px;height:15px;bottom:-5px;right:-5px;cursor:se-resize}.telebox-sw{width:15px;height:15px;bottom:-5px;left:-5px;cursor:sw-resize}.telebox-track-mask{position:fixed;top:0;left:0;z-index:2147483647;width:100%;height:100%;background:rgba(0,0,0,.0001);cursor:move}.telebox-cursor-n{cursor:n-resize}.telebox-cursor-s{cursor:s-resize}.telebox-cursor-w{cursor:w-resize}.telebox-cursor-e{cursor:e-resize}.telebox-cursor-nw{cursor:nw-resize}.telebox-cursor-ne{cursor:ne-resize}.telebox-cursor-se{cursor:se-resize}.telebox-cursor-sw{cursor:sw-resize}.telebox-maximized .telebox-resize-handles,.telebox-no-resize .telebox-resize-handles{display:none}.telebox-maximized{box-shadow:none;transition:none}.telebox-minimized{will-change:transform;transition:width 50ms cubic-bezier(.4,.9,.71,1.02),height 50ms cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .6s ease;opacity:0;pointer-events:none;user-select:none}.telebox-transforming{will-change:transform;transition:opacity .6s cubic-bezier(.7,0,.84,0)}.telebox-readonly .telebox-resize-handle{cursor:initial!important;pointer-events:none!important}.telebox-color-scheme-dark .telebox-box-main{color:#e9e9e9;background:#212126;border-color:#43434d}.telebox-titlebar{box-sizing:border-box;height:26px;display:flex;align-items:center;padding:0 16px;background:#fff;user-select:none;border-bottom:1px solid #eeeef7;touch-action:manipulation}.telebox-title-area{overflow:hidden;position:relative;height:100%;flex:1;display:flex;align-items:center}.telebox-title{overflow:hidden;margin:0;padding:0;font-size:14px;font-weight:400;font-family:PingFangSC-Regular,PingFang SC;white-space:nowrap;word-break:keep-all;text-overflow:ellipsis;color:#191919}.telebox-drag-area{position:absolute;inset:0;margin:auto;z-index:10}.telebox-titlebar-btns{white-space:nowrap;word-break:keep-all;margin-left:auto;font-size:0}.telebox-titlebar-btn{width:22px;height:22px;padding:0;outline:0;border:none;background:0 0;cursor:pointer}.telebox-titlebar-btn~.telebox-titlebar-btn{margin-left:10px}.telebox-titlebar-btn-icon{width:22px;height:22px}.telebox-readonly .telebox-titlebar-btn{cursor:not-allowed}.telebox-titlebar-icon-minimize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPHBhdGggZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBkPSJNOSAxM2gxMHYxLjZIOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-titlebar-icon-maximize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPGcgZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBtYXNrPSJ1cmwoI2IpIj4KICAgICAgICAgICAgPHBhdGgKICAgICAgICAgICAgICAgIGQ9Ik0yMC40ODEgMTcuMWgxLjJ2NC41ODFIMTcuMXYtMS4yaDMuMzgxVjE3LjF6bS0xNC4xOTA1LS4wMDloMS4ydjMuMzgxaDMuMzgwOXYxLjJoLTQuNTgxdi00LjU4MXpNMTcuMSA2LjE5MDVoNC41ODF2NC41ODA5aC0xLjJ2LTMuMzgxSDE3LjF2LTEuMnptLTEwLjcwMDguMTA4N2g0Ljc5ODV2MS4ySDcuNTk5MnYzLjU5ODVoLTEuMlY2LjI5OTJ6IiAvPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg==)}.telebox-titlebar-icon-maximize.is-active{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjZ2MjZIMHoiIC8+CiAgICAgICAgPHBhdGggaWQ9ImMiIGQ9Ik0yNi44NjkgMEwyOCAxLjEzMVYyNi44N0wyNi44NjkgMjhIMS4xM0wwIDI2Ljg3VjEuMTMxTDEuMTMgMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEgMSkiPgogICAgICAgICAgICA8bWFzayBpZD0iYiIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNhIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tNC42NDI5LTQuNjQyOWgzNS4yODU4djM1LjI4NThILTQuNjQyOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8bWFzayBpZD0iZCIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNjIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tMTcuNTE2OCAxNEwxNC0xNy41MTY4IDQ1LjUxNjggMTQgMTQgNDUuNTE2OHoiIG1hc2s9InVybCgjZCkiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxwYXRoIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjIiCiAgICAgICAgICAgIGQ9Ik0xMC4wODg2IDIxLjQ4NjV2LTMuNjk2Nkg2LjM5Mk0yMS4zODU1IDEwLjE4OTVoLTMuNjk2NlY2LjQ5M00yMS40MDIgMTcuNzk4M2gtMy42OTY2djMuNjk2Nk0xMC4yNTAzIDYuMTQ5OHYzLjg5ODVINi4zNTE3IiAvPgogICAgPC9nPgo8L3N2Zz4K)}.telebox-titlebar-icon-close{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAyOCI+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjQiPgogICAgICAgIDxwYXRoIGQ9Ik04LjM1MyAyMC4zMzIxTDIwLjMzMiA4LjM1M00yMC4zMzIyIDIwLjMzMjFMOC4zNTMgOC4zNTMiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-color-scheme-dark .telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-collector{visibility:hidden;display:block;position:absolute;z-index:200;width:40px;height:40px;margin:0;padding:0;border:none;outline:0;font-size:0;border-radius:50%;background:#fff;box-shadow:0 2px 6px #2f419226;cursor:pointer;user-select:none;pointer-events:none;background-repeat:no-repeat;background-size:18px 16px;background-position:center}.telebox-collector-visible{visibility:visible;pointer-events:initial}.telebox-collector-readonly{cursor:not-allowed}.telebox-color-scheme-dark.telebox-collector{background-color:#43434d}.telebox-max-titlebar{display:none;position:absolute;top:0;left:0;z-index:50000;user-select:none}.telebox-max-titlebar .telebox-drag-area{height:100%;min-width:16px;position:static;margin:0;flex-grow:1;flex-shrink:0}.telebox-max-titlebar-maximized{display:flex}.telebox-titles{height:100%;margin:0;overflow-y:hidden;overflow-x:scroll;overflow-x:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.telebox-titles::-webkit-scrollbar{height:8px;width:8px}.telebox-titles::-webkit-scrollbar-track{background-color:transparent}.telebox-titles::-webkit-scrollbar-thumb{background-color:#eeeef7cc;background-color:transparent;border-radius:4px;transition:background-color .4s}.telebox-titles:hover::-webkit-scrollbar-thumb{background-color:#eeeef7cc}.telebox-titles::-webkit-scrollbar-thumb:hover{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:active{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:vertical{min-height:50px}.telebox-titles::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-titles-content{height:100%;display:flex;flex-wrap:nowrap;align-items:center;padding:0}.telebox-titles-tab{height:100%;overflow:hidden;max-width:182px;min-width:50px;padding:0 26px 0 16px;outline:0;font-size:13px;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;text-overflow:ellipsis;white-space:nowrap;word-break:keep-all;border:none;border-right:1px solid #e5e5f0;color:#7b88a0;background:0 0;cursor:pointer;user-select:none}.telebox-titles-tab-focus{color:#357bf6}.telebox-readonly .telebox-titles-tab{cursor:not-allowed}.telebox-color-scheme-dark{color-scheme:dark}.telebox-color-scheme-dark.telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-color-scheme-dark .telebox-titles-tab{border-right-color:#7b88a0}.telebox-color-scheme-dark .telebox-title{color:#e9e9e9}.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}.tippy-box[data-theme~=light]{color:#26323d;box-shadow:0 0 20px 4px #9aa1b126,0 4px 80px -8px #24282f40,0 4px 4px -2px #5b5e6926;background-color:#fff}.tippy-box[data-theme~=light][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff}.tippy-box[data-theme~=light][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff}.tippy-box[data-theme~=light]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light]>.tippy-svg-arrow{fill:#fff}.rc-slider{position:relative;height:14px;padding:5px 0;width:100%;border-radius:6px;touch-action:none;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider *{box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-rail{position:absolute;width:100%;background-color:#e9e9e9;height:4px;border-radius:6px}.rc-slider-track{position:absolute;left:0;height:4px;border-radius:6px;background-color:#abe2fb}.rc-slider-handle{position:absolute;width:14px;height:14px;cursor:pointer;cursor:-webkit-grab;margin-top:-5px;cursor:grab;border-radius:50%;border:solid 2px #96dbfa;background-color:#fff;touch-action:pan-x}.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging{border-color:#57c5f7;box-shadow:0 0 0 5px #96dbfa}.rc-slider-handle:focus{outline:none}.rc-slider-handle-click-focused:focus{border-color:#96dbfa;box-shadow:unset}.rc-slider-handle:hover{border-color:#57c5f7}.rc-slider-handle:active{border-color:#57c5f7;box-shadow:0 0 5px #57c5f7;cursor:-webkit-grabbing;cursor:grabbing}.rc-slider-mark{position:absolute;top:18px;left:0;width:100%;font-size:12px}.rc-slider-mark-text{position:absolute;display:inline-block;vertical-align:middle;text-align:center;cursor:pointer;color:#999}.rc-slider-mark-text-active{color:#666}.rc-slider-step{position:absolute;width:100%;height:4px;background:transparent}.rc-slider-dot{position:absolute;bottom:-2px;margin-left:-4px;width:8px;height:8px;border:2px solid #e9e9e9;background-color:#fff;cursor:pointer;border-radius:50%;vertical-align:middle}.rc-slider-dot-active{border-color:#96dbfa}.rc-slider-dot-reverse{margin-right:-4px}.rc-slider-disabled{background-color:#e9e9e9}.rc-slider-disabled .rc-slider-track{background-color:#ccc}.rc-slider-disabled .rc-slider-handle,.rc-slider-disabled .rc-slider-dot{border-color:#ccc;box-shadow:none;background-color:#fff;cursor:not-allowed}.rc-slider-disabled .rc-slider-mark-text,.rc-slider-disabled .rc-slider-dot{cursor:not-allowed!important}.rc-slider-vertical{width:14px;height:100%;padding:0 5px}.rc-slider-vertical .rc-slider-rail{height:100%;width:4px}.rc-slider-vertical .rc-slider-track{left:5px;bottom:0;width:4px}.rc-slider-vertical .rc-slider-handle{margin-left:-5px;touch-action:pan-y}.rc-slider-vertical .rc-slider-mark{top:0;left:18px;height:100%}.rc-slider-vertical .rc-slider-step{height:100%;width:4px}.rc-slider-vertical .rc-slider-dot{left:2px;margin-bottom:-4px}.rc-slider-vertical .rc-slider-dot:first-child{margin-bottom:-4px}.rc-slider-vertical .rc-slider-dot:last-child{margin-bottom:-4px}.rc-slider-tooltip-zoom-down-enter,.rc-slider-tooltip-zoom-down-appear,.rc-slider-tooltip-zoom-down-leave{animation-duration:.3s;animation-fill-mode:both;display:block!important;animation-play-state:paused}.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active{animation-name:rcSliderTooltipZoomDownIn;animation-play-state:running}.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active{animation-name:rcSliderTooltipZoomDownOut;animation-play-state:running}.rc-slider-tooltip-zoom-down-enter,.rc-slider-tooltip-zoom-down-appear{transform:scale(0);animation-timing-function:cubic-bezier(.23,1,.32,1)}.rc-slider-tooltip-zoom-down-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}@keyframes rcSliderTooltipZoomDownIn{0%{opacity:0;transform-origin:50% 100%;transform:scale(0)}to{transform-origin:50% 100%;transform:scale(1)}}@keyframes rcSliderTooltipZoomDownOut{0%{transform-origin:50% 100%;transform:scale(1)}to{opacity:0;transform-origin:50% 100%;transform:scale(0)}}.rc-slider-tooltip{position:absolute;left:-9999px;top:-9999px;visibility:visible;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-tooltip *{box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-tooltip-hidden{display:none}.rc-slider-tooltip-placement-top{padding:4px 0 8px}.rc-slider-tooltip-inner{padding:6px 2px;min-width:24px;height:24px;font-size:12px;line-height:1;color:#fff;text-align:center;text-decoration:none;background-color:#6c6c6c;border-radius:6px;box-shadow:0 0 4px #d9d9d9}.rc-slider-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow{bottom:4px;left:50%;margin-left:-4px;border-width:4px 4px 0;border-top-color:#6c6c6c}.fastboard-root{position:relative;width:100%;height:100%;overflow:hidden}.fastboard-view{position:absolute;top:0;left:0;width:100%;height:100%}.fastboard-left{position:absolute;top:0;left:0;height:calc(100% - 48px);padding:16px;z-index:201;display:flex;align-items:center}.fastboard-bottom-left,.fastboard-bottom-right{display:flex;gap:10px;position:absolute;bottom:8px;left:8px;padding:8px;z-index:200}.fastboard-bottom-right{left:initial;right:8px}.fastboard-redo-undo{display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-redo-undo.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-redo-undo.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-redo-undo-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-redo-undo-btn svg,.fastboard-redo-undo-btn img{width:1em;height:1em}.fastboard-redo-undo-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-redo-undo-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-redo-undo-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-page-control{display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-page-control.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-page-control.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-page-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-page-control-btn svg,.fastboard-page-control-btn img{width:1em;height:1em}.fastboard-page-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-page-control-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-page-control-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-page-control-cut-line{height:24px;width:.5px}.fastboard-page-control-cut-line.light{background-color:#e7e7e7}.fastboard-page-control-cut-line.dark{background-color:#ffffff26}.fastboard-page-control-slash{opacity:.6}.fastboard-page-control-page,.fastboard-page-control-slash,.fastboard-page-control-page-count{font-size:12px;font-variant-numeric:tabular-nums}.fastboard-zoom-control{position:relative;display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-zoom-control.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-zoom-control.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-zoom-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-zoom-control-btn svg,.fastboard-zoom-control-btn img{width:1em;height:1em}.fastboard-zoom-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-zoom-control-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-zoom-control-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-zoom-control-cut-line{height:24px;width:.5px}.fastboard-zoom-control-cut-line.light{background-color:#e7e7e7}.fastboard-zoom-control-cut-line.dark{background-color:#ffffff26}.fastboard-zoom-control-percent{opacity:.6}.fastboard-zoom-control-scale,.fastboard-zoom-control-percent{font-size:12px;font-variant-numeric:tabular-nums}.fastboard-toolbar{display:flex;align-items:center;padding:4px;border-radius:4px;flex-direction:column;gap:4px;position:absolute;z-index:100;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-toolbar .rc-slider{padding:6px 0}.fastboard-toolbar .rc-slider-rail,.fastboard-toolbar .rc-slider-track{height:2px}.fastboard-toolbar .tippy-content{padding:8px}.fastboard-toolbar .tippy-box{border:1px solid rgba(0,0,0,.15);background-color:#333333f2;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-toolbar .tippy-box[data-theme~=light]{background-color:#fffffff2;box-shadow:0 5px 10px #00000040}.fastboard-toolbar.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-toolbar.expanded{border:1px solid rgba(0,0,0,.15)}.fastboard-toolbar.dark{color:#ddd;background-color:#333333d9}.fastboard-toolbar.expanded:hover{box-shadow:0 0 5px #00000040;transform:translate(0)}.fastboard-toolbar.collapsed{padding:0;background-color:transparent}.fastboard-toolbar-tooltip{display:inline-flex;align-items:center;gap:4px}.fastboard-toolbar-hotkey{margin-right:-4px;width:24px;height:24px;border-radius:4px;background-color:#ffffff1a;display:inline-flex;align-items:center;justify-content:center}.fastboard-toolbar-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:4px;width:32px;height:32px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1;position:relative}.fastboard-toolbar-btn-interactive{display:inline-block;width:32px;height:32px}.fastboard-toolbar-btn svg,.fastboard-toolbar-btn img{width:1em;height:1em}.fastboard-toolbar-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-toolbar-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-toolbar-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-toolbar-triangle{width:0px;height:0px;border-bottom:4px solid;border-left:4px solid transparent;position:absolute;bottom:0;right:0}.fastboard-toolbar-cut-line{display:inline-block;height:.5px;width:100%}.fastboard-toolbar-cut-line.light{background-color:#e7e7e7}.fastboard-toolbar-cut-line.dark{background-color:#ffffff26}.fastboard-toolbar-section{display:inline-flex;flex-flow:column nowrap;gap:4px;scroll-behavior:smooth}.fastboard-toolbar-section.collapsed{transform:translate(-100%);transition:1s transform}.fastboard-toolbar-panel{width:120px;padding:0;display:flex;flex-flow:column nowrap;align-items:center;gap:8px}.fastboard-toolbar-panel.apps{width:224px}.fastboard-toolbar-color-box,.fastboard-toolbar-shapes{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;align-items:center;justify-items:center}.fastboard-toolbar-color-box .fastboard-toolbar-btn,.fastboard-toolbar-shapes .fastboard-toolbar-btn{padding:0;width:24px;height:24px}.fastboard-toolbar-apps{width:100%;display:grid;grid-template-columns:repeat(3,1fr);gap:8px;align-items:center;justify-items:center}.fastboard-toolbar-apps .fastboard-toolbar-btn{width:40px;height:40px;font-size:40px}.fastboard-toolbar-app-icon{padding-top:4px;display:inline-flex;flex-flow:column nowrap;align-items:center;gap:4px}.fastboard-toolbar-app-icon .fastboard-toolbar-btn{padding:0}.fastboard-toolbar-app-icon-text{font-size:12px;color:#5d5d5d;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fastboard-toolbar-color-item{width:24px;height:24px;border-radius:4px;cursor:pointer}.fastboard-toolbar-color-item *.light:hover{background-color:#f5f5f5}.fastboard-toolbar-color-item *.dark:hover{background-color:#333}.fastboard-toolbar-color-border{width:24px;height:24px;border:1px solid transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center}.fastboard-toolbar-color-border.active.light,.fastboard-toolbar-color-border.active.dark{border:1px solid rgba(51,129,255,.8)}.fastboard-toolbar-color-btn{margin:0;border:1px solid rgba(0,0,0,.24);padding:0;appearance:none;width:16px;height:16px;border-radius:4px;cursor:pointer}.fastboard-toolbar-color-btn:focus-visible{outline-offset:2px}.fastboard-toolbar-mask-btn{width:17px;height:62px;cursor:pointer}.fastboard-toolbar-mask-btn.dark{filter:invert(.8)}.fastboard-toolbar-expand-btn{display:flex;align-items:center;position:absolute;left:0}.fastboard-player-control{width:100%;display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-player-control.auto-hide{opacity:0;transition:opacity .2s}.fastboard-player-control.auto-hide:hover{opacity:1}.fastboard-player-control .rc-slider-disabled{background:transparent;opacity:.5}.fastboard-player-control .rc-slider-rail,.fastboard-player-control .rc-slider-track{height:2px}.fastboard-player-control .tippy-content{padding:8px}.fastboard-player-control .tippy-box{border:1px solid rgba(0,0,0,.15);background-color:#333333f2;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-player-control .tippy-box[data-theme~=light]{background-color:#fffffff2;box-shadow:0 5px 10px #00000040}.fastboard-player-control.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-player-control.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-player-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;min-width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1;display:inline-flex;align-items:center;justify-content:center}.fastboard-player-control-btn svg,.fastboard-player-control-btn img{width:1em;height:1em}.fastboard-player-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-player-control-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-player-control-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-player-control-btn.loading{animation:fastboard-player-control-rotate .5s linear infinite}@keyframes fastboard-player-control-rotate{to{transform:rotate(360deg)}}.fastboard-player-control-panel{padding:0;display:flex;flex-flow:column nowrap;align-items:stretch;gap:4px}.fastboard-player-control-panel .fastboard-player-control-btn{width:initial;height:initial;user-select:none;font-size:12px;padding:4px;justify-content:flex-end}.fastboard-player-control-panel .fastboard-player-control-btn.active{color:#3381ff}.fastboard-player-control-slider{width:100%;padding:0 7px}.fastboard-player-control-slider.loading{cursor:not-allowed}.fastboard-player-control-slash{opacity:.6}.fastboard-player-control-current,.fastboard-player-control-slash,.fastboard-player-control-total,.fastboard-player-control-speed-text{font-size:12px;font-variant-numeric:tabular-nums}.tippy-box.fastboard-tip{color:#eee;background-color:#000000f2;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.tippy-box.fastboard-tip[data-placement^=right]>.tippy-arrow:before{top:4px;border-width:4px;border-right-color:#000}.tippy-box.fastboard-tip[data-placement^=top]>.tippy-arrow:before{left:4px;border-width:4px;border-top-color:#000}\n';
143
+
144
+ // src/behaviors/style.ts
145
+ applyStyles(style_default);
146
+
147
+ // src/components/hooks.ts
148
+ var import_window_manager = require("@netless/window-manager");
149
+ var import_react2 = require("react");
150
+ var FastboardAppContext = (0, import_react2.createContext)(null);
151
+ var ThemeContext = (0, import_react2.createContext)("light");
152
+ function useTheme(userTheme) {
153
+ const themeFromContext = (0, import_react2.useContext)(ThemeContext);
154
+ return userTheme || themeFromContext;
155
+ }
156
+ function useFastboardApp() {
157
+ const app = (0, import_react2.useContext)(FastboardAppContext);
158
+ if (!app) {
159
+ throw new Error("useFastboardApp() can only be called inside of <Fastboard>");
160
+ }
161
+ return app;
162
+ }
163
+ function useFastboardValue(val) {
164
+ const [value, setValue] = (0, import_react2.useState)(val.value);
165
+ (0, import_react2.useEffect)(() => val.subscribe(setValue), [val]);
166
+ return value;
167
+ }
168
+ function useWritable() {
169
+ return useFastboardValue(useFastboardApp().writable);
170
+ }
171
+ function useBoxState() {
172
+ return useFastboardValue(useFastboardApp().boxState);
173
+ }
174
+ function useFocusedApp() {
175
+ return useFastboardValue(useFastboardApp().focusedApp);
176
+ }
177
+ function useMaximized() {
178
+ return useBoxState() === "maximized";
179
+ }
180
+ function useHideControls() {
181
+ const maximized = useMaximized();
182
+ const focusedApp = useFocusedApp();
183
+ if (maximized) {
184
+ if (Object.values(import_window_manager.BuiltinApps).some((kind) => focusedApp == null ? void 0 : focusedApp.includes(kind))) {
185
+ return "toolbar-only";
186
+ } else {
187
+ return true;
188
+ }
189
+ }
190
+ return false;
191
+ }
192
+
193
+ // src/components/RedoUndo/hooks.ts
194
+ var import_react3 = require("react");
195
+ function useRedoUndo() {
196
+ const app = useFastboardApp();
197
+ const undoSteps = useFastboardValue(app.canUndoSteps);
198
+ const redoSteps = useFastboardValue(app.canRedoSteps);
199
+ const undo = (0, import_react3.useCallback)(() => {
200
+ app.undo();
201
+ }, [app]);
202
+ const redo = (0, import_react3.useCallback)(() => {
203
+ app.redo();
204
+ }, [app]);
205
+ return { redoSteps, undoSteps, redo, undo };
206
+ }
207
+
208
+ // src/components/RedoUndo/RedoUndo.tsx
209
+ var import_react8 = __toESM(require("@tippyjs/react"));
210
+ var import_clsx = __toESM(require("clsx"));
211
+ var import_react9 = __toESM(require("react"));
212
+
213
+ // src/i18n/index.ts
214
+ var import_react4 = require("react");
215
+ var import_i18next = __toESM(require("i18next"));
216
+
217
+ // src/i18n/en.json
218
+ var translation = {
219
+ clicker: "clicker",
220
+ selector: "selector",
221
+ text: "text",
222
+ pencil: "pencil",
223
+ arrow: "arrow",
224
+ hand: "hand",
225
+ eraser: "eraser",
226
+ laser: "laser",
227
+ collapse: "Collapse",
228
+ expand: "Expand",
229
+ zoomIn: "Zoom In",
230
+ zoomOut: "Zoom Out",
231
+ reset: "Reset",
232
+ prevPage: "Prev Page",
233
+ nextPage: "Next Page",
234
+ addPage: "Add Page",
235
+ redo: "Redo",
236
+ undo: "Undo",
237
+ shape: "Shape",
238
+ triangle: "Triangle",
239
+ rhombus: "Rhombus",
240
+ pentagram: "Pentagram",
241
+ speechBalloon: "Speech Balloon",
242
+ rectangle: "Rectangle",
243
+ ellipse: "Ellipse",
244
+ straight: "Straight",
245
+ speed: "Speed"
246
+ };
247
+ var en_default = {
248
+ translation
249
+ };
250
+
251
+ // src/i18n/zh-CN.json
252
+ var translation2 = {
253
+ clicker: "\u70B9\u51FB",
254
+ selector: "\u9009\u62E9",
255
+ text: "\u6587\u5B57",
256
+ pencil: "\u94C5\u7B14",
257
+ arrow: "\u7BAD\u5934",
258
+ hand: "\u6293\u624B",
259
+ eraser: "\u6A61\u76AE",
260
+ laser: "\u6FC0\u5149\u7B14",
261
+ zoomIn: "\u653E\u5927",
262
+ zoomOut: "\u7F29\u5C0F",
263
+ reset: "\u91CD\u7F6E",
264
+ prevPage: "\u4E0A\u4E00\u9875",
265
+ nextPage: "\u4E0B\u4E00\u9875",
266
+ addPage: "\u6DFB\u52A0\u9875\u9762",
267
+ redo: "\u91CD\u505A",
268
+ undo: "\u64A4\u9500",
269
+ collapse: "\u6536\u8D77",
270
+ expand: "\u5C55\u5F00",
271
+ clean: "\u6E05\u5C4F",
272
+ shape: "\u5F62\u72B6",
273
+ triangle: "\u4E09\u89D2\u5F62",
274
+ rhombus: "\u83F1\u5F62",
275
+ pentagram: "\u4E94\u89D2\u661F",
276
+ speechBalloon: "\u6C14\u7403",
277
+ rectangle: "\u77E9\u5F62",
278
+ ellipse: "\u692D\u5706",
279
+ straight: "\u76F4\u7EBF",
280
+ speed: "\u901F\u5EA6"
281
+ };
282
+ var zh_CN_default = {
283
+ translation: translation2
284
+ };
285
+
286
+ // src/i18n/index.ts
287
+ var createI18n = async ({
288
+ language = navigator.language || "zh-CN"
289
+ } = {}) => {
290
+ await import_i18next.default.init({
291
+ lng: language,
292
+ resources: { en: en_default, "zh-CN": zh_CN_default }
293
+ });
294
+ return import_i18next.default;
295
+ };
296
+ var I18nContext = (0, import_react4.createContext)(null);
297
+ function useTranslation() {
298
+ const i18n = (0, import_react4.useContext)(I18nContext);
299
+ const t = (0, import_react4.useMemo)(() => i18n ? i18n.getFixedT(null, ["translation"]) : (id) => id, [i18n]);
300
+ return { t, i18n };
301
+ }
302
+
303
+ // src/icons/index.tsx
304
+ var import_react5 = __toESM(require("react"));
305
+ function Icon({ fallback, src, alt = "[icon]" }) {
306
+ return src ? import_react5.default.createElement("img", {
307
+ src,
308
+ alt,
309
+ title: alt
310
+ }) : fallback;
311
+ }
312
+
313
+ // src/icons/Redo.tsx
314
+ var import_react6 = __toESM(require("react"));
315
+
316
+ // src/theme.ts
317
+ var light = {
318
+ color: "#5D5D5D",
319
+ activeColor: "#3381FF",
320
+ backgroundColor: "#fff",
321
+ hoverBackgroundColor: "rgba(51, 129, 255, 0.1)"
322
+ };
323
+ var dark = __spreadProps(__spreadValues({}, light), {
324
+ color: "#eee",
325
+ backgroundColor: "#111"
326
+ });
327
+ var themes = { light, dark };
328
+ var getStroke = (props) => {
329
+ let config;
330
+ if (props.theme) {
331
+ config = themes[props.theme];
332
+ } else {
333
+ config = themes.light;
334
+ }
335
+ return props.active ? config.activeColor : config.color;
336
+ };
337
+ var TopOffset = [0, 11];
338
+ var RightOffset = [0, 11];
339
+
340
+ // src/icons/Redo.tsx
341
+ function Redo({ theme = "light", active }) {
342
+ const config = themes[theme];
343
+ const stroke = active ? config.activeColor : config.color;
344
+ return import_react6.default.createElement("svg", {
345
+ viewBox: "0 0 24 24"
346
+ }, import_react6.default.createElement("g", {
347
+ fill: "none",
348
+ fillRule: "evenodd",
349
+ stroke,
350
+ strokeLinecap: "round",
351
+ strokeLinejoin: "round"
352
+ }, import_react6.default.createElement("path", {
353
+ d: "M14 14h4v-4"
354
+ }), import_react6.default.createElement("path", {
355
+ d: "m18 14-.788-.9A7.005 7.005 0 0 0 6 14h0"
356
+ })));
357
+ }
358
+
359
+ // src/icons/Undo.tsx
360
+ var import_react7 = __toESM(require("react"));
361
+ function Undo({ theme = "light", active }) {
362
+ const config = themes[theme];
363
+ const stroke = active ? config.activeColor : config.color;
364
+ return import_react7.default.createElement("svg", {
365
+ viewBox: "0 0 24 24"
366
+ }, import_react7.default.createElement("g", {
367
+ fill: "none",
368
+ fillRule: "evenodd",
369
+ stroke,
370
+ strokeLinecap: "round",
371
+ strokeLinejoin: "round"
372
+ }, import_react7.default.createElement("path", {
373
+ d: "M10 14H6v-4"
374
+ }), import_react7.default.createElement("path", {
375
+ d: "m6 14 .788-.9A7.005 7.005 0 0 1 18 14h0"
376
+ })));
377
+ }
378
+
379
+ // src/components/RedoUndo/RedoUndo.tsx
380
+ var name = "fastboard-redo-undo";
381
+ function RedoUndo({ theme, undoIcon, undoIconDisable, redoIcon, redoIconDisable }) {
382
+ theme = useTheme(theme);
383
+ const { t } = useTranslation();
384
+ const writable = useWritable();
385
+ const { redoSteps, undoSteps, redo, undo } = useRedoUndo();
386
+ const disabled = !writable;
387
+ return import_react9.default.createElement("div", {
388
+ className: (0, import_clsx.default)(name, theme)
389
+ }, import_react9.default.createElement(import_react8.default, {
390
+ className: "fastboard-tip",
391
+ content: t("undo"),
392
+ theme,
393
+ disabled,
394
+ placement: "top",
395
+ delay: [1e3, 400],
396
+ duration: 300,
397
+ offset: TopOffset
398
+ }, import_react9.default.createElement("button", {
399
+ className: (0, import_clsx.default)(`${name}-btn`, "undo", theme),
400
+ disabled: disabled || undoSteps === 0,
401
+ onClick: undo
402
+ }, import_react9.default.createElement(Icon, {
403
+ fallback: import_react9.default.createElement(Undo, {
404
+ theme
405
+ }),
406
+ src: undoSteps === 0 ? undoIconDisable : undoIcon,
407
+ alt: "[undo]"
408
+ }))), import_react9.default.createElement(import_react8.default, {
409
+ className: "fastboard-tip",
410
+ content: t("redo"),
411
+ theme,
412
+ disabled,
413
+ placement: "top",
414
+ delay: [1e3, 400],
415
+ duration: 300,
416
+ offset: TopOffset
417
+ }, import_react9.default.createElement("button", {
418
+ className: (0, import_clsx.default)(`${name}-btn`, "redo", theme),
419
+ disabled: disabled || redoSteps === 0,
420
+ onClick: redo
421
+ }, import_react9.default.createElement(Icon, {
422
+ fallback: import_react9.default.createElement(Redo, {
423
+ theme
424
+ }),
425
+ src: redoSteps === 0 ? redoIconDisable : redoIcon,
426
+ alt: "[redo]"
427
+ }))));
428
+ }
429
+
430
+ // src/components/ZoomControl/hooks.ts
431
+ var import_react10 = require("react");
432
+ var ScalePoints = [
433
+ 0.10737418240000011,
434
+ 0.13421772800000012,
435
+ 0.16777216000000014,
436
+ 0.20971520000000016,
437
+ 0.26214400000000015,
438
+ 0.3276800000000002,
439
+ 0.4096000000000002,
440
+ 0.5120000000000001,
441
+ 0.6400000000000001,
442
+ 0.8,
443
+ 1,
444
+ 1.26,
445
+ 1.5876000000000001,
446
+ 2.000376,
447
+ 2.5204737600000002,
448
+ 3.1757969376000004,
449
+ 4.001504141376,
450
+ 5.041895218133761,
451
+ 6.352787974848539,
452
+ 8.00451284830916,
453
+ 10
454
+ ];
455
+ function nextScale(scale, delta) {
456
+ const { length } = ScalePoints;
457
+ const last = length - 1;
458
+ if (scale < ScalePoints[0])
459
+ return ScalePoints[0];
460
+ if (scale > ScalePoints[last])
461
+ return ScalePoints[last];
462
+ for (let i = 0; i < length; ++i) {
463
+ const curr = ScalePoints[i];
464
+ const prev = i === 0 ? -Infinity : (ScalePoints[i - 1] + curr) / 2;
465
+ const next = i === last ? Infinity : (ScalePoints[i + 1] + curr) / 2;
466
+ if (prev <= scale && scale <= next)
467
+ return ScalePoints[clamp(i + delta, 0, last)];
468
+ }
469
+ return 1;
470
+ }
471
+ function useZoomControl() {
472
+ const app = useFastboardApp();
473
+ const scale = useFastboardValue(app.camera).scale || 1;
474
+ const resetCamera = (0, import_react10.useCallback)(() => {
475
+ app.moveCamera({ scale: 1, centerX: 0, centerY: 0 });
476
+ }, [app]);
477
+ const zoomIn = (0, import_react10.useCallback)(() => {
478
+ app.moveCamera({
479
+ scale: nextScale(scale, 1),
480
+ centerX: 0,
481
+ centerY: 0
482
+ });
483
+ }, [app, scale]);
484
+ const zoomOut = (0, import_react10.useCallback)(() => {
485
+ app.moveCamera({
486
+ scale: nextScale(scale, -1),
487
+ centerX: 0,
488
+ centerY: 0
489
+ });
490
+ }, [app, scale]);
491
+ return { scale, resetCamera, zoomIn, zoomOut };
492
+ }
493
+
494
+ // src/components/ZoomControl/ZoomControl.tsx
495
+ var import_react14 = __toESM(require("@tippyjs/react"));
496
+ var import_clsx2 = __toESM(require("clsx"));
497
+ var import_react15 = __toESM(require("react"));
498
+
499
+ // src/icons/Minus.tsx
500
+ var import_react11 = __toESM(require("react"));
501
+ function Minus({ theme = "light", active }) {
502
+ const config = themes[theme];
503
+ const stroke = active ? config.activeColor : config.color;
504
+ return import_react11.default.createElement("svg", {
505
+ viewBox: "0 0 24 24"
506
+ }, import_react11.default.createElement("path", {
507
+ fill: "none",
508
+ stroke,
509
+ strokeLinecap: "round",
510
+ strokeLinejoin: "round",
511
+ d: "M7 12h10"
512
+ }));
513
+ }
514
+
515
+ // src/icons/Plus.tsx
516
+ var import_react12 = __toESM(require("react"));
517
+ function Plus({ theme = "light", active }) {
518
+ const config = themes[theme];
519
+ const stroke = active ? config.activeColor : config.color;
520
+ return import_react12.default.createElement("svg", {
521
+ viewBox: "0 0 24 24"
522
+ }, import_react12.default.createElement("path", {
523
+ fill: "none",
524
+ stroke,
525
+ strokeLinecap: "round",
526
+ strokeLinejoin: "round",
527
+ d: "M12 7v10m-5-5h10"
528
+ }));
529
+ }
530
+
531
+ // src/icons/Reset.tsx
532
+ var import_react13 = __toESM(require("react"));
533
+ function Reset({ theme = "light", active }) {
534
+ const config = themes[theme];
535
+ const stroke = active ? config.activeColor : config.color;
536
+ return import_react13.default.createElement("svg", {
537
+ viewBox: "0 0 24 24"
538
+ }, import_react13.default.createElement("g", {
539
+ fill: "none",
540
+ fillRule: "evenodd",
541
+ transform: "translate(-176 -684)"
542
+ }, import_react13.default.createElement("path", {
543
+ stroke,
544
+ strokeLinejoin: "round",
545
+ d: "M188 688v4m0 8v4m8-8h-4m-8 0h-4"
546
+ }), import_react13.default.createElement("circle", {
547
+ cx: "188",
548
+ cy: "696",
549
+ r: "6",
550
+ stroke
551
+ }), import_react13.default.createElement("circle", {
552
+ cx: "188",
553
+ cy: "696",
554
+ r: "1",
555
+ fill: stroke
556
+ })));
557
+ }
558
+
559
+ // src/components/ZoomControl/ZoomControl.tsx
560
+ var name2 = "fastboard-zoom-control";
561
+ function ZoomControl({
562
+ theme,
563
+ resetIcon,
564
+ resetIconDisable,
565
+ minusIcon,
566
+ minusIconDisable,
567
+ plusIcon,
568
+ plusIconDisable
569
+ }) {
570
+ theme = useTheme(theme);
571
+ const { t } = useTranslation();
572
+ const writable = useWritable();
573
+ const { scale, resetCamera, zoomIn, zoomOut } = useZoomControl();
574
+ const disabled = !writable;
575
+ return import_react15.default.createElement("div", {
576
+ className: (0, import_clsx2.default)(name2, theme)
577
+ }, import_react15.default.createElement(import_react14.default, {
578
+ className: "fastboard-tip",
579
+ content: t("zoomOut"),
580
+ theme,
581
+ disabled,
582
+ placement: "top",
583
+ delay: [1e3, 400],
584
+ duration: 300,
585
+ offset: TopOffset
586
+ }, import_react15.default.createElement("button", {
587
+ className: (0, import_clsx2.default)(`${name2}-btn`, "minus", theme),
588
+ disabled,
589
+ onClick: zoomOut
590
+ }, import_react15.default.createElement(Icon, {
591
+ fallback: import_react15.default.createElement(Minus, {
592
+ theme
593
+ }),
594
+ src: disabled ? minusIconDisable : minusIcon,
595
+ alt: "[minus]"
596
+ }))), import_react15.default.createElement("span", {
597
+ className: (0, import_clsx2.default)(`${name2}-scale`, theme)
598
+ }, Math.ceil(scale * 100)), import_react15.default.createElement("span", {
599
+ className: (0, import_clsx2.default)(`${name2}-percent`, theme)
600
+ }, "%"), import_react15.default.createElement(import_react14.default, {
601
+ className: "fastboard-tip",
602
+ content: t("zoomIn"),
603
+ theme,
604
+ disabled,
605
+ placement: "top",
606
+ delay: [1e3, 400],
607
+ duration: 300,
608
+ offset: TopOffset
609
+ }, import_react15.default.createElement("button", {
610
+ className: (0, import_clsx2.default)(`${name2}-btn`, "plus", theme),
611
+ disabled,
612
+ onClick: zoomIn
613
+ }, import_react15.default.createElement(Icon, {
614
+ fallback: import_react15.default.createElement(Plus, {
615
+ theme
616
+ }),
617
+ src: disabled ? plusIconDisable : plusIcon,
618
+ alt: "[plus]"
619
+ }))), import_react15.default.createElement(import_react14.default, {
620
+ className: "fastboard-tip",
621
+ content: t("reset"),
622
+ theme,
623
+ disabled,
624
+ placement: "top",
625
+ delay: [1e3, 400],
626
+ duration: 300,
627
+ offset: TopOffset
628
+ }, import_react15.default.createElement("button", {
629
+ className: (0, import_clsx2.default)(`${name2}-btn`, "reset", theme),
630
+ disabled,
631
+ onClick: resetCamera
632
+ }, import_react15.default.createElement(Icon, {
633
+ fallback: import_react15.default.createElement(Reset, {
634
+ theme
635
+ }),
636
+ src: disabled ? resetIconDisable : resetIcon,
637
+ alt: "[reset]"
638
+ }))));
639
+ }
640
+
641
+ // src/components/PageControl/hooks.ts
642
+ var import_react16 = require("react");
643
+ function usePageControl(room, manager) {
644
+ const [pageIndex, setPageIndex] = (0, import_react16.useState)(0);
645
+ const [pageCount, setPageCount] = (0, import_react16.useState)(0);
646
+ const addPage = (0, import_react16.useCallback)(async () => {
647
+ if (manager && room) {
648
+ await manager.switchMainViewToWriter();
649
+ const path = room.state.sceneState.contextPath;
650
+ room.putScenes(path, [{}], pageIndex + 1);
651
+ await manager.setMainViewSceneIndex(pageIndex + 1);
652
+ } else if (!manager && room) {
653
+ const path = room.state.sceneState.contextPath;
654
+ room.putScenes(path, [{}], pageIndex + 1);
655
+ room.setSceneIndex(pageIndex + 1);
656
+ }
657
+ }, [room, manager, pageIndex]);
658
+ const prevPage = (0, import_react16.useCallback)(() => {
659
+ if (manager) {
660
+ manager.setMainViewSceneIndex(pageIndex - 1);
661
+ } else if (room) {
662
+ room.pptPreviousStep();
663
+ }
664
+ }, [room, manager, pageIndex]);
665
+ const nextPage = (0, import_react16.useCallback)(() => {
666
+ if (manager) {
667
+ manager.setMainViewSceneIndex(pageIndex + 1);
668
+ } else if (room) {
669
+ room.pptNextStep();
670
+ }
671
+ }, [room, manager, pageIndex]);
672
+ (0, import_react16.useEffect)(() => {
673
+ if (room) {
674
+ setPageIndex(room.state.sceneState.index);
675
+ setPageCount(room.state.sceneState.scenes.length);
676
+ if (manager) {
677
+ manager.emitter.on("mainViewSceneIndexChange", setPageIndex);
678
+ return () => {
679
+ manager.emitter.off("mainViewSceneIndexChange", setPageIndex);
680
+ };
681
+ } else {
682
+ const onRoomStateChanged = (modifyState) => {
683
+ if (modifyState.sceneState) {
684
+ setPageIndex(modifyState.sceneState.index);
685
+ setPageCount(modifyState.sceneState.scenes.length);
686
+ }
687
+ };
688
+ room.callbacks.on("onRoomStateChanged", onRoomStateChanged);
689
+ return () => {
690
+ room.callbacks.off("onRoomStateChanged", onRoomStateChanged);
691
+ };
692
+ }
693
+ }
694
+ }, [room, manager]);
695
+ return { pageIndex, pageCount, prevPage, nextPage, addPage };
696
+ }
697
+
698
+ // src/components/PageControl/PageControl.tsx
699
+ var import_react20 = __toESM(require("@tippyjs/react"));
700
+ var import_clsx3 = __toESM(require("clsx"));
701
+ var import_react21 = __toESM(require("react"));
702
+
703
+ // src/icons/ChevronLeft.tsx
704
+ var import_react17 = __toESM(require("react"));
705
+ function ChevronLeft({ theme = "light", active }) {
706
+ const config = themes[theme];
707
+ const stroke = active ? config.activeColor : config.color;
708
+ return import_react17.default.createElement("svg", {
709
+ viewBox: "0 0 24 24"
710
+ }, import_react17.default.createElement("path", {
711
+ fill: "none",
712
+ stroke,
713
+ strokeLinecap: "round",
714
+ strokeLinejoin: "round",
715
+ d: "m14 16-2-2-2-2 2-2 2-2"
716
+ }));
717
+ }
718
+
719
+ // src/icons/ChevronRight.tsx
720
+ var import_react18 = __toESM(require("react"));
721
+ function ChevronRight({ theme = "light", active }) {
722
+ const config = themes[theme];
723
+ const stroke = active ? config.activeColor : config.color;
724
+ return import_react18.default.createElement("svg", {
725
+ viewBox: "0 0 24 24"
726
+ }, import_react18.default.createElement("path", {
727
+ fill: "none",
728
+ stroke,
729
+ strokeLinecap: "round",
730
+ strokeLinejoin: "round",
731
+ d: "m10 16 2-2 2-2-2-2-2-2"
732
+ }));
733
+ }
734
+
735
+ // src/icons/FilePlus.tsx
736
+ var import_react19 = __toESM(require("react"));
737
+ function FilePlus({ theme = "light", active }) {
738
+ const config = themes[theme];
739
+ const stroke = active ? config.activeColor : config.color;
740
+ return import_react19.default.createElement("svg", {
741
+ viewBox: "0 0 24 24"
742
+ }, import_react19.default.createElement("path", {
743
+ fill: stroke,
744
+ 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"
745
+ }));
746
+ }
747
+
748
+ // src/components/PageControl/PageControl.tsx
749
+ var name3 = "fastboard-page-control";
750
+ function PageControl({
751
+ theme,
752
+ addIcon,
753
+ addIconDisable,
754
+ prevIcon,
755
+ prevIconDisable,
756
+ nextIcon,
757
+ nextIconDisable
758
+ }) {
759
+ const app = useFastboardApp();
760
+ theme = useTheme(theme);
761
+ const { t } = useTranslation();
762
+ const writable = useWritable();
763
+ const _a = usePageControl(app.room, app.manager), { pageIndex, pageCount } = _a, actions = __objRest(_a, ["pageIndex", "pageCount"]);
764
+ const disabled = !writable;
765
+ return import_react21.default.createElement("div", {
766
+ className: (0, import_clsx3.default)(name3, theme)
767
+ }, import_react21.default.createElement(import_react20.default, {
768
+ className: "fastboard-tip",
769
+ content: t("prevPage"),
770
+ theme,
771
+ disabled,
772
+ placement: "top",
773
+ delay: [1e3, 400],
774
+ duration: 300,
775
+ offset: TopOffset
776
+ }, import_react21.default.createElement("button", {
777
+ className: (0, import_clsx3.default)(`${name3}-btn`, "prev", theme),
778
+ disabled: disabled || pageIndex === 0,
779
+ onClick: actions.prevPage
780
+ }, import_react21.default.createElement(Icon, {
781
+ fallback: import_react21.default.createElement(ChevronLeft, {
782
+ theme
783
+ }),
784
+ src: disabled ? prevIconDisable : prevIcon,
785
+ alt: "[prev]"
786
+ }))), import_react21.default.createElement("span", {
787
+ className: (0, import_clsx3.default)(`${name3}-page`, theme)
788
+ }, pageCount === 0 ? "\u2026" : pageIndex + 1), import_react21.default.createElement("span", {
789
+ className: (0, import_clsx3.default)(`${name3}-slash`, theme)
790
+ }, "/"), import_react21.default.createElement("span", {
791
+ className: (0, import_clsx3.default)(`${name3}-page-count`, theme)
792
+ }, pageCount), import_react21.default.createElement(import_react20.default, {
793
+ className: "fastboard-tip",
794
+ content: t("nextPage"),
795
+ theme,
796
+ disabled,
797
+ placement: "top",
798
+ delay: [1e3, 400],
799
+ duration: 300,
800
+ offset: TopOffset
801
+ }, import_react21.default.createElement("button", {
802
+ className: (0, import_clsx3.default)(`${name3}-btn`, "next", theme),
803
+ disabled: disabled || pageIndex === pageCount - 1,
804
+ onClick: actions.nextPage
805
+ }, import_react21.default.createElement(Icon, {
806
+ fallback: import_react21.default.createElement(ChevronRight, {
807
+ theme
808
+ }),
809
+ src: disabled ? nextIconDisable : nextIcon,
810
+ alt: "[next]"
811
+ }))), import_react21.default.createElement(import_react20.default, {
812
+ className: "fastboard-tip",
813
+ content: t("addPage"),
814
+ theme,
815
+ disabled,
816
+ placement: "top",
817
+ delay: [1e3, 400],
818
+ duration: 300,
819
+ offset: TopOffset
820
+ }, import_react21.default.createElement("button", {
821
+ className: (0, import_clsx3.default)(`${name3}-btn`, "add", theme),
822
+ disabled,
823
+ onClick: actions.addPage
824
+ }, import_react21.default.createElement(Icon, {
825
+ fallback: import_react21.default.createElement(FilePlus, {
826
+ theme
827
+ }),
828
+ src: disabled ? addIconDisable : addIcon,
829
+ alt: "[add]"
830
+ }))));
831
+ }
832
+
833
+ // src/components/Toolbar/hooks.ts
834
+ var import_react22 = require("react");
835
+ function useRoomState() {
836
+ return useFastboardValue(useFastboardApp().memberState);
837
+ }
838
+ function useToolbar() {
839
+ const app = useFastboardApp();
840
+ const writable = useWritable();
841
+ const memberState = useRoomState();
842
+ const cleanCurrentScene = (0, import_react22.useCallback)(() => {
843
+ app.cleanCurrentScene();
844
+ }, [app]);
845
+ const setAppliance = (0, import_react22.useCallback)((appliance, shape) => {
846
+ app.setAppliance(appliance, shape);
847
+ }, [app]);
848
+ const setStrokeWidth = (0, import_react22.useCallback)((strokeWidth) => {
849
+ app.setStrokeWidth(strokeWidth);
850
+ }, [app]);
851
+ const setStrokeColor = (0, import_react22.useCallback)((strokeColor) => {
852
+ app.setStrokeColor(strokeColor);
853
+ }, [app]);
854
+ return {
855
+ writable,
856
+ memberState,
857
+ cleanCurrentScene,
858
+ setAppliance,
859
+ setStrokeWidth,
860
+ setStrokeColor
861
+ };
862
+ }
863
+ var EmptyToolbarHook = {
864
+ writable: false,
865
+ memberState: void 0,
866
+ cleanCurrentScene: noop,
867
+ setAppliance: noop,
868
+ setStrokeWidth: noop,
869
+ setStrokeColor: noop
870
+ };
871
+
872
+ // src/components/Toolbar/Toolbar.tsx
873
+ var import_clsx9 = __toESM(require("clsx"));
874
+ var import_framer_motion = require("framer-motion");
875
+ var import_react60 = __toESM(require("react"));
876
+
877
+ // src/components/Toolbar/components/assets/collapsed.png
878
+ var collapsed_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";
879
+
880
+ // src/components/Toolbar/components/assets/expanded.png
881
+ var expanded_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==";
882
+
883
+ // src/components/Toolbar/components/Mask.tsx
884
+ var import_react23 = __toESM(require("react"));
885
+ var import_react_dom = __toESM(require("react-dom"));
886
+ var Mask = import_react23.default.memo(({ toolbar, children }) => {
887
+ const [rootElement] = (0, import_react23.useState)(() => {
888
+ const element = document.createElement("div");
889
+ element.style.position = "absolute";
890
+ return element;
891
+ });
892
+ (0, import_react23.useEffect)(() => {
893
+ if (toolbar && rootElement) {
894
+ toolbar.appendChild(rootElement);
895
+ }
896
+ }, [rootElement, toolbar]);
897
+ (0, import_react23.useEffect)(() => {
898
+ if (rootElement && toolbar) {
899
+ toolbar.appendChild(rootElement);
900
+ const toolbarRect = toolbar.getBoundingClientRect();
901
+ const halfHeight = toolbarRect.height / 2 - 31;
902
+ rootElement.style.top = halfHeight + "px";
903
+ rootElement.style.left = "41px";
904
+ rootElement.style.width = "17px";
905
+ rootElement.style.height = "62px";
906
+ return () => {
907
+ toolbar.removeChild(rootElement);
908
+ };
909
+ }
910
+ }, [rootElement, toolbar]);
911
+ if (rootElement) {
912
+ return import_react_dom.default.createPortal(children, rootElement);
913
+ } else {
914
+ return null;
915
+ }
916
+ });
917
+
918
+ // src/components/Toolbar/Content.tsx
919
+ var import_clsx8 = __toESM(require("clsx"));
920
+ var import_react59 = __toESM(require("react"));
921
+
922
+ // src/components/Toolbar/components/ApplianceButtons.tsx
923
+ var import_react46 = __toESM(require("react"));
924
+ var import_white_web_sdk = require("white-web-sdk");
925
+
926
+ // src/components/Toolbar/icons/index.ts
927
+ var import_react43 = require("react");
928
+
929
+ // src/components/Toolbar/icons/Apps.tsx
930
+ var import_react24 = __toESM(require("react"));
931
+ var Apps = (props) => {
932
+ const stroke = getStroke(props);
933
+ return import_react24.default.createElement("svg", {
934
+ viewBox: "0 0 24 24"
935
+ }, import_react24.default.createElement("g", {
936
+ fill: stroke
937
+ }, import_react24.default.createElement("path", {
938
+ 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"
939
+ }), import_react24.default.createElement("path", {
940
+ 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"
941
+ })));
942
+ };
943
+
944
+ // src/components/Toolbar/icons/Arrow.tsx
945
+ var import_react25 = __toESM(require("react"));
946
+ var Arrow = (props) => {
947
+ const stroke = getStroke(props);
948
+ return import_react25.default.createElement("svg", {
949
+ viewBox: "0 0 24 24"
950
+ }, import_react25.default.createElement("path", {
951
+ fill: stroke,
952
+ d: "M19 5v6l-2.647-2.646L5.99 18.718l-.708-.708L15.645 7.646 13 5h6Z"
953
+ }));
954
+ };
955
+
956
+ // src/components/Toolbar/icons/Circle.tsx
957
+ var import_react26 = __toESM(require("react"));
958
+ var Circle = (props) => {
959
+ const stroke = getStroke(props);
960
+ return import_react26.default.createElement("svg", {
961
+ viewBox: "0 0 24 24"
962
+ }, import_react26.default.createElement("rect", {
963
+ width: "15",
964
+ height: "15",
965
+ x: "4.5",
966
+ y: "4.5",
967
+ fill: "none",
968
+ stroke,
969
+ rx: "7.5"
970
+ }));
971
+ };
972
+
973
+ // src/components/Toolbar/icons/Clean.tsx
974
+ var import_react27 = __toESM(require("react"));
975
+ var Clean = (props) => {
976
+ const stroke = getStroke(props);
977
+ return import_react27.default.createElement("svg", {
978
+ viewBox: "0 0 24 24"
979
+ }, import_react27.default.createElement("path", {
980
+ fill: stroke,
981
+ 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"
982
+ }));
983
+ };
984
+
985
+ // src/components/Toolbar/icons/Clicker.tsx
986
+ var import_react28 = __toESM(require("react"));
987
+ var Clicker = (props) => {
988
+ const stroke = getStroke(props);
989
+ return import_react28.default.createElement("svg", {
990
+ viewBox: "0 0 24 24"
991
+ }, import_react28.default.createElement("g", {
992
+ fill: "none"
993
+ }, import_react28.default.createElement("path", {
994
+ d: "M0 0h24v24H0z"
995
+ }), import_react28.default.createElement("path", {
996
+ fill: stroke,
997
+ 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"
998
+ })));
999
+ };
1000
+
1001
+ // src/components/Toolbar/icons/Collapse.tsx
1002
+ var import_react29 = __toESM(require("react"));
1003
+ var Collapse = (props) => {
1004
+ const stroke = getStroke(props);
1005
+ return import_react29.default.createElement("svg", {
1006
+ viewBox: "0 0 24 24"
1007
+ }, import_react29.default.createElement("path", {
1008
+ fill: "none",
1009
+ stroke,
1010
+ d: "m8 10-2 2 2 2m10-8H6m12 12H6m12-4h-8m8-4h-8"
1011
+ }));
1012
+ };
1013
+
1014
+ // src/components/Toolbar/icons/Diamond.tsx
1015
+ var import_react30 = __toESM(require("react"));
1016
+ var Diamond = (props) => {
1017
+ const stroke = getStroke(props);
1018
+ return import_react30.default.createElement("svg", {
1019
+ viewBox: "0 0 24 24"
1020
+ }, import_react30.default.createElement("path", {
1021
+ fill: "none",
1022
+ stroke,
1023
+ d: "M4.222 12 12 4.222 19.778 12 12 19.778z"
1024
+ }));
1025
+ };
1026
+
1027
+ // src/components/Toolbar/icons/Down.tsx
1028
+ var import_react31 = __toESM(require("react"));
1029
+ var Down = (props) => {
1030
+ const stroke = getStroke(props);
1031
+ return import_react31.default.createElement("svg", {
1032
+ viewBox: "0 0 24 24"
1033
+ }, import_react31.default.createElement("path", {
1034
+ fill: "none",
1035
+ stroke,
1036
+ d: "m16 13-2 2-2 2-2-2-2-2m8-6-2 2-2 2-2-2-2-2"
1037
+ }));
1038
+ };
1039
+
1040
+ // src/components/Toolbar/icons/Eraser.tsx
1041
+ var import_react32 = __toESM(require("react"));
1042
+ var Eraser = (props) => {
1043
+ const stroke = getStroke(props);
1044
+ return import_react32.default.createElement("svg", {
1045
+ viewBox: "0 0 24 24"
1046
+ }, import_react32.default.createElement("path", {
1047
+ fill: stroke,
1048
+ 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"
1049
+ }));
1050
+ };
1051
+
1052
+ // src/components/Toolbar/icons/Expand.tsx
1053
+ var import_react33 = __toESM(require("react"));
1054
+ var Expand = (props) => {
1055
+ const stroke = getStroke(props);
1056
+ return import_react33.default.createElement("svg", {
1057
+ viewBox: "0 0 24 24"
1058
+ }, import_react33.default.createElement("path", {
1059
+ fill: "none",
1060
+ stroke,
1061
+ d: "m16 10 2 2-2 2M6 6h12M6 18h12M6 14h8m-8-4h8"
1062
+ }));
1063
+ };
1064
+
1065
+ // src/components/Toolbar/icons/Line.tsx
1066
+ var import_react34 = __toESM(require("react"));
1067
+ var Line = (props) => {
1068
+ const stroke = getStroke(props);
1069
+ return import_react34.default.createElement("svg", {
1070
+ viewBox: "0 0 24 24"
1071
+ }, import_react34.default.createElement("path", {
1072
+ fill: stroke,
1073
+ d: "m18.01 5.282.708.708L5.99 18.718l-.708-.708z"
1074
+ }));
1075
+ };
1076
+
1077
+ // src/components/Toolbar/icons/Pencil.tsx
1078
+ var import_react35 = __toESM(require("react"));
1079
+ var Pencil = (props) => {
1080
+ const stroke = getStroke(props);
1081
+ return import_react35.default.createElement("svg", {
1082
+ viewBox: "0 0 24 24"
1083
+ }, import_react35.default.createElement("path", {
1084
+ fill: stroke,
1085
+ 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"
1086
+ }));
1087
+ };
1088
+
1089
+ // src/components/Toolbar/icons/Rectangle.tsx
1090
+ var import_react36 = __toESM(require("react"));
1091
+ var Rectangle = (props) => {
1092
+ const stroke = getStroke(props);
1093
+ return import_react36.default.createElement("svg", {
1094
+ viewBox: "0 0 24 24"
1095
+ }, import_react36.default.createElement("path", {
1096
+ fill: "none",
1097
+ stroke,
1098
+ d: "M5.5 5.5h13v13h-13z"
1099
+ }));
1100
+ };
1101
+
1102
+ // src/components/Toolbar/icons/Selector.tsx
1103
+ var import_react37 = __toESM(require("react"));
1104
+ var Selector = (props) => {
1105
+ const stroke = getStroke(props);
1106
+ return import_react37.default.createElement("svg", {
1107
+ viewBox: "0 0 24 24"
1108
+ }, import_react37.default.createElement("path", {
1109
+ fill: stroke,
1110
+ d: "m12 12 8 2.667-3.556 1.777L14.667 20 12 12Zm3-8v7.5h-1V5H5v9h6.5v1H4V4h11Z"
1111
+ }));
1112
+ };
1113
+
1114
+ // src/components/Toolbar/icons/SpeechBalloon.tsx
1115
+ var import_react38 = __toESM(require("react"));
1116
+ var SpeechBalloon = (props) => {
1117
+ const stroke = getStroke(props);
1118
+ return import_react38.default.createElement("svg", {
1119
+ viewBox: "0 0 24 24"
1120
+ }, import_react38.default.createElement("path", {
1121
+ fill: "none",
1122
+ stroke,
1123
+ 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"
1124
+ }));
1125
+ };
1126
+
1127
+ // src/components/Toolbar/icons/Star.tsx
1128
+ var import_react39 = __toESM(require("react"));
1129
+ var Star = (props) => {
1130
+ const stroke = getStroke(props);
1131
+ return import_react39.default.createElement("svg", {
1132
+ viewBox: "0 0 24 24"
1133
+ }, import_react39.default.createElement("path", {
1134
+ fill: "none",
1135
+ stroke,
1136
+ 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"
1137
+ }));
1138
+ };
1139
+
1140
+ // src/components/Toolbar/icons/Text.tsx
1141
+ var import_react40 = __toESM(require("react"));
1142
+ var Text = (props) => {
1143
+ const stroke = getStroke(props);
1144
+ return import_react40.default.createElement("svg", {
1145
+ viewBox: "0 0 24 24"
1146
+ }, import_react40.default.createElement("path", {
1147
+ fill: stroke,
1148
+ d: "M18.5 5.5V8h-1V6.5H13v11h2v1H9v-1h2v-11H6.5V8h-1V5.5h13Z"
1149
+ }));
1150
+ };
1151
+
1152
+ // src/components/Toolbar/icons/Triangle.tsx
1153
+ var import_react41 = __toESM(require("react"));
1154
+ var Triangle = (props) => {
1155
+ const stroke = getStroke(props);
1156
+ return import_react41.default.createElement("svg", {
1157
+ viewBox: "0 0 24 24"
1158
+ }, import_react41.default.createElement("path", {
1159
+ fill: "none",
1160
+ stroke,
1161
+ d: "M12 6.008 19.138 18.5H4.862L12 6.008Z"
1162
+ }));
1163
+ };
1164
+
1165
+ // src/components/Toolbar/icons/Up.tsx
1166
+ var import_react42 = __toESM(require("react"));
1167
+ var Up = (props) => {
1168
+ const stroke = getStroke(props);
1169
+ return import_react42.default.createElement("svg", {
1170
+ viewBox: "0 0 24 24"
1171
+ }, import_react42.default.createElement("path", {
1172
+ fill: "none",
1173
+ stroke,
1174
+ d: "m16 11-2-2-2-2-2 2-2 2m8 6-2-2-2-2-2 2-2 2"
1175
+ }));
1176
+ };
1177
+
1178
+ // src/components/Toolbar/icons/index.ts
1179
+ var Icons = {
1180
+ Clicker: (0, import_react43.memo)(Clicker),
1181
+ Collapse: (0, import_react43.memo)(Collapse),
1182
+ Eraser: (0, import_react43.memo)(Eraser),
1183
+ Expand: (0, import_react43.memo)(Expand),
1184
+ Pencil: (0, import_react43.memo)(Pencil),
1185
+ Selector: (0, import_react43.memo)(Selector),
1186
+ Rectangle: (0, import_react43.memo)(Rectangle),
1187
+ Text: (0, import_react43.memo)(Text),
1188
+ Apps: (0, import_react43.memo)(Apps),
1189
+ Clean: (0, import_react43.memo)(Clean),
1190
+ Circle: (0, import_react43.memo)(Circle),
1191
+ Line: (0, import_react43.memo)(Line),
1192
+ Arrow: (0, import_react43.memo)(Arrow),
1193
+ Star: (0, import_react43.memo)(Star),
1194
+ Diamond: (0, import_react43.memo)(Diamond),
1195
+ SpeechBalloon: (0, import_react43.memo)(SpeechBalloon),
1196
+ Triangle: (0, import_react43.memo)(Triangle),
1197
+ Up: (0, import_react43.memo)(Up),
1198
+ Down: (0, import_react43.memo)(Down)
1199
+ };
1200
+
1201
+ // src/components/Toolbar/components/Button.tsx
1202
+ var import_clsx4 = __toESM(require("clsx"));
1203
+ var import_react44 = __toESM(require("react"));
1204
+ var import_react45 = __toESM(require("@tippyjs/react"));
1205
+ var Button = (0, import_react44.forwardRef)((props, ref) => {
1206
+ const { content, disabled, active, onClick, interactive, placement = "right", children } = props;
1207
+ const { writable, theme } = (0, import_react44.useContext)(ToolbarContext);
1208
+ return import_react44.default.createElement(import_react45.default, {
1209
+ className: "fastboard-tip",
1210
+ content,
1211
+ interactive,
1212
+ theme,
1213
+ disabled: disabled || !writable,
1214
+ placement,
1215
+ offset: placement.includes("right") ? RightOffset : void 0,
1216
+ delay: [1e3, 400],
1217
+ duration: 300
1218
+ }, import_react44.default.createElement("button", {
1219
+ ref,
1220
+ className: (0, import_clsx4.default)("fastboard-toolbar-btn", theme, { active }),
1221
+ onClick,
1222
+ disabled: disabled || !writable
1223
+ }, children));
1224
+ });
1225
+
1226
+ // src/components/Toolbar/components/ApplianceButtons.tsx
1227
+ function renderToolTip(text, hotkey) {
1228
+ if (!(typeof hotkey === "string"))
1229
+ return text;
1230
+ return import_react46.default.createElement("span", {
1231
+ className: "fastboard-toolbar-tooltip"
1232
+ }, import_react46.default.createElement("span", null, text), import_react46.default.createElement("span", {
1233
+ className: "fastboard-toolbar-hotkey"
1234
+ }, hotkey.toUpperCase()));
1235
+ }
1236
+ function ClickerButton() {
1237
+ var _a;
1238
+ const app = useFastboardApp();
1239
+ const { t } = useTranslation();
1240
+ const { theme, icons, writable, setAppliance, memberState } = (0, import_react46.useContext)(ToolbarContext);
1241
+ const changeAppliance = (0, import_react46.useCallback)(() => setAppliance(import_white_web_sdk.ApplianceNames.clicker), [setAppliance]);
1242
+ const shortcut = (_a = app.hotKeys) == null ? void 0 : _a.changeToClick;
1243
+ const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1244
+ const active = appliance === import_white_web_sdk.ApplianceNames.clicker;
1245
+ const disabled = !writable;
1246
+ return import_react46.default.createElement(Button, {
1247
+ content: renderToolTip(t("clicker"), shortcut),
1248
+ onClick: changeAppliance,
1249
+ active
1250
+ }, import_react46.default.createElement(Icon, {
1251
+ fallback: import_react46.default.createElement(Icons.Clicker, {
1252
+ theme,
1253
+ active
1254
+ }),
1255
+ src: disabled ? icons == null ? void 0 : icons.clickerIconDisable : icons == null ? void 0 : icons.clickerIcon,
1256
+ alt: "[clicker]"
1257
+ }));
1258
+ }
1259
+ function SelectorButton() {
1260
+ const app = useFastboardApp();
1261
+ const { t } = useTranslation();
1262
+ const { theme, icons, writable, setAppliance, memberState } = (0, import_react46.useContext)(ToolbarContext);
1263
+ const changeAppliance = (0, import_react46.useCallback)(() => setAppliance(import_white_web_sdk.ApplianceNames.selector), [setAppliance]);
1264
+ const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1265
+ const active = appliance === import_white_web_sdk.ApplianceNames.selector;
1266
+ const disabled = !writable;
1267
+ const shortcut = (app.hotKeys || defaultHotKeys).changeToSelector;
1268
+ return import_react46.default.createElement(Button, {
1269
+ content: renderToolTip(t("selector"), shortcut),
1270
+ onClick: changeAppliance,
1271
+ active
1272
+ }, import_react46.default.createElement(Icon, {
1273
+ fallback: import_react46.default.createElement(Icons.Selector, {
1274
+ theme,
1275
+ active
1276
+ }),
1277
+ src: disabled ? icons == null ? void 0 : icons.selectorIconDisable : icons == null ? void 0 : icons.selectorIcon,
1278
+ alt: "[selector]"
1279
+ }));
1280
+ }
1281
+ function EraserButton() {
1282
+ const app = useFastboardApp();
1283
+ const { t } = useTranslation();
1284
+ const { theme, icons, writable, setAppliance, memberState } = (0, import_react46.useContext)(ToolbarContext);
1285
+ const changeAppliance = (0, import_react46.useCallback)(() => setAppliance(import_white_web_sdk.ApplianceNames.eraser), [setAppliance]);
1286
+ const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1287
+ const active = appliance === import_white_web_sdk.ApplianceNames.eraser;
1288
+ const disabled = !writable;
1289
+ const shortcut = ((app == null ? void 0 : app.hotKeys) || defaultHotKeys).changeToEraser;
1290
+ return import_react46.default.createElement(Button, {
1291
+ content: renderToolTip(t("eraser"), shortcut),
1292
+ onClick: changeAppliance,
1293
+ active
1294
+ }, import_react46.default.createElement(Icon, {
1295
+ fallback: import_react46.default.createElement(Icons.Eraser, {
1296
+ theme,
1297
+ active
1298
+ }),
1299
+ src: disabled ? icons == null ? void 0 : icons.eraserIconDisable : icons == null ? void 0 : icons.eraserIcon,
1300
+ alt: "[eraser]"
1301
+ }));
1302
+ }
1303
+ function CleanButton() {
1304
+ const { t } = useTranslation();
1305
+ const { theme, icons, writable, cleanCurrentScene } = (0, import_react46.useContext)(ToolbarContext);
1306
+ const disabled = !writable;
1307
+ return import_react46.default.createElement(Button, {
1308
+ content: t("clean"),
1309
+ onClick: cleanCurrentScene
1310
+ }, import_react46.default.createElement(Icon, {
1311
+ fallback: import_react46.default.createElement(Icons.Clean, {
1312
+ theme
1313
+ }),
1314
+ src: disabled ? icons == null ? void 0 : icons.cleanIconDisable : icons == null ? void 0 : icons.cleanIcon,
1315
+ alt: "[clean]"
1316
+ }));
1317
+ }
1318
+
1319
+ // src/components/Toolbar/components/AppsButton.tsx
1320
+ var import_react47 = __toESM(require("@tippyjs/react"));
1321
+ var import_react48 = __toESM(require("react"));
1322
+
1323
+ // src/components/Toolbar/components/assets/vscode.png
1324
+ var vscode_default = "data:image/png;base64,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";
1325
+
1326
+ // src/components/Toolbar/components/assets/geogebra.png
1327
+ var geogebra_default = "data:image/png;base64,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";
1328
+
1329
+ // src/components/Toolbar/components/assets/countdown.png
1330
+ var countdown_default = "data:image/png;base64,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";
1331
+
1332
+ // src/components/Toolbar/components/AppsButton.tsx
1333
+ function AppsButton({ content, onClick }) {
1334
+ const { theme, icons, writable } = (0, import_react48.useContext)(ToolbarContext);
1335
+ const disabled = !writable;
1336
+ const button = import_react48.default.createElement(Button, {
1337
+ content: "Apps",
1338
+ onClick
1339
+ }, import_react48.default.createElement(Icon, {
1340
+ fallback: import_react48.default.createElement(Icons.Apps, {
1341
+ theme
1342
+ }),
1343
+ src: disabled ? icons == null ? void 0 : icons.appsIconDisable : icons == null ? void 0 : icons.appsIcon,
1344
+ alt: "[apps]"
1345
+ }));
1346
+ return content === false ? button : import_react48.default.createElement("span", {
1347
+ className: "fastboard-toolbar-btn-interactive"
1348
+ }, import_react48.default.createElement(import_react47.default, {
1349
+ className: "fastboard-tip",
1350
+ content: renderAppsButtonContent(content),
1351
+ theme,
1352
+ placement: "right-end",
1353
+ trigger: "click",
1354
+ offset: RightOffset,
1355
+ arrow: false,
1356
+ interactive: true
1357
+ }, button));
1358
+ }
1359
+ function renderAppsButtonContent(content) {
1360
+ return import_react48.default.createElement("div", {
1361
+ className: "fastboard-toolbar-panel apps"
1362
+ }, import_react48.default.createElement("div", {
1363
+ className: "fastboard-toolbar-apps"
1364
+ }, content || import_react48.default.createElement(DefaultApps, null)));
1365
+ }
1366
+ function DefaultApps() {
1367
+ const app = useFastboardApp();
1368
+ return import_react48.default.createElement(import_react48.default.Fragment, null, import_react48.default.createElement(AppIcon, {
1369
+ title: "Code Editor",
1370
+ src: vscode_default,
1371
+ alt: "[code editor]",
1372
+ onClick: app == null ? void 0 : app.insertCodeEditor.bind(app)
1373
+ }), import_react48.default.createElement(AppIcon, {
1374
+ title: "GeoGebra",
1375
+ src: geogebra_default,
1376
+ alt: "[geogebra]",
1377
+ onClick: app == null ? void 0 : app.insertGeoGebra.bind(app)
1378
+ }), import_react48.default.createElement(AppIcon, {
1379
+ title: "Countdown",
1380
+ src: countdown_default,
1381
+ alt: "[countdown]",
1382
+ onClick: app == null ? void 0 : app.insertCountdown.bind(app)
1383
+ }));
1384
+ }
1385
+ function AppIcon({ title, src, alt, onClick }) {
1386
+ return import_react48.default.createElement("span", {
1387
+ className: "fastboard-toolbar-app-icon"
1388
+ }, import_react48.default.createElement(Button, {
1389
+ placement: "top",
1390
+ content: title,
1391
+ onClick
1392
+ }, import_react48.default.createElement("img", {
1393
+ src,
1394
+ alt,
1395
+ title
1396
+ })), import_react48.default.createElement("span", {
1397
+ className: "fastboard-toolbar-app-icon-text"
1398
+ }, title));
1399
+ }
1400
+
1401
+ // src/components/Toolbar/components/PencilButton.tsx
1402
+ var import_react52 = __toESM(require("@tippyjs/react"));
1403
+ var import_react53 = __toESM(require("react"));
1404
+ var import_white_web_sdk2 = require("white-web-sdk");
1405
+
1406
+ // src/components/Toolbar/components/ColorBox.tsx
1407
+ var import_clsx5 = __toESM(require("clsx"));
1408
+ var import_react49 = __toESM(require("react"));
1409
+ var colors = {
1410
+ "#E02020": [224, 32, 32],
1411
+ "#F7B500": [247, 181, 0],
1412
+ "#6DD400": [109, 212, 0],
1413
+ "#32C5FF": [50, 197, 255],
1414
+ "#0091FF": [0, 145, 255],
1415
+ "#6236FF": [98, 54, 255],
1416
+ "#B620E0": [182, 32, 224],
1417
+ "#6D7278": [109, 114, 120]
1418
+ };
1419
+ var colorKeys = Object.keys(colors);
1420
+ function ColorBox() {
1421
+ const { theme, memberState, setStrokeColor, writable } = (0, import_react49.useContext)(ToolbarContext);
1422
+ const strokeColor = memberState == null ? void 0 : memberState.strokeColor;
1423
+ const disabled = !writable;
1424
+ return import_react49.default.createElement("div", {
1425
+ className: (0, import_clsx5.default)("fastboard-toolbar-color-box", theme)
1426
+ }, colorKeys.map((key) => import_react49.default.createElement("div", {
1427
+ key,
1428
+ className: (0, import_clsx5.default)("fastboard-toolbar-color-item", theme),
1429
+ onClick: () => setStrokeColor(colors[key])
1430
+ }, import_react49.default.createElement("div", {
1431
+ className: (0, import_clsx5.default)("fastboard-toolbar-color-border", theme, {
1432
+ active: strokeColor && isEqualArray(strokeColor, colors[key])
1433
+ })
1434
+ }, import_react49.default.createElement("button", {
1435
+ className: (0, import_clsx5.default)("fastboard-toolbar-color-btn"),
1436
+ style: { background: key },
1437
+ disabled,
1438
+ onClick: (ev) => {
1439
+ ev.stopPropagation();
1440
+ setStrokeColor(colors[key]);
1441
+ }
1442
+ })))));
1443
+ }
1444
+
1445
+ // src/components/Toolbar/components/CutLine.tsx
1446
+ var import_clsx6 = __toESM(require("clsx"));
1447
+ var import_react50 = __toESM(require("react"));
1448
+ function CutLine() {
1449
+ const { theme } = (0, import_react50.useContext)(ToolbarContext);
1450
+ return import_react50.default.createElement("span", {
1451
+ className: (0, import_clsx6.default)(`${name4}-cut-line`, theme)
1452
+ });
1453
+ }
1454
+
1455
+ // src/components/Toolbar/components/Slider.tsx
1456
+ var import_clsx7 = __toESM(require("clsx"));
1457
+ var import_rc_slider = __toESM(require("rc-slider"));
1458
+ var import_react51 = __toESM(require("react"));
1459
+ function Slider() {
1460
+ const { theme, writable, memberState, setStrokeWidth } = (0, import_react51.useContext)(ToolbarContext);
1461
+ const { activeColor } = themes[theme];
1462
+ const strokeWidth = (memberState == null ? void 0 : memberState.strokeWidth) || 0;
1463
+ return import_react51.default.createElement(import_rc_slider.default, {
1464
+ disabled: !writable,
1465
+ className: (0, import_clsx7.default)("fastboard-toolbar-slider", theme),
1466
+ trackStyle: { background: activeColor },
1467
+ handleStyle: { border: `1px solid ${activeColor}` },
1468
+ value: strokeWidth,
1469
+ onChange: setStrokeWidth,
1470
+ min: 1,
1471
+ max: 32
1472
+ });
1473
+ }
1474
+
1475
+ // src/components/Toolbar/components/PencilButton.tsx
1476
+ function PencilButton() {
1477
+ const app = useFastboardApp();
1478
+ const { t } = useTranslation();
1479
+ const { theme, icons, writable, setAppliance, memberState } = (0, import_react53.useContext)(ToolbarContext);
1480
+ const changeAppliance = (0, import_react53.useCallback)(() => {
1481
+ setAppliance(import_white_web_sdk2.ApplianceNames.pencil);
1482
+ }, [setAppliance]);
1483
+ const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1484
+ const active = appliance === import_white_web_sdk2.ApplianceNames.pencil;
1485
+ const disabled = !writable;
1486
+ const shortcut = ((app == null ? void 0 : app.hotKeys) || defaultHotKeys).changeToPencil;
1487
+ return import_react53.default.createElement("span", {
1488
+ className: "fastboard-toolbar-btn-interactive"
1489
+ }, import_react53.default.createElement(import_react52.default, {
1490
+ className: "fastboard-tip",
1491
+ content: renderPencilButtonContent(),
1492
+ theme,
1493
+ placement: "right-start",
1494
+ trigger: "click",
1495
+ offset: RightOffset,
1496
+ arrow: false,
1497
+ interactive: true
1498
+ }, import_react53.default.createElement(Button, {
1499
+ content: renderToolTip(t("pencil"), shortcut),
1500
+ active,
1501
+ onClick: changeAppliance
1502
+ }, import_react53.default.createElement(Icon, {
1503
+ fallback: import_react53.default.createElement(Icons.Pencil, {
1504
+ theme,
1505
+ active
1506
+ }),
1507
+ src: disabled ? icons == null ? void 0 : icons.pencilIconDisable : icons == null ? void 0 : icons.pencilIcon,
1508
+ alt: "[pencil]"
1509
+ }), import_react53.default.createElement("span", {
1510
+ className: "fastboard-toolbar-triangle"
1511
+ }))));
1512
+ }
1513
+ function renderPencilButtonContent() {
1514
+ return import_react53.default.createElement("div", {
1515
+ className: "fastboard-toolbar-panel pencil"
1516
+ }, import_react53.default.createElement(Slider, null), import_react53.default.createElement(CutLine, null), import_react53.default.createElement(ColorBox, null));
1517
+ }
1518
+
1519
+ // src/components/Toolbar/components/ShapesButton.tsx
1520
+ var import_react54 = __toESM(require("@tippyjs/react"));
1521
+ var import_react55 = __toESM(require("react"));
1522
+ var import_white_web_sdk4 = require("white-web-sdk");
1523
+
1524
+ // src/components/Toolbar/const.ts
1525
+ var import_white_web_sdk3 = require("white-web-sdk");
1526
+ var ShapesMap = {
1527
+ [import_white_web_sdk3.ApplianceNames.rectangle]: Icons.Rectangle,
1528
+ [import_white_web_sdk3.ApplianceNames.ellipse]: Icons.Circle,
1529
+ [import_white_web_sdk3.ApplianceNames.straight]: Icons.Line,
1530
+ [import_white_web_sdk3.ApplianceNames.arrow]: Icons.Arrow,
1531
+ [import_white_web_sdk3.ShapeType.Pentagram]: Icons.Star,
1532
+ [import_white_web_sdk3.ShapeType.Rhombus]: Icons.Diamond,
1533
+ [import_white_web_sdk3.ShapeType.Triangle]: Icons.Triangle,
1534
+ [import_white_web_sdk3.ShapeType.SpeechBalloon]: Icons.SpeechBalloon
1535
+ };
1536
+ var ApplianceShapes = [
1537
+ import_white_web_sdk3.ApplianceNames.rectangle,
1538
+ import_white_web_sdk3.ApplianceNames.ellipse,
1539
+ import_white_web_sdk3.ApplianceNames.straight,
1540
+ import_white_web_sdk3.ApplianceNames.arrow
1541
+ ];
1542
+ var Shapes = [
1543
+ import_white_web_sdk3.ShapeType.Pentagram,
1544
+ import_white_web_sdk3.ShapeType.Rhombus,
1545
+ import_white_web_sdk3.ShapeType.Triangle,
1546
+ import_white_web_sdk3.ShapeType.SpeechBalloon
1547
+ ];
1548
+ var ItemHeight = 32 + 4;
1549
+ var ItemsCount = 8;
1550
+ var MaxHeight = ItemHeight * ItemsCount - 4;
1551
+ var MinHeight = ItemHeight * 2 - 4;
1552
+
1553
+ // src/components/Toolbar/components/ShapesButton.tsx
1554
+ var ShapeTypes = /* @__PURE__ */ new Set([...ApplianceShapes, ...Shapes]);
1555
+ function ShapesButton() {
1556
+ const { t } = useTranslation();
1557
+ const { theme, memberState } = (0, import_react55.useContext)(ToolbarContext);
1558
+ const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1559
+ const shape = memberState == null ? void 0 : memberState.shapeType;
1560
+ const key = appliance === import_white_web_sdk4.ApplianceNames.shape ? shape : appliance;
1561
+ const active = ShapeTypes.has(key);
1562
+ const CurrentIcon = ShapesMap[key] || Icons.Rectangle;
1563
+ return import_react55.default.createElement("span", {
1564
+ className: "fastboard-toolbar-btn-interactive"
1565
+ }, import_react55.default.createElement(import_react54.default, {
1566
+ className: "fastboard-tip",
1567
+ content: renderShapesButtonContent(),
1568
+ theme,
1569
+ placement: "right-start",
1570
+ trigger: "click",
1571
+ offset: RightOffset,
1572
+ arrow: false,
1573
+ interactive: true
1574
+ }, import_react55.default.createElement(Button, {
1575
+ content: t("shape"),
1576
+ active
1577
+ }, import_react55.default.createElement(CurrentIcon, {
1578
+ theme,
1579
+ active
1580
+ }), import_react55.default.createElement("span", {
1581
+ className: "fastboard-toolbar-triangle"
1582
+ }))));
1583
+ }
1584
+ function renderShapesButtonContent() {
1585
+ return import_react55.default.createElement("div", {
1586
+ className: "fastboard-toolbar-panel shapes"
1587
+ }, import_react55.default.createElement(ShapesBox, null), import_react55.default.createElement(CutLine, null), import_react55.default.createElement(Slider, null), import_react55.default.createElement(CutLine, null), import_react55.default.createElement(ColorBox, null));
1588
+ }
1589
+ function ShapesBox() {
1590
+ const { t } = useTranslation();
1591
+ return import_react55.default.createElement("div", {
1592
+ className: "fastboard-toolbar-shapes"
1593
+ }, ApplianceShapes.map((Appliance) => import_react55.default.createElement(ApplianceShapeButton, {
1594
+ key: Appliance,
1595
+ content: t(Appliance),
1596
+ Appliance,
1597
+ Icon: ShapesMap[Appliance]
1598
+ })), Shapes.map((shape) => import_react55.default.createElement(ShapeShapeButton, {
1599
+ key: shape,
1600
+ content: t(shape),
1601
+ shape,
1602
+ Icon: ShapesMap[shape]
1603
+ })));
1604
+ }
1605
+ function ApplianceShapeButton({ content, Appliance, Icon: Icon2 }) {
1606
+ const { theme, writable, setAppliance, memberState } = (0, import_react55.useContext)(ToolbarContext);
1607
+ const current = memberState == null ? void 0 : memberState.currentApplianceName;
1608
+ const disabled = !writable;
1609
+ return import_react55.default.createElement(Button, {
1610
+ content,
1611
+ disabled,
1612
+ placement: "top",
1613
+ onClick: () => setAppliance(Appliance)
1614
+ }, import_react55.default.createElement(Icon2, {
1615
+ theme,
1616
+ active: current === Appliance
1617
+ }));
1618
+ }
1619
+ function ShapeShapeButton({ content, shape, Icon: Icon2 }) {
1620
+ const { theme, writable, setAppliance, memberState } = (0, import_react55.useContext)(ToolbarContext);
1621
+ const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1622
+ const current = appliance === import_white_web_sdk4.ApplianceNames.shape && (memberState == null ? void 0 : memberState.shapeType);
1623
+ const disabled = !writable;
1624
+ return import_react55.default.createElement(Button, {
1625
+ content,
1626
+ disabled,
1627
+ placement: "top",
1628
+ onClick: () => setAppliance(import_white_web_sdk4.ApplianceNames.shape, shape)
1629
+ }, import_react55.default.createElement(Icon2, {
1630
+ theme,
1631
+ active: current === shape
1632
+ }));
1633
+ }
1634
+
1635
+ // src/components/Toolbar/components/TextButton.tsx
1636
+ var import_react56 = __toESM(require("@tippyjs/react"));
1637
+ var import_react57 = __toESM(require("react"));
1638
+ var import_white_web_sdk5 = require("white-web-sdk");
1639
+ function TextButton() {
1640
+ const app = useFastboardApp();
1641
+ const { t } = useTranslation();
1642
+ const { theme, icons, writable, setAppliance, memberState } = (0, import_react57.useContext)(ToolbarContext);
1643
+ const changeAppliance = (0, import_react57.useCallback)(() => {
1644
+ setAppliance(import_white_web_sdk5.ApplianceNames.text);
1645
+ }, [setAppliance]);
1646
+ const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1647
+ const active = appliance === import_white_web_sdk5.ApplianceNames.text;
1648
+ const disabled = !writable;
1649
+ const shortcut = ((app == null ? void 0 : app.hotKeys) || defaultHotKeys).changeToText;
1650
+ return import_react57.default.createElement("span", {
1651
+ className: "fastboard-toolbar-btn-interactive"
1652
+ }, import_react57.default.createElement(import_react56.default, {
1653
+ className: "fastboard-tip",
1654
+ content: renderTextButtonContent(),
1655
+ theme,
1656
+ placement: "right-start",
1657
+ trigger: "click",
1658
+ offset: RightOffset,
1659
+ arrow: false,
1660
+ interactive: true
1661
+ }, import_react57.default.createElement(Button, {
1662
+ content: renderToolTip(t("text"), shortcut),
1663
+ active,
1664
+ onClick: changeAppliance
1665
+ }, import_react57.default.createElement(Icon, {
1666
+ fallback: import_react57.default.createElement(Icons.Text, {
1667
+ theme,
1668
+ active
1669
+ }),
1670
+ src: disabled ? icons == null ? void 0 : icons.textIconDisable : icons == null ? void 0 : icons.textIcon,
1671
+ alt: "[text]"
1672
+ }), import_react57.default.createElement("span", {
1673
+ className: "fastboard-toolbar-triangle"
1674
+ }))));
1675
+ }
1676
+ function renderTextButtonContent() {
1677
+ return import_react57.default.createElement("div", {
1678
+ className: "fastboard-toolbar-panel text"
1679
+ }, import_react57.default.createElement(ColorBox, null));
1680
+ }
1681
+
1682
+ // src/components/Toolbar/components/UpDownButtons.tsx
1683
+ var import_react58 = __toESM(require("react"));
1684
+ function UpButton({ disabled, scrollTo }) {
1685
+ const { theme, icons } = (0, import_react58.useContext)(ToolbarContext);
1686
+ const scrollUp = (0, import_react58.useCallback)(() => scrollTo(-ItemHeight), [scrollTo]);
1687
+ return import_react58.default.createElement(import_react58.default.Fragment, null, import_react58.default.createElement(Button, {
1688
+ content: "Up",
1689
+ disabled,
1690
+ onClick: scrollUp
1691
+ }, import_react58.default.createElement(Icon, {
1692
+ fallback: import_react58.default.createElement(Icons.Up, {
1693
+ theme
1694
+ }),
1695
+ src: disabled ? icons == null ? void 0 : icons.upIconDisable : icons == null ? void 0 : icons.upIcon,
1696
+ alt: "[up]"
1697
+ })), import_react58.default.createElement(CutLine, null));
1698
+ }
1699
+ function DownButton({ disabled, scrollTo }) {
1700
+ const { theme, icons } = (0, import_react58.useContext)(ToolbarContext);
1701
+ const scrollDown = (0, import_react58.useCallback)(() => scrollTo(ItemHeight), [scrollTo]);
1702
+ return import_react58.default.createElement(import_react58.default.Fragment, null, import_react58.default.createElement(CutLine, null), import_react58.default.createElement(Button, {
1703
+ content: "Down",
1704
+ disabled,
1705
+ onClick: scrollDown
1706
+ }, import_react58.default.createElement(Icon, {
1707
+ fallback: import_react58.default.createElement(Icons.Down, {
1708
+ theme
1709
+ }),
1710
+ src: disabled ? icons == null ? void 0 : icons.downIconDisable : icons == null ? void 0 : icons.downIcon,
1711
+ alt: "[down]"
1712
+ })));
1713
+ }
1714
+
1715
+ // src/components/Toolbar/Content.tsx
1716
+ var Content = import_react59.default.memo(() => {
1717
+ const ref = (0, import_react59.useRef)(null);
1718
+ const [scrollTop, setScrollTop] = (0, import_react59.useState)(0);
1719
+ const [parentHeight, setParentHeight] = (0, import_react59.useState)(0);
1720
+ const needScroll = parentHeight < ItemHeight * ItemsCount + 48;
1721
+ const sectionHeight = clamp(parentHeight - 48 * (needScroll ? 3 : 1), MinHeight, MaxHeight);
1722
+ const scrollBuffer = Math.max(parentHeight - sectionHeight - 1, 0);
1723
+ const disableScrollUp = scrollTop === 0;
1724
+ const disableScrollDown = scrollTop === scrollBuffer;
1725
+ const scrollTo = (0, import_react59.useCallback)((height) => {
1726
+ setScrollTop(clamp(scrollTop + height, 0, scrollBuffer));
1727
+ }, [scrollBuffer, scrollTop]);
1728
+ (0, import_react59.useEffect)(() => {
1729
+ if (ref.current) {
1730
+ ref.current.scrollTop = scrollTop;
1731
+ }
1732
+ }, [scrollTop]);
1733
+ (0, import_react59.useEffect)(() => {
1734
+ var _a, _b;
1735
+ const container = (_b = (_a = ref.current) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.parentElement;
1736
+ if (container) {
1737
+ const { paddingTop, paddingBottom } = getComputedStyle(container);
1738
+ const padding = parseInt(paddingTop) + parseInt(paddingBottom) || 0;
1739
+ const resizeObserver = new ResizeObserver(() => {
1740
+ setParentHeight(container.getBoundingClientRect().height - padding);
1741
+ });
1742
+ resizeObserver.observe(container);
1743
+ return () => resizeObserver.disconnect();
1744
+ }
1745
+ }, []);
1746
+ return import_react59.default.createElement(import_react59.default.Fragment, null, needScroll && import_react59.default.createElement(UpButton, {
1747
+ scrollTo,
1748
+ disabled: disableScrollUp
1749
+ }), import_react59.default.createElement("div", {
1750
+ ref,
1751
+ className: (0, import_clsx8.default)(`${name4}-section`),
1752
+ style: {
1753
+ height: `${sectionHeight}px`,
1754
+ overflow: needScroll ? "hidden" : "visible"
1755
+ }
1756
+ }, import_react59.default.createElement(ClickerButton, null), import_react59.default.createElement(SelectorButton, null), import_react59.default.createElement(PencilButton, null), import_react59.default.createElement(TextButton, null), import_react59.default.createElement(ShapesButton, null), import_react59.default.createElement(EraserButton, null), import_react59.default.createElement(CleanButton, null), import_react59.default.createElement(AppsButton, null)), needScroll && import_react59.default.createElement(DownButton, {
1757
+ scrollTo,
1758
+ disabled: disableScrollDown
1759
+ }));
1760
+ });
1761
+
1762
+ // src/components/Toolbar/Toolbar.tsx
1763
+ var ToolbarContext = (0, import_react60.createContext)(__spreadValues({
1764
+ theme: "light"
1765
+ }, EmptyToolbarHook));
1766
+ var name4 = "fastboard-toolbar";
1767
+ var Toolbar = ({ theme, icons }) => {
1768
+ theme = useTheme(theme);
1769
+ const hook = useToolbar();
1770
+ const [expanded, setExpanded] = (0, import_react60.useState)(true);
1771
+ const [toolbar, toolbarRef] = (0, import_react60.useState)(null);
1772
+ const [onHover, setOnHover] = (0, import_react60.useState)(false);
1773
+ const [delayedOnHover, setDelayedOnHover] = (0, import_react60.useState)(false);
1774
+ const [pointEvents, setPointEvents] = (0, import_react60.useState)(true);
1775
+ const disabled = !hook.writable;
1776
+ const toggle = (0, import_react60.useCallback)(() => {
1777
+ setExpanded((e) => !e);
1778
+ }, []);
1779
+ (0, import_react60.useEffect)(() => {
1780
+ const timer = setTimeout(() => {
1781
+ setDelayedOnHover(onHover);
1782
+ }, 400);
1783
+ return () => clearTimeout(timer);
1784
+ }, [onHover]);
1785
+ return import_react60.default.createElement(ToolbarContext.Provider, {
1786
+ value: __spreadValues({ theme, icons }, hook)
1787
+ }, import_react60.default.createElement(import_framer_motion.AnimatePresence, null, expanded ? import_react60.default.createElement(import_framer_motion.motion.div, {
1788
+ initial: { x: -100 },
1789
+ animate: { x: 0, transition: { duration: 0.5 } },
1790
+ key: "toolbar",
1791
+ ref: toolbarRef,
1792
+ className: (0, import_clsx9.default)(name4, theme),
1793
+ onPointerEnter: () => {
1794
+ expanded && setOnHover(true);
1795
+ },
1796
+ onMouseLeave: () => setOnHover(false),
1797
+ exit: { x: -100, transition: { duration: 0.5 } },
1798
+ onAnimationStart: () => setPointEvents(false),
1799
+ onAnimationComplete: () => setPointEvents(true),
1800
+ style: { pointerEvents: pointEvents ? "auto" : "none" }
1801
+ }, import_react60.default.createElement(Content, null), expanded && (onHover || delayedOnHover) && import_react60.default.createElement(Mask, {
1802
+ toolbar
1803
+ }, import_react60.default.createElement("div", {
1804
+ onClick: toggle
1805
+ }, import_react60.default.createElement("img", {
1806
+ draggable: false,
1807
+ className: (0, import_clsx9.default)(`${name4}-mask-btn`, theme),
1808
+ src: collapsed_default
1809
+ })))) : import_react60.default.createElement(import_framer_motion.motion.div, {
1810
+ className: (0, import_clsx9.default)(`${name4}-expand-btn`, theme),
1811
+ key: "expand",
1812
+ onClick: toggle,
1813
+ initial: { x: -100 },
1814
+ animate: { x: 0, transition: { duration: 0.5 } }
1815
+ }, !expanded && import_react60.default.createElement(Icon, {
1816
+ fallback: import_react60.default.createElement("img", {
1817
+ draggable: false,
1818
+ src: expanded_default,
1819
+ className: (0, import_clsx9.default)(`${name4}-mask-btn`, theme)
1820
+ }),
1821
+ src: disabled ? icons == null ? void 0 : icons.expandIconDisable : icons == null ? void 0 : icons.expandIcon
1822
+ }))));
1823
+ };
1824
+
1825
+ // src/components/PlayerControl/hooks.ts
1826
+ var import_react61 = require("react");
1827
+ var import_white_web_sdk6 = require("white-web-sdk");
1828
+ var EMPTY_ARRAY = [];
1829
+ function useForceUpdate2() {
1830
+ const [, forceUpdate_] = (0, import_react61.useState)({});
1831
+ return (0, import_react61.useCallback)(() => forceUpdate_({}), EMPTY_ARRAY);
1832
+ }
1833
+ function usePlayerControl(player) {
1834
+ const togglePlay = (0, import_react61.useCallback)(() => {
1835
+ if (player) {
1836
+ switch (player.phase) {
1837
+ case import_white_web_sdk6.PlayerPhase.WaitingFirstFrame:
1838
+ case import_white_web_sdk6.PlayerPhase.Pause:
1839
+ case import_white_web_sdk6.PlayerPhase.Ended: {
1840
+ player.play();
1841
+ break;
1842
+ }
1843
+ case import_white_web_sdk6.PlayerPhase.Playing: {
1844
+ player.pause();
1845
+ break;
1846
+ }
1847
+ }
1848
+ }
1849
+ }, [player]);
1850
+ const seekToProgressTime = (0, import_react61.useCallback)((time) => {
1851
+ if (player) {
1852
+ player.seekToProgressTime(time);
1853
+ }
1854
+ }, [player]);
1855
+ const lastPlayer = useLastValue(player);
1856
+ const forceUpdate = useForceUpdate2();
1857
+ const setSpeed = (0, import_react61.useCallback)((speed2) => {
1858
+ if (player) {
1859
+ player.playbackSpeed = speed2;
1860
+ forceUpdate();
1861
+ }
1862
+ }, [forceUpdate, player]);
1863
+ (0, import_react61.useEffect)(() => {
1864
+ if (!lastPlayer && player) {
1865
+ forceUpdate();
1866
+ }
1867
+ }, [forceUpdate, lastPlayer, player]);
1868
+ (0, import_react61.useEffect)(() => {
1869
+ if (player) {
1870
+ player.callbacks.on("onPhaseChanged", forceUpdate);
1871
+ player.callbacks.on("onProgressTimeChanged", forceUpdate);
1872
+ return () => {
1873
+ player.callbacks.off("onPhaseChanged", forceUpdate);
1874
+ player.callbacks.off("onProgressTimeChanged", forceUpdate);
1875
+ };
1876
+ }
1877
+ }, [forceUpdate, player]);
1878
+ const phase = player ? player.phase : import_white_web_sdk6.PlayerPhase.WaitingFirstFrame;
1879
+ const currentTime = player ? player.progressTime : 0;
1880
+ const totalTime = player ? player.timeDuration : 0;
1881
+ const speed = player ? player.playbackSpeed : 1;
1882
+ return {
1883
+ phase,
1884
+ currentTime,
1885
+ totalTime,
1886
+ speed,
1887
+ setSpeed,
1888
+ togglePlay,
1889
+ seekToProgressTime
1890
+ };
1891
+ }
1892
+
1893
+ // src/components/PlayerControl/PlayerControl.tsx
1894
+ var import_react68 = __toESM(require("@tippyjs/react"));
1895
+ var import_clsx11 = __toESM(require("clsx"));
1896
+ var import_rc_slider2 = __toESM(require("rc-slider"));
1897
+ var import_react69 = __toESM(require("react"));
1898
+ var import_white_web_sdk7 = require("white-web-sdk");
1899
+
1900
+ // src/components/PlayerControl/components/Button.tsx
1901
+ var import_clsx10 = __toESM(require("clsx"));
1902
+ var import_react62 = __toESM(require("react"));
1903
+ var import_react63 = __toESM(require("@tippyjs/react"));
1904
+ var Button2 = (0, import_react62.forwardRef)((props, ref) => {
1905
+ const { theme, content, disabled, active, onClick, interactive, placement = "top", children } = props;
1906
+ return import_react62.default.createElement(import_react63.default, {
1907
+ className: "fastboard-tip",
1908
+ content,
1909
+ interactive,
1910
+ theme,
1911
+ disabled,
1912
+ placement,
1913
+ offset: TopOffset,
1914
+ delay: [1e3, 400],
1915
+ duration: 300
1916
+ }, import_react62.default.createElement("button", {
1917
+ ref,
1918
+ className: (0, import_clsx10.default)("fastboard-player-control-btn", theme, { active }),
1919
+ onClick,
1920
+ disabled
1921
+ }, children));
1922
+ });
1923
+
1924
+ // src/components/PlayerControl/icons/index.ts
1925
+ var import_react67 = require("react");
1926
+
1927
+ // src/components/PlayerControl/icons/Loading.tsx
1928
+ var import_react64 = __toESM(require("react"));
1929
+ var Loading = (props) => {
1930
+ const stroke = getStroke(props);
1931
+ return import_react64.default.createElement("svg", {
1932
+ viewBox: "0 0 24 24"
1933
+ }, import_react64.default.createElement("path", {
1934
+ d: "M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8z",
1935
+ fill: stroke
1936
+ }));
1937
+ };
1938
+
1939
+ // src/components/PlayerControl/icons/Pause.tsx
1940
+ var import_react65 = __toESM(require("react"));
1941
+ var Pause = (props) => {
1942
+ const stroke = getStroke(props);
1943
+ return import_react65.default.createElement("svg", {
1944
+ viewBox: "0 0 24 24"
1945
+ }, import_react65.default.createElement("path", {
1946
+ d: "M14 19h4V5h-4M6 19h4V5H6v14z",
1947
+ fill: stroke
1948
+ }));
1949
+ };
1950
+
1951
+ // src/components/PlayerControl/icons/Play.tsx
1952
+ var import_react66 = __toESM(require("react"));
1953
+ var Play = (props) => {
1954
+ const stroke = getStroke(props);
1955
+ return import_react66.default.createElement("svg", {
1956
+ viewBox: "0 0 24 24"
1957
+ }, import_react66.default.createElement("path", {
1958
+ d: "M8 5.14v14l11-7l-11-7z",
1959
+ fill: stroke
1960
+ }));
1961
+ };
1962
+
1963
+ // src/components/PlayerControl/icons/index.ts
1964
+ var Icons2 = {
1965
+ Play: (0, import_react67.memo)(Play),
1966
+ Pause: (0, import_react67.memo)(Pause),
1967
+ Loading: (0, import_react67.memo)(Loading)
1968
+ };
1969
+
1970
+ // src/components/PlayerControl/PlayerControl.tsx
1971
+ var name5 = "fastboard-player-control";
1972
+ function PlayerControl(_a) {
1973
+ var _b = _a, { theme, autoHide = false, player: player_ } = _b, icons = __objRest(_b, ["theme", "autoHide", "player"]);
1974
+ theme = useTheme(theme);
1975
+ const { t } = useTranslation();
1976
+ const [currentTime, setCurrentTime] = (0, import_react69.useState)(0);
1977
+ const player = usePlayerControl(player_);
1978
+ (0, import_react69.useEffect)(() => {
1979
+ setCurrentTime(player.currentTime);
1980
+ }, [player.currentTime]);
1981
+ (0, import_react69.useEffect)(() => {
1982
+ if (player.currentTime !== currentTime) {
1983
+ player.seekToProgressTime(currentTime);
1984
+ }
1985
+ }, [currentTime]);
1986
+ const isLoading = player.phase === import_white_web_sdk7.PlayerPhase.WaitingFirstFrame || player.phase === import_white_web_sdk7.PlayerPhase.Buffering;
1987
+ const isPlaying = player.phase === import_white_web_sdk7.PlayerPhase.Playing;
1988
+ const { activeColor } = themes[theme];
1989
+ return import_react69.default.createElement("div", {
1990
+ className: (0, import_clsx11.default)(name5, theme, { "auto-hide": autoHide })
1991
+ }, import_react69.default.createElement("button", {
1992
+ className: (0, import_clsx11.default)(`${name5}-btn`, isLoading ? "loading" : isPlaying ? "pause" : "play", theme),
1993
+ disabled: isLoading,
1994
+ onClick: player.togglePlay
1995
+ }, import_react69.default.createElement(Icon, {
1996
+ fallback: isLoading ? import_react69.default.createElement(Icons2.Loading, {
1997
+ theme
1998
+ }) : isPlaying ? import_react69.default.createElement(Icons2.Pause, {
1999
+ theme
2000
+ }) : import_react69.default.createElement(Icons2.Play, {
2001
+ theme
2002
+ }),
2003
+ src: isLoading ? icons.loadingIcon : isPlaying ? icons.pauseIcon : icons.playIcon,
2004
+ alt: isLoading ? "[loading]" : isPlaying ? "[pause]" : "[play]"
2005
+ })), import_react69.default.createElement("span", {
2006
+ className: (0, import_clsx11.default)(`${name5}-slider`, { loading: isLoading }, theme)
2007
+ }, import_react69.default.createElement(import_rc_slider2.default, {
2008
+ disabled: isLoading,
2009
+ trackStyle: { background: activeColor },
2010
+ handleStyle: { border: `1px solid ${activeColor}` },
2011
+ value: currentTime,
2012
+ onChange: setCurrentTime,
2013
+ min: 0,
2014
+ max: player.totalTime,
2015
+ step: 100
2016
+ })), import_react69.default.createElement("span", {
2017
+ className: (0, import_clsx11.default)(`${name5}-current`, theme)
2018
+ }, renderTime(player.currentTime)), import_react69.default.createElement("span", {
2019
+ className: (0, import_clsx11.default)(`${name5}-slash`, theme)
2020
+ }, "/"), import_react69.default.createElement("span", {
2021
+ className: (0, import_clsx11.default)(`${name5}-total`, theme)
2022
+ }, renderTime(player.totalTime)), import_react69.default.createElement("span", {
2023
+ className: `${name5}-btn-interactive`
2024
+ }, import_react69.default.createElement(import_react68.default, {
2025
+ className: "fastboard-tip",
2026
+ content: renderSpeeds(player),
2027
+ theme,
2028
+ placement: "top-end",
2029
+ trigger: "click",
2030
+ offset: TopOffset,
2031
+ arrow: false,
2032
+ interactive: true
2033
+ }, import_react69.default.createElement(Button2, {
2034
+ content: t("speed"),
2035
+ theme,
2036
+ disabled: isLoading
2037
+ }, import_react69.default.createElement("span", {
2038
+ className: (0, import_clsx11.default)(`${name5}-speed-text`, theme)
2039
+ }, player.speed, "x")))));
2040
+ }
2041
+ function renderTime(ms) {
2042
+ let seconds = ms / 1e3;
2043
+ const minutes = Math.floor(seconds / 60);
2044
+ seconds = Math.floor(seconds) % 60;
2045
+ return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
2046
+ }
2047
+ var Speeds = [2, 1.5, 1.25, 1, 0.75, 0.5];
2048
+ function renderSpeeds({ speed: current, setSpeed }) {
2049
+ return import_react69.default.createElement("div", {
2050
+ className: (0, import_clsx11.default)(`${name5}-panel`, "speed")
2051
+ }, Speeds.map((speed) => import_react69.default.createElement("button", {
2052
+ className: (0, import_clsx11.default)(`${name5}-btn`, "speed", {
2053
+ active: speed === current
2054
+ }),
2055
+ key: speed,
2056
+ onClick: () => setSpeed(speed)
2057
+ }, speed, "x")));
2058
+ }
2059
+
2060
+ // src/components/Fastboard.tsx
2061
+ var import_react70 = __toESM(require("react"));
2062
+ function Fastboard(_a) {
2063
+ var _b = _a, { app } = _b, restProps = __objRest(_b, ["app"]);
2064
+ if (!app) {
2065
+ return import_react70.default.createElement("div", {
2066
+ className: "fastboard-root"
2067
+ });
2068
+ }
2069
+ return import_react70.default.createElement(FastboardAppContext.Provider, {
2070
+ value: app
2071
+ }, import_react70.default.createElement(FastboardInternal, __spreadValues({}, restProps)));
2072
+ }
2073
+ function FastboardInternal({
2074
+ language,
2075
+ layout = {},
2076
+ theme = "light",
2077
+ children
2078
+ }) {
2079
+ const app = useFastboardApp();
2080
+ const forceUpdate = useForceUpdate();
2081
+ const i18n = useAsyncValue(() => createI18n({ language }));
2082
+ (0, import_react70.useEffect)(() => {
2083
+ if (i18n)
2084
+ i18n.changeLanguage(language);
2085
+ forceUpdate();
2086
+ }, [forceUpdate, i18n, language]);
2087
+ const useWhiteboard = (0, import_react70.useCallback)((container) => {
2088
+ container && app && app.manager.bindContainer(container);
2089
+ }, [app]);
2090
+ const hideControls = useHideControls();
2091
+ const showControls = !hideControls;
2092
+ const {
2093
+ Toolbar: toolbar = showControls || hideControls === "toolbar-only",
2094
+ RedoUndo: redo_undo = showControls,
2095
+ ZoomControl: zoom_control = showControls,
2096
+ PageControl: page_control = showControls
2097
+ } = layout;
2098
+ return import_react70.default.createElement(ThemeContext.Provider, {
2099
+ value: theme
2100
+ }, import_react70.default.createElement(I18nContext.Provider, {
2101
+ value: i18n
2102
+ }, import_react70.default.createElement("div", {
2103
+ className: "fastboard-root"
2104
+ }, import_react70.default.createElement("div", {
2105
+ className: "fastboard-view",
2106
+ ref: useWhiteboard
2107
+ }), children ? children : import_react70.default.createElement(import_react70.default.Fragment, null, toolbar && import_react70.default.createElement("div", {
2108
+ className: "fastboard-left"
2109
+ }, import_react70.default.createElement(Toolbar, null)), (redo_undo || zoom_control) && import_react70.default.createElement("div", {
2110
+ className: "fastboard-bottom-left"
2111
+ }, redo_undo && import_react70.default.createElement(RedoUndo, null), zoom_control && import_react70.default.createElement(ZoomControl, null)), page_control && import_react70.default.createElement("div", {
2112
+ className: "fastboard-bottom-right"
2113
+ }, import_react70.default.createElement(PageControl, null))))));
2114
+ }
2115
+ module.exports = __toCommonJS(src_exports);
2116
+ //# sourceMappingURL=index.js.map