@fmsim/board 2.0.0-beta.11 → 2.0.0-beta.111
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/custom-elements.json +6502 -2308
- package/demo/index-modeller.html +1 -1
- package/demo/index-player.html +2 -2
- package/demo/index-viewer.html +2 -2
- package/demo/index.html +2 -2
- package/dist/src/board-i18n.d.ts +37 -0
- package/dist/src/board-i18n.js +121 -0
- package/dist/src/board-i18n.js.map +1 -0
- package/dist/src/component/etc.js +36 -0
- package/dist/src/component/etc.js.map +1 -1
- package/dist/src/component/index.d.ts +1 -0
- package/dist/src/component/index.js +1 -0
- package/dist/src/component/index.js.map +1 -1
- package/dist/src/component/restful-property-editor-backdrop-faces.d.ts +50 -0
- package/dist/src/component/restful-property-editor-backdrop-faces.js +524 -0
- package/dist/src/component/restful-property-editor-backdrop-faces.js.map +1 -0
- package/dist/src/config/flow-replay.d.ts +14 -0
- package/dist/src/config/flow-replay.js +20 -0
- package/dist/src/config/flow-replay.js.map +1 -0
- package/dist/src/data-storage/board-model-cache.d.ts +13 -0
- package/dist/src/data-storage/board-model-cache.js +66 -0
- package/dist/src/data-storage/board-model-cache.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/layers/mcs-mouse-event-handler.js +28 -3
- package/dist/src/layers/mcs-mouse-event-handler.js.map +1 -1
- package/dist/src/layers/movement-layer.d.ts +9 -6
- package/dist/src/layers/movement-layer.js +35 -10
- package/dist/src/layers/movement-layer.js.map +1 -1
- package/dist/src/modeller/bulk-create-dialog.d.ts +62 -0
- package/dist/src/modeller/bulk-create-dialog.js +595 -0
- package/dist/src/modeller/bulk-create-dialog.js.map +1 -0
- package/dist/src/modeller/bulk-create.d.ts +107 -0
- package/dist/src/modeller/bulk-create.js +201 -0
- package/dist/src/modeller/bulk-create.js.map +1 -0
- package/dist/src/modeller/component-toolbar/component-menu.d.ts +1 -1
- package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +7 -1
- package/dist/src/modeller/component-toolbar/component-toolbar.js +18 -2
- package/dist/src/modeller/component-toolbar/component-toolbar.js.map +1 -1
- package/dist/src/modeller/edit-toolbar.d.ts +13 -0
- package/dist/src/modeller/edit-toolbar.js +177 -7
- package/dist/src/modeller/edit-toolbar.js.map +1 -1
- package/dist/src/modeller/property-sidebar/abstract-property.js +10 -2
- package/dist/src/modeller/property-sidebar/abstract-property.js.map +1 -1
- package/dist/src/modeller/property-sidebar/data-binding/data-binding.d.ts +1 -1
- package/dist/src/modeller/property-sidebar/effects/effects.d.ts +10 -1
- package/dist/src/modeller/property-sidebar/effects/effects.js +67 -1
- package/dist/src/modeller/property-sidebar/effects/effects.js.map +1 -1
- package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.d.ts +44 -0
- package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.js +70 -0
- package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.js.map +1 -0
- package/dist/src/modeller/property-sidebar/effects/property-event.d.ts +13 -3
- package/dist/src/modeller/property-sidebar/effects/property-event.js +20 -11
- package/dist/src/modeller/property-sidebar/effects/property-event.js.map +1 -1
- package/dist/src/modeller/property-sidebar/inspector/inspector-controller.d.ts +66 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-controller.js +288 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-controller.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.d.ts +15 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.js +67 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-highlight.d.ts +7 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-highlight.js +25 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-highlight.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-model.d.ts +44 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-model.js +72 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-model.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-tree-view.d.ts +18 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-tree-view.js +61 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-tree-view.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector.d.ts +17 -12
- package/dist/src/modeller/property-sidebar/inspector/inspector.js +287 -151
- package/dist/src/modeller/property-sidebar/inspector/inspector.js.map +1 -1
- package/dist/src/modeller/property-sidebar/property-sidebar.d.ts +1 -1
- package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.d.ts +75 -0
- package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js +355 -0
- package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js.map +1 -0
- package/dist/src/modeller/property-sidebar/shapes/shapes.d.ts +22 -1
- package/dist/src/modeller/property-sidebar/shapes/shapes.js +110 -2
- package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -1
- package/dist/src/modeller/property-sidebar/specifics/parent-object.d.ts +29 -0
- package/dist/src/modeller/property-sidebar/specifics/parent-object.js +74 -0
- package/dist/src/modeller/property-sidebar/specifics/parent-object.js.map +1 -0
- package/dist/src/modeller/property-sidebar/specifics/specifics.d.ts +27 -1
- package/dist/src/modeller/property-sidebar/specifics/specifics.js +95 -3
- package/dist/src/modeller/property-sidebar/specifics/specifics.js.map +1 -1
- package/dist/src/modeller/property-sidebar/styles/styles.d.ts +1 -1
- package/dist/src/modeller/scene-viewer/ox-scene-layer.d.ts +4 -3
- package/dist/src/modeller/scene-viewer/ox-scene-layer.js +2 -1
- package/dist/src/modeller/scene-viewer/ox-scene-layer.js.map +1 -1
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +2 -1
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +5 -1
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -1
- package/dist/src/ox-board-component-info.d.ts +1 -0
- package/dist/src/ox-board-component-info.js +42 -2
- package/dist/src/ox-board-component-info.js.map +1 -1
- package/dist/src/ox-board-modeller.d.ts +6 -3
- package/dist/src/ox-board-modeller.js +21 -1
- package/dist/src/ox-board-modeller.js.map +1 -1
- package/dist/src/ox-board-viewer.d.ts +117 -13
- package/dist/src/ox-board-viewer.js +688 -102
- package/dist/src/ox-board-viewer.js.map +1 -1
- package/dist/src/ox-editor-board-selector.d.ts +3 -0
- package/dist/src/ox-editor-board-selector.js +40 -9
- package/dist/src/ox-editor-board-selector.js.map +1 -1
- package/dist/src/ox-playback-controls.d.ts +115 -18
- package/dist/src/ox-playback-controls.js +744 -167
- package/dist/src/ox-playback-controls.js.map +1 -1
- package/dist/src/playback/carrier-tracking-store.d.ts +51 -0
- package/dist/src/playback/carrier-tracking-store.js +115 -0
- package/dist/src/playback/carrier-tracking-store.js.map +1 -0
- package/dist/src/playback/playback-engine.d.ts +106 -0
- package/dist/src/playback/playback-engine.js +395 -0
- package/dist/src/playback/playback-engine.js.map +1 -0
- package/dist/src/scene-monitor-renderer.d.ts +10 -0
- package/dist/src/scene-monitor-renderer.js +226 -0
- package/dist/src/scene-monitor-renderer.js.map +1 -0
- package/dist/src/selector/ox-board-selector.js +14 -2
- package/dist/src/selector/ox-board-selector.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/icons/components/text.png +0 -0
- package/icons/fab/mode-2d.svg +25 -0
- package/icons/fab/mode-3d.svg +25 -0
- package/icons/fab/playback-play.svg +49 -0
- package/icons/fab/playback-stop.svg +50 -0
- package/package.json +8 -4
|
@@ -5,8 +5,55 @@ import { __decorate } from "tslib";
|
|
|
5
5
|
import { html, LitElement } from 'lit';
|
|
6
6
|
import { property, state } from 'lit/decorators.js';
|
|
7
7
|
import { copyToClipboard, isMacOS } from '@operato/utils';
|
|
8
|
+
import { OxPopup } from '@operato/popup';
|
|
8
9
|
import { style } from './edit-toolbar-style';
|
|
10
|
+
import './bulk-create-dialog.js';
|
|
11
|
+
import { parentObjectForTemplate } from './property-sidebar/specifics/parent-object.js';
|
|
9
12
|
const MACOS = isMacOS();
|
|
13
|
+
/**
|
|
14
|
+
* 컴포넌트 model JSON 만으로 type-aware bounding box (width, height) 추출.
|
|
15
|
+
*
|
|
16
|
+
* things-scene 의 component.bounds 는 *path 의 bounding box* 인데, model JSON 만
|
|
17
|
+
* 으로는 path 를 그릴 수 없으므로 type-specific 필드를 직접 본다.
|
|
18
|
+
* - width/height 명시 (Rect, Container 등) → 그대로
|
|
19
|
+
* - rx/ry (Ellipse 등) → 2*rx, 2*ry
|
|
20
|
+
* - points 배열 (Line, Polygon 등) → 점들의 bounding box
|
|
21
|
+
* - 그 외 → 50x50 fallback
|
|
22
|
+
*
|
|
23
|
+
* bulk-paste 가 영역 안에 N 개 복제할 때 *원본 크기를 보존* 하기 위해 사용.
|
|
24
|
+
*/
|
|
25
|
+
function deriveBoundsFromModel(model) {
|
|
26
|
+
if (typeof model.width === 'number' && typeof model.height === 'number') {
|
|
27
|
+
return { width: model.width, height: model.height };
|
|
28
|
+
}
|
|
29
|
+
if (typeof model.rx === 'number' && typeof model.ry === 'number') {
|
|
30
|
+
return { width: 2 * Math.abs(model.rx), height: 2 * Math.abs(model.ry) };
|
|
31
|
+
}
|
|
32
|
+
if (Array.isArray(model.points) && model.points.length > 0) {
|
|
33
|
+
let minX = Infinity;
|
|
34
|
+
let maxX = -Infinity;
|
|
35
|
+
let minY = Infinity;
|
|
36
|
+
let maxY = -Infinity;
|
|
37
|
+
for (const p of model.points) {
|
|
38
|
+
if (typeof (p === null || p === void 0 ? void 0 : p.x) === 'number') {
|
|
39
|
+
if (p.x < minX)
|
|
40
|
+
minX = p.x;
|
|
41
|
+
if (p.x > maxX)
|
|
42
|
+
maxX = p.x;
|
|
43
|
+
}
|
|
44
|
+
if (typeof (p === null || p === void 0 ? void 0 : p.y) === 'number') {
|
|
45
|
+
if (p.y < minY)
|
|
46
|
+
minY = p.y;
|
|
47
|
+
if (p.y > maxY)
|
|
48
|
+
maxY = p.y;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (isFinite(minX) && isFinite(maxX) && isFinite(minY) && isFinite(maxY)) {
|
|
52
|
+
return { width: maxX - minX, height: maxY - minY };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { width: 50, height: 50 };
|
|
56
|
+
}
|
|
10
57
|
export class EditToolbar extends LitElement {
|
|
11
58
|
constructor() {
|
|
12
59
|
super(...arguments);
|
|
@@ -246,7 +293,13 @@ export class EditToolbar extends LitElement {
|
|
|
246
293
|
this.onTapCut();
|
|
247
294
|
break;
|
|
248
295
|
case 'KeyV':
|
|
249
|
-
if (ctrlKey && !
|
|
296
|
+
if (ctrlKey && shiftKey && !altKey) {
|
|
297
|
+
// Ctrl+Shift+V = Bulk Paste (Paste Special 컨벤션) — 클립보드의
|
|
298
|
+
// 단일 컴포넌트를 N개로 일괄 붙여넣기.
|
|
299
|
+
this.onBulkPaste();
|
|
300
|
+
defaultPrevent = true;
|
|
301
|
+
}
|
|
302
|
+
else if (ctrlKey && !shiftKey) {
|
|
250
303
|
this.onTapPaste();
|
|
251
304
|
defaultPrevent = false;
|
|
252
305
|
}
|
|
@@ -266,21 +319,35 @@ export class EditToolbar extends LitElement {
|
|
|
266
319
|
this.onTapUngroup();
|
|
267
320
|
}
|
|
268
321
|
break;
|
|
269
|
-
case '
|
|
322
|
+
case 'BracketRight':
|
|
323
|
+
// Ctrl+] = Bring Forward, Ctrl+Shift+] = Bring to Front
|
|
324
|
+
// (Photoshop / Illustrator 표준 컨벤션)
|
|
270
325
|
if (this._dimension === '2d') {
|
|
271
|
-
if (ctrlKey && !shiftKey)
|
|
326
|
+
if (ctrlKey && !shiftKey) {
|
|
272
327
|
(_a = this.scene) === null || _a === void 0 ? void 0 : _a.zorder('forward');
|
|
273
|
-
|
|
328
|
+
defaultPrevent = true;
|
|
329
|
+
}
|
|
330
|
+
else if (ctrlKey && shiftKey) {
|
|
274
331
|
(_b = this.scene) === null || _b === void 0 ? void 0 : _b.zorder('front');
|
|
332
|
+
defaultPrevent = true;
|
|
333
|
+
}
|
|
275
334
|
}
|
|
276
335
|
break;
|
|
277
|
-
case '
|
|
336
|
+
case 'BracketLeft':
|
|
337
|
+
// Ctrl+[ = Send Backward, Ctrl+Shift+[ = Send to Back
|
|
278
338
|
if (this._dimension === '2d') {
|
|
279
|
-
if (ctrlKey && !shiftKey)
|
|
339
|
+
if (ctrlKey && !shiftKey) {
|
|
280
340
|
(_c = this.scene) === null || _c === void 0 ? void 0 : _c.zorder('backward');
|
|
281
|
-
|
|
341
|
+
defaultPrevent = true;
|
|
342
|
+
}
|
|
343
|
+
else if (ctrlKey && shiftKey) {
|
|
282
344
|
(_d = this.scene) === null || _d === void 0 ? void 0 : _d.zorder('back');
|
|
345
|
+
defaultPrevent = true;
|
|
346
|
+
}
|
|
283
347
|
}
|
|
348
|
+
break;
|
|
349
|
+
case 'KeyB':
|
|
350
|
+
// zorder 는 BracketLeft 로 이동. KeyB 의 Alt+Shift+B = align bottom 만 유지.
|
|
284
351
|
if (altKey && shiftKey)
|
|
285
352
|
this.onTapAlign('bottom');
|
|
286
353
|
break;
|
|
@@ -458,6 +525,109 @@ export class EditToolbar extends LitElement {
|
|
|
458
525
|
var _a;
|
|
459
526
|
(_a = this.scene) === null || _a === void 0 ? void 0 : _a.remove();
|
|
460
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* 멀티 컴포넌트 일괄 붙여넣기 — Ctrl+Shift+V 진입점.
|
|
530
|
+
*
|
|
531
|
+
* 흐름:
|
|
532
|
+
* 1. 클립보드 (this.cliped) 검증 — *단일* 컴포넌트만 허용
|
|
533
|
+
* 2. scene.startBulkCreateMode → AddLayer 가 캔버스 위에 드래그 박스 그림
|
|
534
|
+
* 3. 사용자가 영역 드래그 → Promise resolve({area, template})
|
|
535
|
+
* ESC/취소 → Promise resolve(null)
|
|
536
|
+
* 4. 영역이 결정되면 dialog 오픈
|
|
537
|
+
*/
|
|
538
|
+
async onBulkPaste() {
|
|
539
|
+
var _a;
|
|
540
|
+
if (!this.cliped) {
|
|
541
|
+
console.warn('bulk-paste: 먼저 Ctrl+C 로 컴포넌트를 복사하세요.');
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
let parsed;
|
|
545
|
+
try {
|
|
546
|
+
parsed = JSON.parse(this.cliped);
|
|
547
|
+
}
|
|
548
|
+
catch (e) {
|
|
549
|
+
console.warn('bulk-paste: 클립보드 파싱 실패', e);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
553
|
+
console.warn('bulk-paste: 클립보드 비어있음');
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
if (parsed.length > 1) {
|
|
557
|
+
console.warn('bulk-paste: 단일 컴포넌트만 일괄 붙여넣기 가능. 다중은 일반 paste 사용.');
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
const template = parsed[0];
|
|
561
|
+
// bulk 모드 임을 시각 구분하기 위해 파란 점선 (일반 add 의 검정과 색만 차별).
|
|
562
|
+
const result = await ((_a = this.scene) === null || _a === void 0 ? void 0 : _a.startBulkCreateMode(template, { boxStrokeStyle: '#2964c2' }));
|
|
563
|
+
if (result) {
|
|
564
|
+
this._openBulkCreateDialog(template, result.area);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
_openBulkCreateDialog(template, initialArea) {
|
|
568
|
+
var _a;
|
|
569
|
+
const dialogEl = document.createElement('bulk-create-dialog');
|
|
570
|
+
dialogEl.template = template;
|
|
571
|
+
dialogEl.initialArea = initialArea;
|
|
572
|
+
// 충돌 검사용 — scene 의 모든 컴포넌트 id 수집.
|
|
573
|
+
// (scene.ids 는 indexMap 기반인데 fmsim 의 일부 컴포넌트는 indexMap 미등록
|
|
574
|
+
// 되는 케이스가 있어 직접 컴포넌트 트리 walk.)
|
|
575
|
+
const existingIds = new Set();
|
|
576
|
+
const collectIds = (comp) => {
|
|
577
|
+
var _a, _b, _c;
|
|
578
|
+
if (!comp)
|
|
579
|
+
return;
|
|
580
|
+
const id = (_b = (_a = comp === null || comp === void 0 ? void 0 : comp.state) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : (_c = comp === null || comp === void 0 ? void 0 : comp.model) === null || _c === void 0 ? void 0 : _c.id;
|
|
581
|
+
if (typeof id === 'string' && id)
|
|
582
|
+
existingIds.add(id);
|
|
583
|
+
const children = comp.components || [];
|
|
584
|
+
for (const c of children)
|
|
585
|
+
collectIds(c);
|
|
586
|
+
};
|
|
587
|
+
const root = (_a = this.scene) === null || _a === void 0 ? void 0 : _a.root;
|
|
588
|
+
if (root)
|
|
589
|
+
collectIds(root);
|
|
590
|
+
dialogEl.existingIds = existingIds;
|
|
591
|
+
// parentObject 커스터마이징: template 타입이 ParentObjectMixin 이면 상위객체 선택 필드 노출.
|
|
592
|
+
// 후보 리스트는 타입의 parentObjectTypes 기준으로 씬에서 수집 (속성창과 동일 로직 재사용).
|
|
593
|
+
const { has, items } = parentObjectForTemplate(template, root);
|
|
594
|
+
dialogEl.hasParentObject = has;
|
|
595
|
+
dialogEl.parentObjectItems = items;
|
|
596
|
+
dialogEl.onConfirm = (models) => {
|
|
597
|
+
const scene = this.scene;
|
|
598
|
+
if (!scene || !models.length) {
|
|
599
|
+
popup === null || popup === void 0 ? void 0 : popup.close();
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
// cliped 의 template model 자체에서 type-aware bounds 추출. things-scene 의
|
|
603
|
+
// component.bounds (= path bounding box) 와 동일 결과를 model JSON 의
|
|
604
|
+
// type-specific 필드 (width/height, rx/ry, points) 만으로 계산.
|
|
605
|
+
const bounds = deriveBoundsFromModel(template);
|
|
606
|
+
scene.undoableChange(() => {
|
|
607
|
+
for (const m of models) {
|
|
608
|
+
const cx = m.left + m.width / 2;
|
|
609
|
+
const cy = m.top + m.height / 2;
|
|
610
|
+
scene.add(m, {
|
|
611
|
+
left: cx - bounds.width / 2,
|
|
612
|
+
top: cy - bounds.height / 2,
|
|
613
|
+
width: bounds.width,
|
|
614
|
+
height: bounds.height
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
popup === null || popup === void 0 ? void 0 : popup.close();
|
|
619
|
+
};
|
|
620
|
+
dialogEl.onCancel = () => {
|
|
621
|
+
popup === null || popup === void 0 ? void 0 : popup.close();
|
|
622
|
+
};
|
|
623
|
+
const popup = OxPopup.open({
|
|
624
|
+
template: dialogEl,
|
|
625
|
+
backdrop: true,
|
|
626
|
+
// 내부 입력(parentObject 검색 드롭다운 등)이 blur/focusout 될 때 팝업이 자동으로
|
|
627
|
+
// 닫히지 않도록. 닫기는 OK/취소 버튼 또는 backdrop/Escape 로만.
|
|
628
|
+
preventCloseOnBlur: true
|
|
629
|
+
});
|
|
630
|
+
}
|
|
461
631
|
onTapSelectAll() {
|
|
462
632
|
var _a;
|
|
463
633
|
(_a = this.scene) === null || _a === void 0 ? void 0 : _a.select('(child)');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit-toolbar.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGnD,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAEzD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAE5C,MAAM,KAAK,GAAG,OAAO,EAAE,CAAA;AAEvB,MAAM,OAAO,WAAY,SAAQ,UAAU;IAA3C;;QAI6B,aAAQ,GAAU,EAAE,CAAA;QAClB,iBAAY,GAAY,KAAK,CAAA;QAEzC,eAAU,GAAuB,IAAI,CAAA;QACrC,mBAAc,GAAG,KAAK,CAAA;IA+jBzC,CAAC;IA3jBC,YAAY;QACV,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAkB,EAAE,KAAK,CAAC,CAAA;QAEzF,+CAA+C;QAC/C,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;;YAClC,CAAC;YAAA,MAAA,MAAC,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAY,0CAAE,OAAO,0CAAE,KAAK,EAAE,CAAA;QAC9C,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAQ,EAAE,EAAE;;YAC5C,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,GAAG,MAAC,CAAoB,CAAC,aAAa,0CAAE,OAAO,CAAC,YAAY,CAAC,CAAA;YAC1E,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAA;YACxC,CAAC;QACH,CAAC,CAAC,CAAA;QACF,kDAAkD;IACpD,CAAC;IAED,OAAO,CAAC,OAA6B;QACnC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAU,CAAC,CAAA;QACtF,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAgB,CAAC,CAAA;IAC1G,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;;UAIL,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA,6BAA6B;;8CAE5B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS;8CAC7D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS;;;;0DAI1D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,qBAAqB;gEACnE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,wBAAwB;;;;4CAIhG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,QAAQ;8CAC1D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS;gDAC3D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;2BAEnF,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;mBAChF,IAAI,CAAC,WAAW;;;;;+BAKJ,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;iCAErE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;gCAExE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;;8BAGzE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;iCAEpE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;iCAEvE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;;;4CAG5D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,eAAe;;0CAE9E,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,eAAe;;UAE5G,IAAI,CAAC,UAAU,KAAK,IAAI;YACxB,CAAC,CAAC,IAAI,CAAA;;;kGAGkF,IAAI,CAAC,UAAU;qGACZ,IAAI,CAAC,UAAU;+FACrB,IAAI,CAAC,UAAU;+FACf,IAAI,CAAC,eAAe;aACtG;YACH,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI;gBACxB,CAAC,CAAC,IAAI,CAAA;;;;2CAIyB,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,WAAW;;yCAE1E,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,WAAW;;0CAEvE,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,WAAW;;0CAE/D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,WAAW;eAC1F;gBACH,CAAC,CAAC,EAAE;;UAEN,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;;;kDAGS,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,UAAU;sDAC1D,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,YAAY;SACtH,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;;;;qBAItB,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC;;;;;;;;;;qBAUrC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;;;;;;;qBAOlC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;;;;;;;SAO7C,CAAC,CAAC,CAAC,EAAE;;;;4EAI8D,IAAI,CAAC,iBAAiB;gGACF,IAAI,CAAC,iBAAiB;;;kBAGpG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;;;wDAGY,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,aAAa;;;;oDAIrE,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,YAAY;;0DAE3D,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,eAAe;;;0CAG9E,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC;kCAC1C,IAAI,CAAC,WAAW;;KAE7C,CAAA;IACH,CAAC;IAED,YAAY;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAoB,CAAA;QACrE,OAAO,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,GAAG,MAAM,MAAK,CAAC,CAAA;IAC3C,CAAC;IAED,YAAY,CAAC,CAAQ;QACnB,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAG,CAAgB,CAAC,MAAM,IAAI,CAAE,CAAgB,CAAC,MAAM,CAAC,CAAC,CAAA;QAC5F,IAAI,CAAC,UAAU,IAAI,KAAK,GAAG,EAAE,CAAA;QAE7B,CAAC,CAAC,cAAc,EAAE,CAAA;IACpB,CAAC;IAED,SAAS,CAAC,GAAW;QACnB,IAAI,MAAM,CAAA;QACV,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,KAAK,CAAC;YACX,KAAK,MAAM;gBACT,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAA;gBAC7B,MAAK;YACP,KAAK,OAAO;gBACV,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAA;gBAC9B,MAAK;YACP,KAAK,KAAK,CAAC;YACX,KAAK,QAAQ;gBACX,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAA;gBAC5B,MAAK;YACP,KAAK,WAAW;gBACd,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAA;gBAClC,MAAK;YACP,KAAK,QAAQ;gBACX,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAA;gBAC5B,MAAK;YACP;gBACE,MAAM,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;gBAC1B,MAAK;QACT,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,iBAAiB,CAAC,GAAG,IAAc;QACzC,IAAI,OAAO,GAAG,EAAE,CAAA;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5C,CAAC;QAED,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACvC,CAAC;IAED,UAAU,CAAC,CAAgB;;QACzB,IAAI,KAAK;YAAE,IAAI,OAAO,GAAG,CAAC,CAAC,OAAO,CAAA;;YAC7B,IAAI,OAAO,GAAG,CAAC,CAAC,OAAO,CAAA;QAE5B,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM,CAAA;QACrB,IAAI,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAA;QAEzB,IAAI,cAAc,GAAG,OAAO,IAAI,MAAM,CAAA;QAEtC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAA;qBACrC,IAAI,OAAO,IAAI,QAAQ;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAA;gBAC9C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAA;gBAC1C,MAAK;YACP,KAAK,QAAQ;gBACX,IAAI,OAAO;oBAAE,IAAI,CAAC,qBAAqB,EAAE,CAAA;gBACzC,MAAK;YACP,KAAK,QAAQ;gBACX,IAAI,OAAO;oBAAE,IAAI,CAAC,wBAAwB,EAAE,CAAA;gBAC5C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAA;qBACrC,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;gBACtD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,QAAQ,EAAE,CAAA;gBACzC,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACzB,IAAI,CAAC,UAAU,EAAE,CAAA;oBACjB,cAAc,GAAG,KAAK,CAAA;gBACxB,CAAC;qBAAM,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;gBAC/D,MAAK;YACP,KAAK,QAAQ,CAAC;YACd,KAAK,WAAW;gBACd,IAAI,CAAC,WAAW,EAAE,CAAA;gBAClB,cAAc,GAAG,IAAI,CAAA;gBACrB,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC7B,IAAI,OAAO,IAAI,CAAC,QAAQ;wBAAE,IAAI,CAAC,UAAU,EAAE,CAAA;yBACtC,IAAI,OAAO,IAAI,QAAQ;wBAAE,IAAI,CAAC,YAAY,EAAE,CAAA;gBACnD,CAAC;gBACD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC7B,IAAI,OAAO,IAAI,CAAC,QAAQ;wBAAE,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,SAAS,CAAC,CAAA;yBAClD,IAAI,OAAO,IAAI,QAAQ;wBAAE,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,OAAO,CAAC,CAAA;gBAC3D,CAAC;gBACD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC7B,IAAI,OAAO,IAAI,CAAC,QAAQ;wBAAE,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,UAAU,CAAC,CAAA;yBACnD,IAAI,OAAO,IAAI,QAAQ;wBAAE,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,MAAM,CAAC,CAAA;gBAC1D,CAAC;gBACD,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;gBACjD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,CAAC,QAAQ;oBAAE,IAAI,CAAC,WAAW,EAAE,CAAA;qBACvC,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAA;gBAC/D,MAAK;YACP,KAAK,KAAK;gBACR,IAAI,CAAC,eAAe,EAAE,CAAA;gBACtB,cAAc,GAAG,IAAI,CAAA;gBACrB,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,YAAY,EAAE,CAAA;oBACnB,cAAc,GAAG,IAAI,CAAA;gBACvB,CAAC;gBACD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO;oBAAE,IAAI,CAAC,cAAc,EAAE,CAAA;gBAClC,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;gBAC/C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;gBAChD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;gBACjD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,MAAM,IAAI,QAAQ;oBAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;gBAC9C,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,aAAa,EAAE,CAAA;oBACpB,cAAc,GAAG,IAAI,CAAA;gBACvB,CAAC;gBACD,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,IAAI,QAAQ;oBAAE,IAAI,CAAC,kBAAkB,EAAE,CAAA;gBAClD,MAAK;YAEP,KAAK,QAAQ;gBACX,MAAA,IAAI,CAAC,KAAK,0CAAE,kBAAkB,EAAE,CAAA;gBAChC,MAAA,IAAI,CAAC,KAAK,0CAAE,qBAAqB,EAAE,CAAA;gBACnC,cAAc,GAAG,IAAI,CAAA;gBACrB,MAAK;YAEP;gBACE,OAAO,KAAK,CAAA;QAChB,CAAC;QAED,IAAI,cAAc;YAAE,CAAC,CAAC,cAAc,EAAE,CAAA;QACtC,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,YAAY,CAAC,EAAU,EAAE,QAAiB;QAChD,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAClD,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IAC/E,CAAC;IAED,SAAS,CAAC,OAAe,EAAE,QAAiB,EAAE,QAAiB;QAC7D,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;QACpC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,MAAM,CAAC,QAAiB,EAAE,QAAiB;QACzC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;QACpC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,MAAM,CAAC,QAAiB,EAAE,QAAiB;QACzC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;QACpC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,cAAc,CAAC,KAAa,EAAE,MAAc;;QAC1C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACrC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACrC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAA;YACvD,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAA;QAC7D,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YACzC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACnC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACnC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAA;YACrD,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAA;YAEzD,oDAAoD;YACpD,MAAM,MAAM,GAAG,MAAA,MAAC,KAAa,CAAC,WAAW,0CAAE,KAAK,0CAAE,MAAM,CAAA;YACxD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;QACxC,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAC,SAAsB;QAChD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;IAC7B,CAAC;IAEO,qBAAqB,CAAC,UAAmB;QAC/C,IAAI,CAAC,cAAc,GAAG,UAAU,CAAA;IAClC,CAAC;IAEO,aAAa,CAAC,IAAsC;;QAC1D,CAAC;QAAA,MAAC,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAY,0CAAE,YAAY,CAAC,IAAI,CAAC,CAAA;IAChD,CAAC;IAED,iBAAiB,CAAC,KAAkB,EAAE,MAAmB;QACvD,IAAI,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;QACnC,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAG/B;QAAA,CAAC,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CACrE,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CACrC,CAAA;QAED,QAAQ;QACR,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAC5D,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAC7E,CAAA;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,OAAO,GAAG,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;YAEhC,yCAAyC;YACzC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAA;YACtC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAA;YAEvC,oCAAoC;YACpC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAA;YACnD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAA;QACpD,CAAC;QAED,QAAQ;QACR,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CACjE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAC7E,CAAA;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC3D,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;YACnF,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,SAAS;;QACP,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,SAAS;;QACP,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,qBAAqB;;QACnB,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,MAAM,MAAK,CAAC;YAAE,OAAM;QACvC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAK,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,CAAA;YAAE,OAAM;QACjD,MAAA,IAAI,CAAC,KAAK,0CAAE,mBAAmB,EAAE,CAAA;IACnC,CAAC;IAED,wBAAwB;;QACtB,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,MAAM,MAAK,CAAC;YAAE,OAAM;QACvC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAK,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,CAAA;YAAE,OAAM;QACjD,MAAA,IAAI,CAAC,KAAK,0CAAE,sBAAsB,EAAE,CAAA;IACtC,CAAC;IAED,QAAQ;;QACN,MAAA,IAAI,CAAC,KAAK,0CAAE,GAAG,EAAE,CAAA;IACnB,CAAC;IAED,KAAK,CAAC,SAAS;;QACb,IAAI,MAAM,GAAG,MAAA,IAAI,CAAC,KAAK,0CAAE,IAAI,EAAE,CAAA;QAE/B,IAAI,CAAC,MAAM;YAAE,OAAM;QAEnB,MAAM,eAAe,CAAC,MAAM,CAAC,CAAA;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,UAAU;QACR,UAAU,CAAC,GAAG,EAAE;;YACd,IAAI,CAAC,MAAM,KAAI,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA,CAAA;QAC/C,CAAC,EAAE,GAAG,CAAC,CAAA;IACT,CAAC;IAED,WAAW;;QACT,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,EAAE,CAAA;IACtB,CAAC;IAED,cAAc;;QACZ,MAAA,IAAI,CAAC,KAAK,0CAAE,MAAM,CAAC,SAAS,CAAC,CAAA;IAC/B,CAAC;IAED,iBAAiB,CAAC,CAAa;;QAC7B,IAAI,QAAQ,GAAG,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,CAAA;QACnC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QAED,MAAA,IAAI,CAAC,KAAK,0CAAE,cAAc,CAAC;YACzB,QAAS,CAAC,OAAO,CAAC,UAAU,SAAoB;gBAC9C,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;gBAExC,IAAI,CAAC,QAAQ;oBAAE,QAAQ,GAAG,IAAI,CAAA;gBAE9B,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;oBAC7B,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;gBACrC,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,iBAAiB,CAAC,CAAa;;QAC7B,IAAI,QAAQ,GAAG,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,CAAA;QAEnC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QAED,MAAA,IAAI,CAAC,KAAK,0CAAE,cAAc,CAAC;YACzB,QAAS,CAAC,OAAO,CAAC,UAAU,SAAoB;gBAC9C,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;gBAExC,IAAI,CAAC,QAAQ;oBAAE,QAAQ,GAAG,IAAI,CAAA;gBAE9B,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;oBAC7B,IAAI,IAAI,GAAG,CAAC;wBAAE,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;gBACnD,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,UAAU,CAAC,CAAsB;QAC/B,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QAEvB,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAA;QAElC,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,MAAsB,CAAC,YAAY,CAAC,YAAY,CAAC,CAAA;QAC5F,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACzB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;IAED,WAAW,CAAC,CAAsB;QAChC,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QAEvB,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAA;QAClC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAM;QAE/B,IAAI,MAAM,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,MAAsB,CAAC,YAAY,CAAC,aAAa,CAAC,CAAA;QAE9F,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;IAED,UAAU;QACR,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;IAClC,CAAC;IAED,YAAY;QACV,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAA;IACpC,CAAC;IAED,eAAe;QACb,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,qBAAqB,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED,WAAW;QACT,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,CAAA;QACtC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,uBAAuB,EAAE;YACvC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE;SACrC,CAAC,CACH,CAAA;IACH,CAAC;IAED,aAAa;QACX,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;YACnB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,cAAc,CAAC,CAAC,CAAA;IACrD,CAAC;IAED,kBAAkB;QAChB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAAA;IACvD,CAAC;IAED,eAAe,CAAC,CAAsB;QACpC,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QAEvB,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAA;QAClC,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACzB,OAAM;QACR,CAAC;QAED,IAAI,UAAU,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,MAAuB,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAA;QAEvG,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;IACjD,CAAC;;AArkBM,kBAAM,GAAG,CAAC,KAAK,CAAC,AAAV,CAAU;AAEK;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAAc;AACd;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;6CAAqB;AAClB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;iDAA8B;AAEzC;IAAhB,KAAK,EAAE;+CAA8C;AACrC;IAAhB,KAAK,EAAE;mDAA+B","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { html, LitElement, PropertyValues } from 'lit'\nimport { property, state } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { copyToClipboard, isMacOS } from '@operato/utils'\n\nimport { style } from './edit-toolbar-style'\n\nconst MACOS = isMacOS()\n\nexport class EditToolbar extends LitElement {\n static styles = [style]\n\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: any[] = []\n @property({ type: Boolean }) hideProperty: boolean = false\n\n @state() private _dimension: '2d' | '3d' | null = null\n @state() private _gizmoAttached = false\n\n private cliped?: string\n\n firstUpdated() {\n this.addEventListener('mousewheel', this.onWheelEvent.bind(this) as EventListener, false)\n\n // 툴바 버튼 클릭 후 씬으로 포커스를 돌려서 키보드 단축키가 계속 작동하도록 한다\n this.addEventListener('click', () => {\n ;(this.scene?.root as any)?.element?.focus()\n })\n\n window.addEventListener('paste', (e: Event) => {\n try {\n this.cliped = (e as ClipboardEvent).clipboardData?.getData('text/plain')\n } catch (e) {\n console.error('model paste failed', e)\n }\n })\n // 모든 버튼은 템플릿 @click 디렉티브로 바인딩 — 조건부 렌더링 시에도 정상 작동\n }\n\n updated(changes: PropertyValues<this>) {\n changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene') as Scene)\n changes.has('selected') && this.onSelectedChanged(this.selected, changes.get('selected') as Component[])\n }\n\n render() {\n return html`\n <div tools>\n <span><slot></slot></span>\n\n ${this.hasEmptySlot() ? html`` : html`<span class=\"vline\"></span>`}\n\n <span button id=\"undo\" title=\"undo (${this.getShortcutString('cmd', 'z')})\" @click=${this.onTapUndo}> </span>\n <span button id=\"redo\" title=\"redo (${this.getShortcutString('cmd', 'shift', 'z')})\" @click=${this.onTapRedo}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"style-copy\" title=\"style copy (${this.getShortcutString('cmd', '1')})\" @click=${this.onStartStylePasteMode}> </span>\n <span button id=\"databind-copy\" title=\"databind copy (${this.getShortcutString('cmd', '2')})\" @click=${this.onStartDatabindPasteMode}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"cut\" title=\"cut (${this.getShortcutString('cmd', 'x')})\" @click=${this.onTapCut}> </span>\n <span button id=\"copy\" title=\"copy (${this.getShortcutString('cmd', 'c')})\" @click=${this.onTapCopy}> </span>\n <span button id=\"paste\" title=\"paste (${this.getShortcutString('cmd', 'v')})\" @click=${this.onTapPaste}> </span>\n <span button id=\"delete\"\n title=\"delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})\"\n @click=${this.onTapDelete}> </span>\n\n <span class=\"vline\"></span>\n\n <span button data-align=\"left\" id=\"align-left\"\n title=\"align left (${this.getShortcutString('alt', 'shift', 'l')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"center\" id=\"align-center\"\n title=\"align center (${this.getShortcutString('alt', 'shift', 'c')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"right\" id=\"align-right\"\n title=\"align right (${this.getShortcutString('alt', 'shift', 'r')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-align=\"top\" id=\"align-top\"\n title=\"align top (${this.getShortcutString('alt', 'shift', 't')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"middle\" id=\"align-middle\"\n title=\"align middle (${this.getShortcutString('alt', 'shift', 'm')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"bottom\" id=\"align-bottom\"\n title=\"align bottom (${this.getShortcutString('alt', 'shift', 'b')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-distribute=\"HORIZONTAL\" id=\"distribute-horizontal\"\n title=\"distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})\" @click=${this.onTapDistribute}> </span>\n <span button data-distribute=\"VERTICAL\" id=\"distribute-vertical\"\n title=\"distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})\" @click=${this.onTapDistribute}> </span>\n\n ${this._dimension === '3d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button data-align=\"z-front\" id=\"align-z-front\" title=\"align Z front\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-middle\" id=\"align-z-middle\" title=\"align Z middle\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-back\" id=\"align-z-back\" title=\"align Z back\" @click=${this.onTapAlign}> </span>\n <span button data-distribute=\"Z\" id=\"distribute-z\" title=\"distribute Z\" @click=${this.onTapDistribute}> </span>\n `\n : this._dimension === '2d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"front\" data-zorder=\"front\"\n title=\"bring to front (${this.getShortcutString('cmd', 'shift', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"back\" data-zorder=\"back\"\n title=\"send to back (${this.getShortcutString('cmd', 'shift', 'b')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"forward\" data-zorder=\"forward\"\n title=\"bring forward (${this.getShortcutString('cmd', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"backward\" data-zorder=\"backward\"\n title=\"send backward (${this.getShortcutString('cmd', 'b')})\" @click=${this.onTapZorder}> </span>\n `\n : ''}\n\n ${this._dimension === '2d' ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"group\" title=\"group (${this.getShortcutString('cmd', 'g')})\" @click=${this.onTapGroup}> </span>\n <span button id=\"ungroup\" title=\"ungroup (${this.getShortcutString('cmd', 'shift', 'g')})\" @click=${this.onTapUngroup}> </span>\n ` : this._dimension === '3d' ? html`\n <span class=\"vline\"></span>\n\n <span button class=\"gizmo-btn\" data-gizmo=\"translate\" title=\"Move (W)\"\n @click=${() => this._setGizmoMode('translate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"10\" y1=\"2\" x2=\"10\" y2=\"18\"/><line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\"/>\n <polyline points=\"10,2 7.5,5\"/><polyline points=\"10,2 12.5,5\"/>\n <polyline points=\"18,10 15,7.5\"/><polyline points=\"18,10 15,12.5\"/>\n <polyline points=\"10,18 7.5,15\"/><polyline points=\"10,18 12.5,15\"/>\n <polyline points=\"2,10 5,7.5\"/><polyline points=\"2,10 5,12.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"rotate\" title=\"Rotate (E)\"\n @click=${() => this._setGizmoMode('rotate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <path d=\"M14.5 3.5A7 7 0 1 0 17 10\"/>\n <polyline points=\"14,1 15,3.5 12.5,4.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"scale\" title=\"Scale (R)\"\n @click=${() => this._setGizmoMode('scale')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"4\" y1=\"16\" x2=\"16\" y2=\"4\"/>\n <rect x=\"2\" y=\"13\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n <rect x=\"14\" y=\"2\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n </svg>\n </span>\n ` : ''}\n\n <span class=\"vline\"></span>\n\n <span button id=\"font-increase\" title=\"increase font size\" @click=${this.onTapFontIncrease}></span>\n <span button id=\"font-decrease\" title=\"decrease font size\" style=\"scale: 0.7;\" @click=${this.onTapFontDecrease}></span>\n\n <span class=\"vline\"></span>\n <span>(v${process.env['APP-VERSION']})</span>\n <span padding></span>\n\n <span button id=\"fit-scene\" title=\"fit scene (${this.getShortcutString('cmd', 'd')})\" @click=${this.onTapFitScene}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"preview\" title=\"preview (${this.getShortcutString('ctrl', 'p')})\" @click=${this.onTapPreview}> </span>\n\n <span button id=\"fullscreen\" title=\"fullscreen (${this.getShortcutString('f11')})\" @click=${this.onTapFullscreen}> </span>\n\n <span button id=\"toggle-property\"\n title=\"toggle property panel (${this.getShortcutString('cmd', 'h')})\"\n toggles=\"true\" @click=${this.onTapToggle}> </span>\n </div>\n `\n }\n\n hasEmptySlot() {\n const slot = this.renderRoot.querySelector('slot') as HTMLSlotElement\n return slot?.assignedNodes().length === 0\n }\n\n onWheelEvent(e: Event) {\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n getSymbol(key: string) {\n var symbol\n switch (key) {\n case 'cmd':\n case 'ctrl':\n symbol = MACOS ? '⌘' : 'Ctrl'\n break\n case 'shift':\n symbol = MACOS ? '⇧' : 'Shift'\n break\n case 'alt':\n case 'option':\n symbol = MACOS ? '⌥' : 'Alt'\n break\n case 'backspace':\n symbol = MACOS ? '⌫' : 'BackSpace'\n break\n case 'delete':\n symbol = MACOS ? '⌦' : 'Del'\n break\n default:\n symbol = key.toUpperCase()\n break\n }\n\n return symbol\n }\n\n private getShortcutString(...keys: string[]) {\n var symbols = []\n for (var i = 0; i < arguments.length; i++) {\n symbols.push(this.getSymbol(arguments[i]))\n }\n\n return symbols.join(MACOS ? '' : '+')\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n var altKey = e.altKey\n var shiftKey = e.shiftKey\n\n var defaultPrevent = ctrlKey || altKey\n\n switch (e.code) {\n case 'KeyZ':\n if (ctrlKey && !shiftKey) this.onTapUndo()\n else if (ctrlKey && shiftKey) this.onTapRedo()\n break\n case 'KeyY':\n if (ctrlKey && !shiftKey) this.onTapRedo()\n break\n case 'Digit1':\n if (ctrlKey) this.onStartStylePasteMode()\n break\n case 'Digit2':\n if (ctrlKey) this.onStartDatabindPasteMode()\n break\n case 'KeyC':\n if (ctrlKey && !shiftKey) this.onTapCopy()\n else if (altKey && shiftKey) this.onTapAlign('center')\n break\n case 'KeyX':\n if (ctrlKey && !shiftKey) this.onTapCut()\n break\n case 'KeyV':\n if (ctrlKey && !shiftKey) {\n this.onTapPaste()\n defaultPrevent = false\n } else if (altKey && shiftKey) this.onTapDistribute('VERTICAL')\n break\n case 'Delete':\n case 'Backspace':\n this.onTapDelete()\n defaultPrevent = true\n break\n case 'KeyG':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.onTapGroup()\n else if (ctrlKey && shiftKey) this.onTapUngroup()\n }\n break\n case 'KeyF':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.scene?.zorder('forward')\n else if (ctrlKey && shiftKey) this.scene?.zorder('front')\n }\n break\n case 'KeyB':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.scene?.zorder('backward')\n else if (ctrlKey && shiftKey) this.scene?.zorder('back')\n }\n if (altKey && shiftKey) this.onTapAlign('bottom')\n break\n case 'KeyH':\n if (ctrlKey && !shiftKey) this.onTapToggle()\n else if (altKey && shiftKey) this.onTapDistribute('HORIZONTAL')\n break\n case 'F11':\n this.onTapFullscreen()\n defaultPrevent = true\n break\n case 'KeyP':\n if (ctrlKey) {\n this.onTapPreview()\n defaultPrevent = true\n }\n break\n case 'KeyA':\n if (ctrlKey) this.onTapSelectAll()\n break\n case 'KeyL':\n if (altKey && shiftKey) this.onTapAlign('left')\n break\n case 'KeyR':\n if (altKey && shiftKey) this.onTapAlign('right')\n break\n case 'KeyM':\n if (altKey && shiftKey) this.onTapAlign('middle')\n break\n case 'KeyT':\n if (altKey && shiftKey) this.onTapAlign('top')\n break\n case 'KeyD':\n if (ctrlKey) {\n this.onTapFitScene()\n defaultPrevent = true\n }\n break\n case 'KeyE':\n if (ctrlKey && shiftKey) this.onTapDownloadModel()\n break\n\n case 'Escape':\n this.scene?.stopStylePasteMode()\n this.scene?.stopDatabindPasteMode()\n defaultPrevent = true\n break\n\n default:\n return false\n }\n\n if (defaultPrevent) e.preventDefault()\n return true\n }\n\n private _setDisabled(id: string, disabled: boolean) {\n const el = this.renderRoot.querySelector(`#${id}`)\n disabled ? el?.setAttribute('disabled', '') : el?.removeAttribute('disabled')\n }\n\n onExecute(command: string, undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onUndo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onRedo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onSceneChanged(after?: Scene, before?: Scene) {\n if (before) {\n before.off('execute', this.onExecute, this)\n before.off('undo', this.onUndo, this)\n before.off('redo', this.onRedo, this)\n before.off('dimension', this._onDimensionChanged, this)\n before.off('gizmoattach', this._onGizmoAttachChanged, this)\n }\n\n if (after) {\n after.on('execute', this.onExecute, this)\n after.on('undo', this.onUndo, this)\n after.on('redo', this.onRedo, this)\n after.on('dimension', this._onDimensionChanged, this)\n after.on('gizmoattach', this._onGizmoAttachChanged, this)\n\n // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)\n const threed = (after as any).model_layer?.model?.threed\n this._dimension = threed ? '3d' : '2d'\n }\n }\n\n private _onDimensionChanged(dimension: '2d' | '3d') {\n this._dimension = dimension\n }\n\n private _onGizmoAttachChanged(isAttached: boolean) {\n this._gizmoAttached = isAttached\n }\n\n private _setGizmoMode(mode: 'translate' | 'rotate' | 'scale') {\n ;(this.scene?.root as any)?.setGizmoMode(mode)\n }\n\n onSelectedChanged(after: Component[], before: Component[]) {\n var hasSelection = after.length > 0\n var alignable = after.length > 1\n\n // 선택 필요 버튼\n ;['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id =>\n this._setDisabled(id, !hasSelection)\n )\n\n // 정렬 버튼\n this.renderRoot.querySelectorAll('[data-align]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '2d') {\n var movable = after.length === 1\n\n /* forward, backward 이동은 한 컴포넌트만 가능하다. */\n this._setDisabled('forward', !movable)\n this._setDisabled('backward', !movable)\n\n /* 여러 컴포넌트는 front, back 이동이 가능하다. */\n this._setDisabled('front', !(alignable || movable))\n this._setDisabled('back', !(alignable || movable))\n }\n\n // 분배 버튼\n this.renderRoot.querySelectorAll('[data-distribute]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '3d') {\n this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {\n hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '')\n })\n }\n }\n\n onTapUndo() {\n this.scene?.undo()\n }\n\n onTapRedo() {\n this.scene?.redo()\n }\n\n onStartStylePasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startStylePasteMode()\n }\n\n onStartDatabindPasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startDatabindPasteMode()\n }\n\n onTapCut() {\n this.scene?.cut()\n }\n\n async onTapCopy() {\n var copied = this.scene?.copy()\n\n if (!copied) return\n\n await copyToClipboard(copied)\n this.cliped = copied\n }\n\n onTapPaste() {\n setTimeout(() => {\n this.cliped && this.scene?.paste(this.cliped)\n }, 100)\n }\n\n onTapDelete() {\n this.scene?.remove()\n }\n\n onTapSelectAll() {\n this.scene?.select('(child)')\n }\n\n onTapFontIncrease(e: TouchEvent) {\n var selected = this.scene?.selected\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n component.set('fontSize', size + 1)\n }\n })\n })\n }\n\n onTapFontDecrease(e: TouchEvent) {\n var selected = this.scene?.selected\n\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n if (size > 1) component.set('fontSize', size - 1)\n }\n })\n })\n }\n\n onTapAlign(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n\n var align = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-align')\n if (!align) {\n return\n }\n\n if (selected.length <= 1) {\n this.scene.place(align)\n } else {\n this.scene.align(align)\n }\n }\n\n onTapZorder(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length < 1) return\n\n var zorder = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-zorder')\n\n zorder && this.scene.zorder(zorder)\n }\n\n onTapGroup() {\n this.scene && this.scene.group()\n }\n\n onTapUngroup() {\n this.scene && this.scene.ungroup()\n }\n\n onTapFullscreen() {\n this.dispatchEvent(new CustomEvent('modeller-fullscreen'))\n }\n\n onTapToggle() {\n this.hideProperty = !this.hideProperty\n this.dispatchEvent(\n new CustomEvent('hide-property-changed', {\n bubbles: true,\n composed: true,\n detail: { value: this.hideProperty }\n })\n )\n }\n\n onTapFitScene() {\n if (this.scene) {\n this.scene.resize()\n this.scene.fit('ratio')\n }\n }\n\n onTapPreview() {\n this.dispatchEvent(new CustomEvent('open-preview'))\n }\n\n onTapDownloadModel() {\n this.dispatchEvent(new CustomEvent('download-model'))\n }\n\n onTapDistribute(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length <= 1) {\n return\n }\n\n var distribute = typeof e === 'string' ? e : (e.target as HTMLElement)!.getAttribute('data-distribute')\n\n distribute && this.scene.distribute(distribute)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"edit-toolbar.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { html, LitElement, PropertyValues } from 'lit'\nimport { property, state } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { copyToClipboard, isMacOS } from '@operato/utils'\nimport { OxPopup } from '@operato/popup'\n\nimport { style } from './edit-toolbar-style'\nimport './bulk-create-dialog.js'\nimport type { BulkCreateDialog } from './bulk-create-dialog.js'\nimport { parentObjectForTemplate } from './property-sidebar/specifics/parent-object.js'\n\nconst MACOS = isMacOS()\n\n/**\n * 컴포넌트 model JSON 만으로 type-aware bounding box (width, height) 추출.\n *\n * things-scene 의 component.bounds 는 *path 의 bounding box* 인데, model JSON 만\n * 으로는 path 를 그릴 수 없으므로 type-specific 필드를 직접 본다.\n * - width/height 명시 (Rect, Container 등) → 그대로\n * - rx/ry (Ellipse 등) → 2*rx, 2*ry\n * - points 배열 (Line, Polygon 등) → 점들의 bounding box\n * - 그 외 → 50x50 fallback\n *\n * bulk-paste 가 영역 안에 N 개 복제할 때 *원본 크기를 보존* 하기 위해 사용.\n */\nfunction deriveBoundsFromModel(model: Record<string, any>): { width: number; height: number } {\n if (typeof model.width === 'number' && typeof model.height === 'number') {\n return { width: model.width, height: model.height }\n }\n if (typeof model.rx === 'number' && typeof model.ry === 'number') {\n return { width: 2 * Math.abs(model.rx), height: 2 * Math.abs(model.ry) }\n }\n if (Array.isArray(model.points) && model.points.length > 0) {\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (const p of model.points) {\n if (typeof p?.x === 'number') {\n if (p.x < minX) minX = p.x\n if (p.x > maxX) maxX = p.x\n }\n if (typeof p?.y === 'number') {\n if (p.y < minY) minY = p.y\n if (p.y > maxY) maxY = p.y\n }\n }\n if (isFinite(minX) && isFinite(maxX) && isFinite(minY) && isFinite(maxY)) {\n return { width: maxX - minX, height: maxY - minY }\n }\n }\n return { width: 50, height: 50 }\n}\n\nexport class EditToolbar extends LitElement {\n static styles = [style]\n\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: any[] = []\n @property({ type: Boolean }) hideProperty: boolean = false\n\n @state() private _dimension: '2d' | '3d' | null = null\n @state() private _gizmoAttached = false\n\n private cliped?: string\n\n firstUpdated() {\n this.addEventListener('mousewheel', this.onWheelEvent.bind(this) as EventListener, false)\n\n // 툴바 버튼 클릭 후 씬으로 포커스를 돌려서 키보드 단축키가 계속 작동하도록 한다\n this.addEventListener('click', () => {\n ;(this.scene?.root as any)?.element?.focus()\n })\n\n window.addEventListener('paste', (e: Event) => {\n try {\n this.cliped = (e as ClipboardEvent).clipboardData?.getData('text/plain')\n } catch (e) {\n console.error('model paste failed', e)\n }\n })\n // 모든 버튼은 템플릿 @click 디렉티브로 바인딩 — 조건부 렌더링 시에도 정상 작동\n }\n\n updated(changes: PropertyValues<this>) {\n changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene') as Scene)\n changes.has('selected') && this.onSelectedChanged(this.selected, changes.get('selected') as Component[])\n }\n\n render() {\n return html`\n <div tools>\n <span><slot></slot></span>\n\n ${this.hasEmptySlot() ? html`` : html`<span class=\"vline\"></span>`}\n\n <span button id=\"undo\" title=\"undo (${this.getShortcutString('cmd', 'z')})\" @click=${this.onTapUndo}> </span>\n <span button id=\"redo\" title=\"redo (${this.getShortcutString('cmd', 'shift', 'z')})\" @click=${this.onTapRedo}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"style-copy\" title=\"style copy (${this.getShortcutString('cmd', '1')})\" @click=${this.onStartStylePasteMode}> </span>\n <span button id=\"databind-copy\" title=\"databind copy (${this.getShortcutString('cmd', '2')})\" @click=${this.onStartDatabindPasteMode}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"cut\" title=\"cut (${this.getShortcutString('cmd', 'x')})\" @click=${this.onTapCut}> </span>\n <span button id=\"copy\" title=\"copy (${this.getShortcutString('cmd', 'c')})\" @click=${this.onTapCopy}> </span>\n <span button id=\"paste\" title=\"paste (${this.getShortcutString('cmd', 'v')})\" @click=${this.onTapPaste}> </span>\n <span button id=\"delete\"\n title=\"delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})\"\n @click=${this.onTapDelete}> </span>\n\n <span class=\"vline\"></span>\n\n <span button data-align=\"left\" id=\"align-left\"\n title=\"align left (${this.getShortcutString('alt', 'shift', 'l')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"center\" id=\"align-center\"\n title=\"align center (${this.getShortcutString('alt', 'shift', 'c')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"right\" id=\"align-right\"\n title=\"align right (${this.getShortcutString('alt', 'shift', 'r')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-align=\"top\" id=\"align-top\"\n title=\"align top (${this.getShortcutString('alt', 'shift', 't')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"middle\" id=\"align-middle\"\n title=\"align middle (${this.getShortcutString('alt', 'shift', 'm')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"bottom\" id=\"align-bottom\"\n title=\"align bottom (${this.getShortcutString('alt', 'shift', 'b')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-distribute=\"HORIZONTAL\" id=\"distribute-horizontal\"\n title=\"distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})\" @click=${this.onTapDistribute}> </span>\n <span button data-distribute=\"VERTICAL\" id=\"distribute-vertical\"\n title=\"distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})\" @click=${this.onTapDistribute}> </span>\n\n ${this._dimension === '3d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button data-align=\"z-front\" id=\"align-z-front\" title=\"align Z front\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-middle\" id=\"align-z-middle\" title=\"align Z middle\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-back\" id=\"align-z-back\" title=\"align Z back\" @click=${this.onTapAlign}> </span>\n <span button data-distribute=\"Z\" id=\"distribute-z\" title=\"distribute Z\" @click=${this.onTapDistribute}> </span>\n `\n : this._dimension === '2d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"front\" data-zorder=\"front\"\n title=\"bring to front (${this.getShortcutString('cmd', 'shift', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"back\" data-zorder=\"back\"\n title=\"send to back (${this.getShortcutString('cmd', 'shift', 'b')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"forward\" data-zorder=\"forward\"\n title=\"bring forward (${this.getShortcutString('cmd', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"backward\" data-zorder=\"backward\"\n title=\"send backward (${this.getShortcutString('cmd', 'b')})\" @click=${this.onTapZorder}> </span>\n `\n : ''}\n\n ${this._dimension === '2d' ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"group\" title=\"group (${this.getShortcutString('cmd', 'g')})\" @click=${this.onTapGroup}> </span>\n <span button id=\"ungroup\" title=\"ungroup (${this.getShortcutString('cmd', 'shift', 'g')})\" @click=${this.onTapUngroup}> </span>\n ` : this._dimension === '3d' ? html`\n <span class=\"vline\"></span>\n\n <span button class=\"gizmo-btn\" data-gizmo=\"translate\" title=\"Move (W)\"\n @click=${() => this._setGizmoMode('translate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"10\" y1=\"2\" x2=\"10\" y2=\"18\"/><line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\"/>\n <polyline points=\"10,2 7.5,5\"/><polyline points=\"10,2 12.5,5\"/>\n <polyline points=\"18,10 15,7.5\"/><polyline points=\"18,10 15,12.5\"/>\n <polyline points=\"10,18 7.5,15\"/><polyline points=\"10,18 12.5,15\"/>\n <polyline points=\"2,10 5,7.5\"/><polyline points=\"2,10 5,12.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"rotate\" title=\"Rotate (E)\"\n @click=${() => this._setGizmoMode('rotate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <path d=\"M14.5 3.5A7 7 0 1 0 17 10\"/>\n <polyline points=\"14,1 15,3.5 12.5,4.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"scale\" title=\"Scale (R)\"\n @click=${() => this._setGizmoMode('scale')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"4\" y1=\"16\" x2=\"16\" y2=\"4\"/>\n <rect x=\"2\" y=\"13\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n <rect x=\"14\" y=\"2\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n </svg>\n </span>\n ` : ''}\n\n <span class=\"vline\"></span>\n\n <span button id=\"font-increase\" title=\"increase font size\" @click=${this.onTapFontIncrease}></span>\n <span button id=\"font-decrease\" title=\"decrease font size\" style=\"scale: 0.7;\" @click=${this.onTapFontDecrease}></span>\n\n <span class=\"vline\"></span>\n <span>(v${process.env['APP-VERSION']})</span>\n <span padding></span>\n\n <span button id=\"fit-scene\" title=\"fit scene (${this.getShortcutString('cmd', 'd')})\" @click=${this.onTapFitScene}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"preview\" title=\"preview (${this.getShortcutString('ctrl', 'p')})\" @click=${this.onTapPreview}> </span>\n\n <span button id=\"fullscreen\" title=\"fullscreen (${this.getShortcutString('f11')})\" @click=${this.onTapFullscreen}> </span>\n\n <span button id=\"toggle-property\"\n title=\"toggle property panel (${this.getShortcutString('cmd', 'h')})\"\n toggles=\"true\" @click=${this.onTapToggle}> </span>\n </div>\n `\n }\n\n hasEmptySlot() {\n const slot = this.renderRoot.querySelector('slot') as HTMLSlotElement\n return slot?.assignedNodes().length === 0\n }\n\n onWheelEvent(e: Event) {\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n getSymbol(key: string) {\n var symbol\n switch (key) {\n case 'cmd':\n case 'ctrl':\n symbol = MACOS ? '⌘' : 'Ctrl'\n break\n case 'shift':\n symbol = MACOS ? '⇧' : 'Shift'\n break\n case 'alt':\n case 'option':\n symbol = MACOS ? '⌥' : 'Alt'\n break\n case 'backspace':\n symbol = MACOS ? '⌫' : 'BackSpace'\n break\n case 'delete':\n symbol = MACOS ? '⌦' : 'Del'\n break\n default:\n symbol = key.toUpperCase()\n break\n }\n\n return symbol\n }\n\n private getShortcutString(...keys: string[]) {\n var symbols = []\n for (var i = 0; i < arguments.length; i++) {\n symbols.push(this.getSymbol(arguments[i]))\n }\n\n return symbols.join(MACOS ? '' : '+')\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n var altKey = e.altKey\n var shiftKey = e.shiftKey\n\n var defaultPrevent = ctrlKey || altKey\n\n switch (e.code) {\n case 'KeyZ':\n if (ctrlKey && !shiftKey) this.onTapUndo()\n else if (ctrlKey && shiftKey) this.onTapRedo()\n break\n case 'KeyY':\n if (ctrlKey && !shiftKey) this.onTapRedo()\n break\n case 'Digit1':\n if (ctrlKey) this.onStartStylePasteMode()\n break\n case 'Digit2':\n if (ctrlKey) this.onStartDatabindPasteMode()\n break\n case 'KeyC':\n if (ctrlKey && !shiftKey) this.onTapCopy()\n else if (altKey && shiftKey) this.onTapAlign('center')\n break\n case 'KeyX':\n if (ctrlKey && !shiftKey) this.onTapCut()\n break\n case 'KeyV':\n if (ctrlKey && shiftKey && !altKey) {\n // Ctrl+Shift+V = Bulk Paste (Paste Special 컨벤션) — 클립보드의\n // 단일 컴포넌트를 N개로 일괄 붙여넣기.\n this.onBulkPaste()\n defaultPrevent = true\n } else if (ctrlKey && !shiftKey) {\n this.onTapPaste()\n defaultPrevent = false\n } else if (altKey && shiftKey) this.onTapDistribute('VERTICAL')\n break\n case 'Delete':\n case 'Backspace':\n this.onTapDelete()\n defaultPrevent = true\n break\n case 'KeyG':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.onTapGroup()\n else if (ctrlKey && shiftKey) this.onTapUngroup()\n }\n break\n case 'BracketRight':\n // Ctrl+] = Bring Forward, Ctrl+Shift+] = Bring to Front\n // (Photoshop / Illustrator 표준 컨벤션)\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) {\n this.scene?.zorder('forward')\n defaultPrevent = true\n } else if (ctrlKey && shiftKey) {\n this.scene?.zorder('front')\n defaultPrevent = true\n }\n }\n break\n case 'BracketLeft':\n // Ctrl+[ = Send Backward, Ctrl+Shift+[ = Send to Back\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) {\n this.scene?.zorder('backward')\n defaultPrevent = true\n } else if (ctrlKey && shiftKey) {\n this.scene?.zorder('back')\n defaultPrevent = true\n }\n }\n break\n case 'KeyB':\n // zorder 는 BracketLeft 로 이동. KeyB 의 Alt+Shift+B = align bottom 만 유지.\n if (altKey && shiftKey) this.onTapAlign('bottom')\n break\n case 'KeyH':\n if (ctrlKey && !shiftKey) this.onTapToggle()\n else if (altKey && shiftKey) this.onTapDistribute('HORIZONTAL')\n break\n case 'F11':\n this.onTapFullscreen()\n defaultPrevent = true\n break\n case 'KeyP':\n if (ctrlKey) {\n this.onTapPreview()\n defaultPrevent = true\n }\n break\n case 'KeyA':\n if (ctrlKey) this.onTapSelectAll()\n break\n case 'KeyL':\n if (altKey && shiftKey) this.onTapAlign('left')\n break\n case 'KeyR':\n if (altKey && shiftKey) this.onTapAlign('right')\n break\n case 'KeyM':\n if (altKey && shiftKey) this.onTapAlign('middle')\n break\n case 'KeyT':\n if (altKey && shiftKey) this.onTapAlign('top')\n break\n case 'KeyD':\n if (ctrlKey) {\n this.onTapFitScene()\n defaultPrevent = true\n }\n break\n case 'KeyE':\n if (ctrlKey && shiftKey) this.onTapDownloadModel()\n break\n\n case 'Escape':\n this.scene?.stopStylePasteMode()\n this.scene?.stopDatabindPasteMode()\n defaultPrevent = true\n break\n\n default:\n return false\n }\n\n if (defaultPrevent) e.preventDefault()\n return true\n }\n\n private _setDisabled(id: string, disabled: boolean) {\n const el = this.renderRoot.querySelector(`#${id}`)\n disabled ? el?.setAttribute('disabled', '') : el?.removeAttribute('disabled')\n }\n\n onExecute(command: string, undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onUndo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onRedo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onSceneChanged(after?: Scene, before?: Scene) {\n if (before) {\n before.off('execute', this.onExecute, this)\n before.off('undo', this.onUndo, this)\n before.off('redo', this.onRedo, this)\n before.off('dimension', this._onDimensionChanged, this)\n before.off('gizmoattach', this._onGizmoAttachChanged, this)\n }\n\n if (after) {\n after.on('execute', this.onExecute, this)\n after.on('undo', this.onUndo, this)\n after.on('redo', this.onRedo, this)\n after.on('dimension', this._onDimensionChanged, this)\n after.on('gizmoattach', this._onGizmoAttachChanged, this)\n\n // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)\n const threed = (after as any).model_layer?.model?.threed\n this._dimension = threed ? '3d' : '2d'\n }\n }\n\n private _onDimensionChanged(dimension: '2d' | '3d') {\n this._dimension = dimension\n }\n\n private _onGizmoAttachChanged(isAttached: boolean) {\n this._gizmoAttached = isAttached\n }\n\n private _setGizmoMode(mode: 'translate' | 'rotate' | 'scale') {\n ;(this.scene?.root as any)?.setGizmoMode(mode)\n }\n\n onSelectedChanged(after: Component[], before: Component[]) {\n var hasSelection = after.length > 0\n var alignable = after.length > 1\n\n // 선택 필요 버튼\n ;['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id =>\n this._setDisabled(id, !hasSelection)\n )\n\n // 정렬 버튼\n this.renderRoot.querySelectorAll('[data-align]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '2d') {\n var movable = after.length === 1\n\n /* forward, backward 이동은 한 컴포넌트만 가능하다. */\n this._setDisabled('forward', !movable)\n this._setDisabled('backward', !movable)\n\n /* 여러 컴포넌트는 front, back 이동이 가능하다. */\n this._setDisabled('front', !(alignable || movable))\n this._setDisabled('back', !(alignable || movable))\n }\n\n // 분배 버튼\n this.renderRoot.querySelectorAll('[data-distribute]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '3d') {\n this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {\n hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '')\n })\n }\n }\n\n onTapUndo() {\n this.scene?.undo()\n }\n\n onTapRedo() {\n this.scene?.redo()\n }\n\n onStartStylePasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startStylePasteMode()\n }\n\n onStartDatabindPasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startDatabindPasteMode()\n }\n\n onTapCut() {\n this.scene?.cut()\n }\n\n async onTapCopy() {\n var copied = this.scene?.copy()\n\n if (!copied) return\n\n await copyToClipboard(copied)\n this.cliped = copied\n }\n\n onTapPaste() {\n setTimeout(() => {\n this.cliped && this.scene?.paste(this.cliped)\n }, 100)\n }\n\n onTapDelete() {\n this.scene?.remove()\n }\n\n /**\n * 멀티 컴포넌트 일괄 붙여넣기 — Ctrl+Shift+V 진입점.\n *\n * 흐름:\n * 1. 클립보드 (this.cliped) 검증 — *단일* 컴포넌트만 허용\n * 2. scene.startBulkCreateMode → AddLayer 가 캔버스 위에 드래그 박스 그림\n * 3. 사용자가 영역 드래그 → Promise resolve({area, template})\n * ESC/취소 → Promise resolve(null)\n * 4. 영역이 결정되면 dialog 오픈\n */\n async onBulkPaste() {\n if (!this.cliped) {\n console.warn('bulk-paste: 먼저 Ctrl+C 로 컴포넌트를 복사하세요.')\n return\n }\n let parsed: any[]\n try {\n parsed = JSON.parse(this.cliped)\n } catch (e) {\n console.warn('bulk-paste: 클립보드 파싱 실패', e)\n return\n }\n if (!Array.isArray(parsed) || parsed.length === 0) {\n console.warn('bulk-paste: 클립보드 비어있음')\n return\n }\n if (parsed.length > 1) {\n console.warn('bulk-paste: 단일 컴포넌트만 일괄 붙여넣기 가능. 다중은 일반 paste 사용.')\n return\n }\n\n const template = parsed[0]\n // bulk 모드 임을 시각 구분하기 위해 파란 점선 (일반 add 의 검정과 색만 차별).\n const result = await this.scene?.startBulkCreateMode(template, { boxStrokeStyle: '#2964c2' })\n if (result) {\n this._openBulkCreateDialog(template, result.area)\n }\n }\n\n private _openBulkCreateDialog(\n template: Record<string, any>,\n initialArea: { left: number; top: number; width: number; height: number }\n ) {\n const dialogEl = document.createElement('bulk-create-dialog') as BulkCreateDialog\n dialogEl.template = template\n dialogEl.initialArea = initialArea\n // 충돌 검사용 — scene 의 모든 컴포넌트 id 수집.\n // (scene.ids 는 indexMap 기반인데 fmsim 의 일부 컴포넌트는 indexMap 미등록\n // 되는 케이스가 있어 직접 컴포넌트 트리 walk.)\n const existingIds = new Set<string>()\n const collectIds = (comp: any) => {\n if (!comp) return\n const id = comp?.state?.id ?? comp?.model?.id\n if (typeof id === 'string' && id) existingIds.add(id)\n const children = comp.components || []\n for (const c of children) collectIds(c)\n }\n const root = (this.scene as any)?.root\n if (root) collectIds(root)\n dialogEl.existingIds = existingIds\n\n // parentObject 커스터마이징: template 타입이 ParentObjectMixin 이면 상위객체 선택 필드 노출.\n // 후보 리스트는 타입의 parentObjectTypes 기준으로 씬에서 수집 (속성창과 동일 로직 재사용).\n const { has, items } = parentObjectForTemplate(template, root)\n dialogEl.hasParentObject = has\n dialogEl.parentObjectItems = items\n\n dialogEl.onConfirm = (models) => {\n const scene = this.scene\n if (!scene || !models.length) {\n popup?.close()\n return\n }\n // cliped 의 template model 자체에서 type-aware bounds 추출. things-scene 의\n // component.bounds (= path bounding box) 와 동일 결과를 model JSON 의\n // type-specific 필드 (width/height, rx/ry, points) 만으로 계산.\n const bounds = deriveBoundsFromModel(template)\n scene.undoableChange(() => {\n for (const m of models) {\n const cx = m.left + m.width / 2\n const cy = m.top + m.height / 2\n scene.add(m, {\n left: cx - bounds.width / 2,\n top: cy - bounds.height / 2,\n width: bounds.width,\n height: bounds.height\n })\n }\n })\n popup?.close()\n }\n dialogEl.onCancel = () => {\n popup?.close()\n }\n const popup = OxPopup.open({\n template: dialogEl,\n backdrop: true,\n // 내부 입력(parentObject 검색 드롭다운 등)이 blur/focusout 될 때 팝업이 자동으로\n // 닫히지 않도록. 닫기는 OK/취소 버튼 또는 backdrop/Escape 로만.\n preventCloseOnBlur: true\n })\n }\n\n onTapSelectAll() {\n this.scene?.select('(child)')\n }\n\n onTapFontIncrease(e: TouchEvent) {\n var selected = this.scene?.selected\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n component.set('fontSize', size + 1)\n }\n })\n })\n }\n\n onTapFontDecrease(e: TouchEvent) {\n var selected = this.scene?.selected\n\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n if (size > 1) component.set('fontSize', size - 1)\n }\n })\n })\n }\n\n onTapAlign(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n\n var align = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-align')\n if (!align) {\n return\n }\n\n if (selected.length <= 1) {\n this.scene.place(align)\n } else {\n this.scene.align(align)\n }\n }\n\n onTapZorder(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length < 1) return\n\n var zorder = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-zorder')\n\n zorder && this.scene.zorder(zorder)\n }\n\n onTapGroup() {\n this.scene && this.scene.group()\n }\n\n onTapUngroup() {\n this.scene && this.scene.ungroup()\n }\n\n onTapFullscreen() {\n this.dispatchEvent(new CustomEvent('modeller-fullscreen'))\n }\n\n onTapToggle() {\n this.hideProperty = !this.hideProperty\n this.dispatchEvent(\n new CustomEvent('hide-property-changed', {\n bubbles: true,\n composed: true,\n detail: { value: this.hideProperty }\n })\n )\n }\n\n onTapFitScene() {\n if (this.scene) {\n this.scene.resize()\n this.scene.fit('ratio')\n }\n }\n\n onTapPreview() {\n this.dispatchEvent(new CustomEvent('open-preview'))\n }\n\n onTapDownloadModel() {\n this.dispatchEvent(new CustomEvent('download-model'))\n }\n\n onTapDistribute(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length <= 1) {\n return\n }\n\n var distribute = typeof e === 'string' ? e : (e.target as HTMLElement)!.getAttribute('data-distribute')\n\n distribute && this.scene.distribute(distribute)\n }\n}\n"]}
|
|
@@ -23,9 +23,17 @@ export class AbstractProperty extends LitElement {
|
|
|
23
23
|
case 'checkbox':
|
|
24
24
|
value = element.checked;
|
|
25
25
|
break;
|
|
26
|
-
case 'number':
|
|
27
|
-
|
|
26
|
+
case 'number': {
|
|
27
|
+
// Empty or invalid numeric input (e.g. user cleared the field)
|
|
28
|
+
// produces NaN via `valueAsNumber`. Persisting NaN poisons every
|
|
29
|
+
// downstream Math.* call and eventually surfaces as
|
|
30
|
+
// "BufferGeometry computeBoundingSphere: radius is NaN".
|
|
31
|
+
// Emit `undefined` so the component falls back to its default
|
|
32
|
+
// (e.g. Placeable's defaultDepth = operation - floor).
|
|
33
|
+
const n = element.valueAsNumber;
|
|
34
|
+
value = Number.isFinite(n) ? n : undefined;
|
|
28
35
|
break;
|
|
36
|
+
}
|
|
29
37
|
case 'text':
|
|
30
38
|
value = String(element.value);
|
|
31
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-property.js","sourceRoot":"","sources":["../../../../src/modeller/property-sidebar/abstract-property.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAEhC,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,IAAI,OAAO,GAAG,CAAC,CAAC,MAAqB,CAAA;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAE3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QAED,IAAI,KAAK,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;QAElD,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,wBAAwB,CAAC,OAAoB;QAC3C,IAAI,KAAK,CAAA;QAET,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;YACxB,KAAK,OAAO;gBACV,QAAS,OAAe,CAAC,IAAI,EAAE,CAAC;oBAC9B,KAAK,UAAU;wBACb,KAAK,GAAI,OAAe,CAAC,OAAO,CAAA;wBAChC,MAAK;oBACP,KAAK,QAAQ;
|
|
1
|
+
{"version":3,"file":"abstract-property.js","sourceRoot":"","sources":["../../../../src/modeller/property-sidebar/abstract-property.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAEhC,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,IAAI,OAAO,GAAG,CAAC,CAAC,MAAqB,CAAA;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAE3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QAED,IAAI,KAAK,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;QAElD,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,wBAAwB,CAAC,OAAoB;QAC3C,IAAI,KAAK,CAAA;QAET,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;YACxB,KAAK,OAAO;gBACV,QAAS,OAAe,CAAC,IAAI,EAAE,CAAC;oBAC9B,KAAK,UAAU;wBACb,KAAK,GAAI,OAAe,CAAC,OAAO,CAAA;wBAChC,MAAK;oBACP,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACd,+DAA+D;wBAC/D,iEAAiE;wBACjE,oDAAoD;wBACpD,yDAAyD;wBACzD,8DAA8D;wBAC9D,uDAAuD;wBACvD,MAAM,CAAC,GAAI,OAAe,CAAC,aAAa,CAAA;wBACxC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;wBAC1C,MAAK;oBACP,CAAC;oBACD,KAAK,MAAM;wBACT,KAAK,GAAG,MAAM,CAAE,OAAe,CAAC,KAAK,CAAC,CAAA;gBAC1C,CAAC;gBACD,MAAK;YAEP,KAAK,cAAc;gBACjB,KAAK,GAAI,OAAe,CAAC,MAAM,CAAA;gBAC/B,MAAK;YAEP,KAAK,eAAe;gBAClB,KAAK,GAAI,OAAe,CAAC,QAAQ,CAAA;gBACjC,MAAK;YAEP;gBACE,KAAK,GAAI,OAAe,CAAC,KAAK,CAAA;gBAC9B,MAAK;QACT,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,mBAAmB,CAAC,GAAW,EAAE,KAAU;QACzC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;YACjC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,CAAC,GAAG,CAAC,EAAE,KAAK;aACb;SACF,CAAC,CACH,CAAA;IACH,CAAC;CACF","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { LitElement } from 'lit'\n\nexport class AbstractProperty extends LitElement {\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n _onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this._getValueFromEventTarget(element)\n\n this._onAfterValueChange(key, value)\n }\n\n _getValueFromEventTarget(element: HTMLElement) {\n var value\n\n switch (element.tagName) {\n case 'INPUT':\n switch ((element as any).type) {\n case 'checkbox':\n value = (element as any).checked\n break\n case 'number': {\n // Empty or invalid numeric input (e.g. user cleared the field)\n // produces NaN via `valueAsNumber`. Persisting NaN poisons every\n // downstream Math.* call and eventually surfaces as\n // \"BufferGeometry computeBoundingSphere: radius is NaN\".\n // Emit `undefined` so the component falls back to its default\n // (e.g. Placeable's defaultDepth = operation - floor).\n const n = (element as any).valueAsNumber\n value = Number.isFinite(n) ? n : undefined\n break\n }\n case 'text':\n value = String((element as any).value)\n }\n break\n\n case 'PAPER-BUTTON':\n value = (element as any).active\n break\n\n case 'PAPER-LISTBOX':\n value = (element as any).selected\n break\n\n default:\n value = (element as any).value\n break\n }\n\n return value\n }\n\n _onAfterValueChange(key: string, value: any) {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n [key]: value\n }\n })\n )\n }\n}\n"]}
|
|
@@ -9,7 +9,7 @@ import { PropertyValues } from 'lit';
|
|
|
9
9
|
import { Properties, Scene } from '@hatiolab/things-scene';
|
|
10
10
|
import { AbstractProperty } from '../abstract-property.js';
|
|
11
11
|
import { DataBindingMapper } from './data-binding-mapper.js';
|
|
12
|
-
declare const PropertyDataBinding_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types
|
|
12
|
+
declare const PropertyDataBinding_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
|
|
13
13
|
export declare class PropertyDataBinding extends PropertyDataBinding_base {
|
|
14
14
|
static styles: import("lit").CSSResult[];
|
|
15
15
|
value?: Properties;
|
|
@@ -6,7 +6,7 @@ import { Component, Properties, Scene } from '@hatiolab/things-scene';
|
|
|
6
6
|
import { AbstractProperty } from '../abstract-property.js';
|
|
7
7
|
import { PropertyEvent } from './property-event.js';
|
|
8
8
|
import { PropertyShadow } from './property-shadow.js';
|
|
9
|
-
declare const PropertyEffects_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types
|
|
9
|
+
declare const PropertyEffects_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
|
|
10
10
|
export declare class PropertyEffects extends PropertyEffects_base {
|
|
11
11
|
static styles: import("lit").CSSResult[];
|
|
12
12
|
value?: Properties;
|
|
@@ -18,5 +18,14 @@ export declare class PropertyEffects extends PropertyEffects_base {
|
|
|
18
18
|
'property-event': typeof PropertyEvent;
|
|
19
19
|
};
|
|
20
20
|
render(): import("lit-html").TemplateResult<1>;
|
|
21
|
+
/**
|
|
22
|
+
* 3D 그림자 토글 — material3d.castShadow / receiveShadow 만 갱신.
|
|
23
|
+
*
|
|
24
|
+
* material3d 는 단일 객체 속성이므로 기존 material3d 전체를 보존한 채 해당
|
|
25
|
+
* 키만 덮어써 dispatch 한다 ({ castShadow } 만 보내면 set() 의 top-level shallow
|
|
26
|
+
* merge 로 material3d 전체가 사라짐). value-key 를 두지 않아 AbstractProperty
|
|
27
|
+
* 의 제너릭 change 핸들러는 이 입력을 무시한다.
|
|
28
|
+
*/
|
|
29
|
+
private _onShadow3dChange;
|
|
21
30
|
}
|
|
22
31
|
export {};
|
|
@@ -5,6 +5,7 @@ import { __decorate } from "tslib";
|
|
|
5
5
|
import '@operato/i18n/ox-i18n.js';
|
|
6
6
|
import { html, nothing } from 'lit';
|
|
7
7
|
import { property } from 'lit/decorators.js';
|
|
8
|
+
import { isThreedEnabled } from '@hatiolab/things-scene';
|
|
8
9
|
import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|
9
10
|
import { AbstractProperty } from '../abstract-property.js';
|
|
10
11
|
import { PropertySharedStyle } from '../property-shared-style.js';
|
|
@@ -25,7 +26,15 @@ export class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
render() {
|
|
29
|
+
var _a, _b, _c;
|
|
28
30
|
const value = this.value || {};
|
|
31
|
+
// 3D 그림자 편집은 단일 선택 + 3D 표현 가능한 컴포넌트에서만 노출.
|
|
32
|
+
// (material3d 는 컴포넌트별 객체라 다중 선택 일괄 병합은 위험 — 단일로 제한.)
|
|
33
|
+
const target = this.selected.length == 1 ? this.selected[0] : null;
|
|
34
|
+
const supports3d = !!((_a = target === null || target === void 0 ? void 0 : target.is3dish) === null || _a === void 0 ? void 0 : _a.call(target));
|
|
35
|
+
const material3d = value.material3d || {};
|
|
36
|
+
const castShadow = (_b = material3d.castShadow) !== null && _b !== void 0 ? _b : true;
|
|
37
|
+
const receiveShadow = (_c = material3d.receiveShadow) !== null && _c !== void 0 ? _c : false;
|
|
29
38
|
return html `
|
|
30
39
|
<fieldset>
|
|
31
40
|
<legend>
|
|
@@ -35,11 +44,68 @@ export class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {
|
|
|
35
44
|
<property-shadow value-key="shadow" .value=${value.shadow || {}}> </property-shadow>
|
|
36
45
|
</fieldset>
|
|
37
46
|
|
|
47
|
+
${supports3d && isThreedEnabled()
|
|
48
|
+
? html `
|
|
49
|
+
<fieldset>
|
|
50
|
+
<legend>
|
|
51
|
+
<ox-i18n topic="board-modeller/effects/shadow-3d" msgid="label.shadow-3d">3D shadow</ox-i18n>
|
|
52
|
+
</legend>
|
|
53
|
+
|
|
54
|
+
<div>
|
|
55
|
+
<input
|
|
56
|
+
id="cb-cast-shadow"
|
|
57
|
+
type="checkbox"
|
|
58
|
+
.checked=${castShadow}
|
|
59
|
+
@change=${(e) => this._onShadow3dChange('castShadow', e)}
|
|
60
|
+
/>
|
|
61
|
+
<label for="cb-cast-shadow">
|
|
62
|
+
<ox-i18n msgid="label.cast-shadow">cast shadow</ox-i18n>
|
|
63
|
+
</label>
|
|
64
|
+
|
|
65
|
+
<input
|
|
66
|
+
id="cb-receive-shadow"
|
|
67
|
+
type="checkbox"
|
|
68
|
+
.checked=${receiveShadow}
|
|
69
|
+
@change=${(e) => this._onShadow3dChange('receiveShadow', e)}
|
|
70
|
+
/>
|
|
71
|
+
<label for="cb-receive-shadow">
|
|
72
|
+
<ox-i18n msgid="label.receive-shadow">receive shadow</ox-i18n>
|
|
73
|
+
</label>
|
|
74
|
+
</div>
|
|
75
|
+
</fieldset>
|
|
76
|
+
`
|
|
77
|
+
: nothing}
|
|
78
|
+
|
|
38
79
|
${this.selected.length == 1
|
|
39
|
-
? html `
|
|
80
|
+
? html `
|
|
81
|
+
<property-event
|
|
82
|
+
value-key="eventHandlers"
|
|
83
|
+
.scene=${this.scene}
|
|
84
|
+
.value=${value.eventHandlers || []}
|
|
85
|
+
>
|
|
86
|
+
</property-event>
|
|
87
|
+
`
|
|
40
88
|
: nothing}
|
|
41
89
|
`;
|
|
42
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* 3D 그림자 토글 — material3d.castShadow / receiveShadow 만 갱신.
|
|
93
|
+
*
|
|
94
|
+
* material3d 는 단일 객체 속성이므로 기존 material3d 전체를 보존한 채 해당
|
|
95
|
+
* 키만 덮어써 dispatch 한다 ({ castShadow } 만 보내면 set() 의 top-level shallow
|
|
96
|
+
* merge 로 material3d 전체가 사라짐). value-key 를 두지 않아 AbstractProperty
|
|
97
|
+
* 의 제너릭 change 핸들러는 이 입력을 무시한다.
|
|
98
|
+
*/
|
|
99
|
+
_onShadow3dChange(key, e) {
|
|
100
|
+
var _a;
|
|
101
|
+
const checked = e.target.checked;
|
|
102
|
+
const current = ((_a = this.value) === null || _a === void 0 ? void 0 : _a.material3d) || {};
|
|
103
|
+
this.dispatchEvent(new CustomEvent('property-change', {
|
|
104
|
+
bubbles: true,
|
|
105
|
+
composed: true,
|
|
106
|
+
detail: { material3d: { ...current, [key]: checked } }
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
43
109
|
}
|
|
44
110
|
PropertyEffects.styles = [PropertySharedStyle];
|
|
45
111
|
__decorate([
|