@operato/image-marker 8.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.editorconfig +29 -0
  2. package/.storybook/main.js +3 -0
  3. package/.storybook/preview.js +52 -0
  4. package/.storybook/server.mjs +8 -0
  5. package/CHANGELOG.md +11 -0
  6. package/README.md +0 -0
  7. package/assets/images/no-image.png +0 -0
  8. package/demo/index.html +22 -0
  9. package/dist/src/base-image-marker.d.ts +24 -0
  10. package/dist/src/base-image-marker.js +137 -0
  11. package/dist/src/base-image-marker.js.map +1 -0
  12. package/dist/src/index.d.ts +0 -0
  13. package/dist/src/index.js +2 -0
  14. package/dist/src/index.js.map +1 -0
  15. package/dist/src/ox-image-marker-mode.d.ts +13 -0
  16. package/dist/src/ox-image-marker-mode.js +140 -0
  17. package/dist/src/ox-image-marker-mode.js.map +1 -0
  18. package/dist/src/ox-image-marker-view.d.ts +4 -0
  19. package/dist/src/ox-image-marker-view.js +26 -0
  20. package/dist/src/ox-image-marker-view.js.map +1 -0
  21. package/dist/src/ox-image-marker.d.ts +33 -0
  22. package/dist/src/ox-image-marker.js +583 -0
  23. package/dist/src/ox-image-marker.js.map +1 -0
  24. package/dist/src/types.d.ts +20 -0
  25. package/dist/src/types.js +2 -0
  26. package/dist/src/types.js.map +1 -0
  27. package/dist/stories/ox-image-marker-mode.stories.d.ts +16 -0
  28. package/dist/stories/ox-image-marker-mode.stories.js +31 -0
  29. package/dist/stories/ox-image-marker-mode.stories.js.map +1 -0
  30. package/dist/stories/ox-image-marker-view.stories.d.ts +41 -0
  31. package/dist/stories/ox-image-marker-view.stories.js +103 -0
  32. package/dist/stories/ox-image-marker-view.stories.js.map +1 -0
  33. package/dist/stories/ox-image-marker.stories.d.ts +33 -0
  34. package/dist/stories/ox-image-marker.stories.js +86 -0
  35. package/dist/stories/ox-image-marker.stories.js.map +1 -0
  36. package/dist/tsconfig.tsbuildinfo +1 -0
  37. package/package.json +97 -0
  38. package/src/base-image-marker.ts +144 -0
  39. package/src/index.ts +0 -0
  40. package/src/ox-image-marker-mode.ts +145 -0
  41. package/src/ox-image-marker-view.ts +23 -0
  42. package/src/ox-image-marker.ts +626 -0
  43. package/src/types.ts +20 -0
  44. package/stories/ox-image-marker-mode.stories.ts +41 -0
  45. package/stories/ox-image-marker-view.stories.ts +134 -0
  46. package/stories/ox-image-marker.stories.ts +102 -0
  47. package/themes/app-theme.css +138 -0
  48. package/themes/calendar-theme.css +59 -0
  49. package/themes/dark.css +51 -0
  50. package/themes/form-theme.css +70 -0
  51. package/themes/grist-theme.css +175 -0
  52. package/themes/layout-theme.css +94 -0
  53. package/themes/light.css +51 -0
  54. package/themes/material-theme.css +23 -0
  55. package/themes/md-typescale-styles.css +100 -0
  56. package/themes/oops-theme.css +22 -0
  57. package/themes/report-theme.css +47 -0
  58. package/themes/spacing.css +23 -0
  59. package/themes/state-color.css +6 -0
  60. package/themes/tooltip-theme.css +11 -0
  61. package/translations/en.json +1 -0
  62. package/translations/ja.json +1 -0
  63. package/translations/ko.json +1 -0
  64. package/translations/ms.json +1 -0
  65. package/translations/zh.json +1 -0
  66. package/tsconfig.json +25 -0
  67. package/web-dev-server.config.mjs +27 -0
  68. package/web-test-runner.config.mjs +41 -0
