@netless/fastboard-ui 1.0.0-canary.6 → 1.0.0-canary.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/fastboard-ui",
3
- "version": "1.0.0-canary.6",
3
+ "version": "1.0.0-canary.8",
4
4
  "description": "The front-end of @netless/fastboard-core.",
5
5
  "main": "dist/index.js",
6
6
  "svelte": "dist/index.svelte.mjs",
@@ -13,14 +13,14 @@
13
13
  ],
14
14
  "repository": "netless-io/fastboard",
15
15
  "peerDependencies": {
16
- "@netless/fastboard-core": "1.0.0-canary.6"
16
+ "@netless/fastboard-core": "1.0.0-canary.8"
17
17
  },
18
18
  "dependencies": {
19
19
  "tippy.js": "^6.3.7"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@netless/esbuild-plugin-inline-sass": "0.1.0",
23
- "@netless/fastboard-core": "1.0.0-canary.6"
23
+ "@netless/fastboard-core": "1.0.0-canary.8"
24
24
  },
25
25
  "scripts": {
26
26
  "cleanup": "rimraf dist",
@@ -7,6 +7,7 @@
7
7
  export { className as class };
8
8
  export let name = "fastboard-ui";
9
9
  export let theme: Theme = "light";
10
+ export let active = false;
10
11
  export let disabled = false;
11
12
  export let content: Content = "";
12
13
  export let placement: Placement = "top";
@@ -19,6 +20,7 @@
19
20
  <span class="{name}-btn-interactive {theme}" use:tippy={{ content, placement, className }}>
20
21
  <button
21
22
  class="{name}-btn {className} {theme}"
23
+ class:is-active={active}
22
24
  {disabled}
23
25
  on:click
24
26
  use:tippy={{
@@ -37,6 +39,7 @@
37
39
  {:else}
38
40
  <button
39
41
  class="{name}-btn {className} {theme}"
42
+ class:is-active={active}
40
43
  {disabled}
41
44
  on:click
42
45
  use:tippy={{ content, placement, className }}
@@ -45,7 +48,7 @@
45
48
  </button>
46
49
  {/if}
47
50
  {:else}
48
- <button class="{name}-btn {className} {theme}" {disabled} on:click>
51
+ <button class="{name}-btn {className} {theme}" class:is-active={active} {disabled} on:click>
49
52
  <slot />
50
53
  </button>
51
54
  {/if}
@@ -6,6 +6,7 @@ export declare interface ButtonProps {
6
6
  class?: string;
7
7
  name?: string;
8
8
  theme?: Theme;
9
+ active?: boolean;
9
10
  disabled?: boolean;
10
11
  content?: Content;
11
12
  placement?: Placement;
@@ -17,14 +17,14 @@
17
17
  display: flex;
18
18
  align-items: center;
19
19
  position: absolute;
20
- bottom: 62px;
20
+ bottom: 50px;
21
21
  top: 8px;
22
22
  left: 0;
23
23
  z-index: 200;
24
24
  pointer-events: none;
25
25
 
26
26
  .fastboard-toolbar {
27
- padding-left: 16px;
27
+ padding-left: 8px;
28
28
  }
29
29
  }
30
30
 
@@ -34,7 +34,6 @@
34
34
  position: absolute;
35
35
  bottom: 8px;
36
36
  left: 8px;
37
- padding: 8px;
38
37
  z-index: 200;
39
38
  pointer-events: none;
40
39
  }
@@ -7,12 +7,12 @@ $name: "fastboard-toolbar";
7
7
  display: flex;
8
8
  align-items: center;
9
9
  position: relative;
10
- transform: translateX(0);
11
- transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
10
+ left: 0px;
11
+ transition: left 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
12
12
  pointer-events: none;
13
13
 
14
14
  &.collapsed {
15
- transform: translateX(-100%);
15
+ left: -100%;
16
16
  }
17
17
  }
18
18
 
@@ -71,7 +71,7 @@ $name: "fastboard-toolbar";
71
71
  }
72
72
 
73
73
  .#{$name}-btn {
