seat-editor 1.5.7 → 1.6.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 (63) hide show
  1. package/dist/app/layout.d.ts +1 -1
  2. package/dist/app/new-board/page.d.ts +1 -1
  3. package/dist/app/new-board/page.jsx +21 -26
  4. package/dist/app/old-board/page.d.ts +2 -1
  5. package/dist/app/only-view/page.d.ts +1 -1
  6. package/dist/app/page.d.ts +1 -1
  7. package/dist/components/button-tools/index.d.ts +1 -1
  8. package/dist/components/form-tools/label.d.ts +1 -1
  9. package/dist/components/form-tools/shape.d.ts +1 -1
  10. package/dist/components/input/number-indicator.d.ts +1 -1
  11. package/dist/components/joystick/index.d.ts +2 -1
  12. package/dist/components/layer/index.d.ts +1 -1
  13. package/dist/components/layer/index.jsx +29 -9
  14. package/dist/components/lib/index.d.ts +1 -1
  15. package/dist/components/modal-preview/index.d.ts +1 -1
  16. package/dist/features/board/index.d.ts +1 -1
  17. package/dist/features/board/index.jsx +44 -6
  18. package/dist/features/navbar/index.d.ts +1 -1
  19. package/dist/features/package/index.d.ts +1 -1
  20. package/dist/features/package/index.jsx +11 -2
  21. package/dist/features/panel/index.d.ts +1 -1
  22. package/dist/features/panel/index.jsx +7 -2
  23. package/dist/features/panel/select-tool.d.ts +1 -1
  24. package/dist/features/panel/square-circle-tool.d.ts +1 -1
  25. package/dist/features/panel/table-seat-circle.d.ts +1 -1
  26. package/dist/features/panel/text-tool.d.ts +1 -1
  27. package/dist/features/panel/upload-tool.d.ts +1 -1
  28. package/dist/features/side-tool/index.d.ts +1 -1
  29. package/dist/features/side-tool/index.jsx +7 -2
  30. package/dist/features/view/index.d.ts +1 -1
  31. package/dist/features/view-only/index.d.ts +1 -1
  32. package/dist/provider/redux-provider.d.ts +1 -1
  33. package/dist/provider/store-provider.d.ts +1 -1
  34. package/dist/seat-editor.css +1 -1
  35. package/package.json +1 -1
  36. package/dist/app/layout.js +0 -22
  37. package/dist/app/new-board/page.js +0 -40
  38. package/dist/app/old-board/page.js +0 -377
  39. package/dist/app/only-view/page.js +0 -41
  40. package/dist/app/page.js +0 -8
  41. package/dist/components/button-tools/index.js +0 -11
  42. package/dist/components/form-tools/label.js +0 -7
  43. package/dist/components/form-tools/shape.js +0 -25
  44. package/dist/components/input/number-indicator.js +0 -27
  45. package/dist/components/joystick/index.js +0 -48
  46. package/dist/components/layer/index.js +0 -278
  47. package/dist/components/lib/index.js +0 -28
  48. package/dist/components/modal-preview/index.js +0 -10
  49. package/dist/features/board/index.js +0 -650
  50. package/dist/features/navbar/index.js +0 -6
  51. package/dist/features/package/index.js +0 -95
  52. package/dist/features/panel/index.js +0 -97
  53. package/dist/features/panel/select-tool.js +0 -48
  54. package/dist/features/panel/square-circle-tool.js +0 -8
  55. package/dist/features/panel/table-seat-circle.js +0 -9
  56. package/dist/features/panel/text-tool.js +0 -7
  57. package/dist/features/panel/upload-tool.js +0 -146
  58. package/dist/features/side-tool/index.js +0 -244
  59. package/dist/features/view/index.js +0 -219
  60. package/dist/features/view-only/index.js +0 -197
  61. package/dist/provider/antd-provider.js +0 -43
  62. package/dist/provider/redux-provider.js +0 -7
  63. package/dist/provider/store-provider.js +0 -9
@@ -3,4 +3,4 @@ import "./globals.css";
3
3
  export declare const metadata: Metadata;
4
4
  export default function RootLayout({ children, }: Readonly<{
5
5
  children: React.ReactNode;
6
- }>): import("react/jsx-runtime").JSX.Element;
6
+ }>): import("react").JSX.Element;
@@ -1 +1 @@
1
- export default function NewBoard(): import("react/jsx-runtime").JSX.Element;
1
+ export default function NewBoard(): import("react").JSX.Element;
@@ -1,22 +1,23 @@
1
1
  "use client";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  import { useEffect, useState } from "react";
12
3
  import SeatEditor from "../../features/package";
13
4
  import { constantData } from "../constant";