@@ -0,0 +1,583 @@
1
+ import { __decorate } from "tslib";
2
+ import './ox-image-marker-mode';
3
+ import { html, css, svg, nothing } from 'lit';
4
+ import { state, customElement } from 'lit/decorators.js';
5
+ import { ifDefined } from 'lit/directives/if-defined.js';
6
+ import { keyed } from 'lit/directives/keyed.js';
7
+ import { BaseImageMarker } from './base-image-marker';
8
+ let OxImageMarker = class OxImageMarker extends BaseImageMarker {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.currentMode = 'select';
12
+ this.selectedShape = null;
13
+ this.drawing = false;
14
+ this.startX = 0;
15
+ this.startY = 0;
16
+ this.offsetX = 0;
17
+ this.offsetY = 0;
18
+ // 마우스 이동 이벤트 핸들러 (도형 그리기 중)
19
+ this.onMouseMove = (event) => {
20
+ if (!this.drawing || !this.selectedShape)
21
+ return;
22
+ const { x, y } = this.getSvgPoint(event);
23
+ switch (this.selectedShape.type) {
24
+ case 'text':
25
+ break;
26
+ case 'rectangle':
27
+ this.selectedShape.width = x - this.startX;
28
+ this.selectedShape.height = y - this.startY;
29
+ break;
30
+ case 'circle':
31
+ const dx = x - this.selectedShape.cx;
32
+ const dy = y - this.selectedShape.cy;
33
+ this.selectedShape.r = Math.sqrt(dx * dx + dy * dy);
34
+ break;
35
+ case 'triangle':
36
+ const x2 = x;
37
+ const y2 = y;
38
+ const x3 = this.startX - (x - this.startX);
39
+ const y3 = y;
40
+ this.selectedShape.points = `${this.startX},${this.startY} ${x2},${y2} ${x3},${y3}`;
41
+ break;
42
+ case 'line':
43
+ case 'arrow':
44
+ this.selectedShape.x2 = x;
45
+ this.selectedShape.y2 = y;
46
+ break;
47
+ }
48
+ this.requestUpdate();
49
+ };
50
+ // 마우스 업 이벤트 핸들러 (도형 그리기 종료)
51
+ this.onMouseUp = () => {
52
+ this.drawing = false;
53
+ const svg = this.svg;
54
+ svg.removeEventListener('mousemove', this.onMouseMove);
55
+ svg.removeEventListener('mouseup', this.onMouseUp);
56
+ this.selectedShape.selected = true;
57
+ this.requestUpdate();
58
+ };
59
+ this.onShapeMouseMove = (event) => {
60
+ if (!this.selectedShape) {
61
+ return;
62
+ }
63
+ const { x, y } = this.getSvgPoint(event);
64
+ // 마우스 이동에 따라 도형의 위치 업데이트
65
+ switch (this.selectedShape.type) {
66
+ case 'text':
67
+ case 'rectangle':
68
+ this.selectedShape.x = x - this.offsetX;
69
+ this.selectedShape.y = y - this.offsetY;
70
+ break;
71
+ case 'circle':
72
+ this.selectedShape.cx = x - this.offsetX;
73
+ this.selectedShape.cy = y - this.offsetY;
74
+ break;
75
+ case 'triangle':
76
+ const points = this.selectedShape.points.split(' ').map(p => p.split(',').map(Number));
77
+ const [ox, oy] = points[0];
78
+ this.selectedShape.points = points
79
+ .map(([px, py]) => [px - ox + x - this.offsetX, py - oy + y - this.offsetY].join(','))
80
+ .join(' ');
81
+ break;
82
+ case 'line':
83
+ case 'arrow':
84
+ const dxLine = x - this.offsetX;
85
+ const dyLine = y - this.offsetY;
86
+ const deltaX = dxLine - this.selectedShape.x1;
87
+ const deltaY = dyLine - this.selectedShape.y1;
88
+ this.selectedShape.x1 = dxLine;
89
+ this.selectedShape.y1 = dyLine;
90
+ this.selectedShape.x2 = this.selectedShape.x2 + deltaX;
91
+ this.selectedShape.y2 = this.selectedShape.y2 + deltaY;
92
+ break;
93
+ }
94
+ this.requestUpdate(); // 화면 업데이트
95
+ };
96
+ this.onShapeMouseUp = () => {
97
+ const svg = this.svg;
98
+ svg.removeEventListener('mousemove', this.onShapeMouseMove);
99
+ svg.removeEventListener('mouseup', this.onShapeMouseUp);
100
+ };
101
+ this.onHandleMouseMove = (event) => {
102
+ if (!this.selectedShape)
103
+ return;
104
+ const { x, y } = this.getSvgPoint(event);
105
+ switch (this.selectedShape.type) {
106
+ case 'text':
107
+ case 'rectangle':
108
+ this.selectedShape.width = Math.abs(x - this.selectedShape.x);
109
+ this.selectedShape.height = Math.abs(y - this.selectedShape.y);
110
+ if (x < this.selectedShape.x)
111
+ this.selectedShape.x = x;
112
+ if (y < this.selectedShape.y)
113
+ this.selectedShape.y = y;
114
+ break;
115
+ case 'circle':
116
+ const dx = x - this.selectedShape.cx;
117
+ const dy = y - this.selectedShape.cy;
118
+ this.selectedShape.r = Math.sqrt(dx * dx + dy * dy);
119
+ break;
120
+ case 'triangle':
121
+ const points = this.selectedShape.points.split(' ').map(p => p.split(',').map(Number));
122
+ const index = points.findIndex(([px, py]) => px === this.offsetX && py === this.offsetY);
123
+ if (index !== -1) {
124
+ points[index] = [x, y];
125
+ this.selectedShape.points = points.map(p => p.join(',')).join(' ');
126
+ this.offsetX = x;
127
+ this.offsetY = y;
128
+ }
129
+ break;
130
+ case 'line':
131
+ case 'arrow':
132
+ if (this.offsetX === this.selectedShape.x1 && this.offsetY === this.selectedShape.y1) {
133
+ this.selectedShape.x1 = x;
134
+ this.selectedShape.y1 = y;
135
+ }
136
+ else if (this.offsetX === this.selectedShape.x2 && this.offsetY === this.selectedShape.y2) {
137
+ this.selectedShape.x2 = x;
138
+ this.selectedShape.y2 = y;
139
+ }
140
+ this.offsetX = x;
141
+ this.offsetY = y;
142
+ break;
143
+ }
144
+ this.requestUpdate();
145
+ };
146
+ this.onHandleMouseUp = () => {
147
+ const svg = this.svg;
148
+ svg.removeEventListener('mousemove', this.onHandleMouseMove);
149
+ svg.removeEventListener('mouseup', this.onHandleMouseUp);
150
+ this.selectedShape = null;
151
+ };
152
+ }
153
+ static { this.styles = [
154
+ ...BaseImageMarker.styles,
155
+ css `
156
+ :host {
157
+ position: relative;
158
+ display: flex;
159
+ width: 100%;
160
+ height: 100%;
161
+ }
162
+
163
+ ox-image-marker-mode {
164
+ position: absolute;
165
+ top: 0;
166
+ right: 0;
167
+ }
168
+
169
+ svg {
170
+ cursor: crosshair;
171
+ }
172
+
173
+ svg.dragging {
174
+ cursor: move;
175
+ }
176
+
177
+ .resize-handle {
178
+ cursor: nwse-resize;
179
+ }
180
+ `
181
+ ]; }
182
+ render() {
183
+ return html `
184
+ <div class="container">
185
+ <svg
186
+ @mousedown=${this.onSvgMouseDown}
187
+ @wheel=${this.onWheel}
188
+ @dblclick=${this.onDoubleClick}
189
+ viewBox=${this.viewBox}
190
+ >
191
+ <image href=${this.imageUrl} @load=${this.onImageLoad}></image>
192
+ ${this.shapes.map(shape => keyed(shape.id, this.renderShape(shape)))}
193
+ </svg>
194
+ </div>
195
+
196
+ <ox-image-marker-mode
197
+ currentMode=${this.currentMode}
198
+ currentShapeType=${ifDefined(this.currentShapeType)}
199
+ @mode-changed=${(e) => {
200
+ const { mode, shapeType } = e.detail;
201
+ this.setMode(mode, shapeType);
202
+ }}
203
+ @clicked-delete=${() => {
204
+ if (this.selectedShape) {
205
+ this.shapes = this.shapes.filter(s => s.id !== this.selectedShape.id);
206
+ this.requestUpdate();
207
+ }
208
+ }}
209
+ @clicked-save=${() => {
210
+ this.dispatchEvent(new CustomEvent('shapes-changed', {
211
+ detail: this.shapes,
212
+ bubbles: true,
213
+ composed: true
214
+ }));
215
+ }}
216
+ ></ox-image-marker-mode>
217
+ `;
218
+ }
219
+ onSvgMouseDown(event) {
220
+ const svg = this.svg;
221
+ this.selectedShape = null;
222
+ this.shapes = this.shapes.map(s => {
223
+ return { ...s, selected: false };
224
+ });
225
+ this.selectedShape = null;
226
+ if (this.currentMode === 'move') {
227
+ this.isPanning = true;
228
+ this.panStart = { x: event.clientX, y: event.clientY };
229
+ svg.classList.add('dragging');
230
+ svg.addEventListener('mousemove', this.onPanMouseMove);
231
+ svg.addEventListener('mouseup', this.onPanMouseUp);
232
+ }
233
+ else if (this.currentMode === 'select') {
234
+ this.startShapeDragging(event);
235
+ svg.addEventListener('mousemove', this.onShapeMouseMove);
236
+ svg.addEventListener('mouseup', this.onShapeMouseUp);
237
+ }
238
+ else if (this.currentMode === 'draw') {
239
+ this.startDrawing(event);
240
+ svg.addEventListener('mousemove', this.onMouseMove);
241
+ svg.addEventListener('mouseup', this.onMouseUp);
242
+ }
243
+ }
244
+ startShapeDragging(event) {
245
+ const { x, y } = this.getSvgPoint(event);
246
+ if (this.selectedShape) {
247
+ this.offsetX = x - (this.selectedShape.x || this.selectedShape.cx || 0);
248
+ this.offsetY = y - (this.selectedShape.y || this.selectedShape.cy || 0);
249
+ }
250
+ }
251
+ startDrawing(event) {
252
+ this.drawing = true;
253
+ const { x, y } = this.getSvgPoint(event);
254
+ this.startX = x;
255
+ this.startY = y;
256
+ let newShape;
257
+ switch (this.currentShapeType) {
258
+ case 'text':
259
+ newShape = {
260
+ id: Date.now().toString(),
261
+ type: 'text',
262
+ x: this.startX,
263
+ y: this.startY,
264
+ text: 'ABC'
265
+ };
266
+ break;
267
+ case 'rectangle':
268
+ newShape = {
269
+ id: Date.now().toString(),
270
+ type: 'rectangle',
271
+ x: this.startX,
272
+ y: this.startY,
273
+ width: 0,
274
+ height: 0
275
+ };
276
+ break;
277
+ case 'circle':
278
+ newShape = {
279
+ id: Date.now().toString(),
280
+ type: 'circle',
281
+ cx: this.startX,
282
+ cy: this.startY,
283
+ r: 0
284
+ };
285
+ break;
286
+ case 'triangle':
287
+ newShape = {
288
+ id: Date.now().toString(),
289
+ type: 'triangle',
290
+ x1: this.startX,
291
+ y1: this.startY,
292
+ width: 0,
293
+ height: 0,
294
+ points: `${this.startX},${this.startY} ${this.startX},${this.startY} ${this.startX},${this.startY}`
295
+ };
296
+ break;
297
+ case 'line':
298
+ newShape = {
299
+ id: Date.now().toString(),
300
+ type: 'line',
301
+ x1: this.startX,
302
+ y1: this.startY,
303
+ width: 0,
304
+ height: 0
305
+ };
306
+ break;
307
+ case 'arrow':
308
+ newShape = {
309
+ id: Date.now().toString(),
310
+ type: 'arrow',
311
+ x1: this.startX,
312
+ y1: this.startY,
313
+ width: 0,
314
+ height: 0
315
+ };
316
+ break;
317
+ default:
318
+ return;
319
+ }
320
+ this.selectedShape = newShape;
321
+ this.shapes = [...this.shapes, newShape];
322
+ }
323
+ setMode(mode, shapeType) {
324
+ this.currentMode = mode;
325
+ this.currentShapeType = shapeType;
326
+ }
327
+ // SVG 좌표계로 마우스 좌표 변환
328
+ getSvgPoint(event) {
329
+ const svg = this.svg;
330
+ const point = svg.createSVGPoint();
331
+ point.x = event.clientX;
332
+ point.y = event.clientY;
333
+ const ctm = svg.getScreenCTM().inverse();
334
+ return point.matrixTransform(ctm);
335
+ }
336
+ // 도형 렌더링 함수
337
+ renderShape(shape) {
338
+ const commonAttrs = {
339
+ stroke: shape.selected ? 'blue' : 'red',
340
+ 'stroke-width': shape.selected ? 2 : 1,
341
+ fill: 'transparent',
342
+ cursor: 'pointer'
343
+ };
344
+ switch (shape.type) {
345
+ case 'text':
346
+ return svg `
347
+
348
+ <text
349
+ x="${shape.x}"
350
+ y="${shape.y}"
351
+ fill="${commonAttrs.stroke}"
352
+ style="cursor: ${commonAttrs.cursor}; font-size: 16px; text-decoration: ${shape.selected ? 'underline' : 'none'};"
353
+ @mousedown="${(e) => this.onShapeMouseDown(e, shape)}"
354
+ @dblclick="${(e) => this.onTextDoubleClick(e, shape)}"
355
+ >${shape.text}</text>
356
+ `;
357
+ case 'rectangle':
358
+ return svg `
359
+ <rect
360
+ x="${shape.x}"
361
+ y="${shape.y}"
362
+ width="${shape.width}"
363
+ height="${shape.height}"
364
+ stroke="${commonAttrs.stroke}"
365
+ stroke-width="${commonAttrs['stroke-width']}"
366
+ fill="${commonAttrs.fill}"
367
+ style="cursor: ${commonAttrs.cursor}"
368
+ @mousedown="${(e) => this.onShapeMouseDown(e, shape)}"
369
+ ></rect>
370
+ ${shape.selected ? this.renderResizeHandles(shape) : ''}
371
+ `;
372
+ case 'circle':
373
+ return svg `
374
+ <circle
375
+ cx="${shape.cx}"
376
+ cy="${shape.cy}"
377
+ r="${shape.r}"
378
+ stroke="${commonAttrs.stroke}"
379
+ stroke-width="${commonAttrs['stroke-width']}"
380
+ fill="${commonAttrs.fill}"
381
+ style="cursor: ${commonAttrs.cursor}"
382
+ @mousedown="${(e) => this.onShapeMouseDown(e, shape)}"
383
+ ></circle>
384
+ ${shape.selected ? this.renderResizeHandles(shape) : ''}
385
+ `;
386
+ case 'triangle':
387
+ return svg `
388
+ <polygon
389
+ points="${shape.points}"
390
+ stroke="${commonAttrs.stroke}"
391
+ stroke-width="${commonAttrs['stroke-width']}"
392
+ fill="${commonAttrs.fill}"
393
+ style="cursor: ${commonAttrs.cursor}"
394
+ @mousedown="${(e) => this.onShapeMouseDown(e, shape)}"
395
+ ></polygon>
396
+ ${shape.selected ? this.renderResizeHandles(shape) : ''}
397
+ `;
398
+ case 'line':
399
+ return svg `
400
+ <line
401
+ x1="${shape.x1}"
402
+ y1="${shape.y1}"
403
+ x2="${shape.x2 ?? shape.x1}"
404
+ y2="${shape.y2 ?? shape.y1}"
405
+ stroke="${commonAttrs.stroke}"
406
+ stroke-width="${commonAttrs['stroke-width']}"
407
+ style="cursor: ${commonAttrs.cursor}"
408
+ @mousedown="${(e) => this.onShapeMouseDown(e, shape)}"
409
+ ></line>
410
+ ${shape.selected ? this.renderResizeHandles(shape) : ''}
411
+ `;
412
+ case 'arrow':
413
+ return svg `
414
+ <defs>
415
+ <marker id="arrowhead-${shape.id}" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
416
+ <polygon points="0 0, 10 3.5, 0 7" fill="${commonAttrs.stroke}"></polygon>
417
+ </marker>
418
+ </defs>
419
+ <line
420
+ x1="${shape.x1}"
421
+ y1="${shape.y1}"
422
+ x2="${shape.x2 ?? shape.x1}"
423
+ y2="${shape.y2 ?? shape.y1}"
424
+ stroke="${commonAttrs.stroke}"
425
+ stroke-width="${commonAttrs['stroke-width']}"
426
+ marker-end="url(#arrowhead-${shape.id})"
427
+ style="cursor: ${commonAttrs.cursor}"
428
+ @mousedown="${(e) => this.onShapeMouseDown(e, shape)}"
429
+ ></line>
430
+ ${shape.selected ? this.renderResizeHandles(shape) : ''}
431
+ `;
432
+ default:
433
+ return nothing;
434
+ }
435
+ }
436
+ onShapeMouseDown(event, shape) {
437
+ event.stopPropagation();
438
+ this.shapes = this.shapes.map(s => ({
439
+ ...s,
440
+ selected: s.id === shape.id
441
+ }));
442
+ this.selectedShape = this.shapes.find(s => s.id == shape.id);
443
+ // 마우스 클릭 좌표와 도형의 현재 좌표 차이 계산
444
+ const { x, y } = this.getSvgPoint(event);
445
+ switch (shape.type) {
446
+ case 'text':
447
+ case 'rectangle':
448
+ case 'circle':
449
+ this.offsetX = x - (shape.x || shape.cx || 0);
450
+ this.offsetY = y - (shape.y || shape.cy || 0);
451
+ break;
452
+ case 'triangle':
453
+ const points = this.selectedShape.points.split(' ').map(p => p.split(',').map(Number));
454
+ const [px, py] = points[0] || [0, 0];
455
+ this.offsetX = x - px;
456
+ this.offsetY = y - py;
457
+ break;
458
+ case 'line':
459
+ case 'arrow':
460
+ this.offsetX = x - shape.x1;
461
+ this.offsetY = y - shape.y1;
462
+ break;
463
+ }
464
+ // 드래그 이벤트 리스너 추가
465
+ const svg = this.svg;
466
+ svg.addEventListener('mousemove', this.onShapeMouseMove);
467
+ svg.addEventListener('mouseup', this.onShapeMouseUp);
468
+ }
469
+ getScale() {
470
+ if (!this.svg) {
471
+ return 1;
472
+ }
473
+ const [vbWidth, vbHeight] = this.viewBox.split(' ').map(Number);
474
+ const scaleX = vbWidth / this.svg.clientWidth;
475
+ const scaleY = vbHeight / this.svg.clientHeight;
476
+ return Math.max(scaleX, scaleY);
477
+ }
478
+ renderResizeHandles(shape) {
479
+ let handles = [];
480
+ switch (shape.type) {
481
+ case 'text':
482
+ case 'rectangle':
483
+ handles = [
484
+ { x: shape.x, y: shape.y, cursor: 'nwse-resize' },
485
+ { x: shape.x + shape.width, y: shape.y, cursor: 'nesw-resize' },
486
+ { x: shape.x, y: shape.y + shape.height, cursor: 'nesw-resize' },
487
+ { x: shape.x + shape.width, y: shape.y + shape.height, cursor: 'nwse-resize' }
488
+ ];
489
+ break;
490
+ case 'circle':
491
+ handles = [
492
+ { x: shape.cx + shape.r, y: shape.cy, cursor: 'ew-resize' },
493
+ { x: shape.cx - shape.r, y: shape.cy, cursor: 'ew-resize' },
494
+ { x: shape.cx, y: shape.cy + shape.r, cursor: 'ns-resize' },
495
+ { x: shape.cx, y: shape.cy - shape.r, cursor: 'ns-resize' }
496
+ ];
497
+ break;
498
+ case 'triangle':
499
+ const points = shape.points.split(' ').map(p => p.split(',').map(Number));
500
+ handles = points.map(([x, y]) => ({ x, y, cursor: 'move' }));
501
+ break;
502
+ case 'line':
503
+ case 'arrow':
504
+ handles = [
505
+ { x: shape.x1, y: shape.y1, cursor: 'move' },
506
+ { x: shape.x2, y: shape.y2, cursor: 'move' }
507
+ ];
508
+ break;
509
+ }
510
+ return svg `
511
+ ${handles.map(handle => svg `
512
+ <g
513
+ class="resize-handle-group"
514
+ style="transform: translate(${handle.x}px, ${handle.y}px) scale(${1 / this.zoomLevel});"
515
+ >
516
+ <rect
517
+ x="-5"
518
+ y="-5"
519
+ width="10"
520
+ height="10"
521
+ fill="white"
522
+ stroke="black"
523
+ class="resize-handle"
524
+ style="cursor: ${handle.cursor};"
525
+ @mousedown="${(e) => this.onHandleMouseDown(e, shape, handle)}"
526
+ ></rect>
527
+ </g>
528
+ `)}
529
+ `;
530
+ }
531
+ onHandleMouseDown(event, shape, handle) {
532
+ event.stopPropagation();
533
+ this.selectedShape = shape;
534
+ this.offsetX = handle.x;
535
+ this.offsetY = handle.y;
536
+ const svg = this.svg;
537
+ svg.addEventListener('mousemove', this.onHandleMouseMove);
538
+ svg.addEventListener('mouseup', this.onHandleMouseUp);
539
+ }
540
+ onTextDoubleClick(event, shape) {
541
+ event.stopPropagation();
542
+ var input = document.createElement('input');
543
+ input.style.position = 'absolute';
544
+ input.style.left = `${event.clientX}px`;
545
+ input.style.top = `${event.clientY}px`;
546
+ input.value = shape.text || '';
547
+ document.body.appendChild(input);
548
+ input.focus();
549
+ input.addEventListener('keydown', e => {
550
+ if (e.key === 'Enter') {
551
+ shape.text = input.value;
552
+ document.body.removeChild(input);
553
+ input = null;
554
+ this.requestUpdate();
555
+ }
556
+ else if (e.key === 'Escape') {
557
+ document.body.removeChild(input);
558
+ input = null;
559
+ this.requestUpdate();
560
+ }
561
+ });
562
+ input.addEventListener('blur', () => {
563
+ requestAnimationFrame(() => {
564
+ input && document.body.removeChild(input);
565
+ input = null;
566
+ });
567
+ });
568
+ }
569
+ };
570
+ __decorate([
571
+ state()
572
+ ], OxImageMarker.prototype, "currentShapeType", void 0);
573
+ __decorate([
574
+ state()
575
+ ], OxImageMarker.prototype, "currentMode", void 0);
576
+ __decorate([
577
+ state()
578
+ ], OxImageMarker.prototype, "selectedShape", void 0);
579
+ OxImageMarker = __decorate([
580
+ customElement('ox-image-marker')
581
+ ], OxImageMarker);
582
+ export { OxImageMarker };
583
+ //# sourceMappingURL=ox-image-marker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-image-marker.js","sourceRoot":"","sources":["../../src/ox-image-marker.ts"],"names":[],"mappings":";AAAA,OAAO,wBAAwB,CAAA;AAE/B,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAC7C,OAAO,EAAY,KAAK,EAAE,aAAa,EAAS,MAAM,mBAAmB,CAAA;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAG/C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAG9C,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,eAAe;IAA3C;;QAgCY,gBAAW,GAAoB,QAAQ,CAAA;QACvC,kBAAa,GAAiB,IAAI,CAAA;QAE3C,YAAO,GAAG,KAAK,CAAA;QACf,WAAM,GAAG,CAAC,CAAA;QACV,WAAM,GAAG,CAAC,CAAA;QACV,YAAO,GAAG,CAAC,CAAA;QACX,YAAO,GAAG,CAAC,CAAA;QA4JnB,4BAA4B;QACpB,gBAAW,GAAG,CAAC,KAAiB,EAAE,EAAE;YAC1C,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,OAAM;YAChD,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YAExC,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;gBAChC,KAAK,MAAM;oBACT,MAAK;gBACP,KAAK,WAAW;oBACd,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;oBAC1C,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;oBAC3C,MAAK;gBACP,KAAK,QAAQ;oBACX,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,EAAG,CAAA;oBACrC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,EAAG,CAAA;oBACrC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;oBACnD,MAAK;gBACP,KAAK,UAAU;oBACb,MAAM,EAAE,GAAG,CAAC,CAAA;oBACZ,MAAM,EAAE,GAAG,CAAC,CAAA;oBACZ,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;oBAC1C,MAAM,EAAE,GAAG,CAAC,CAAA;oBACZ,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAA;oBACnF,MAAK;gBACP,KAAK,MAAM,CAAC;gBACZ,KAAK,OAAO;oBACV,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAA;oBACzB,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAA;oBACzB,MAAK;YACT,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC,CAAA;QAED,4BAA4B;QACpB,cAAS,GAAG,GAAG,EAAE;YACvB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;YACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAoB,CAAA;YACrC,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;YACtD,GAAG,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;YAElD,IAAI,CAAC,aAAc,CAAC,QAAQ,GAAG,IAAI,CAAA;YACnC,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC,CAAA;QAmKO,qBAAgB,GAAG,CAAC,KAAiB,EAAE,EAAE;YAC/C,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,OAAM;YACR,CAAC;YAED,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YAExC,yBAAyB;YACzB,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;gBAChC,KAAK,MAAM,CAAC;gBACZ,KAAK,WAAW;oBACd,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;oBACvC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;oBACvC,MAAK;gBACP,KAAK,QAAQ;oBACX,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;oBACxC,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;oBACxC,MAAK;gBACP,KAAK,UAAU;oBACb,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;oBACvF,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;oBAE1B,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,MAAM;yBAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;yBACrF,IAAI,CAAC,GAAG,CAAC,CAAA;oBACZ,MAAK;gBACP,KAAK,MAAM,CAAC;gBACZ,KAAK,OAAO;oBACV,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;oBAC/B,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;oBAC/B,MAAM,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,EAAG,CAAA;oBAC9C,MAAM,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,EAAG,CAAA;oBAC9C,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,MAAM,CAAA;oBAC9B,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,MAAM,CAAA;oBAC9B,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,EAAG,GAAG,MAAM,CAAA;oBACvD,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,EAAG,GAAG,MAAM,CAAA;oBACvD,MAAK;YACT,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAA,CAAC,UAAU;QACjC,CAAC,CAAA;QAEO,mBAAc,GAAG,GAAG,EAAE;YAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAoB,CAAA;YACrC,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;YAC3D,GAAG,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QACzD,CAAC,CAAA;QAmFO,sBAAiB,GAAG,CAAC,KAAiB,EAAE,EAAE;YAChD,IAAI,CAAC,IAAI,CAAC,aAAa;gBAAE,OAAM;YAC/B,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YAExC,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;gBAChC,KAAK,MAAM,CAAC;gBACZ,KAAK,WAAW;oBACd,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAE,CAAC,CAAA;oBAC9D,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAE,CAAC,CAAA;oBAC/D,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAE;wBAAE,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAA;oBACvD,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAE;wBAAE,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAA;oBACvD,MAAK;gBACP,KAAK,QAAQ;oBACX,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,EAAG,CAAA;oBACrC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,EAAG,CAAA;oBACrC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;oBACnD,MAAK;gBACP,KAAK,UAAU;oBACb,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;oBACvF,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,IAAI,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,CAAA;oBACxF,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;wBACjB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;wBACtB,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;wBAClE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;wBAChB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;oBAClB,CAAC;oBACD,MAAK;gBACP,KAAK,MAAM,CAAC;gBACZ,KAAK,OAAO;oBACV,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,aAAa,CAAC,EAAE,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;wBACrF,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAA;wBACzB,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAA;oBAC3B,CAAC;yBAAM,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,aAAa,CAAC,EAAE,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;wBAC5F,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAA;wBACzB,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAA;oBAC3B,CAAC;oBACD,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;oBAChB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;oBAChB,MAAK;YACT,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC,CAAA;QAEO,oBAAe,GAAG,GAAG,EAAE;YAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAoB,CAAA;YACrC,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;YAC5D,GAAG,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;YACxD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QAC3B,CAAC,CAAA;IAmCH,CAAC;aArmBQ,WAAM,GAAG;QACd,GAAG,eAAe,CAAC,MAAM;QACzB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAyBF;KACF,AA5BY,CA4BZ;IAYD,MAAM;QACJ,OAAO,IAAI,CAAA;;;uBAGQ,IAAI,CAAC,cAAc;mBACvB,IAAI,CAAC,OAAO;sBACT,IAAI,CAAC,aAAa;oBACpB,IAAI,CAAC,OAAO;;wBAER,IAAI,CAAC,QAAQ,UAAU,IAAI,CAAC,WAAW;YACnD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;;;;;sBAKxD,IAAI,CAAC,WAAW;2BACX,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC;wBACnC,CAAC,CAAc,EAAE,EAAE;YACjC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,MAAM,CAAA;YACpC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QAC/B,CAAC;0BACiB,GAAG,EAAE;YACrB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,aAAc,CAAC,EAAE,CAAC,CAAA;gBACtE,IAAI,CAAC,aAAa,EAAE,CAAA;YACtB,CAAC;QACH,CAAC;wBACe,GAAG,EAAE;YACnB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,gBAAgB,EAAE;gBAChC,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf,CAAC,CACH,CAAA;QACH,CAAC;;KAEJ,CAAA;IACH,CAAC;IAES,cAAc,CAAC,KAAiB;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;QAEpB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAChC,OAAO,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QACzB,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;YAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;YACrB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;YACtD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;YAC7B,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;YACtD,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;QACpD,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;YAC9B,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;YACxD,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QACtD,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;YACvC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;YACxB,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;YACnD,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,KAAiB;QAC1C,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACxC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;YACvE,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;QACzE,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,KAAiB;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACxC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;QACf,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;QAEf,IAAI,QAAe,CAAA;QACnB,QAAQ,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9B,KAAK,MAAM;gBACT,QAAQ,GAAG;oBACT,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,MAAM;oBACZ,CAAC,EAAE,IAAI,CAAC,MAAM;oBACd,CAAC,EAAE,IAAI,CAAC,MAAM;oBACd,IAAI,EAAE,KAAK;iBACZ,CAAA;gBACD,MAAK;YACP,KAAK,WAAW;gBACd,QAAQ,GAAG;oBACT,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,WAAW;oBACjB,CAAC,EAAE,IAAI,CAAC,MAAM;oBACd,CAAC,EAAE,IAAI,CAAC,MAAM;oBACd,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,CAAC;iBACV,CAAA;gBACD,MAAK;YACP,KAAK,QAAQ;gBACX,QAAQ,GAAG;oBACT,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,QAAQ;oBACd,EAAE,EAAE,IAAI,CAAC,MAAM;oBACf,EAAE,EAAE,IAAI,CAAC,MAAM;oBACf,CAAC,EAAE,CAAC;iBACL,CAAA;gBACD,MAAK;YACP,KAAK,UAAU;gBACb,QAAQ,GAAG;oBACT,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,UAAU;oBAChB,EAAE,EAAE,IAAI,CAAC,MAAM;oBACf,EAAE,EAAE,IAAI,CAAC,MAAM;oBACf,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,CAAC;oBACT,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE;iBACpG,CAAA;gBACD,MAAK;YACP,KAAK,MAAM;gBACT,QAAQ,GAAG;oBACT,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,MAAM;oBACZ,EAAE,EAAE,IAAI,CAAC,MAAM;oBACf,EAAE,EAAE,IAAI,CAAC,MAAM;oBACf,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,CAAC;iBACV,CAAA;gBACD,MAAK;YACP,KAAK,OAAO;gBACV,QAAQ,GAAG;oBACT,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;oBACzB,IAAI,EAAE,OAAO;oBACb,EAAE,EAAE,IAAI,CAAC,MAAM;oBACf,EAAE,EAAE,IAAI,CAAC,MAAM;oBACf,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,CAAC;iBACV,CAAA;gBACD,MAAK;YACP;gBACE,OAAM;QACV,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAA;QAC7B,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC1C,CAAC;IAEO,OAAO,CAAC,IAAqB,EAAE,SAAoB;QACzD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACvB,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAA;IACnC,CAAC;IA+CD,qBAAqB;IACb,WAAW,CAAC,KAAiB;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;QACpB,MAAM,KAAK,GAAG,GAAG,CAAC,cAAc,EAAE,CAAA;QAClC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAA;QACvB,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAA;QACvB,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,EAAG,CAAC,OAAO,EAAE,CAAA;QACzC,OAAO,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;IACnC,CAAC;IAED,YAAY;IACF,WAAW,CAAC,KAAY;QAChC,MAAM,WAAW,GAAG;YAClB,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;YACvC,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,SAAS;SAClB,CAAA;QAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM;gBACT,OAAO,GAAG,CAAA;;;iBAGD,KAAK,CAAC,CAAE;iBACR,KAAK,CAAC,CAAE;oBACL,WAAW,CAAC,MAAM;6BACT,WAAW,CAAC,MAAM,uCAAuC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;0BACjG,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC;yBACnD,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC;aAC/D,KAAK,CAAC,IAAI;SACd,CAAA;YAEH,KAAK,WAAW;gBACd,OAAO,GAAG,CAAA;;iBAED,KAAK,CAAC,CAAE;iBACR,KAAK,CAAC,CAAE;qBACJ,KAAK,CAAC,KAAM;sBACX,KAAK,CAAC,MAAO;sBACb,WAAW,CAAC,MAAM;4BACZ,WAAW,CAAC,cAAc,CAAC;oBACnC,WAAW,CAAC,IAAI;6BACP,WAAW,CAAC,MAAM;0BACrB,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC;;YAEhE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;SACxD,CAAA;YAEH,KAAK,QAAQ;gBACX,OAAO,GAAG,CAAA;;kBAEA,KAAK,CAAC,EAAG;kBACT,KAAK,CAAC,EAAG;iBACV,KAAK,CAAC,CAAE;sBACH,WAAW,CAAC,MAAM;4BACZ,WAAW,CAAC,cAAc,CAAC;oBACnC,WAAW,CAAC,IAAI;6BACP,WAAW,CAAC,MAAM;0BACrB,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC;;YAEhE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;SACxD,CAAA;YAEH,KAAK,UAAU;gBACb,OAAO,GAAG,CAAA;;sBAEI,KAAK,CAAC,MAAO;sBACb,WAAW,CAAC,MAAM;4BACZ,WAAW,CAAC,cAAc,CAAC;oBACnC,WAAW,CAAC,IAAI;6BACP,WAAW,CAAC,MAAM;0BACrB,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC;;YAEhE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;SACxD,CAAA;YAEH,KAAK,MAAM;gBACT,OAAO,GAAG,CAAA;;kBAEA,KAAK,CAAC,EAAG;kBACT,KAAK,CAAC,EAAG;kBACT,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE;kBACpB,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE;sBAChB,WAAW,CAAC,MAAM;4BACZ,WAAW,CAAC,cAAc,CAAC;6BAC1B,WAAW,CAAC,MAAM;0BACrB,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC;;YAEhE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;SACxD,CAAA;YAEH,KAAK,OAAO;gBACV,OAAO,GAAG,CAAA;;oCAEkB,KAAK,CAAC,EAAE;yDACa,WAAW,CAAC,MAAM;;;;kBAIzD,KAAK,CAAC,EAAG;kBACT,KAAK,CAAC,EAAG;kBACT,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE;kBACpB,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE;sBAChB,WAAW,CAAC,MAAM;4BACZ,WAAW,CAAC,cAAc,CAAC;yCACd,KAAK,CAAC,EAAE;6BACpB,WAAW,CAAC,MAAM;0BACrB,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC;;YAEhE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;SACxD,CAAA;YAEH;gBACE,OAAO,OAAO,CAAA;QAClB,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,KAAiB,EAAE,KAAY;QACtD,KAAK,CAAC,eAAe,EAAE,CAAA;QAEvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClC,GAAG,CAAC;YACJ,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE;SAC5B,CAAC,CAAC,CAAA;QAEH,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,CAAE,CAAA;QAE7D,6BAA6B;QAC7B,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAExC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM,CAAC;YACZ,KAAK,WAAW,CAAC;YACjB,KAAK,QAAQ;gBACX,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;gBAC7C,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;gBAC7C,MAAK;YAEP,KAAK,UAAU;gBACb,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;gBACvF,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;gBAEpC,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,CAAA;gBACrB,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,CAAA;gBAErB,MAAK;YAEP,KAAK,MAAM,CAAC;YACZ,KAAK,OAAO;gBACV,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,EAAG,CAAA;gBAC5B,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,EAAG,CAAA;gBAC5B,MAAK;QACT,CAAC;QAED,iBAAiB;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAoB,CAAA;QACrC,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;QACxD,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;IACtD,CAAC;IAkDO,QAAQ;QACd,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,CAAA;QACV,CAAC;QAED,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAE/D,MAAM,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAA;QAC7C,MAAM,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAA;QAE/C,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,CAAC;IAEO,mBAAmB,CAAC,KAAY;QACtC,IAAI,OAAO,GAAoD,EAAE,CAAA;QAEjE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM,CAAC;YACZ,KAAK,WAAW;gBACd,OAAO,GAAG;oBACR,EAAE,CAAC,EAAE,KAAK,CAAC,CAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAE,EAAE,MAAM,EAAE,aAAa,EAAE;oBACnD,EAAE,CAAC,EAAE,KAAK,CAAC,CAAE,GAAG,KAAK,CAAC,KAAM,EAAE,CAAC,EAAE,KAAK,CAAC,CAAE,EAAE,MAAM,EAAE,aAAa,EAAE;oBAClE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAE,GAAG,KAAK,CAAC,MAAO,EAAE,MAAM,EAAE,aAAa,EAAE;oBACnE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAE,GAAG,KAAK,CAAC,KAAM,EAAE,CAAC,EAAE,KAAK,CAAC,CAAE,GAAG,KAAK,CAAC,MAAO,EAAE,MAAM,EAAE,aAAa,EAAE;iBACnF,CAAA;gBACD,MAAK;YACP,KAAK,QAAQ;gBACX,OAAO,GAAG;oBACR,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,GAAG,KAAK,CAAC,CAAE,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,EAAE,MAAM,EAAE,WAAW,EAAE;oBAC9D,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,GAAG,KAAK,CAAC,CAAE,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,EAAE,MAAM,EAAE,WAAW,EAAE;oBAC9D,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,GAAG,KAAK,CAAC,CAAE,EAAE,MAAM,EAAE,WAAW,EAAE;oBAC9D,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,GAAG,KAAK,CAAC,CAAE,EAAE,MAAM,EAAE,WAAW,EAAE;iBAC/D,CAAA;gBACD,MAAK;YACP,KAAK,UAAU;gBACb,MAAM,MAAM,GAAG,KAAK,CAAC,MAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;gBAC1E,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;gBAC5D,MAAK;YACP,KAAK,MAAM,CAAC;YACZ,KAAK,OAAO;gBACV,OAAO,GAAG;oBACR,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,EAAE,MAAM,EAAE,MAAM,EAAE;oBAC9C,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,EAAE,CAAC,EAAE,KAAK,CAAC,EAAG,EAAE,MAAM,EAAE,MAAM,EAAE;iBAC/C,CAAA;gBACD,MAAK;QACT,CAAC;QAED,OAAO,GAAG,CAAA;QACN,OAAO,CAAC,GAAG,CACX,MAAM,CAAC,EAAE,CAAC,GAAG,CAAA;;;0CAGqB,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS;;;;;;;;;;+BAUjE,MAAM,CAAC,MAAM;4BAChB,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC;;;SAG9E,CACF;KACF,CAAA;IACH,CAAC;IAEO,iBAAiB,CAAC,KAAiB,EAAE,KAAY,EAAE,MAAW;QACpE,KAAK,CAAC,eAAe,EAAE,CAAA;QACvB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAA;QAC1B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAA;QACvB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAA;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAoB,CAAA;QACrC,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;QACzD,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;IACvD,CAAC;IAqDO,iBAAiB,CAAC,KAAiB,EAAE,KAAY;QACvD,KAAK,CAAC,eAAe,EAAE,CAAA;QAEvB,IAAI,KAAK,GAA4B,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QACpE,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAA;QACjC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,CAAA;QACvC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,CAAA;QACtC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAA;QAC9B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAChC,KAAK,CAAC,KAAK,EAAE,CAAA;QAEb,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE;YACpC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;gBACtB,KAAK,CAAC,IAAI,GAAG,KAAM,CAAC,KAAK,CAAA;gBACzB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAM,CAAC,CAAA;gBACjC,KAAK,GAAG,IAAI,CAAA;gBAEZ,IAAI,CAAC,aAAa,EAAE,CAAA;YACtB,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAM,CAAC,CAAA;gBACjC,KAAK,GAAG,IAAI,CAAA;gBAEZ,IAAI,CAAC,aAAa,EAAE,CAAA;YACtB,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE;YAClC,qBAAqB,CAAC,GAAG,EAAE;gBACzB,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;gBACzC,KAAK,GAAG,IAAI,CAAA;YACd,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;;AAtkBgB;IAAhB,KAAK,EAAE;uDAAqC;AAC5B;IAAhB,KAAK,EAAE;kDAAgD;AACvC;IAAhB,KAAK,EAAE;oDAA2C;AAjCxC,aAAa;IADzB,aAAa,CAAC,iBAAiB,CAAC;GACpB,aAAa,CAsmBzB","sourcesContent":["import './ox-image-marker-mode'\n\nimport { html, css, svg, nothing } from 'lit'\nimport { property, state, customElement, query } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { keyed } from 'lit/directives/keyed.js'\n\nimport { ImageMarkerMode, Shape, ShapeType } from './types'\nimport { BaseImageMarker } from './base-image-marker'\n\n@customElement('ox-image-marker')\nexport class OxImageMarker extends BaseImageMarker {\n static styles = [\n ...BaseImageMarker.styles,\n css`\n :host {\n position: relative;\n display: flex;\n width: 100%;\n height: 100%;\n }\n\n ox-image-marker-mode {\n position: absolute;\n top: 0;\n right: 0;\n }\n\n svg {\n cursor: crosshair;\n }\n\n svg.dragging {\n cursor: move;\n }\n\n .resize-handle {\n cursor: nwse-resize;\n }\n `\n ]\n\n @state() private currentShapeType?: ShapeType\n @state() private currentMode: ImageMarkerMode = 'select'\n @state() private selectedShape: Shape | null = null\n\n private drawing = false\n private startX = 0\n private startY = 0\n private offsetX = 0\n private offsetY = 0\n\n render() {\n return html`\n <div class=\"container\">\n <svg\n @mousedown=${this.onSvgMouseDown}\n @wheel=${this.onWheel}\n @dblclick=${this.onDoubleClick}\n viewBox=${this.viewBox}\n >\n <image href=${this.imageUrl} @load=${this.onImageLoad}></image>\n ${this.shapes.map(shape => keyed(shape.id, this.renderShape(shape)))}\n </svg>\n </div>\n\n <ox-image-marker-mode\n currentMode=${this.currentMode}\n currentShapeType=${ifDefined(this.currentShapeType)}\n @mode-changed=${(e: CustomEvent) => {\n const { mode, shapeType } = e.detail\n this.setMode(mode, shapeType)\n }}\n @clicked-delete=${() => {\n if (this.selectedShape) {\n this.shapes = this.shapes.filter(s => s.id !== this.selectedShape!.id)\n this.requestUpdate()\n }\n }}\n @clicked-save=${() => {\n this.dispatchEvent(\n new CustomEvent('shapes-changed', {\n detail: this.shapes,\n bubbles: true,\n composed: true\n })\n )\n }}\n ></ox-image-marker-mode>\n `\n }\n\n protected onSvgMouseDown(event: MouseEvent) {\n const svg = this.svg\n\n this.selectedShape = null\n this.shapes = this.shapes.map(s => {\n return { ...s, selected: false }\n })\n\n this.selectedShape = null\n if (this.currentMode === 'move') {\n this.isPanning = true\n this.panStart = { x: event.clientX, y: event.clientY }\n svg.classList.add('dragging')\n svg.addEventListener('mousemove', this.onPanMouseMove)\n svg.addEventListener('mouseup', this.onPanMouseUp)\n } else if (this.currentMode === 'select') {\n this.startShapeDragging(event)\n svg.addEventListener('mousemove', this.onShapeMouseMove)\n svg.addEventListener('mouseup', this.onShapeMouseUp)\n } else if (this.currentMode === 'draw') {\n this.startDrawing(event)\n svg.addEventListener('mousemove', this.onMouseMove)\n svg.addEventListener('mouseup', this.onMouseUp)\n }\n }\n\n private startShapeDragging(event: MouseEvent) {\n const { x, y } = this.getSvgPoint(event)\n if (this.selectedShape) {\n this.offsetX = x - (this.selectedShape.x || this.selectedShape.cx || 0)\n this.offsetY = y - (this.selectedShape.y || this.selectedShape.cy || 0)\n }\n }\n\n private startDrawing(event: MouseEvent) {\n this.drawing = true\n const { x, y } = this.getSvgPoint(event)\n this.startX = x\n this.startY = y\n\n let newShape: Shape\n switch (this.currentShapeType) {\n case 'text':\n newShape = {\n id: Date.now().toString(),\n type: 'text',\n x: this.startX,\n y: this.startY,\n text: 'ABC'\n }\n break\n case 'rectangle':\n newShape = {\n id: Date.now().toString(),\n type: 'rectangle',\n x: this.startX,\n y: this.startY,\n width: 0,\n height: 0\n }\n break\n case 'circle':\n newShape = {\n id: Date.now().toString(),\n type: 'circle',\n cx: this.startX,\n cy: this.startY,\n r: 0\n }\n break\n case 'triangle':\n newShape = {\n id: Date.now().toString(),\n type: 'triangle',\n x1: this.startX,\n y1: this.startY,\n width: 0,\n height: 0,\n points: `${this.startX},${this.startY} ${this.startX},${this.startY} ${this.startX},${this.startY}`\n }\n break\n case 'line':\n newShape = {\n id: Date.now().toString(),\n type: 'line',\n x1: this.startX,\n y1: this.startY,\n width: 0,\n height: 0\n }\n break\n case 'arrow':\n newShape = {\n id: Date.now().toString(),\n type: 'arrow',\n x1: this.startX,\n y1: this.startY,\n width: 0,\n height: 0\n }\n break\n default:\n return\n }\n\n this.selectedShape = newShape\n this.shapes = [...this.shapes, newShape]\n }\n\n private setMode(mode: ImageMarkerMode, shapeType: ShapeType) {\n this.currentMode = mode\n this.currentShapeType = shapeType\n }\n\n // 마우스 이동 이벤트 핸들러 (도형 그리기 중)\n private onMouseMove = (event: MouseEvent) => {\n if (!this.drawing || !this.selectedShape) return\n const { x, y } = this.getSvgPoint(event)\n\n switch (this.selectedShape.type) {\n case 'text':\n break\n case 'rectangle':\n this.selectedShape.width = x - this.startX\n this.selectedShape.height = y - this.startY\n break\n case 'circle':\n const dx = x - this.selectedShape.cx!\n const dy = y - this.selectedShape.cy!\n this.selectedShape.r = Math.sqrt(dx * dx + dy * dy)\n break\n case 'triangle':\n const x2 = x\n const y2 = y\n const x3 = this.startX - (x - this.startX)\n const y3 = y\n this.selectedShape.points = `${this.startX},${this.startY} ${x2},${y2} ${x3},${y3}`\n break\n case 'line':\n case 'arrow':\n this.selectedShape.x2 = x\n this.selectedShape.y2 = y\n break\n }\n\n this.requestUpdate()\n }\n\n // 마우스 업 이벤트 핸들러 (도형 그리기 종료)\n private onMouseUp = () => {\n this.drawing = false\n const svg = this.svg as SVGSVGElement\n svg.removeEventListener('mousemove', this.onMouseMove)\n svg.removeEventListener('mouseup', this.onMouseUp)\n\n this.selectedShape!.selected = true\n this.requestUpdate()\n }\n\n // SVG 좌표계로 마우스 좌표 변환\n private getSvgPoint(event: MouseEvent) {\n const svg = this.svg\n const point = svg.createSVGPoint()\n point.x = event.clientX\n point.y = event.clientY\n const ctm = svg.getScreenCTM()!.inverse()\n return point.matrixTransform(ctm)\n }\n\n // 도형 렌더링 함수\n protected renderShape(shape: Shape) {\n const commonAttrs = {\n stroke: shape.selected ? 'blue' : 'red',\n 'stroke-width': shape.selected ? 2 : 1,\n fill: 'transparent',\n cursor: 'pointer'\n }\n\n switch (shape.type) {\n case 'text':\n return svg`\n \n <text\n x=\"${shape.x!}\"\n y=\"${shape.y!}\"\n fill=\"${commonAttrs.stroke}\"\n style=\"cursor: ${commonAttrs.cursor}; font-size: 16px; text-decoration: ${shape.selected ? 'underline' : 'none'};\"\n @mousedown=\"${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}\"\n @dblclick=\"${(e: MouseEvent) => this.onTextDoubleClick(e, shape)}\"\n >${shape.text}</text>\n `\n\n case 'rectangle':\n return svg`\n <rect\n x=\"${shape.x!}\"\n y=\"${shape.y!}\"\n width=\"${shape.width!}\"\n height=\"${shape.height!}\"\n stroke=\"${commonAttrs.stroke}\"\n stroke-width=\"${commonAttrs['stroke-width']}\"\n fill=\"${commonAttrs.fill}\"\n style=\"cursor: ${commonAttrs.cursor}\"\n @mousedown=\"${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}\"\n ></rect>\n ${shape.selected ? this.renderResizeHandles(shape) : ''}\n `\n\n case 'circle':\n return svg`\n <circle\n cx=\"${shape.cx!}\"\n cy=\"${shape.cy!}\"\n r=\"${shape.r!}\"\n stroke=\"${commonAttrs.stroke}\"\n stroke-width=\"${commonAttrs['stroke-width']}\"\n fill=\"${commonAttrs.fill}\"\n style=\"cursor: ${commonAttrs.cursor}\"\n @mousedown=\"${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}\"\n ></circle>\n ${shape.selected ? this.renderResizeHandles(shape) : ''}\n `\n\n case 'triangle':\n return svg`\n <polygon\n points=\"${shape.points!}\"\n stroke=\"${commonAttrs.stroke}\"\n stroke-width=\"${commonAttrs['stroke-width']}\"\n fill=\"${commonAttrs.fill}\"\n style=\"cursor: ${commonAttrs.cursor}\"\n @mousedown=\"${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}\"\n ></polygon>\n ${shape.selected ? this.renderResizeHandles(shape) : ''}\n `\n\n case 'line':\n return svg`\n <line\n x1=\"${shape.x1!}\"\n y1=\"${shape.y1!}\"\n x2=\"${shape.x2 ?? shape.x1}\"\n y2=\"${shape.y2 ?? shape.y1}\"\n stroke=\"${commonAttrs.stroke}\"\n stroke-width=\"${commonAttrs['stroke-width']}\"\n style=\"cursor: ${commonAttrs.cursor}\"\n @mousedown=\"${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}\"\n ></line>\n ${shape.selected ? this.renderResizeHandles(shape) : ''}\n `\n\n case 'arrow':\n return svg`\n <defs>\n <marker id=\"arrowhead-${shape.id}\" markerWidth=\"10\" markerHeight=\"7\" refX=\"10\" refY=\"3.5\" orient=\"auto\">\n <polygon points=\"0 0, 10 3.5, 0 7\" fill=\"${commonAttrs.stroke}\"></polygon>\n </marker>\n </defs>\n <line\n x1=\"${shape.x1!}\"\n y1=\"${shape.y1!}\"\n x2=\"${shape.x2 ?? shape.x1}\"\n y2=\"${shape.y2 ?? shape.y1}\"\n stroke=\"${commonAttrs.stroke}\"\n stroke-width=\"${commonAttrs['stroke-width']}\"\n marker-end=\"url(#arrowhead-${shape.id})\"\n style=\"cursor: ${commonAttrs.cursor}\"\n @mousedown=\"${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}\"\n ></line>\n ${shape.selected ? this.renderResizeHandles(shape) : ''}\n `\n\n default:\n return nothing\n }\n }\n\n private onShapeMouseDown(event: MouseEvent, shape: Shape) {\n event.stopPropagation()\n\n this.shapes = this.shapes.map(s => ({\n ...s,\n selected: s.id === shape.id\n }))\n\n this.selectedShape = this.shapes.find(s => s.id == shape.id)!\n\n // 마우스 클릭 좌표와 도형의 현재 좌표 차이 계산\n const { x, y } = this.getSvgPoint(event)\n\n switch (shape.type) {\n case 'text':\n case 'rectangle':\n case 'circle':\n this.offsetX = x - (shape.x || shape.cx || 0)\n this.offsetY = y - (shape.y || shape.cy || 0)\n break\n\n case 'triangle':\n const points = this.selectedShape.points!.split(' ').map(p => p.split(',').map(Number))\n const [px, py] = points[0] || [0, 0]\n\n this.offsetX = x - px\n this.offsetY = y - py\n\n break\n\n case 'line':\n case 'arrow':\n this.offsetX = x - shape.x1!\n this.offsetY = y - shape.y1!\n break\n }\n\n // 드래그 이벤트 리스너 추가\n const svg = this.svg as SVGSVGElement\n svg.addEventListener('mousemove', this.onShapeMouseMove)\n svg.addEventListener('mouseup', this.onShapeMouseUp)\n }\n\n private onShapeMouseMove = (event: MouseEvent) => {\n if (!this.selectedShape) {\n return\n }\n\n const { x, y } = this.getSvgPoint(event)\n\n // 마우스 이동에 따라 도형의 위치 업데이트\n switch (this.selectedShape.type) {\n case 'text':\n case 'rectangle':\n this.selectedShape.x = x - this.offsetX\n this.selectedShape.y = y - this.offsetY\n break\n case 'circle':\n this.selectedShape.cx = x - this.offsetX\n this.selectedShape.cy = y - this.offsetY\n break\n case 'triangle':\n const points = this.selectedShape.points!.split(' ').map(p => p.split(',').map(Number))\n const [ox, oy] = points[0]\n\n this.selectedShape.points = points\n .map(([px, py]) => [px - ox + x - this.offsetX, py - oy + y - this.offsetY].join(','))\n .join(' ')\n break\n case 'line':\n case 'arrow':\n const dxLine = x - this.offsetX\n const dyLine = y - this.offsetY\n const deltaX = dxLine - this.selectedShape.x1!\n const deltaY = dyLine - this.selectedShape.y1!\n this.selectedShape.x1 = dxLine\n this.selectedShape.y1 = dyLine\n this.selectedShape.x2 = this.selectedShape.x2! + deltaX\n this.selectedShape.y2 = this.selectedShape.y2! + deltaY\n break\n }\n\n this.requestUpdate() // 화면 업데이트\n }\n\n private onShapeMouseUp = () => {\n const svg = this.svg as SVGSVGElement\n svg.removeEventListener('mousemove', this.onShapeMouseMove)\n svg.removeEventListener('mouseup', this.onShapeMouseUp)\n }\n\n private getScale(): number {\n if (!this.svg) {\n return 1\n }\n\n const [vbWidth, vbHeight] = this.viewBox.split(' ').map(Number)\n\n const scaleX = vbWidth / this.svg.clientWidth\n const scaleY = vbHeight / this.svg.clientHeight\n\n return Math.max(scaleX, scaleY)\n }\n\n private renderResizeHandles(shape: Shape) {\n let handles: Array<{ x: number; y: number; cursor: string }> = []\n\n switch (shape.type) {\n case 'text':\n case 'rectangle':\n handles = [\n { x: shape.x!, y: shape.y!, cursor: 'nwse-resize' },\n { x: shape.x! + shape.width!, y: shape.y!, cursor: 'nesw-resize' },\n { x: shape.x!, y: shape.y! + shape.height!, cursor: 'nesw-resize' },\n { x: shape.x! + shape.width!, y: shape.y! + shape.height!, cursor: 'nwse-resize' }\n ]\n break\n case 'circle':\n handles = [\n { x: shape.cx! + shape.r!, y: shape.cy!, cursor: 'ew-resize' },\n { x: shape.cx! - shape.r!, y: shape.cy!, cursor: 'ew-resize' },\n { x: shape.cx!, y: shape.cy! + shape.r!, cursor: 'ns-resize' },\n { x: shape.cx!, y: shape.cy! - shape.r!, cursor: 'ns-resize' }\n ]\n break\n case 'triangle':\n const points = shape.points!.split(' ').map(p => p.split(',').map(Number))\n handles = points.map(([x, y]) => ({ x, y, cursor: 'move' }))\n break\n case 'line':\n case 'arrow':\n handles = [\n { x: shape.x1!, y: shape.y1!, cursor: 'move' },\n { x: shape.x2!, y: shape.y2!, cursor: 'move' }\n ]\n break\n }\n\n return svg`\n ${handles.map(\n handle => svg`\n <g\n class=\"resize-handle-group\"\n style=\"transform: translate(${handle.x}px, ${handle.y}px) scale(${1 / this.zoomLevel});\"\n >\n <rect\n x=\"-5\"\n y=\"-5\"\n width=\"10\"\n height=\"10\"\n fill=\"white\"\n stroke=\"black\"\n class=\"resize-handle\"\n style=\"cursor: ${handle.cursor};\"\n @mousedown=\"${(e: MouseEvent) => this.onHandleMouseDown(e, shape, handle)}\"\n ></rect>\n </g>\n `\n )}\n `\n }\n\n private onHandleMouseDown(event: MouseEvent, shape: Shape, handle: any) {\n event.stopPropagation()\n this.selectedShape = shape\n this.offsetX = handle.x\n this.offsetY = handle.y\n const svg = this.svg as SVGSVGElement\n svg.addEventListener('mousemove', this.onHandleMouseMove)\n svg.addEventListener('mouseup', this.onHandleMouseUp)\n }\n\n private onHandleMouseMove = (event: MouseEvent) => {\n if (!this.selectedShape) return\n const { x, y } = this.getSvgPoint(event)\n\n switch (this.selectedShape.type) {\n case 'text':\n case 'rectangle':\n this.selectedShape.width = Math.abs(x - this.selectedShape.x!)\n this.selectedShape.height = Math.abs(y - this.selectedShape.y!)\n if (x < this.selectedShape.x!) this.selectedShape.x = x\n if (y < this.selectedShape.y!) this.selectedShape.y = y\n break\n case 'circle':\n const dx = x - this.selectedShape.cx!\n const dy = y - this.selectedShape.cy!\n this.selectedShape.r = Math.sqrt(dx * dx + dy * dy)\n break\n case 'triangle':\n const points = this.selectedShape.points!.split(' ').map(p => p.split(',').map(Number))\n const index = points.findIndex(([px, py]) => px === this.offsetX && py === this.offsetY)\n if (index !== -1) {\n points[index] = [x, y]\n this.selectedShape.points = points.map(p => p.join(',')).join(' ')\n this.offsetX = x\n this.offsetY = y\n }\n break\n case 'line':\n case 'arrow':\n if (this.offsetX === this.selectedShape.x1 && this.offsetY === this.selectedShape.y1) {\n this.selectedShape.x1 = x\n this.selectedShape.y1 = y\n } else if (this.offsetX === this.selectedShape.x2 && this.offsetY === this.selectedShape.y2) {\n this.selectedShape.x2 = x\n this.selectedShape.y2 = y\n }\n this.offsetX = x\n this.offsetY = y\n break\n }\n\n this.requestUpdate()\n }\n\n private onHandleMouseUp = () => {\n const svg = this.svg as SVGSVGElement\n svg.removeEventListener('mousemove', this.onHandleMouseMove)\n svg.removeEventListener('mouseup', this.onHandleMouseUp)\n this.selectedShape = null\n }\n\n private onTextDoubleClick(event: MouseEvent, shape: Shape) {\n event.stopPropagation()\n\n var input: HTMLInputElement | null = document.createElement('input')\n input.style.position = 'absolute'\n input.style.left = `${event.clientX}px`\n input.style.top = `${event.clientY}px`\n input.value = shape.text || ''\n document.body.appendChild(input)\n input.focus()\n\n input.addEventListener('keydown', e => {\n if (e.key === 'Enter') {\n shape.text = input!.value\n document.body.removeChild(input!)\n input = null\n\n this.requestUpdate()\n } else if (e.key === 'Escape') {\n document.body.removeChild(input!)\n input = null\n\n this.requestUpdate()\n }\n })\n\n input.addEventListener('blur', () => {\n requestAnimationFrame(() => {\n input && document.body.removeChild(input)\n input = null\n })\n })\n }\n}\n"]}