74
- @include btn(32px, 4px);
74
+ @include btn(32px, 4px, 8px);
75
75
  }
76
76
 
77
77
  @import "./components/Slider.scss";
@@ -45,20 +45,29 @@
45
45
  </div>
46
46
  <label class="{name}-handler {theme}">
47
47
  <input type="checkbox" bind:checked={collapsed} />
48
- <svg fill="none" stroke-width="2" viewBox="0 0 32 120">
48
+ <svg width="17" height="42" viewBox="0 0 17 42" fill="none">
49
49
  <path
50
+ d="M0 41H12C14.2091 41 16 39.2091 16 37V5C16 2.79086 14.2091 1 12 1H0"
51
+ stroke="#000"
50
52
  fill="#fff"
51
- stroke="none"
52
- d="m0 0 24 16q6 4 6 14v60q0 10-6 14L0 120"
53
- class="{name}-handler-bg-color"
53
+ class="{name}-handler-border-color {name}-handler-bg-color"
54
54
  />
55
- <path stroke="#000" d="m0 0 24 16q6 4 6 14v60q0 10-6 14L0 120" class="{name}-handler-border-color" />
56
55
  {#if collapsed}
57
- <path stroke="#000" d="M10 52v16" class="{name}-handler-image-stroke-color" />
58
- <path fill="#000" stroke="none" d="M14 52v16l8-8z" class="{name}-handler-image-fill-color" />
56
+ <path
57
+ fill-rule="evenodd"
58
+ clip-rule="evenodd"
59
+ d="M8 19L6 17V25L8 23L10 21L8 19ZM4 17H5V25H4V17Z"
60
+ fill="#fff"
61
+ class="{name}-handler-image-fill-color"
62
+ />
59
63
  {:else}
60
- <path stroke="#000" d="M20 52v16" class="{name}-handler-image-stroke-color" />
61
- <path fill="#000" stroke="none" d="M16 52v16l-8-8z" class="{name}-handler-image-fill-color" />
64
+ <path
65
+ fill-rule="evenodd"
66
+ clip-rule="evenodd"
67
+ d="M6 19L8 17V25L6 23L4 21L6 19ZM10 17H9V25H10V17Z"
68
+ fill="#fff"
69
+ class="{name}-handler-image-fill-color"
70
+ />
62
71
  {/if}
63
72
  </svg>
64
73
  </label>
@@ -20,8 +20,8 @@ $name: "fastboard-toolbar";
20
20
  .#{$name}-triangle {
21
21
  width: 0px;
22
22
  height: 0px;
23
- border-bottom: 4px solid;
24
- border-left: 4px solid transparent;
23
+ border-bottom: 3px solid;
24
+ border-left: 3px solid transparent;
25
25
  position: absolute;
26
26
  bottom: 0;
27
27
  right: 0;
@@ -36,7 +36,7 @@ $name: "fastboard-toolbar";
36
36
  overflow: hidden;
37
37
  display: flex;
38
38
  flex-direction: column;
39
- gap: 4px;
39
+ gap: 0;
40
40
  }
41
41
 
42
42
  .#{$name}-tooltip {
@@ -121,35 +121,68 @@
121
121
  </Button>
122
122
  {/if}
123
123
  <div class="{name}-scrollable" class:scrollable use:scrollHeight={scroll_height} use:scrollTop={top}>