14
5
  export default function NewBoard() {
15
6
  const [initialValue, setInitialValue] = useState([]);
7
+ const [extraComponents, setExtraComponents] = useState([]);
16
8
  const [viewOnly, setViewOnly] = useState(true);
17
- console.log("constantData", constantData);
9
+ console.log("constantData", constantData, initialValue);
18
10
  useEffect(() => {
19
11
  setInitialValue(constantData);
12
+ setExtraComponents([{
13
+ src: "https://d3l3j4e3k9p181.cloudfront.net/dev/5bf923de-2366-4a11-9b8b-e92de0afbf05/3a65cb36-7d85-4c38-9403-a15f94641920/68d45207-d66b-4bb5-92a2-4e5a87715e98/rsvp/1751350513582817819_download (10).jpg",
14
+ id: 1747388267450,
15
+ x: 0,
16
+ y: 0,
17
+ shape: "background",
18
+ width: 100,
19
+ height: 100,
20
+ }]);
20
21
  }, []);
21
22
  return (<>
22
23
  <div className="w-full h-screen flex flex-col relative justify-center">
@@ -35,24 +36,18 @@ export default function NewBoard() {
35
36
  {viewOnly ? "Edit Mode" : "View Mode"}
36
37
  </button>
37
38
  <div className="flex-1 h-full">
38
- <SeatEditor componentProps={initialValue} viewOnly={viewOnly} mappingKey="properties" onCurrentStateChange={(setState) => {
39
- var _a;
39
+ <SeatEditor componentProps={initialValue} viewOnly={viewOnly} dragOnly mappingKey="properties" onCurrentStateChange={(setState) => {
40
+ var _a, _b, _c, _d;
40
41
  console.log("setState", setState);
41
- setInitialValue((_a = setState === null || setState === void 0 ? void 0 : setState.components) !== null && _a !== void 0 ? _a : []);
42
- }} extraComponentProps={[{
43
- src: "https://d3l3j4e3k9p181.cloudfront.net/dev/5bf923de-2366-4a11-9b8b-e92de0afbf05/3a65cb36-7d85-4c38-9403-a15f94641920/68d45207-d66b-4bb5-92a2-4e5a87715e98/rsvp/1751350513582817819_download (10).jpg",
44
- id: 1747388267450,
45
- x: 0,
46
- y: 0,
47
- shape: "background",
48
- width: 100,
49
- height: 100,
50
- }]} defaultBackground="#ffffff"
42
+ if (((_a = setState === null || setState === void 0 ? void 0 : setState.components) === null || _a === void 0 ? void 0 : _a.length) > 0) {
43
+ setInitialValue((_b = setState === null || setState === void 0 ? void 0 : setState.components) !== null && _b !== void 0 ? _b : []);
44
+ }
45
+ if (((_c = setState === null || setState === void 0 ? void 0 : setState.extraComponents) === null || _c === void 0 ? void 0 : _c.length) > 0) {
46
+ setExtraComponents((_d = setState === null || setState === void 0 ? void 0 : setState.extraComponents) !== null && _d !== void 0 ? _d : []);
47
+ }
48
+ }} extraComponentProps={extraComponents} defaultBackground="#ffffff"
51
49
  // dragOnly={true}
52
- statusKey="status" action={(action) => __awaiter(this, void 0, void 0, function* () {
53
- console.log({ action });
54
- return null;
55
- })}/>
50
+ statusKey="status"/>
56
51
  </div>
57
52
 
58
53
  </div>
@@ -1,2 +1,3 @@
1
- declare const SeatEditor: () => import("react/jsx-runtime").JSX.Element;
1
+ import React from "react";
2
+ declare const SeatEditor: () => React.JSX.Element;
2
3
  export default SeatEditor;
@@ -1,2 +1,2 @@
1
- declare const TouchScrollDetect: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const TouchScrollDetect: () => import("react").JSX.Element;
2
2
  export default TouchScrollDetect;
@@ -1,2 +1,2 @@
1
- declare const TableEditor: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const TableEditor: () => import("react").JSX.Element;
2
2
  export default TableEditor;
@@ -7,5 +7,5 @@ interface ButtonToolsProps {
7
7
  }>;
8
8
  popoverProps?: PopoverProps;
9
9
  }
10
- declare const ButtonTools: (props: ButtonToolsProps) => import("react/jsx-runtime").JSX.Element;
10
+ declare const ButtonTools: (props: ButtonToolsProps) => import("react").JSX.Element;
11
11
  export default ButtonTools;
@@ -1,2 +1,2 @@
1
- declare const SectionLabel: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const SectionLabel: () => import("react").JSX.Element;
2
2
  export default SectionLabel;
@@ -1,2 +1,2 @@
1
- declare const SectionShape: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const SectionShape: () => import("react").JSX.Element;
2
2
  export default SectionShape;
@@ -3,5 +3,5 @@ interface NumberIndicatorProps {
3
3
  defaultValue?: number;
4
4
  onChange: (value: number) => void;
5
5
  }
6
- declare const NumberIndicator: ({ name, defaultValue, onChange }: NumberIndicatorProps) => import("react/jsx-runtime").JSX.Element;
6
+ declare const NumberIndicator: ({ name, defaultValue, onChange }: NumberIndicatorProps) => import("react").JSX.Element;
7
7
  export default NumberIndicator;
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  type JoystickPosition = {
2
3
  x: number;
3
4
  y: number;
@@ -7,5 +8,5 @@ type JoystickProps = {
7
8
  onMove?: (pos: JoystickPosition) => void;
8
9
  onEnd?: () => void;
9
10
  };
10
- export declare const Joystick: ({ size, onMove, onEnd, }: JoystickProps) => import("react/jsx-runtime").JSX.Element;
11
+ export declare const Joystick: ({ size, onMove, onEnd, }: JoystickProps) => React.JSX.Element;
11
12
  export {};
@@ -15,5 +15,5 @@ interface LayersProps {
15
15
  onTouchMove?: (e: React.TouchEvent<SVGRectElement | SVGCircleElement | SVGTextElement | SVGImageElement>) => void;
16
16
  onTouchEnd?: (e: React.TouchEvent<SVGRectElement | SVGCircleElement | SVGTextElement | SVGImageElement>) => void;
17
17
  }
18
- declare const Layers: ({ shadowShape, components, onClick, selectedComponent, selectedTable, activeTool, onMouseDown, onMouseUp, onBlur, selectedTableColor, mode, style, onTouchEnd, onTouchMove, onTouchStart }: LayersProps) => import("react/jsx-runtime").JSX.Element;
18
+ declare const Layers: ({ shadowShape, components, onClick, selectedComponent, selectedTable, activeTool, onMouseDown, onMouseUp, onBlur, selectedTableColor, mode, style, onTouchEnd, onTouchMove, onTouchStart }: LayersProps) => import("react").JSX.Element;
19
19
  export default Layers;
@@ -1,6 +1,13 @@
1
1
  "use client";
2
+ import { useRef } from "react";
2
3
  import { omit } from "lodash";
3
4
  const Layers = ({ shadowShape, components, onClick, selectedComponent, selectedTable, activeTool, onMouseDown, onMouseUp, onBlur, selectedTableColor, mode = "edit", style, onTouchEnd, onTouchMove, onTouchStart }) => {
5
+ const refItemTemp = useRef(null);
6
+ const handleOnHover = (item) => {
7
+ if (mode === "edit") {
8
+ refItemTemp.current = item;
9
+ }
10
+ };
4
11
  const renderShadowShape = (item) => {
5
12
  const { id, x, y, width, height, fill, opacity, rotation, shape, fontColor, text, seatFill, labels, } = item;
6
13
  const commonProps = { fill, opacity };
@@ -70,26 +77,37 @@ const Layers = ({ shadowShape, components, onClick, selectedComponent, selectedT
70
77
  </g>);
71
78
  }
72
79
  case "text":
73
- return (<g key={id} onClick={() => onClick(item)}>
80
+ return (<g key={id} onClick={() => {
81
+ onClick && onClick(item);
82
+ }}>
74
83
  <rect x={x} y={y} width={width} height={height} fill="transparent" opacity={opacity}/>
75
84
  <text x={x + width / 2} y={y + height / 2} textAnchor="middle" dominantBaseline="middle" fill={fontColor} fontSize={height * 0.6} opacity={opacity}>
76
85
  {text}
77
86
  </text>
87
+ </g>);
88
+ case "ruler":
89
+ return (<g key={id}>
90
+ <rect x={x - (window.innerWidth * 3) / 2} y={y} width={window.innerWidth * 3} height={1} fill="black"/>
91
+ <rect x={x} y={y - (window.innerHeight * 3) / 2} width={1} height={window.innerHeight * 3} fill="black"/>
92
+
78
93
  </g>);
79
94
  default:
80
95
  return null;
81
96
  }
82
97
  };
83
98
  const renderShape = (item) => {
84
- const { id, x, y, width, height, fill, opacity, rotation, shape, text, stroke, strokeWidth, labels, fontSize, fontColor, label, seatFill, src, } = item;
99
+ const { id, x, y, width, height, fill, opacity, rotation = 0, shape, text, stroke, strokeWidth, labels, fontSize, fontColor, label, seatFill, src, } = item;
85
100
  const commonProps = {
86
101
  fill,
87
102
  opacity,
88
103
  stroke,
89
104
  strokeWidth,
90
105
  onMouseDown: (e) => {
106
+ onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(e, item || refItemTemp.current);
107
+ },
108
+ onMouseEnter: (e) => {
91
109
  // e.stopPropagation();
92
- onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(e, item);
110
+ handleOnHover === null || handleOnHover === void 0 ? void 0 : handleOnHover(item);
93
111
  },
94
112
  onClick: (e) => {
95
113
  // e.stopPropagation();
@@ -126,9 +144,9 @@ const Layers = ({ shadowShape, components, onClick, selectedComponent, selectedT
126
144
  <rect key={id} x={x} y={y} width={width} height={height} fill={selectedTableColor !== null && selectedTableColor !== void 0 ? selectedTableColor : fill} style={Object.assign({ cursor: mode === "view" ? "pointer" : "default" }, style)} opacity={id === (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id) ? 0.5 : opacity} {...omit(commonProps, "opacity")} transform={`rotate(${rotation} ${x + width / 2} ${y + height / 2})`}/>
127
145
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
128
146
  var _a, _b, _c, _d;
129
- return (<text key={`${id}-label-${index}`} x={x + width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0)} y={y + height / 2 + ((_b = _ === null || _ === void 0 ? void 0 : _.y) !== null && _b !== void 0 ? _b : 0)} fill={(_c = _ === null || _ === void 0 ? void 0 : _.fontColor) !== null && _c !== void 0 ? _c : "black"} fontSize={`${(_d = _ === null || _ === void 0 ? void 0 : _.fontSize) !== null && _d !== void 0 ? _d : 10}px`} fontWeight="bold" textAnchor="middle" dominantBaseline="middle" transform={`rotate(${rotation} ${x + width / 2} ${y + height / 2})`} onClick={(e) => {
147
+ return (<text {...omit(commonProps, ["opacity", "stroke", "strokeWidth"])} key={`${id}-label-${index}`} x={x + width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0)} y={y + height / 2 + ((_b = _ === null || _ === void 0 ? void 0 : _.y) !== null && _b !== void 0 ? _b : 0)} fill={(_c = _ === null || _ === void 0 ? void 0 : _.fontColor) !== null && _c !== void 0 ? _c : "black"} fontSize={`${(_d = _ === null || _ === void 0 ? void 0 : _.fontSize) !== null && _d !== void 0 ? _d : 10}px`} fontWeight="bold" textAnchor="middle" dominantBaseline="middle" transform={`rotate(${rotation} ${x + width / 2} ${y + height / 2})`} onClick={(e) => {
130
148
  e.stopPropagation();
131
- onClick(item);
149
+ onClick && onClick(item);
132
150
  }}>
133
151
  {_ === null || _ === void 0 ? void 0 : _.label}
134
152
  </text>);
@@ -141,7 +159,7 @@ const Layers = ({ shadowShape, components, onClick, selectedComponent, selectedT
141
159
  var _a, _b, _c, _d;
142
160
  return (<text key={`${id}-label-${index}`} x={x + width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0)} y={y + height / 2 + ((_b = _ === null || _ === void 0 ? void 0 : _.y) !== null && _b !== void 0 ? _b : 0)} fill={(_c = _ === null || _ === void 0 ? void 0 : _.fontColor) !== null && _c !== void 0 ? _c : "black"} fontSize={`${(_d = _ === null || _ === void 0 ? void 0 : _.fontSize) !== null && _d !== void 0 ? _d : 10}px`} fontWeight="bold" textAnchor="middle" dominantBaseline="middle" transform={`rotate(${rotation} ${x + width / 2} ${y + height / 2})`} onClick={(e) => {
143
161
  e.stopPropagation();
144
- onClick(item);
162
+ onClick && onClick(item);
145
163
  }}>
146
164
  {_ === null || _ === void 0 ? void 0 : _.label}
147
165
  </text>);
@@ -177,7 +195,7 @@ const Layers = ({ shadowShape, components, onClick, selectedComponent, selectedT
177
195
  var _a, _b, _c, _d;
178
196
  return (<text key={`${id}-label-${index}`} x={x + width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0)} y={y + height / 2 + ((_b = _ === null || _ === void 0 ? void 0 : _.y) !== null && _b !== void 0 ? _b : 0)} fill={(_c = _ === null || _ === void 0 ? void 0 : _.fontColor) !== null && _c !== void 0 ? _c : "black"} fontSize={`${(_d = _ === null || _ === void 0 ? void 0 : _.fontSize) !== null && _d !== void 0 ? _d : 10}px`} fontWeight="bold" textAnchor="middle" dominantBaseline="middle" transform={`rotate(${rotation} ${x + width / 2} ${y + height / 2})`} onClick={(e) => {
179
197
  e.stopPropagation();
180
- onClick(item);
198
+ onClick && onClick(item);
181
199
  }}>
182
200
  {_ === null || _ === void 0 ? void 0 : _.label}
183
201
  </text>);
@@ -221,7 +239,7 @@ const Layers = ({ shadowShape, components, onClick, selectedComponent, selectedT
221
239
  return (<g key={id}>
222
240
  <rect x={x} y={y} width={width} height={height} fill="transparent" opacity={opacity} onClick={(e) => {
223
241
  e.stopPropagation();
224
- onClick(item);
242
+ onClick && onClick(item);
225
243
  }}/>
226
244
  <text x={x + width / 2} y={y + height / 2} textAnchor="middle" dominantBaseline="middle" fill={fontColor} fontSize={fontSize !== null && fontSize !== void 0 ? fontSize : height * 0.6} opacity={opacity} {...omit(commonProps, ["fill", "opacity"])}>
227
245
  {text}
@@ -229,7 +247,9 @@ const Layers = ({ shadowShape, components, onClick, selectedComponent, selectedT
229
247
  </g>);
230
248
  case "image-table":
231
249
  case "background":
232
- return (<g key={id} onClick={() => onClick(item)}>
250
+ return (<g key={id} onClick={() => {
251
+ onClick && onClick(item);
252
+ }}>
233
253
  <image href={src} x={x} y={y} width={width} height={height} transform={`rotate(${rotation} ${x + width / 2} ${y + height / 2})`} {...commonProps}/>
234
254
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
235
255
  var _a, _b, _c, _d;
@@ -3,6 +3,6 @@ export interface LayerViewProps {
3
3
  componentProps: any[];
4
4
  extraComponentProps: any[];
5
5
  }
6
- declare const TableEditor: ({ componentProps, extraComponentProps, }: LayerViewProps) => import("react/jsx-runtime").JSX.Element;
6
+ declare const TableEditor: ({ componentProps, extraComponentProps, }: LayerViewProps) => import("react").JSX.Element;
7
7
  export default TableEditor;
8
8
  export { LayerView };
@@ -1,4 +1,4 @@
1
1
  declare const ModalPreview: ({ children }: {
2
2
  children: React.ReactNode;
3
- }) => import("react/jsx-runtime").JSX.Element;
3
+ }) => import("react").JSX.Element;
4
4
  export default ModalPreview;
@@ -2,5 +2,5 @@ interface BoardTemplateProps {
2
2
  onSelectComponent?: (items: any) => void;
3
3
  mappingKey?: string;
4
4
  }
5
- declare const BoardTemplate: ({ onSelectComponent }: BoardTemplateProps) => import("react/jsx-runtime").JSX.Element;
5
+ declare const BoardTemplate: ({ onSelectComponent }: BoardTemplateProps) => import("react").JSX.Element;
6
6
  export default BoardTemplate;
@@ -25,6 +25,12 @@ const BoardTemplate = ({ onSelectComponent }) => {
25
25
  const activeTool = useAppSelector((state) => state.tool.active);
26
26
  const { components: componentsProps, extraComponents: extraComponentsProps, flagChange, } = useAppSelector((state) => state.board);
27
27
  const isTouching = useRef(false);
28
+ useEffect(() => {
29
+ var _a;
30
+ if (activeTool !== ((_a = shadowShape[0]) === null || _a === void 0 ? void 0 : _a.shape)) {
31
+ setShadowShape([]);
32
+ }
33
+ }, [activeTool]);
28
34
  // const [isDragging, setIsDragging] = useState(false);
29
35
  const [resizeDirection, setResizeDirection] = useState(null);
30
36
  const backgroundColor = useAppSelector((state) => state.board.backgroundColor);
@@ -82,7 +88,8 @@ const BoardTemplate = ({ onSelectComponent }) => {
82
88
  isSyncingFromRedux.current = false;
83
89
  return;
84
90
  }
85
- if (!isEqual(componentsState, componentsProps) && !isEqual(componentsState, [])) {
91
+ if (!isEqual(componentsState, componentsProps) &&
92
+ !isEqual(componentsState, [])) {
86
93
  debouncedSyncComponents.current(componentsState);
87
94
  }
88
95
  if (!isEqual(extraComponentsState, extraComponentsProps)) {
@@ -140,7 +147,7 @@ const BoardTemplate = ({ onSelectComponent }) => {
140
147
  const dx = Math.abs(event.clientX - startPos.current.x);
141
148
  const dy = Math.abs(event.clientY - startPos.current.y);
142
149
  if (dx > 1 || dy > 1) {
143
- if (!moveComponent.current) {
150
+ if (!moveComponent.current && item) {
144
151
  dispatch({ type: "panel/setSelectedComponent", payload: item });
145
152
  setSelectedComponent(item);
146
153
  }
@@ -157,9 +164,11 @@ const BoardTemplate = ({ onSelectComponent }) => {
157
164
  isDragging.current = true;
158
165
  moveComponent.current = false;
159
166
  setResizeDirection(direction);
160
- dispatch({ type: "panel/setSelectedComponent", payload: item });
161
- dispatch({ type: "panel/setShow", payload: true });
162
- setSelectedComponent(item);
167
+ if (item) {
168
+ dispatch({ type: "panel/setSelectedComponent", payload: item });
169
+ dispatch({ type: "panel/setShow", payload: true });
170
+ setSelectedComponent(item);
171
+ }
163
172
  }
164
173
  };
165
174
  // Pasang ke `document` agar global
@@ -231,6 +240,7 @@ const BoardTemplate = ({ onSelectComponent }) => {
231
240
  "table-seat-circle",
232
241
  "table-seat-square",
233
242
  "text",
243
+ "ruler",
234
244
  ].includes(activeTool)) {
235
245
  const { x, y } = getSvgCoords(e);
236
246
  setShadowShape([createShape(x, y, theme === null || theme === void 0 ? void 0 : theme.primaryColor)]);
@@ -390,7 +400,7 @@ const BoardTemplate = ({ onSelectComponent }) => {
390
400
  };
391
401
  const handleTouchStart = (e, items, direction) => {
392
402
  var _a, _b, _c, _d;
393
- if (activeTool === "select" && !direction) {
403
+ if (activeTool === "select" && !direction && items) {
394
404
  // dispatch({ type: "panel/setShow", payload: false });
395
405
  // setMoveComponent(true);
396
406
  moveComponent.current = true;
@@ -589,6 +599,9 @@ const BoardTemplate = ({ onSelectComponent }) => {
589
599
  else if (activeTool === "grab") {
590
600
  return "grab";
591
601
  }
602
+ else if (activeTool === "ruler") {
603
+ return "crosshair";
604
+ }
592
605
  };
593
606
  const renderMiniMap = () => {
594
607
  return (<MiniMap width={250} height={250}>
@@ -661,6 +674,7 @@ const BoardTemplate = ({ onSelectComponent }) => {
661
674
  }} onMouseLeave={handleMouseLeave} xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" style={{
662
675
  background: backgroundColor,
663
676
  display: "block",
677
+ cursor: activeTool === "ruler" ? "crosshair" : "auto",
664
678
  }}>
665
679
  <Layers shadowShape={shadowShape} components={[...extraComponentsState, ...componentsState]} style={{
666
680
  cursor: getCursorStyle(),
@@ -669,6 +683,30 @@ const BoardTemplate = ({ onSelectComponent }) => {
669
683
  onMouseDown={handleMouseDown}
670
684
  // onMouseUp={handleMouseUp}
671
685
  onBlur={handleUnSelectComponent} selectedComponent={selectedComponent} activeTool={activeTool} onTouchStart={(e, item, direction) => handleTouchStart(e, item, direction)} onTouchMove={(e) => handleTouchMove(e)} onTouchEnd={handleTouchEnd}/>
686
+ {activeTool === "ruler" && (<>
687
+ <g id="horizontal-ruler">
688
+ <rect x="0" y="0" width={window.innerWidth} height="30" fill="#e0e0e0"/>
689
+ <g stroke="#888" font-size="10" text-anchor="middle">
690
+ {Array.from({ length: window.innerWidth / 50 }, (_, i) => (<g key={i}>
691
+ <line x1={i * 50} y1="0" x2={i * 50} y2="10"/>
692
+ <text x={i * 50} y="15">
693
+ {i * 50}
694
+ </text>
695
+ </g>))}
696
+ </g>
697
+ </g>
698
+ <g id="vertical-ruler">
699
+ <rect x="0" y="0" width="30" height={window.innerHeight} fill="#e0e0e0"/>
700
+ <g stroke="#888" font-size="10" text-anchor="middle">
701
+ {Array.from({ length: window.innerHeight / 10 }, (_, i) => (<g key={i}>
702
+ <line x1="0" y1={i * 50} x2="10" y2={i * 50}/>
703
+ <text x="15" y={i * 50}>
704
+ {i * 50}
705
+ </text>
706
+ </g>))}
707
+ </g>
708
+ </g>
709
+ </>)}
672
710
  </svg>
673
711
  </TransformComponent>
674
712
  </TransformWrapper>
@@ -1,2 +1,2 @@
1
- declare const Navbar: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const Navbar: () => import("react").JSX.Element;
2
2
  export default Navbar;
@@ -23,5 +23,5 @@ export interface TableEditorProps {
23
23
  dragOnly?: boolean;
24
24
  viewOnly?: boolean;
25
25
  }
26
- declare const TableEditor: (props: TableEditorProps) => import("react/jsx-runtime").JSX.Element;
26
+ declare const TableEditor: (props: TableEditorProps) => import("react").JSX.Element;
27
27
  export default TableEditor;
@@ -9,8 +9,16 @@ import LayerView from "../view";
9
9
  const TableEditor = (props) => {
10
10
  const [initialValue, setInitialValue] = useState(null);
11
11
  const { componentProps, extraComponentProps, onCurrentStateChange, dragOnly, mappingKey, viewOnly, } = props;
12
- const { components, extraComponents } = useAppSelector((state) => state.board);
12
+ const { components, extraComponents, backgroundColor } = useAppSelector((state) => state.board);
13
13
  const dispatch = useAppDispatch();
14
+ useEffect(() => {
15
+ if (!viewOnly) {
16
+ dispatch({
17
+ type: "panel/setSelectedComponent",
18
+ payload: null,
19
+ });
20
+ }
21
+ }, [viewOnly]);
14
22
  const onUpdateCurrentState = () => {
15
23
  let matchInitialValueWithComponents = initialValue === null || initialValue === void 0 ? void 0 : initialValue.map((item) => {
16
24
  if (mappingKey && (item === null || item === void 0 ? void 0 : item[mappingKey])) {
@@ -35,6 +43,7 @@ const TableEditor = (props) => {
35
43
  onCurrentStateChange({
36
44
  components: matchInitialValueWithComponents,
37
45
  extraComponents,
46
+ background: backgroundColor,
38
47
  });
39
48
  }
40
49
  };
@@ -43,7 +52,7 @@ const TableEditor = (props) => {
43
52
  !isEqual(extraComponents, extraComponentProps)) {
44
53
  onCurrentStateChange && onUpdateCurrentState();
45
54
  }
46
- }, [components, extraComponents]);
55
+ }, [components, extraComponents, backgroundColor]);
47
56
  const convertComponentProps = () => {
48
57
  let mappingData = componentProps === null || componentProps === void 0 ? void 0 : componentProps.map((item) => {
49
58
  if (mappingKey && (item === null || item === void 0 ? void 0 : item[mappingKey])) {
@@ -7,5 +7,5 @@ interface ControlPanelsProps {
7
7
  src: string;
8
8
  };
9
9
  }
10
- declare const ControlPanels: (props: ControlPanelsProps) => import("react/jsx-runtime").JSX.Element;
10
+ declare const ControlPanels: (props: ControlPanelsProps) => import("react").JSX.Element;
11
11
  export default ControlPanels;
@@ -28,6 +28,7 @@ const ControlPanels = (props) => {
28
28
  const [form] = Form.useForm();
29
29
  let values = Form.useWatch([], form);
30
30
  useEffect(() => {
31
+ form.resetFields();
31
32
  if (selectedComponent) {
32
33
  const isDifferentId = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id) !== (values === null || values === void 0 ? void 0 : values.id) || !(values === null || values === void 0 ? void 0 : values.id);
33
34
  const isSameIdAndSameDimensions = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id) === (values === null || values === void 0 ? void 0 : values.id) &&
@@ -91,8 +92,12 @@ const ControlPanels = (props) => {
91
92
  });
92
93
  };
93
94
  // if(!show) return null
94
- return (<Drawer open={show} onClose={handleClose} title="Panel">
95
- <div className="bg-white h-full max-h-screen overflow-y-auto w-full">
95
+ return (<Drawer open={show} onClose={handleClose} title="Panel" styles={{
96
+ body: {
97
+ paddingBottom: 0
98
+ }
99
+ }}>
100
+ <div className="bg-white h-full max-h-screen w-full p-2">
96
101
  <Form layout="vertical" form={form} name="table" onFinish={(values) => { }} onValuesChange={handleChangeComponent} initialValues={{ labels: [{}] }}>
97
102
  <Form.Item name="id" hidden>
98
103
  <Input />
@@ -2,5 +2,5 @@ declare const SelectToolForm: ({ title, action, responseMapping }: {
2
2
  title?: string;
3
3
  action: any;
4
4
  responseMapping: any;
5
- }) => import("react/jsx-runtime").JSX.Element;
5
+ }) => import("react").JSX.Element;
6
6
  export default SelectToolForm;
@@ -1,2 +1,2 @@
1
- declare const SquareToolForm: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const SquareToolForm: () => import("react").JSX.Element;
2
2
  export default SquareToolForm;
@@ -1,2 +1,2 @@
1
- declare const SeatCircle: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const SeatCircle: () => import("react").JSX.Element;
2
2
  export default SeatCircle;
@@ -1,2 +1,2 @@
1
- declare const TextTool: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const TextTool: () => import("react").JSX.Element;
2
2
  export default TextTool;
@@ -10,5 +10,5 @@ interface UploadToolProps {
10
10
  };
11
11
  defaultValue?: any;
12
12
  }
13
- declare const UploadTool: ({ name, type, action, responseMapping, defaultValue, }: UploadToolProps) => import("react/jsx-runtime").JSX.Element;
13
+ declare const UploadTool: ({ name, type, action, responseMapping, defaultValue, }: UploadToolProps) => import("react").JSX.Element;
14
14
  export default UploadTool;
@@ -1,4 +1,4 @@
1
1
  declare const SideTool: ({ dragOnly }: {
2
2
  dragOnly?: boolean;
3
- }) => import("react/jsx-runtime").JSX.Element;
3
+ }) => import("react").JSX.Element;
4
4
  export default SideTool;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { Circle, CopyPlus, Eye, EyeOff, Image, Layers2, MousePointer, PaintBucket, Ratio, SquareMousePointer, Trash, Type, Upload, Hand, Layers } from "lucide-react";
2
+ import { Circle, CopyPlus, Eye, EyeOff, Image, Layers2, MousePointer, PaintBucket, Ratio, SquareMousePointer, Trash, Type, Upload, Hand, Layers, Ruler } from "lucide-react";
3
3
  import ButtonTools from "../../components/button-tools";
4
4
  import { Divider, ColorPicker, Button, } from "antd";
5
5
  import { useAppDispatch, useAppSelector } from "../../hooks/use-redux";
@@ -21,6 +21,11 @@ const SideTool = ({ dragOnly }) => {
21
21
  id: "grab",
22
22
  name: "Grab Tool",
23
23
  icon: <Hand />,
24
+ },
25
+ {
26
+ id: "ruler",
27
+ name: "Ruler",
28
+ icon: <Ruler />,
24
29
  }
25
30
  ];
26
31
  const actionsTools = [
@@ -78,7 +83,7 @@ const SideTool = ({ dragOnly }) => {
78
83
  // }
79
84
  ];
80
85
  const hanldeSelectTool = (id) => {
81
- if (id === "background" || id === "text" || id === "image-table") {
86
+ if (id === "background" || id === "image-table") {
82
87
  dispatch({
83
88
  type: "panel/setShow",
84
89
  payload: true,
@@ -15,5 +15,5 @@ export interface LayerViewProps {
15
15
  containerProps?: any;
16
16
  svgProps?: any;
17
17
  }
18
- declare const LayerView: (props: LayerViewProps) => import("react/jsx-runtime").JSX.Element;
18
+ declare const LayerView: (props: LayerViewProps) => import("react").JSX.Element;
19
19
  export default LayerView;
@@ -15,5 +15,5 @@ export interface LayerViewProps {
15
15
  containerProps?: any;
16
16
  svgProps?: any;
17
17
  }
18
- declare const LayerView: (props: LayerViewProps) => import("react/jsx-runtime").JSX.Element;
18
+ declare const LayerView: (props: LayerViewProps) => import("react").JSX.Element;
19
19
  export default LayerView;
@@ -1,3 +1,3 @@
1
1
  export declare const ReduxProvider: ({ children }: {
2
2
  children: React.ReactNode;
3
- }) => import("react/jsx-runtime").JSX.Element;
3
+ }) => import("react").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  export declare const StoreProvider: ({ children, themeColor, }: {
2
2
  children: React.ReactNode;
3
3
  themeColor?: string;
4
- }) => import("react/jsx-runtime").JSX.Element;
4
+ }) => import("react").JSX.Element;
@@ -1 +1 @@
1
- *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.bottom-2{bottom:.5rem}.bottom-5{bottom:1.25rem}.bottom-\[60px\]{bottom:60px}.left-0{left:0}.left-1\/2{left:50%}.right-0{right:0}.z-10{z-index:10}.mb-2{margin-bottom:.5rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.block{display:block}.flex{display:flex}.table{display:table}.hidden{display:none}.h-3{height:.75rem}.h-\[1000px\]{height:1000px}.h-\[500px\]{height:500px}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[200px\]{max-height:200px}.max-h-screen{max-height:100vh}.w-16{width:4rem}.w-3{width:.75rem}.w-full{width:100%}.flex-1{flex:1 1 0%}.-translate-x-1\/2{--tw-translate-x:-50%}.-translate-x-1\/2,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:.5rem}.gap-4{gap:1rem}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-r{border-right-width:1px}.border-r-2{border-right-width:2px}.border-dashed{border-style:dashed}.border-black{--tw-border-opacity:1;border-color:rgb(0 0 0/var(--tw-border-opacity,1))}.border-blue-400{--tw-border-opacity:1;border-color:rgb(96 165 250/var(--tw-border-opacity,1))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-gray-800{--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity,1))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.object-cover{-o-object-fit:cover;object-fit:cover}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-4{padding-bottom:1rem}.pt-4,.py-4{padding-top:1rem}.text-center{text-align:center}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.heading-s{font-size:20px;font-weight:600;line-height:24px;letter-spacing:-.0006em}.text-sm{font-size:12px;font-weight:500;line-height:16px;letter-spacing:0}.divider-dashed{border-top:1px dashed var(--netral-04);width:100%;margin:16px 0}:root{--background:#fff;--foreground:#171717;--primary-color:#181e49;--secondary-color:#f0f2f5;--background-color:#f5f5f5;--success-color:#63cc47;--netral-03:#ededed;--netral-04:#e0e0e0;--netral-05:#c2c2c2;--netral-06:#9e9e9e;--netral-07:#757575;--netral-08:#616161;--netral-09:#404040;--netral-10:#0a0a0a;--danger:#cb3a31;--accent:#ff9800;--info:#3267e3}@media (prefers-color-scheme:dark){:root{--background:#0a0a0a;--foreground:#ededed}}body{color:var(--foreground);background:var(--background);font-family:Arial,Helvetica,sans-serif}.custom-styles .excalidraw{--color-primary:#fcc6d9;--color-primary-darker:#f783ac;--color-primary-darkest:#e64980;--color-primary-light:#f2a9c4}.custom-styles .excalidraw.theme--dark{--color-primary:#d494aa;--color-primary-darker:#d64c7e;--color-primary-darkest:#e86e99;--color-primary-light:#dcbec9}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-webkit-appearance:textfield;appearance:textfield;-moz-appearance:textfield}.ant-drawer-mask{background:none!important}
1
+ *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.bottom-2{bottom:.5rem}.bottom-5{bottom:1.25rem}.bottom-\[60px\]{bottom:60px}.left-0{left:0}.left-1\/2{left:50%}.right-0{right:0}.z-10{z-index:10}.mb-2{margin-bottom:.5rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.block{display:block}.flex{display:flex}.table{display:table}.hidden{display:none}.h-3{height:.75rem}.h-\[1000px\]{height:1000px}.h-\[500px\]{height:500px}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[200px\]{max-height:200px}.max-h-screen{max-height:100vh}.w-16{width:4rem}.w-3{width:.75rem}.w-full{width:100%}.flex-1{flex:1 1 0%}.-translate-x-1\/2{--tw-translate-x:-50%}.-translate-x-1\/2,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:.5rem}.gap-4{gap:1rem}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-r{border-right-width:1px}.border-r-2{border-right-width:2px}.border-dashed{border-style:dashed}.border-black{--tw-border-opacity:1;border-color:rgb(0 0 0/var(--tw-border-opacity,1))}.border-blue-400{--tw-border-opacity:1;border-color:rgb(96 165 250/var(--tw-border-opacity,1))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-gray-800{--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity,1))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.object-cover{-o-object-fit:cover;object-fit:cover}.p-2{padding:.5rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-4{padding-bottom:1rem}.pt-4,.py-4{padding-top:1rem}.text-center{text-align:center}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.heading-s{font-size:20px;font-weight:600;line-height:24px;letter-spacing:-.0006em}.text-sm{font-size:12px;font-weight:500;line-height:16px;letter-spacing:0}.divider-dashed{border-top:1px dashed var(--netral-04);width:100%;margin:16px 0}:root{--background:#fff;--foreground:#171717;--primary-color:#181e49;--secondary-color:#f0f2f5;--background-color:#f5f5f5;--success-color:#63cc47;--netral-03:#ededed;--netral-04:#e0e0e0;--netral-05:#c2c2c2;--netral-06:#9e9e9e;--netral-07:#757575;--netral-08:#616161;--netral-09:#404040;--netral-10:#0a0a0a;--danger:#cb3a31;--accent:#ff9800;--info:#3267e3}@media (prefers-color-scheme:dark){:root{--background:#0a0a0a;--foreground:#ededed}}body{color:var(--foreground);background:var(--background);font-family:Arial,Helvetica,sans-serif}.custom-styles .excalidraw{--color-primary:#fcc6d9;--color-primary-darker:#f783ac;--color-primary-darkest:#e64980;--color-primary-light:#f2a9c4}.custom-styles .excalidraw.theme--dark{--color-primary:#d494aa;--color-primary-darker:#d64c7e;--color-primary-darkest:#e86e99;--color-primary-light:#dcbec9}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-webkit-appearance:textfield;appearance:textfield;-moz-appearance:textfield}.ant-drawer-mask{background:none!important}