124
- <Button class="clicker" {...btn_props} on:click={clicker} content={c.clicker}>
124
+ <Button
125
+ class="clicker"
126
+ active={appliance === "clicker"}
127
+ {...btn_props}
128
+ on:click={clicker}
129
+ content={c.clicker}
130
+ >
125
131
  {#if appliance === "clicker"}
126
132
  <Icons.ClickFilled {theme} active />
127
133
  {:else}
128
134
  <Icons.Click {theme} />
129
135
  {/if}
130
136
  </Button>
131
- <Button class="selector" {...btn_props} on:click={selector} content={c.selector}>
137
+ <Button
138
+ class="selector"
139
+ active={appliance === "selector"}
140
+ {...btn_props}
141
+ on:click={selector}
142
+ content={c.selector}
143
+ >
132
144
  {#if appliance === "selector"}
133
145
  <Icons.SelectorFilled {theme} active />
134
146
  {:else}
135
147
  <Icons.Selector {theme} />
136
148
  {/if}
137
149
  </Button>
138
- <Button class="pencil" {...btn_props} on:click={pencil} content={c.pencil} menu={pencil_panel}>
150
+ <Button
151
+ class="pencil"
152
+ active={appliance === "pencil"}
153
+ {...btn_props}
154
+ on:click={pencil}
155
+ content={c.pencil}
156
+ menu={pencil_panel}
157
+ >
139
158
  {#if appliance === "pencil"}
140
159
  <Icons.PencilFilled {theme} active />
141
160
  {:else}
142
161
  <Icons.Pencil {theme} />
143
162
  {/if}
144
163
  </Button>
145
- <Button class="text" {...btn_props} on:click={text} content={c.text} menu={text_panel}>
164
+ <Button
165
+ class="text"
166
+ active={appliance === "text"}
167
+ {...btn_props}
168
+ on:click={text}
169
+ content={c.text}
170
+ menu={text_panel}
171
+ >
146
172
  {#if appliance === "text"}
147
173
  <Icons.TextFilled {theme} active />
148
174
  {:else}
149
175
  <Icons.Text {theme} />
150
176
  {/if}
151
177
  </Button>
152
- <Button class="shapes" {...btn_props} on:click={select_last_shape} content={t.shapes} menu={shapes_panel}>
178
+ <Button
179
+ class="shapes"
180
+ active={appliance === last_shape || (appliance === "shape" && shape === last_shape)}
181
+ {...btn_props}
182
+ on:click={select_last_shape}
183
+ content={t.shapes}
184
+ menu={shapes_panel}
185
+ >
153
186
  {#if appliance === last_shape || (appliance === "shape" && shape === last_shape)}
154
187
  <svelte:component this={shapesIconActive[last_shape]} {theme} active />
155
188
  {:else}
@@ -157,7 +190,13 @@
157
190
  {/if}
158
191
  </Button>
159
192
  {#if eraser_type === "delete"}
160
- <Button class="eraser" {...btn_props} on:click={select_eraser} content={c.eraser}>
193
+ <Button
194
+ class="eraser"
195
+ active={appliance === "eraser"}
196
+ {...btn_props}
197
+ on:click={select_eraser}
198
+ content={c.eraser}
199
+ >
161
200
  {#if appliance === "eraser"}
162
201
  <Icons.EraserFilled {theme} active />
163
202
  {:else}
@@ -167,6 +206,7 @@
167
206
  {:else if eraser_type === "pencil"}
168
207
  <Button
169
208
  class="eraser"
209
+ active={appliance === "pencilEraser"}
170
210
  {...btn_props}
171
211
  on:click={select_pencil_eraser}
172
212
  content={c.pencilEraser}
@@ -181,6 +221,7 @@
181
221
  {:else}
182
222
  <Button
183
223
  class="eraser"
224
+ active={appliance === last_eraser}
184
225
  {...btn_props}
185
226
  on:click={select_last_eraser}
186
227
  content={t[last_eraser]}
@@ -229,6 +270,7 @@
229
270
  <div class="{name}-panel-btns">
230
271
  <Button
231
272
  class="eraser"
273
+ active={appliance === "pencilEraser"}
232
274
  {...btn_props}
233
275
  on:click={select_pencil_eraser}
234
276
  placement="top"
@@ -242,6 +284,7 @@
242
284
  </Button>
243
285
  <Button
244
286
  class="eraser"
287
+ active={appliance === "eraser"}
245
288
  {...btn_props}
246
289
  on:click={select_eraser}
247
290
  placement="top"
@@ -65,6 +65,7 @@
65
65
  }
66
66
  </script>
67
67
 
68
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
68
69
  <div class="fastboard-toolbar-shapes {theme}" on:click={set_appliance_or_shape}>
69
70
  {#each shapes as key (key)}
70
71
  {@const is_selected = appliance === "shape" ? shape === key : appliance === key}
@@ -25,6 +25,7 @@
25
25
  }
26
26
  </script>
27
27
 
28
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
28
29
  <div class="fastboard-toolbar-colors {theme}" on:click={set_stroke_color}>
29
30
  {#each colorKeys as key (key)}
30
31
  <button
@@ -25,6 +25,7 @@
25
25
  }
26
26
  </script>
27
27
 
28
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
28
29
  <div class="fastboard-toolbar-colors {theme}" on:click={set_stroke_color}>
29
30
  {#each colorKeys as key (key)}
30
31
  <button
@@ -55,7 +55,7 @@
55
55
  let type: IconType;
56
56
  $: type = disabled ? "disable" : "normal";
57
57
 
58
- $: camera = app?.baseCamera;
58
+ $: camera = app?.camera;
59
59
  $: scale = $camera?.scale ?? 1;
60
60
  $: plus_disabled = disabled || next_scale(scale, 1) <= scale;
61
61
  $: minus_disabled = disabled || next_scale(scale, -1) >= scale;
@@ -7,6 +7,7 @@ $themes: (
7
7
  active-color: $blue-6,
8
8
  bg-color: color.change(white, $alpha: 0.9),
9
9
  hover-bg-color: $blue-1,
10
+ active-bg-color: $blue-1,
10
11
  border-color: $grey-1,
11
12
  ),
12
13
  dark: (
@@ -14,6 +15,7 @@ $themes: (
14
15
  active-color: $blue-7,
15
16
  bg-color: color.change($grey-10, $alpha: 0.9),
16
17
  hover-bg-color: $grey-8,
18
+ active-bg-color: $grey-8,
17
19
  border-color: $grey-8,
18
20
  ),
19
21
  );
@@ -58,7 +60,7 @@ $themes: (
58
60
  }
59
61
  }
60
62
 
61
- @mixin btn($size: 24px, $padding: 0) {
63
+ @mixin btn($size: 24px, $padding: 0, $radius: 4px) {
62
64
  appearance: none;
63
65
  cursor: pointer;
64
66
  margin: 0;
@@ -67,7 +69,7 @@ $themes: (
67
69
  width: $size;
68
70
  height: $size;
69
71
  background-color: transparent;
70
- border-radius: 4px;
72
+ border-radius: $radius;
71
73
  font-size: 0;
72
74
  line-height: 1;
73
75
  flex-shrink: 0;
@@ -85,8 +87,13 @@ $themes: (
85
87
  }
86
88
 
87
89
  @each $name, $theme in $themes {
88
- &.#{$name}:not(:disabled):hover {
89
- background-color: read($theme, "hover-bg-color");
90
+ &.#{$name}:not(:disabled) {
91
+ &:hover {
92
+ background-color: read($theme, "hover-bg-color");
93
+ }
94
+ &.is-active {
95
+ background-color: read($theme, "active-bg-color");
96
+ }
90
97
  }
91
98
  }
92
99
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["sass:./style.scss"],"sourcesContent":[".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}.fastboard-icon.light .fastboard-icon-stroke-color{stroke:var(--fastboard-color, #5d6066)}.fastboard-icon.light .fastboard-icon-fill-color{fill:var(--fastboard-color, #5d6066)}.fastboard-icon.light.is-active .fastboard-icon-stroke-color{stroke:var(--fastboard-active-color, #3381ff)}.fastboard-icon.light.is-active .fastboard-icon-fill-color{fill:var(--fastboard-active-color, #3381ff)}.fastboard-icon.dark .fastboard-icon-stroke-color{stroke:var(--fastboard-color, #7b7e84)}.fastboard-icon.dark .fastboard-icon-fill-color{fill:var(--fastboard-color, #7b7e84)}.fastboard-icon.dark.is-active .fastboard-icon-stroke-color{stroke:var(--fastboard-active-color, #2867cc)}.fastboard-icon.dark.is-active .fastboard-icon-fill-color{fill:var(--fastboard-active-color, #2867cc)}.fastboard-redo-undo{box-sizing:border-box;display:inline-flex;align-items:center;gap:4px;padding:4px;border:1px solid;border-radius:4px;font-size:14px;font-family:system-ui;pointer-events:auto;backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px)}.fastboard-redo-undo *{box-sizing:inherit}.fastboard-redo-undo.light{color:var(--fastboard-color, #5d6066);background-color:var(--fastboard-bg-color, rgba(255, 255, 255, .9));border-color:var(--fastboard-border-color, #e5e8f0)}.fastboard-redo-undo.dark{color:var(--fastboard-color, #7b7e84);background-color:var(--fastboard-bg-color, rgba(20, 24, 30, .9));border-color:var(--fastboard-border-color, #383b42)}.fastboard-redo-undo-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:#0000;border-radius:4px;font-size:0;line-height:1;flex-shrink:0}.fastboard-redo-undo-btn svg,.fastboard-redo-undo-btn img{width:100%;height:100%;pointer-events:none}.fastboard-redo-undo-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-redo-undo-btn.light:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #ebf2ff)}.fastboard-redo-undo-btn.dark:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #383b42)}.fastboard-zoom-control{box-sizing:border-box;display:inline-flex;align-items:center;gap:4px;padding:4px;border:1px solid;border-radius:4px;font-size:14px;font-family:system-ui;pointer-events:auto;backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px)}.fastboard-zoom-control *{box-sizing:inherit}.fastboard-zoom-control.light{color:var(--fastboard-color, #5d6066);background-color:var(--fastboard-bg-color, rgba(255, 255, 255, .9));border-color:var(--fastboard-border-color, #e5e8f0)}.fastboard-zoom-control.dark{color:var(--fastboard-color, #7b7e84);background-color:var(--fastboard-bg-color, rgba(20, 24, 30, .9));border-color:var(--fastboard-border-color, #383b42)}.fastboard-zoom-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:#0000;border-radius:4px;font-size:0;line-height:1;flex-shrink:0}.fastboard-zoom-control-btn svg,.fastboard-zoom-control-btn img{width:100%;height:100%;pointer-events:none}.fastboard-zoom-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-zoom-control-btn.light:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #ebf2ff)}.fastboard-zoom-control-btn.dark:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #383b42)}.fastboard-zoom-control-text{font-variant-numeric:tabular-nums}.fastboard-page-control{box-sizing:border-box;display:inline-flex;align-items:center;gap:4px;padding:4px;border:1px solid;border-radius:4px;font-size:14px;font-family:system-ui;pointer-events:auto;backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px)}.fastboard-page-control *{box-sizing:inherit}.fastboard-page-control.light{color:var(--fastboard-color, #5d6066);background-color:var(--fastboard-bg-color, rgba(255, 255, 255, .9));border-color:var(--fastboard-border-color, #e5e8f0)}.fastboard-page-control.dark{color:var(--fastboard-color, #7b7e84);background-color:var(--fastboard-bg-color, rgba(20, 24, 30, .9));border-color:var(--fastboard-border-color, #383b42)}.fastboard-page-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:#0000;border-radius:4px;font-size:0;line-height:1;flex-shrink:0}.fastboard-page-control-btn svg,.fastboard-page-control-btn img{width:100%;height:100%;pointer-events:none}.fastboard-page-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-page-control-btn.light:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #ebf2ff)}.fastboard-page-control-btn.dark:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #383b42)}.fastboard-page-control-text{font-variant-numeric:tabular-nums}.fastboard-player-control{box-sizing:border-box;display:inline-flex;align-items:center;gap:4px;padding:4px;border:1px solid;border-radius:4px;font-size:14px;font-family:system-ui;pointer-events:auto;backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);width:100%}.fastboard-player-control *{box-sizing:inherit}.fastboard-player-control.light{color:var(--fastboard-color, #5d6066);background-color:var(--fastboard-bg-color, rgba(255, 255, 255, .9));border-color:var(--fastboard-border-color, #e5e8f0)}.fastboard-player-control.dark{color:var(--fastboard-color, #7b7e84);background-color:var(--fastboard-bg-color, rgba(20, 24, 30, .9));border-color:var(--fastboard-border-color, #383b42)}.fastboard-player-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:#0000;border-radius:4px;font-size:0;line-height:1;flex-shrink:0;display:inline}.fastboard-player-control-btn svg,.fastboard-player-control-btn img{width:100%;height:100%;pointer-events:none}.fastboard-player-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-player-control-btn.light:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #ebf2ff)}.fastboard-player-control-btn.dark:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #383b42)}.fastboard-player-control-btn.loading svg,.fastboard-player-control-btn.loading img{animation:fastboard-player-control-rotate .5s linear infinite}@keyframes fastboard-player-control-rotate{to{transform:rotate(360deg)}}.fastboard-player-control-btn.speed{width:auto;padding:4px;text-align:right;font-size:14px;font-variant-numeric:tabular-nums}.fastboard-player-control-btn.is-active.light{color:var(--fastboard-active-color, #3381ff)}.fastboard-player-control-btn.is-active.dark{color:var(--fastboard-active-color, #2867cc)}.fastboard-player-control-speed-text,.fastboard-player-control-progress{font-size:14px;font-variant-numeric:tabular-nums;line-height:16px}.fastboard-player-control-progress{display:inline-flex;align-items:center}.fastboard-player-control-panel.speed{display:flex;flex-direction:column}.fastboard-toolbar{height:100%;display:flex;align-items:center;position:relative;transform:translate(0);transition:transform .5s cubic-bezier(.34,1.56,.64,1);pointer-events:none}.fastboard-toolbar.collapsed{transform:translate(-100%)}.fastboard-toolbar-handler{position:absolute;left:100%;width:17px;font-size:0;border-radius:3px;cursor:pointer;pointer-events:auto}.fastboard-toolbar-handler:focus-visible{outline:2px solid -webkit-focus-ring-color}.fastboard-toolbar-handler input[type=checkbox]{position:absolute;top:0;left:0;appearance:none;margin:0;width:100%;height:100%;cursor:pointer;opacity:0;z-index:-1}.fastboard-toolbar-handler svg{opacity:0;transition:opacity .5s 1s;pointer-events:none}.fastboard-toolbar-handler.light .fastboard-toolbar-handler-bg-color{fill:var(--fastboard-bg-color, rgba(255, 255, 255, .9))}.fastboard-toolbar-handler.light .fastboard-toolbar-handler-border-color{stroke:var(--fastboard-border-color, #e5e8f0)}.fastboard-toolbar-handler.light .fastboard-toolbar-handler-image-stroke-color{stroke:var(--fastboard-color, #5d6066)}.fastboard-toolbar-handler.light .fastboard-toolbar-handler-image-fill-color{fill:var(--fastboard-color, #5d6066)}.fastboard-toolbar-handler.dark .fastboard-toolbar-handler-bg-color{fill:var(--fastboard-bg-color, rgba(20, 24, 30, .9))}.fastboard-toolbar-handler.dark .fastboard-toolbar-handler-border-color{stroke:var(--fastboard-border-color, #383b42)}.fastboard-toolbar-handler.dark .fastboard-toolbar-handler-image-stroke-color{stroke:var(--fastboard-color, #7b7e84)}.fastboard-toolbar-handler.dark .fastboard-toolbar-handler-image-fill-color{fill:var(--fastboard-color, #7b7e84)}.fastboard-toolbar:hover .fastboard-toolbar-handler svg,.fastboard-toolbar.collapsed .fastboard-toolbar-handler svg{opacity:1;transition:opacity .2s}.fastboard-toolbar-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:4px;width:32px;height:32px;background-color:#0000;border-radius:4px;font-size:0;line-height:1;flex-shrink:0}.fastboard-toolbar-btn svg,.fastboard-toolbar-btn img{width:100%;height:100%;pointer-events:none}.fastboard-toolbar-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-toolbar-btn.light:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #ebf2ff)}.fastboard-toolbar-btn.dark:not(:disabled):hover{background-color:var(--fastboard-hover-bg-color, #383b42)}.fastboard-slider{box-sizing:border-box;position:relative;width:100%;height:100%;display:flex;align-items:center}.fastboard-slider *{box-sizing:inherit}.fastboard-slider-track{appearance:none;background:rgba(0,0,0,0);border:0;border-radius:26px;flex:1;display:block;height:19px;margin:0;width:0;min-width:0;padding:0;transition:box-shadow .3s ease;cursor:pointer;touch-action:manipulation}.fastboard-slider-track::-webkit-slider-runnable-track{border:0;border-radius:2.5px;height:5px;transition:box-shadow .3s ease;user-select:none;background-color:#80808040;-webkit-user-select:none;background-image:linear-gradient(to right,currentColor var(--value, 0%),transparent var(--value, 0%))}.fastboard-slider-track::-webkit-slider-thumb{background:#fff;border:0;border-radius:100%;box-shadow:0 1px 1px #23292f26,0 0 0 1px #23292f33;width:13px;height:13px;position:relative;transition:all .2s ease;cursor:grab;appearance:none;margin-top:-4px}.fastboard-slider-track::-moz-range-track{border:0;border-radius:2.5px;height:5px;transition:box-shadow .3s ease;user-select:none;background-color:#80808040;-webkit-user-select:none}.fastboard-slider-track::-moz-range-thumb{appearance:none;background:#fff;border:0;border-radius:100%;box-shadow:0 1px 1px #23292f26,0 0 0 1px #23292f33;width:13px;height:13px;position:relative;transition:all .2s ease;cursor:grab}.fastboard-slider-track::-moz-range-progress{background:currentColor;border-radius:2.5px;height:5px}.fastboard-slider-track::-ms-track{border:0;border-radius:2.5px;height:5px;transition:box-shadow .3s ease;user-select:none;background-color:#80808040;-webkit-user-select:none;color:#0000}.fastboard-slider-track::-ms-thumb{appearance:none;background:#fff;border:0;border-radius:100%;box-shadow:0 1px 1px #23292f26,0 0 0 1px #23292f33;width:13px;height:13px;position:relative;transition:all .2s ease;cursor:grab;margin-top:0}.fastboard-slider-track::-ms-tooltip{display:none}.fastboard-slider-track::-moz-focus-outer{border:0}.fastboard-slider-track.grabbing::-webkit-slider-thumb{cursor:grabbing}.fastboard-slider-track.light{color:var(--fastboard-active-color, #3381ff)}.fastboard-slider-track.dark{color:var(--fastboard-active-color, #2867cc)}.fastboard-toolbar-contents{box-sizing:border-box;display:inline-flex;align-items:center;gap:4px;border:1px solid;border-radius:4px;font-size:14px;font-family:system-ui;pointer-events:auto;backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);padding:2px 0;gap:0;flex-direction:column}.fastboard-toolbar-contents *{box-sizing:inherit}.fastboard-toolbar-contents.light{color:var(--fastboard-color, #5d6066);background-color:var(--fastboard-bg-color, rgba(255, 255, 255, .9));border-color:var(--fastboard-border-color, #e5e8f0)}.fastboard-toolbar-contents.dark{color:var(--fastboard-color, #7b7e84);background-color:var(--fastboard-bg-color, rgba(20, 24, 30, .9));border-color:var(--fastboard-border-color, #383b42)}.fastboard-toolbar-contents>.fastboard-toolbar-btn{margin:2px 4px}.fastboard-toolbar-btn-interactive{position:relative}.fastboard-toolbar-triangle{width:0px;height:0px;border-bottom:4px solid;border-left:4px solid rgba(0,0,0,0);position:absolute;bottom:0;right:0}.fastboard-toolbar-btn:focus+.fastboard-toolbar-triangle{opacity:0}.fastboard-toolbar-scrollable{padding:2px 4px;overflow:hidden;display:flex;flex-direction:column;gap:4px}.fastboard-toolbar-tooltip{display:inline-flex;align-items:center;gap:4px}.fastboard-toolbar-hotkey{display:inline-flex;margin-right:-4px;width:24px;height:24px;align-items:center;justify-content:center;background-color:#ffffff1a;border-radius:4px}.fastboard-toolbar-panel-wrapper{display:none}.fastboard-toolbar-panel{display:flex;flex-direction:column}.fastboard-toolbar-panel-divider{height:.5px;width:100%;margin:4px 0;background-color:#ffffff26}.fastboard-toolbar-slider.pencil-eraser-size{width:136px}.fastboard-toolbar-colors,.fastboard-toolbar-shapes{display:grid;align-self:center;grid-template:repeat(2,1fr)/repeat(4,1fr);align-items:center;justify-items:center;gap:4px}.fastboard-toolbar-shape-btn,.fastboard-toolbar-color-btn{width:24px;height:24px;padding:0;display:inline-flex;align-items:center;justify-content:center}.fastboard-toolbar-color-btn{border:1px solid rgba(0,0,0,0)}.fastboard-toolbar-color-btn.light.is-active{border-color:var(--fastboard-active-color, #3381ff)}.fastboard-toolbar-color-btn.dark.is-active{border-color:var(--fastboard-active-color, #2867cc)}.fastboard-toolbar-color-item{display:inline-block;width:16px;height:16px;border-radius:4px;pointer-events:none}.fastboard-toolbar-panel.apps{display:grid;grid-template-columns:repeat(min(var(--n, 3),3),minmax(max-content,1fr));gap:4px}.fastboard-toolbar-app-btn{margin:0;border:0;border-radius:2px;padding:4px 6px;background-color:#0000;display:inline-flex;flex-direction:column;align-items:center;gap:4px;font-size:0}.fastboard-toolbar-app-btn:disabled{opacity:.8}.fastboard-toolbar-app-btn-icon{width:32px;height:32px;pointer-events:none}.fastboard-toolbar-app-btn-text{font-size:14px;line-height:1;max-width:100%;overflow:hidden;text-overflow:ellipsis}.fastboard-toolbar-app-btn.is-loading{cursor:progress}.fastboard-toolbar-app-btn.is-failed{cursor:not-allowed;opacity:.5}.fastboard-toolbar-app-btn:not(:disabled,.is-loading,.is-failed):hover.light{cursor:pointer;background-color:var(--fastboard-hover-bg-color, #ebf2ff)}.fastboard-toolbar-app-btn-text.light{color:var(--fastboard-color, #5d6066)}.fastboard-toolbar-app-btn:not(:disabled,.is-loading,.is-failed):hover.dark{cursor:pointer;background-color:var(--fastboard-hover-bg-color, #383b42)}.fastboard-toolbar-app-btn-text.dark{color:var(--fastboard-color, #7b7e84)}.fastboard-root{position:relative;width:100%;height:100%;overflow:hidden}.fastboard-view{position:absolute;top:0;left:0;width:100%;height:100%}.fastboard-left{display:flex;align-items:center;position:absolute;bottom:62px;top:8px;left:0;z-index:200;pointer-events:none}.fastboard-left .fastboard-toolbar{padding-left:16px}.fastboard-bottom-left,.fastboard-bottom,.fastboard-bottom-right{display:flex;gap:10px;position:absolute;bottom:8px;left:8px;padding:8px;z-index:200;pointer-events:none}.fastboard-bottom-right{left:auto;right:8px}.fastboard-bottom{right:8px}.fastboard-left.hidden *,.fastboard-bottom.hidden *,.fastboard-bottom-left.hidden *,.fastboard-bottom-right.hidden *{opacity:0;pointer-events:none}.fastboard-tip{font-family:inherit;color:#d5d9e0;background-color:#03060d}.fastboard-tip[data-placement^=right]>.tippy-arrow:before{top:4px;border-width:4px;border-right-color:#03060d}.fastboard-tip[data-placement^=top]>.tippy-arrow:before{left:4px;border-width:4px;border-top-color:#03060d}.fastboard-panel .tippy-content{padding:8px}.netless-whiteboard:focus-visible{outline:none}"],"mappings":"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","names":[]}