luo-image-annotator 0.0.9 → 0.0.11

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.
@@ -1,59 +1,59 @@
1
1
  var Jt = Object.defineProperty;
2
- var jt = (m, t, i) => t in m ? Jt(m, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : m[t] = i;
3
- var I = (m, t, i) => jt(m, typeof t != "symbol" ? t + "" : t, i);
4
- import { defineComponent as G, ref as k, watchEffect as Xt, openBlock as y, createElementBlock as x, normalizeClass as V, computed as O, onMounted as Yt, watch as J, createElementVNode as g, toDisplayString as $, Fragment as L, renderList as F, normalizeStyle as N, createCommentVNode as z, createVNode as H, createTextVNode as j, withDirectives as it, vModelText as ot, createBlock as mt, nextTick as qt } from "vue";
5
- const at = (m, t) => Math.sqrt(Math.pow(m.x - t.x, 2) + Math.pow(m.y - t.y, 2)), Gt = (m, t) => {
2
+ var jt = (v, t, i) => t in v ? Jt(v, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : v[t] = i;
3
+ var k = (v, t, i) => jt(v, typeof t != "symbol" ? t + "" : t, i);
4
+ import { defineComponent as K, ref as S, watchEffect as Yt, openBlock as f, createElementBlock as p, normalizeClass as V, computed as U, onMounted as Xt, watch as Y, createElementVNode as g, toDisplayString as T, Fragment as R, renderList as F, normalizeStyle as O, createCommentVNode as $, createVNode as H, withModifiers as qt, createTextVNode as X, withDirectives as lt, vModelText as rt, createBlock as ft, nextTick as Gt } from "vue";
5
+ const ct = (v, t) => Math.sqrt(Math.pow(v.x - t.x, 2) + Math.pow(v.y - t.y, 2)), Kt = (v, t) => {
6
6
  let i = !1;
7
- for (let e = 0, l = t.length - 1; e < t.length; l = e++) {
8
- const r = t[e].x, c = t[e].y, o = t[l].x, h = t[l].y;
9
- c > m.y != h > m.y && m.x < (o - r) * (m.y - c) / (h - c) + r && (i = !i);
7
+ for (let e = 0, a = t.length - 1; e < t.length; a = e++) {
8
+ const r = t[e].x, c = t[e].y, o = t[a].x, h = t[a].y;
9
+ c > v.y != h > v.y && v.x < (o - r) * (v.y - c) / (h - c) + r && (i = !i);
10
10
  }
11
11
  return i;
12
- }, ft = (m, t, i) => {
13
- const e = i * (Math.PI / 180), l = Math.cos(e), r = Math.sin(e), c = m.x - t.x, o = m.y - t.y;
12
+ }, yt = (v, t, i) => {
13
+ const e = i * (Math.PI / 180), a = Math.cos(e), r = Math.sin(e), c = v.x - t.x, o = v.y - t.y;
14
14
  return {
15
- x: t.x + (c * l - o * r),
16
- y: t.y + (c * r + o * l)
15
+ x: t.x + (c * a - o * r),
16
+ y: t.y + (c * r + o * a)
17
17
  };
18
18
  };
19
- class Kt {
19
+ class Zt {
20
20
  constructor(t) {
21
- I(this, "canvas");
22
- I(this, "ctx");
23
- I(this, "img");
24
- I(this, "annotations", []);
21
+ k(this, "canvas");
22
+ k(this, "ctx");
23
+ k(this, "img");
24
+ k(this, "annotations", []);
25
25
  // 状态
26
- I(this, "currentTool", null);
27
- I(this, "interactionMode", "none");
28
- I(this, "activeAnnotation", null);
29
- I(this, "hoverAnnotation", null);
30
- I(this, "isDrawing", !1);
31
- I(this, "isDragging", !1);
32
- I(this, "isPanning", !1);
26
+ k(this, "currentTool", null);
27
+ k(this, "interactionMode", "none");
28
+ k(this, "activeAnnotation", null);
29
+ k(this, "hoverAnnotation", null);
30
+ k(this, "isDrawing", !1);
31
+ k(this, "isDragging", !1);
32
+ k(this, "isPanning", !1);
33
33
  // 平移模式
34
- I(this, "panStartPoint", null);
34
+ k(this, "panStartPoint", null);
35
35
  // 平移起点
36
- I(this, "dragStartPoint", null);
37
- I(this, "dragStartAnnotation", null);
36
+ k(this, "dragStartPoint", null);
37
+ k(this, "dragStartAnnotation", null);
38
38
  // 快照用于撤销/diff
39
- I(this, "lastMouseMovePoint", null);
39
+ k(this, "lastMouseMovePoint", null);
40
40
  // 用于绘制辅助线
41
- I(this, "isHoveringStartPoint", !1);
41
+ k(this, "isHoveringStartPoint", !1);
42
42
  // 多边形闭合吸附状态
43
43
  // 设置
44
- I(this, "currentLabelColor", "#FF4081");
44
+ k(this, "currentLabelColor", "#FF4081");
45
45
  // 当前选中标签颜色
46
- I(this, "visibleLabels", /* @__PURE__ */ new Set());
46
+ k(this, "visibleLabels", /* @__PURE__ */ new Set());
47
47
  // 可见标签集合 (如果为空则全部可见,或者由外部控制渲染列表)
48
48
  // 交互
49
- I(this, "selectedHandleIndex", -1);
49
+ k(this, "selectedHandleIndex", -1);
50
50
  // -1: 主体, >=0: 顶点索引, -2: 旋转手柄
51
- I(this, "hoverHandleIndex", -1);
51
+ k(this, "hoverHandleIndex", -1);
52
52
  // 视口
53
- I(this, "scale", 1);
54
- I(this, "offset", { x: 0, y: 0 });
55
- I(this, "listeners", {});
56
- I(this, "imageUrl", "");
53
+ k(this, "scale", 1);
54
+ k(this, "offset", { x: 0, y: 0 });
55
+ k(this, "listeners", {});
56
+ k(this, "imageUrl", "");
57
57
  this.canvas = t;
58
58
  const i = t.getContext("2d");
59
59
  if (!i) throw new Error("Could not get 2d context");
@@ -89,8 +89,8 @@ class Kt {
89
89
  zoom(t) {
90
90
  const e = t > 0 ? this.scale * 1.1 : this.scale / 1.1;
91
91
  if (e < 0.1 || e > 10) return;
92
- const l = this.canvas.width / 2, r = this.canvas.height / 2, c = this.toImageCoords(l, r);
93
- this.scale = e, this.offset.x = l - c.x * this.scale, this.offset.y = r - c.y * this.scale, this.render();
92
+ const a = this.canvas.width / 2, r = this.canvas.height / 2, c = this.toImageCoords(a, r);
93
+ this.scale = e, this.offset.x = a - c.x * this.scale, this.offset.y = r - c.y * this.scale, this.clampViewportOffset(), this.render();
94
94
  }
95
95
  resize() {
96
96
  this.fitImageToCanvas(), this.render();
@@ -113,7 +113,23 @@ class Kt {
113
113
  if (t) {
114
114
  if (this.canvas.width = t.clientWidth, this.canvas.height = t.clientHeight, this.img.width === 0) return;
115
115
  const i = this.canvas.width / this.img.width, e = this.canvas.height / this.img.height;
116
- this.scale = Math.min(i, e), this.offset.x = (this.canvas.width - this.img.width * this.scale) / 2, this.offset.y = (this.canvas.height - this.img.height * this.scale) / 2;
116
+ this.scale = Math.min(i, e), this.offset.x = (this.canvas.width - this.img.width * this.scale) / 2, this.offset.y = (this.canvas.height - this.img.height * this.scale) / 2, this.clampViewportOffset();
117
+ }
118
+ }
119
+ clampViewportOffset() {
120
+ if (this.img.width === 0 || this.img.height === 0) return;
121
+ const t = this.img.width * this.scale, i = this.img.height * this.scale;
122
+ if (t <= this.canvas.width)
123
+ this.offset.x = (this.canvas.width - t) / 2;
124
+ else {
125
+ const e = this.canvas.width - t, a = 0;
126
+ this.offset.x = Math.min(a, Math.max(e, this.offset.x));
127
+ }
128
+ if (i <= this.canvas.height)
129
+ this.offset.y = (this.canvas.height - i) / 2;
130
+ else {
131
+ const e = this.canvas.height - i, a = 0;
132
+ this.offset.y = Math.min(a, Math.max(e, this.offset.y));
117
133
  }
118
134
  }
119
135
  // --- 事件处理 ---
@@ -135,19 +151,19 @@ class Kt {
135
151
  }
136
152
  }
137
153
  handleMouseDown(t) {
138
- const i = this.canvas.getBoundingClientRect(), e = t.clientX - i.left, l = t.clientY - i.top, r = this.toImageCoords(e, l);
154
+ const i = this.canvas.getBoundingClientRect(), e = t.clientX - i.left, a = t.clientY - i.top, r = this.toImageCoords(e, a);
139
155
  if (this.canvas.style.cursor === "grab" || this.canvas.style.cursor === "grabbing") {
140
- this.isPanning = !0, this.panStartPoint = { x: e, y: l }, this.canvas.style.cursor = "grabbing";
156
+ this.isPanning = !0, this.panStartPoint = { x: e, y: a }, this.canvas.style.cursor = "grabbing";
141
157
  return;
142
158
  }
143
159
  if (this.interactionMode === "select" && this.activeAnnotation) {
144
- const h = this.getHitHandle(e, l, this.activeAnnotation);
160
+ const h = this.getHitHandle(e, a, this.activeAnnotation);
145
161
  if (h !== -100) {
146
162
  this.isDragging = !0, this.dragStartPoint = r, this.selectedHandleIndex = h, this.dragStartAnnotation = JSON.parse(JSON.stringify(this.activeAnnotation));
147
163
  return;
148
164
  }
149
165
  }
150
- const c = this.interactionMode === "select" ? this.getHitCategory(e, l) : null;
166
+ const c = this.interactionMode === "select" ? this.getHitCategory(e, a) : null;
151
167
  if (c) {
152
168
  this.activeAnnotation = c, this.isDragging = !1, this.selectedHandleIndex = -1, this.emit("annotationChange", { action: "select", changedItem: c, imageUrl: this.imageUrl }), this.render();
153
169
  return;
@@ -166,7 +182,7 @@ class Kt {
166
182
  if (this.interactionMode === "draw") {
167
183
  if (this.isDrawing && this.currentTool === "polygon" && this.activeAnnotation) {
168
184
  const h = this.activeAnnotation.coordinates;
169
- if (h.points.length > 2 && at(r, h.points[0]) < 20 / this.scale) {
185
+ if (h.points.length > 2 && ct(r, h.points[0]) < 20 / this.scale) {
170
186
  this.finishDrawing();
171
187
  return;
172
188
  }
@@ -185,23 +201,23 @@ class Kt {
185
201
  this.activeAnnotation = null, this.render();
186
202
  }
187
203
  handleMouseMove(t) {
188
- const i = this.canvas.getBoundingClientRect(), e = t.clientX - i.left, l = t.clientY - i.top, r = this.toImageCoords(e, l);
204
+ const i = this.canvas.getBoundingClientRect(), e = t.clientX - i.left, a = t.clientY - i.top, r = this.toImageCoords(e, a);
189
205
  if (this.isPanning && this.panStartPoint) {
190
- const c = e - this.panStartPoint.x, o = l - this.panStartPoint.y;
191
- this.offset.x += c, this.offset.y += o, this.panStartPoint = { x: e, y: l }, this.render();
206
+ const c = e - this.panStartPoint.x, o = a - this.panStartPoint.y;
207
+ this.offset.x += c, this.offset.y += o, this.clampViewportOffset(), this.panStartPoint = { x: e, y: a }, this.render();
192
208
  return;
193
209
  }
194
210
  if (this.lastMouseMovePoint = r, this.isDrawing) {
195
211
  if (this.currentTool === "polygon" && this.activeAnnotation) {
196
212
  const c = this.activeAnnotation.coordinates;
197
213
  if (c.points.length > 2) {
198
- const o = c.points[0], h = at(r, o);
214
+ const o = c.points[0], h = ct(r, o);
199
215
  this.isHoveringStartPoint = h < 20 / this.scale;
200
216
  } else
201
217
  this.isHoveringStartPoint = !1;
202
218
  }
203
219
  this.updateDrawing(r);
204
- } else this.isDragging && this.activeAnnotation && this.dragStartPoint ? this.updateDragging(r) : this.checkHover(e, l, r);
220
+ } else this.isDragging && this.activeAnnotation && this.dragStartPoint ? this.updateDragging(r) : this.checkHover(e, a, r);
205
221
  this.render();
206
222
  }
207
223
  handleMouseUp(t) {
@@ -226,8 +242,8 @@ class Kt {
226
242
  // 辅助函数:将 hex 转换为 rgba
227
243
  hexToRgba(t, i) {
228
244
  if (!t.startsWith("#")) return t;
229
- const e = parseInt(t.slice(1, 3), 16), l = parseInt(t.slice(3, 5), 16), r = parseInt(t.slice(5, 7), 16);
230
- return `rgba(${e}, ${l}, ${r}, ${i})`;
245
+ const e = parseInt(t.slice(1, 3), 16), a = parseInt(t.slice(3, 5), 16), r = parseInt(t.slice(5, 7), 16);
246
+ return `rgba(${e}, ${a}, ${r}, ${i})`;
231
247
  }
232
248
  startDrawing(t) {
233
249
  if (!this.currentTool) return;
@@ -283,8 +299,8 @@ class Kt {
283
299
  const i = this.activeAnnotation.coordinates;
284
300
  i.x2 = t.x, i.y2 = t.y;
285
301
  } else if (this.activeAnnotation.type === "rotatedRect" && this.dragStartPoint) {
286
- const i = this.activeAnnotation.coordinates, e = Math.abs(t.x - this.dragStartPoint.x), l = Math.abs(t.y - this.dragStartPoint.y);
287
- i.width = e * 2, i.height = l * 2;
302
+ const i = this.activeAnnotation.coordinates, e = Math.abs(t.x - this.dragStartPoint.x), a = Math.abs(t.y - this.dragStartPoint.y);
303
+ i.width = e * 2, i.height = a * 2;
288
304
  } else this.activeAnnotation.type;
289
305
  }
290
306
  finishDrawing() {
@@ -295,8 +311,8 @@ class Kt {
295
311
  this.activeAnnotation = null, this.isDrawing = !1;
296
312
  return;
297
313
  }
298
- const i = Math.min(t.x1, t.x2), e = Math.max(t.x1, t.x2), l = Math.min(t.y1, t.y2), r = Math.max(t.y1, t.y2);
299
- t.x1 = i, t.x2 = e, t.y1 = l, t.y2 = r, this.annotations.push(this.activeAnnotation), this.emit("annotationChange", { action: "add", changedItem: this.activeAnnotation, imageUrl: this.imageUrl });
314
+ const i = Math.min(t.x1, t.x2), e = Math.max(t.x1, t.x2), a = Math.min(t.y1, t.y2), r = Math.max(t.y1, t.y2);
315
+ t.x1 = i, t.x2 = e, t.y1 = a, t.y2 = r, this.annotations.push(this.activeAnnotation), this.emit("annotationChange", { action: "add", changedItem: this.activeAnnotation, imageUrl: this.imageUrl });
300
316
  } else if (this.activeAnnotation.type === "polygon") {
301
317
  if (this.activeAnnotation.coordinates.points.length < 3) {
302
318
  this.activeAnnotation = null, this.isDrawing = !1;
@@ -320,40 +336,40 @@ class Kt {
320
336
  const i = t.x - this.dragStartPoint.x, e = t.y - this.dragStartPoint.y;
321
337
  this.selectedHandleIndex === -1 ? this.moveAnnotation(this.activeAnnotation, this.dragStartAnnotation, i, e) : this.resizeAnnotation(this.activeAnnotation, this.dragStartAnnotation, this.selectedHandleIndex, t);
322
338
  }
323
- moveAnnotation(t, i, e, l) {
339
+ moveAnnotation(t, i, e, a) {
324
340
  if (t.type === "rectangle") {
325
341
  const r = i.coordinates, c = t.coordinates;
326
- c.x1 = r.x1 + e, c.x2 = r.x2 + e, c.y1 = r.y1 + l, c.y2 = r.y2 + l;
342
+ c.x1 = r.x1 + e, c.x2 = r.x2 + e, c.y1 = r.y1 + a, c.y2 = r.y2 + a;
327
343
  } else if (t.type === "point") {
328
344
  const r = i.coordinates, c = t.coordinates;
329
- c.points = r.points.map((o) => ({ x: o.x + e, y: o.y + l }));
345
+ c.points = r.points.map((o) => ({ x: o.x + e, y: o.y + a }));
330
346
  } else if (t.type === "rotatedRect") {
331
347
  const r = i.coordinates, c = t.coordinates;
332
- c.x = r.x + e, c.y = r.y + l;
348
+ c.x = r.x + e, c.y = r.y + a;
333
349
  } else if (t.type === "polygon") {
334
350
  const r = i.coordinates, c = t.coordinates;
335
- c.points = r.points.map((o) => ({ x: o.x + e, y: o.y + l }));
351
+ c.points = r.points.map((o) => ({ x: o.x + e, y: o.y + a }));
336
352
  }
337
353
  }
338
- resizeAnnotation(t, i, e, l) {
354
+ resizeAnnotation(t, i, e, a) {
339
355
  if (t.type === "rectangle") {
340
356
  const r = t.coordinates;
341
- e === 0 && (r.x1 = l.x, r.y1 = l.y), e === 1 && (r.x2 = l.x, r.y1 = l.y), e === 2 && (r.x2 = l.x, r.y2 = l.y), e === 3 && (r.x1 = l.x, r.y2 = l.y);
357
+ e === 0 && (r.x1 = a.x, r.y1 = a.y), e === 1 && (r.x2 = a.x, r.y1 = a.y), e === 2 && (r.x2 = a.x, r.y2 = a.y), e === 3 && (r.x1 = a.x, r.y2 = a.y);
342
358
  } else if (t.type === "polygon") {
343
359
  const r = t.coordinates;
344
- e >= 0 && e < r.points.length && (r.points[e] = l);
360
+ e >= 0 && e < r.points.length && (r.points[e] = a);
345
361
  } else if (t.type === "point") {
346
362
  const r = t.coordinates;
347
- e >= 0 && e < r.points.length && (r.points[e] = l);
363
+ e >= 0 && e < r.points.length && (r.points[e] = a);
348
364
  } else if (t.type === "rotatedRect") {
349
365
  const r = t.coordinates;
350
366
  if (e === -2) {
351
- const c = r.x, o = r.y, h = l.x - c, p = l.y - o;
352
- let C = Math.atan2(p, h) * 180 / Math.PI;
353
- C += 90, r.angle = C;
367
+ const c = r.x, o = r.y, h = a.x - c, u = a.y - o;
368
+ let A = Math.atan2(u, h) * 180 / Math.PI;
369
+ A += 90, r.angle = A;
354
370
  } else {
355
- const c = r.angle * Math.PI / 180, o = Math.cos(-c), h = Math.sin(-c), p = l.x - r.x, C = l.y - r.y, u = p * o - C * h, f = p * h + C * o;
356
- (e === 0 || e === 3) && (r.width / 2, r.width = Math.abs(u) * 2), (e === 1 || e === 2) && (r.width = Math.abs(u) * 2), (e === 0 || e === 1) && (r.height = Math.abs(f) * 2), (e === 2 || e === 3) && (r.height = Math.abs(f) * 2);
371
+ const c = r.angle * Math.PI / 180, o = Math.cos(-c), h = Math.sin(-c), u = a.x - r.x, A = a.y - r.y, y = u * o - A * h, w = u * h + A * o;
372
+ (e === 0 || e === 3) && (r.width / 2, r.width = Math.abs(y) * 2), (e === 1 || e === 2) && (r.width = Math.abs(y) * 2), (e === 0 || e === 1) && (r.height = Math.abs(w) * 2), (e === 2 || e === 3) && (r.height = Math.abs(w) * 2);
357
373
  }
358
374
  }
359
375
  }
@@ -372,18 +388,18 @@ class Kt {
372
388
  return t.x >= e.x1 && t.x <= e.x2 && t.y >= e.y1 && t.y <= e.y2;
373
389
  } else if (i.type === "polygon") {
374
390
  const e = i.coordinates;
375
- return Gt(t, e.points);
391
+ return Kt(t, e.points);
376
392
  } else if (i.type === "rotatedRect") {
377
- const e = i.coordinates, l = ft(t, { x: e.x, y: e.y }, -e.angle), r = e.width / 2, c = e.height / 2;
378
- return l.x >= e.x - r && l.x <= e.x + r && l.y >= e.y - c && l.y <= e.y + c;
393
+ const e = i.coordinates, a = yt(t, { x: e.x, y: e.y }, -e.angle), r = e.width / 2, c = e.height / 2;
394
+ return a.x >= e.x - r && a.x <= e.x + r && a.y >= e.y - c && a.y <= e.y + c;
379
395
  } else if (i.type === "point")
380
- return i.coordinates.points.some((l) => at(t, l) < 10 / this.scale);
396
+ return i.coordinates.points.some((a) => ct(t, a) < 10 / this.scale);
381
397
  return !1;
382
398
  }
383
399
  getHitHandle(t, i, e) {
384
- const l = this.getAnnotationHandles(e), r = 6;
385
- for (let c = 0; c < l.length; c++) {
386
- const o = l[c], h = this.toScreenCoords(o.x, o.y);
400
+ const a = this.getAnnotationHandles(e), r = 6;
401
+ for (let c = 0; c < a.length; c++) {
402
+ const o = a[c], h = this.toScreenCoords(o.x, o.y);
387
403
  if (Math.abs(t - h.x) < r && Math.abs(i - h.y) < r)
388
404
  return e.type === "rotatedRect" && c === 4 ? -2 : c;
389
405
  }
@@ -408,16 +424,16 @@ class Kt {
408
424
  if (t.type === "point")
409
425
  return t.coordinates.points;
410
426
  if (t.type === "rotatedRect") {
411
- const i = t.coordinates, e = { x: i.x, y: i.y }, l = i.width / 2, r = i.height / 2, c = { x: i.x - l, y: i.y - r }, o = { x: i.x + l, y: i.y - r }, h = { x: i.x + l, y: i.y + r }, p = { x: i.x - l, y: i.y + r }, C = { x: i.x, y: i.y - r - 20 / this.scale };
412
- return [c, o, h, p, C].map((u) => ft(u, e, i.angle));
427
+ const i = t.coordinates, e = { x: i.x, y: i.y }, a = i.width / 2, r = i.height / 2, c = { x: i.x - a, y: i.y - r }, o = { x: i.x + a, y: i.y - r }, h = { x: i.x + a, y: i.y + r }, u = { x: i.x - a, y: i.y + r }, A = { x: i.x, y: i.y - r - 20 / this.scale };
428
+ return [c, o, h, u, A].map((y) => yt(y, e, i.angle));
413
429
  }
414
430
  }
415
431
  return [];
416
432
  }
417
433
  checkHover(t, i, e) {
418
- const l = this.getHitCategory(t, i);
419
- if (l) {
420
- this.canvas.style.cursor = "pointer", this.hoverAnnotation = l;
434
+ const a = this.getHitCategory(t, i);
435
+ if (a) {
436
+ this.canvas.style.cursor = "pointer", this.hoverAnnotation = a;
421
437
  return;
422
438
  }
423
439
  if (this.activeAnnotation && this.getHitHandle(t, i, this.activeAnnotation) !== -100) {
@@ -437,38 +453,38 @@ class Kt {
437
453
  if (t.length === 0) return;
438
454
  this.ctx.save(), this.ctx.font = "14px sans-serif", this.ctx.textBaseline = "top";
439
455
  let i = 10;
440
- const e = 10, l = 8, r = 4, c = 24, o = 8;
456
+ const e = 10, a = 8, r = 4, c = 24, o = 8;
441
457
  t.forEach((h) => {
442
- const p = h.label || "Unlabeled", C = this.ctx.measureText(p).width + l * 2, u = this.activeAnnotation === h, f = this.hoverAnnotation === h;
443
- this.ctx.fillStyle = u ? "#E3F2FD" : f ? "#F5F5F5" : "rgba(255, 255, 255, 0.9)", this.ctx.strokeStyle = u ? "#2196F3" : "#666", this.ctx.lineWidth = u ? 2 : 1, this.ctx.beginPath(), this.ctx.rect(i, e, C, c), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = u ? "#1976D2" : "#333", this.ctx.fillText(p, i + l, e + r), i += C + o;
458
+ const u = h.label || "Unlabeled", A = this.ctx.measureText(u).width + a * 2, y = this.activeAnnotation === h, w = this.hoverAnnotation === h;
459
+ this.ctx.fillStyle = y ? "#E3F2FD" : w ? "#F5F5F5" : "rgba(255, 255, 255, 0.9)", this.ctx.strokeStyle = y ? "#2196F3" : "#666", this.ctx.lineWidth = y ? 2 : 1, this.ctx.beginPath(), this.ctx.rect(i, e, A, c), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = y ? "#1976D2" : "#333", this.ctx.fillText(u, i + a, e + r), i += A + o;
444
460
  }), this.ctx.restore();
445
461
  }
446
462
  getHitCategory(t, i) {
447
- const e = this.annotations.filter((C) => C.type === "category");
463
+ const e = this.annotations.filter((A) => A.type === "category");
448
464
  if (e.length === 0) return null;
449
465
  this.ctx.save(), this.ctx.font = "14px sans-serif";
450
- let l = 10;
466
+ let a = 10;
451
467
  const r = 10, c = 8, o = 24, h = 8;
452
- let p = null;
453
- for (const C of e) {
454
- const u = C.label || "Unlabeled", f = this.ctx.measureText(u).width + c * 2;
455
- if (t >= l && t <= l + f && i >= r && i <= r + o) {
456
- p = C;
468
+ let u = null;
469
+ for (const A of e) {
470
+ const y = A.label || "Unlabeled", w = this.ctx.measureText(y).width + c * 2;
471
+ if (t >= a && t <= a + w && i >= r && i <= r + o) {
472
+ u = A;
457
473
  break;
458
474
  }
459
- l += f + h;
475
+ a += w + h;
460
476
  }
461
- return this.ctx.restore(), p;
477
+ return this.ctx.restore(), u;
462
478
  }
463
479
  drawItem(t, i) {
464
480
  var r;
465
481
  if (this.visibleLabels.size > 0 && !this.visibleLabels.has(t.label) && !i)
466
482
  return;
467
483
  this.ctx.save();
468
- const e = ((r = t.style) == null ? void 0 : r.strokeColor) || "#FF4081", l = i ? "#00E5FF" : e;
469
- if (this.ctx.strokeStyle = l, this.ctx.lineWidth = 2, i ? this.ctx.fillStyle = "rgba(0, 229, 255, 0.2)" : this.ctx.fillStyle = this.hexToRgba(e, 0.2), t.type === "rectangle") {
470
- const c = t.coordinates, o = this.toScreenCoords(c.x1, c.y1), h = this.toScreenCoords(c.x2, c.y2), p = Math.min(o.x, h.x), C = Math.min(o.y, h.y), u = Math.abs(o.x - h.x), f = Math.abs(o.y - h.y);
471
- this.ctx.strokeRect(p, C, u, f), this.ctx.fillStyle = i ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fillRect(p, C, u, f), i && this.drawHandles(this.getAnnotationHandles(t));
484
+ const e = ((r = t.style) == null ? void 0 : r.strokeColor) || "#FF4081", a = i ? "#00E5FF" : e;
485
+ if (this.ctx.strokeStyle = a, this.ctx.lineWidth = 2, i ? this.ctx.fillStyle = "rgba(0, 229, 255, 0.2)" : this.ctx.fillStyle = this.hexToRgba(e, 0.2), t.type === "rectangle") {
486
+ const c = t.coordinates, o = this.toScreenCoords(c.x1, c.y1), h = this.toScreenCoords(c.x2, c.y2), u = Math.min(o.x, h.x), A = Math.min(o.y, h.y), y = Math.abs(o.x - h.x), w = Math.abs(o.y - h.y);
487
+ this.ctx.strokeRect(u, A, y, w), this.ctx.fillStyle = i ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fillRect(u, A, y, w), i && this.drawHandles(this.getAnnotationHandles(t));
472
488
  } else if (t.type === "polygon") {
473
489
  const c = t.coordinates;
474
490
  if (c.points.length === 0) {
@@ -479,8 +495,8 @@ class Kt {
479
495
  const o = this.toScreenCoords(c.points[0].x, c.points[0].y);
480
496
  this.ctx.moveTo(o.x, o.y);
481
497
  for (let h = 1; h < c.points.length; h++) {
482
- const p = this.toScreenCoords(c.points[h].x, c.points[h].y);
483
- this.ctx.lineTo(p.x, p.y);
498
+ const u = this.toScreenCoords(c.points[h].x, c.points[h].y);
499
+ this.ctx.lineTo(u.x, u.y);
484
500
  }
485
501
  if (!this.isDrawing || t !== this.activeAnnotation)
486
502
  this.ctx.closePath();
@@ -488,11 +504,11 @@ class Kt {
488
504
  let h = this.lastMouseMovePoint;
489
505
  if (this.isHoveringStartPoint && c.points.length > 0) {
490
506
  h = c.points[0];
491
- const C = this.toScreenCoords(c.points[0].x, c.points[0].y);
492
- this.ctx.save(), this.ctx.beginPath(), this.ctx.arc(C.x, C.y, 10, 0, Math.PI * 2), this.ctx.fillStyle = "rgba(255, 215, 0, 0.6)", this.ctx.strokeStyle = "#FFFFFF", this.ctx.lineWidth = 2, this.ctx.fill(), this.ctx.stroke(), this.ctx.restore();
507
+ const A = this.toScreenCoords(c.points[0].x, c.points[0].y);
508
+ this.ctx.save(), this.ctx.beginPath(), this.ctx.arc(A.x, A.y, 10, 0, Math.PI * 2), this.ctx.fillStyle = "rgba(255, 215, 0, 0.6)", this.ctx.strokeStyle = "#FFFFFF", this.ctx.lineWidth = 2, this.ctx.fill(), this.ctx.stroke(), this.ctx.restore();
493
509
  }
494
- const p = this.toScreenCoords(h.x, h.y);
495
- this.ctx.lineTo(p.x, p.y);
510
+ const u = this.toScreenCoords(h.x, h.y);
511
+ this.ctx.lineTo(u.x, u.y);
496
512
  }
497
513
  this.ctx.stroke(), this.ctx.fillStyle = i ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fill(), i && this.drawHandles(this.getAnnotationHandles(t));
498
514
  } else if (t.type === "rotatedRect") {
@@ -513,63 +529,63 @@ class Kt {
513
529
  });
514
530
  }
515
531
  }
516
- const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
532
+ const Qt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
517
533
  <path d="M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896z m0-320a64 64 0 1 0 0-128 64 64 0 0 0 0 128z m0 64a128 128 0 1 1 0-256 128 128 0 0 1 0 256z" fill="currentColor"/>\r
518
- </svg>`, Qt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
519
- <path d="M609.408 149.376l-277.76 277.76a96 96 0 0 0 0 135.68l277.76 277.76a32 32 0 1 0 45.248-45.248L376.96 512l277.76-277.76a32 32 0 0 0-45.248-45.248z" fill="currentColor"/>\r
520
534
  </svg>`, te = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
521
- <path d="M704 192h160v160h-160z m-64-64v288h288V128H640zM160 672h160v160H160z m-64-64v288h288V608H96z m256-320h320v64H352z" fill="currentColor"/>\r
535
+ <path d="M609.408 149.376l-277.76 277.76a96 96 0 0 0 0 135.68l277.76 277.76a32 32 0 1 0 45.248-45.248L376.96 512l277.76-277.76a32 32 0 0 0-45.248-45.248z" fill="currentColor"/>\r
522
536
  </svg>`, ee = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
523
- <path d="M256 256h512v512H256z m-64-64v640h640V192H192z" fill="currentColor"/>\r
537
+ <path d="M704 192h160v160h-160z m-64-64v288h288V128H640zM160 672h160v160H160z m-64-64v288h288V608H96z m256-320h320v64H352z" fill="currentColor"/>\r
524
538
  </svg>`, ne = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
525
- <path d="M160 256h704a32 32 0 1 1 0 64h-64v608a32 32 0 0 1-32 32H256a32 32 0 0 1-32-32V320h-64a32 32 0 1 1 0-64zm128 64v576h448V320H288z m128 0v512a32 32 0 1 1-64 0V320a32 32 0 1 1 64 0zm256 0v512a32 32 0 1 1-64 0V320a32 32 0 1 1 64 0zM352 128h320a32 32 0 0 1 32 32v64H320v-64a32 32 0 0 1 32-32z" fill="currentColor"/>\r
539
+ <path d="M256 256h512v512H256z m-64-64v640h640V192H192z" fill="currentColor"/>\r
526
540
  </svg>`, se = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
527
- <path d="M512 666.56l-186.88-186.88a32 32 0 0 0-45.248 45.248l209.536 209.536a96 96 0 0 0 135.68 0l209.536-209.536a32 32 0 1 0-45.248-45.248L544 666.56V128a32 32 0 0 0-64 0v538.56zM192 832h640a32 32 0 1 1 0 64H192a32 32 0 1 1 0-64z" fill="currentColor"/>\r
541
+ <path d="M160 256h704a32 32 0 1 1 0 64h-64v608a32 32 0 0 1-32 32H256a32 32 0 0 1-32-32V320h-64a32 32 0 1 1 0-64zm128 64v576h448V320H288z m128 0v512a32 32 0 1 1-64 0V320a32 32 0 1 1 64 0zm256 0v512a32 32 0 1 1-64 0V320a32 32 0 1 1 64 0zM352 128h320a32 32 0 0 1 32 32v64H320v-64a32 32 0 0 1 32-32z" fill="currentColor"/>\r
528
542
  </svg>`, ie = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
529
- <path d="M832 512a32 32 0 1 1 64 0v352a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h352a32 32 0 0 1 0 64H192v640h640V512z m-144-320l-480 480v160h160l480-480-160-160z m-114.56 480H256v-117.76L653.44 236.8l117.76 117.76L573.44 672z m208-208l-117.76-117.76 66.56-66.56a32 32 0 0 1 45.248 0l72.512 72.512a32 32 0 0 1 0 45.248l-66.56 66.56z" fill="currentColor"/>\r
543
+ <path d="M512 666.56l-186.88-186.88a32 32 0 0 0-45.248 45.248l209.536 209.536a96 96 0 0 0 135.68 0l209.536-209.536a32 32 0 1 0-45.248-45.248L544 666.56V128a32 32 0 0 0-64 0v538.56zM192 832h640a32 32 0 1 1 0 64H192a32 32 0 1 1 0-64z" fill="currentColor"/>\r
530
544
  </svg>`, oe = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
531
- <path d="M940.48 876.16L148.16 83.84a32 32 0 1 0-45.12 45.12L236.8 262.4C163.52 337.28 107.52 429.12 82.56 528.96a32 32 0 0 0 0 20.48C144.384 727.68 314.88 840.96 512 840.96c103.04 0 199.36-30.72 283.52-83.84l99.84 99.84a32 32 0 1 0 45.12-45.12zM512 776.96c-176.64 0-333.44-98.56-402.56-248.96 25.6-56.32 63.36-107.52 110.08-151.04L364.8 522.24a128 128 0 0 0 147.2 147.2l123.52 123.52A445.44 445.44 0 0 1 512 776.96z m373.12-32.64l-64-64C857.6 627.84 879.616 572.16 879.616 512c0-176.64-156.8-328.96-367.616-328.96-58.24 0-113.6 11.52-164.48 32.64l-55.68-55.68C346.88 136.96 427.52 119.04 512 119.04c229.76 0 425.216 142.08 493.44 346.24a32 32 0 0 1 0 20.48 450.56 450.56 0 0 1-120.32 258.56z m-309.12-309.12l-128-128A128 128 0 0 1 576 435.2z" fill="currentColor"/>\r
545
+ <path d="M832 512a32 32 0 1 1 64 0v352a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h352a32 32 0 0 1 0 64H192v640h640V512z m-144-320l-480 480v160h160l480-480-160-160z m-114.56 480H256v-117.76L653.44 236.8l117.76 117.76L573.44 672z m208-208l-117.76-117.76 66.56-66.56a32 32 0 0 1 45.248 0l72.512 72.512a32 32 0 0 1 0 45.248l-66.56 66.56z" fill="currentColor"/>\r
532
546
  </svg>`, ae = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
533
- <path d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm0 832a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm-48-384H320a32 32 0 0 1 0-64h144V304a32 32 0 1 1 64 0v144h144a32 32 0 1 1 0 64H528v144a32 32 0 1 1-64 0V512z" fill="currentColor"/>\r
547
+ <path d="M940.48 876.16L148.16 83.84a32 32 0 1 0-45.12 45.12L236.8 262.4C163.52 337.28 107.52 429.12 82.56 528.96a32 32 0 0 0 0 20.48C144.384 727.68 314.88 840.96 512 840.96c103.04 0 199.36-30.72 283.52-83.84l99.84 99.84a32 32 0 1 0 45.12-45.12zM512 776.96c-176.64 0-333.44-98.56-402.56-248.96 25.6-56.32 63.36-107.52 110.08-151.04L364.8 522.24a128 128 0 0 0 147.2 147.2l123.52 123.52A445.44 445.44 0 0 1 512 776.96z m373.12-32.64l-64-64C857.6 627.84 879.616 572.16 879.616 512c0-176.64-156.8-328.96-367.616-328.96-58.24 0-113.6 11.52-164.48 32.64l-55.68-55.68C346.88 136.96 427.52 119.04 512 119.04c229.76 0 425.216 142.08 493.44 346.24a32 32 0 0 1 0 20.48 450.56 450.56 0 0 1-120.32 258.56z m-309.12-309.12l-128-128A128 128 0 0 1 576 435.2z" fill="currentColor"/>\r
534
548
  </svg>`, le = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
535
- <path d="M224 448a32 32 0 0 0 9.536 22.592l416 416a32 32 0 0 0 45.248 0l226.24-226.24a32 32 0 0 0 0-45.248l-416-416A32 32 0 0 0 482.432 192H256a64 64 0 0 0-64 64v192z m64-192h160l384 384-160 160-384-384V256z m64 128a64 64 0 1 0 0-128 64 64 0 0 0 0 128z" fill="currentColor"/>\r
549
+ <path d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm0 832a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm-48-384H320a32 32 0 0 1 0-64h144V304a32 32 0 1 1 64 0v144h144a32 32 0 1 1 0 64H528v144a32 32 0 1 1-64 0V512z" fill="currentColor"/>\r
536
550
  </svg>`, re = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
537
- <path d="M160 832h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64zm0-704h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64zm0 352h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64z" fill="currentColor"/>\r
551
+ <path d="M224 448a32 32 0 0 0 9.536 22.592l416 416a32 32 0 0 0 45.248 0l226.24-226.24a32 32 0 0 0 0-45.248l-416-416A32 32 0 0 0 482.432 192H256a64 64 0 0 0-64 64v192z m64-192h160l384 384-160 160-384-384V256z m64 128a64 64 0 1 0 0-128 64 64 0 0 0 0 128z" fill="currentColor"/>\r
538
552
  </svg>`, ce = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
539
- <path d="M784.512 230.272v-50.56a32 32 0 1 1 64 0v149.056a32 32 0 0 1-32 32H667.52a32 32 0 1 1 0-64h92.992A320 320 0 1 0 524.8 833.152a320 320 0 0 0 320-320h64a384 384 0 0 1-384 384 384 384 0 0 1-384-384 384 384 0 0 1 643.712-282.88z" fill="currentColor"/>\r
553
+ <path d="M160 832h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64zm0-704h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64zm0 352h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64z" fill="currentColor"/>\r
540
554
  </svg>`, he = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
541
- <path d="M340.864 149.376a32 32 0 0 0-45.248 45.248L573.44 512l-277.76 317.376a32 32 0 0 0 45.248 45.248l277.76-277.76a96 96 0 0 0 0-135.68L340.864 149.376z" fill="currentColor"/>\r
555
+ <path d="M784.512 230.272v-50.56a32 32 0 1 1 64 0v149.056a32 32 0 0 1-32 32H667.52a32 32 0 1 1 0-64h92.992A320 320 0 1 0 524.8 833.152a320 320 0 0 0 320-320h64a384 384 0 0 1-384 384 384 384 0 0 1-384-384 384 384 0 0 1 643.712-282.88z" fill="currentColor"/>\r
542
556
  </svg>`, de = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
543
- <path d="M512 192c229.76 0 425.216 142.08 493.44 346.24a32 32 0 0 1 0 20.48C937.216 762.88 741.76 904.96 512 904.96S86.784 762.88 18.56 558.72a32 32 0 0 1 0-20.48C86.784 334.08 282.24 192 512 192zm0 64c-197.12 0-367.616 120.32-428.16 296.32C144.384 727.68 314.88 840.96 512 840.96s367.616-113.28 428.16-288.64C879.616 376.32 709.12 256 512 256zm0 160a128 128 0 1 1 0 256 128 128 0 0 1 0-256zm0 64a64 64 0 1 0 0 128 64 64 0 0 0 0-128z" fill="currentColor"/>\r
557
+ <path d="M340.864 149.376a32 32 0 0 0-45.248 45.248L573.44 512l-277.76 317.376a32 32 0 0 0 45.248 45.248l277.76-277.76a96 96 0 0 0 0-135.68L340.864 149.376z" fill="currentColor"/>\r
544
558
  </svg>`, ge = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
545
- <path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM416 448h96a32 32 0 0 1 0 64h-96v96a32 32 0 0 1-64 0v-96h-96a32 32 0 0 1 0-64h96v-96a32 32 0 0 1 64 0v96z" fill="currentColor"/>\r
559
+ <path d="M512 192c229.76 0 425.216 142.08 493.44 346.24a32 32 0 0 1 0 20.48C937.216 762.88 741.76 904.96 512 904.96S86.784 762.88 18.56 558.72a32 32 0 0 1 0-20.48C86.784 334.08 282.24 192 512 192zm0 64c-197.12 0-367.616 120.32-428.16 296.32C144.384 727.68 314.88 840.96 512 840.96s367.616-113.28 428.16-288.64C879.616 376.32 709.12 256 512 256zm0 160a128 128 0 1 1 0 256 128 128 0 0 1 0-256zm0 64a64 64 0 1 0 0 128 64 64 0 0 0 0-128z" fill="currentColor"/>\r
546
560
  </svg>`, ue = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
561
+ <path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM416 448h96a32 32 0 0 1 0 64h-96v96a32 32 0 0 1-64 0v-96h-96a32 32 0 0 1 0-64h96v-96a32 32 0 0 1 64 0v96z" fill="currentColor"/>\r
562
+ </svg>`, ve = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
547
563
  <path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM256 448h320a32 32 0 1 1 0 64H256a32 32 0 1 1 0-64z" fill="currentColor"/>\r
548
- </svg>`, ve = ["innerHTML"], me = /* @__PURE__ */ G({
564
+ </svg>`, me = ["innerHTML"], fe = /* @__PURE__ */ K({
549
565
  __name: "SvgIcon",
550
566
  props: {
551
567
  name: {},
552
568
  size: {}
553
569
  },
554
- setup(m) {
555
- const t = m, i = k(""), e = /* @__PURE__ */ Object.assign({ "../assets/svg/aim.svg": Zt, "../assets/svg/back.svg": Qt, "../assets/svg/connection.svg": te, "../assets/svg/crop.svg": ee, "../assets/svg/delete.svg": ne, "../assets/svg/download.svg": se, "../assets/svg/edit.svg": ie, "../assets/svg/hide.svg": oe, "../assets/svg/pointer.svg": ae, "../assets/svg/price-tag.svg": le, "../assets/svg/rank.svg": re, "../assets/svg/refresh-right.svg": ce, "../assets/svg/right.svg": he, "../assets/svg/view.svg": de, "../assets/svg/zoom-in.svg": ge, "../assets/svg/zoom-out.svg": ue });
556
- return Xt(() => {
557
- const l = `../assets/svg/${t.name}.svg`, r = e[l];
558
- r ? i.value = r : (console.warn(`Icon ${t.name} not found at path ${l}`), i.value = "");
559
- }), (l, r) => (y(), x("i", {
560
- class: V(["svg-icon", [m.size ? `size-${m.size}` : ""]]),
570
+ setup(v) {
571
+ const t = v, i = S(""), e = /* @__PURE__ */ Object.assign({ "../assets/svg/aim.svg": Qt, "../assets/svg/back.svg": te, "../assets/svg/connection.svg": ee, "../assets/svg/crop.svg": ne, "../assets/svg/delete.svg": se, "../assets/svg/download.svg": ie, "../assets/svg/edit.svg": oe, "../assets/svg/hide.svg": ae, "../assets/svg/pointer.svg": le, "../assets/svg/price-tag.svg": re, "../assets/svg/rank.svg": ce, "../assets/svg/refresh-right.svg": he, "../assets/svg/right.svg": de, "../assets/svg/view.svg": ge, "../assets/svg/zoom-in.svg": ue, "../assets/svg/zoom-out.svg": ve });
572
+ return Yt(() => {
573
+ const a = `../assets/svg/${t.name}.svg`, r = e[a];
574
+ r ? i.value = r : (console.warn(`Icon ${t.name} not found at path ${a}`), i.value = "");
575
+ }), (a, r) => (f(), p("i", {
576
+ class: V(["svg-icon", [v.size ? `size-${v.size}` : ""]]),
561
577
  innerHTML: i.value
562
- }, null, 10, ve));
578
+ }, null, 10, me));
563
579
  }
564
- }), K = (m, t) => {
565
- const i = m.__vccOpts || m;
566
- for (const [e, l] of t)
567
- i[e] = l;
580
+ }), Z = (v, t) => {
581
+ const i = v.__vccOpts || v;
582
+ for (const [e, a] of t)
583
+ i[e] = a;
568
584
  return i;
569
- }, P = /* @__PURE__ */ K(me, [["__scopeId", "data-v-3928607b"]]), fe = {
585
+ }, P = /* @__PURE__ */ Z(fe, [["__scopeId", "data-v-3928607b"]]), ye = {
570
586
  key: 0,
571
587
  class: "image-list-sidebar"
572
- }, ye = { class: "image-list-title" }, pe = { class: "image-list-scroll" }, xe = ["onClick"], be = { class: "image-list-stage" }, we = ["src", "alt"], Ce = {
588
+ }, pe = { class: "image-list-title" }, xe = { class: "image-list-scroll" }, be = ["onClick"], we = { class: "image-list-stage" }, Ce = ["src", "alt"], Ae = {
573
589
  key: 0,
574
590
  class: "thumb-overlay-layer"
575
591
  }, _e = {
@@ -577,25 +593,25 @@ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
577
593
  class: "thumb-overlay-svg",
578
594
  viewBox: "0 0 100 100",
579
595
  preserveAspectRatio: "none"
580
- }, Ae = ["points"], Ie = { class: "image-list-text" }, ke = {
596
+ }, Ie = ["points"], ke = { class: "image-list-text" }, Se = {
581
597
  key: 1,
582
598
  class: "left-sidebar"
583
- }, Se = ["onClick", "title"], Me = { class: "center-area" }, ze = {
599
+ }, Me = ["onClick", "title"], ze = { class: "center-area" }, $e = {
584
600
  key: 0,
585
601
  class: "top-bar"
586
- }, $e = { class: "label-selector" }, Te = { class: "tags-row" }, Pe = ["onClick"], He = {
602
+ }, Te = { class: "label-selector" }, Pe = { class: "tags-row" }, He = ["onClick"], Le = {
587
603
  key: 0,
588
604
  class: "no-labels"
589
- }, Le = {
605
+ }, Re = {
590
606
  key: 1,
591
607
  class: "batch-nav"
592
- }, Be = ["disabled"], De = ["disabled"], Re = {
608
+ }, Be = ["disabled"], De = ["disabled"], Ue = {
593
609
  key: 2,
594
610
  class: "right-sidebar"
595
- }, Ue = { class: "label-list" }, Fe = { class: "label-row" }, Ee = ["onUpdate:modelValue", "onChange"], Oe = ["title"], Ve = ["onClick"], Ne = { class: "action-icon more-actions" }, We = ["onClick"], Je = {
611
+ }, Fe = { class: "label-list" }, Ee = { class: "label-row" }, Oe = ["onUpdate:modelValue", "onChange"], Ve = ["title"], Ne = ["onClick"], We = { class: "action-icon more-actions" }, Je = ["onClick"], je = {
596
612
  key: 3,
597
613
  class: "modal-overlay"
598
- }, je = { class: "modal-content" }, Xe = { class: "form-group" }, Ye = { class: "form-group" }, qe = { class: "color-input-wrapper" }, Ge = /* @__PURE__ */ G({
614
+ }, Ye = { class: "modal-content" }, Xe = { class: "form-group" }, qe = { class: "form-group" }, Ge = { class: "color-input-wrapper" }, Ke = /* @__PURE__ */ K({
599
615
  __name: "ImageAnnotator",
600
616
  props: {
601
617
  annotationTypes: { default: () => ["rectangle", "polygon", "point", "rotatedRect"] },
@@ -612,215 +628,218 @@ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
612
628
  maxZoom: {}
613
629
  },
614
630
  emits: ["annotationChange", "batchChange", "labelChange", "ready", "error", "tool:change", "viewport:change", "annotation:add", "annotation:update", "annotation:delete", "annotation:select", "prediction:loaded", "prediction:apply", "prediction:reject"],
615
- setup(m, { expose: t, emit: i }) {
616
- const e = m, l = i, r = k(null), c = k(null), o = k(null), h = k(null), p = k(0), C = k(""), u = k([]), f = k(""), A = k(!1), T = k({ name: "", color: "#FF0000" }), B = k("none"), D = k([]), E = k({}), lt = O(() => h.value === "select" && !!C.value), Z = (n) => {
617
- if (!n || E.value[n]) return;
631
+ setup(v, { expose: t, emit: i }) {
632
+ const e = v, a = i, r = S(null), c = S(null), o = S(null), h = S(null), u = S(0), A = S(""), y = S([]), w = S(""), I = S(!1), C = S({ name: "", color: "#FF0000" }), B = S("none"), D = S([]), L = S({}), Q = U(() => h.value === "select" && !!A.value), J = (n) => {
633
+ if (!n || L.value[n]) return;
618
634
  const s = new Image();
619
635
  s.onload = () => {
620
- const a = s.naturalWidth || 1, d = s.naturalHeight || 1;
621
- E.value = {
622
- ...E.value,
623
- [n]: { width: a, height: d }
636
+ const l = s.naturalWidth || 1, d = s.naturalHeight || 1;
637
+ L.value = {
638
+ ...L.value,
639
+ [n]: { width: l, height: d }
624
640
  };
625
641
  }, s.src = n;
626
- }, X = () => {
642
+ }, tt = () => {
627
643
  e.batchImages.forEach((n) => {
628
- Z(n.imageUrl);
644
+ J(n.imageUrl);
629
645
  });
630
- }, R = () => {
631
- var a, d, v, _;
632
- const n = e.batchImages[p.value], s = (n == null ? void 0 : n.imageUrl) || ((a = e.image) == null ? void 0 : a.url);
646
+ }, E = () => {
647
+ var l, d, m, _;
648
+ const n = e.batchImages[u.value], s = (n == null ? void 0 : n.imageUrl) || ((l = e.image) == null ? void 0 : l.url);
633
649
  return {
634
650
  eventId: `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
635
651
  timestamp: Date.now(),
636
652
  requestId: e.requestId,
637
653
  taskId: (d = e.session) == null ? void 0 : d.taskId,
638
- imageId: ((v = e.image) == null ? void 0 : v.id) || s,
654
+ imageId: ((m = e.image) == null ? void 0 : m.id) || s,
639
655
  operator: (_ = e.session) == null ? void 0 : _.userId
640
656
  };
641
- }, Q = (n) => {
657
+ }, et = (n) => {
642
658
  var d;
643
659
  const s = n == null ? void 0 : n.action;
644
660
  if (!s) return;
645
- const a = {
646
- meta: R(),
661
+ const l = {
662
+ meta: E(),
647
663
  action: s,
648
664
  current: n == null ? void 0 : n.changedItem,
649
665
  source: (d = n == null ? void 0 : n.changedItem) != null && d.predictionId ? "prediction" : "manual"
650
666
  };
651
- s === "add" && l("annotation:add", a), s === "update" && l("annotation:update", a), s === "delete" && l("annotation:delete", a), s === "select" && l("annotation:select", a);
652
- }, tt = O(() => e.annotationTypes.filter((n) => n !== "category")), et = (n) => ({
667
+ s === "add" && a("annotation:add", l), s === "update" && a("annotation:update", l), s === "delete" && a("annotation:delete", l), s === "select" && a("annotation:select", l);
668
+ }, nt = U(() => e.annotationTypes.filter((n) => n !== "category")), st = (n) => ({
653
669
  rectangle: "crop",
654
670
  polygon: "connection",
655
671
  point: "aim",
656
672
  rotatedRect: "refresh-right",
657
673
  category: "price-tag"
658
- })[n] || n, b = (n) => ({
674
+ })[n] || n, it = (n) => ({
659
675
  rectangle: "矩形框",
660
676
  polygon: "多边形",
661
677
  point: "关键点",
662
678
  rotatedRect: "旋转矩形",
663
679
  category: "分类标签"
664
680
  })[n] || n;
665
- Yt(() => {
666
- if (X(), r.value) {
667
- o.value = new Kt(r.value), o.value.on("annotationChange", (s) => {
668
- var a, d;
681
+ Xt(() => {
682
+ if (tt(), r.value) {
683
+ o.value = new Zt(r.value), o.value.on("annotationChange", (s) => {
684
+ var l, d;
669
685
  if (s.action === "add" && s.changedItem) {
670
- const v = u.value.find((_) => _.id === f.value);
671
- v && (s.changedItem.label = v.name, s.changedItem.labelId = v.id);
686
+ const m = y.value.find((_) => _.id === w.value);
687
+ m && (s.changedItem.label = m.name, s.changedItem.labelId = m.id);
672
688
  }
673
- s.action === "select" ? C.value = ((a = s.changedItem) == null ? void 0 : a.id) || "" : s.action === "delete" && ((d = s.changedItem) == null ? void 0 : d.id) === C.value && (C.value = ""), l("annotationChange", s), Q(s);
674
- }), S(), w();
689
+ s.action === "select" ? A.value = ((l = s.changedItem) == null ? void 0 : l.id) || "" : s.action === "delete" && ((d = s.changedItem) == null ? void 0 : d.id) === A.value && (A.value = ""), a("annotationChange", s), et(s);
690
+ }), x(), N();
675
691
  const n = new ResizeObserver(() => {
676
692
  var s;
677
693
  (s = o.value) == null || s.resize();
678
694
  });
679
- c.value && n.observe(c.value), e.defaultActiveType && U(e.defaultActiveType), l("ready", { meta: R() });
695
+ c.value && n.observe(c.value), e.defaultActiveType && b(e.defaultActiveType), a("ready", { meta: E() });
680
696
  }
681
697
  });
682
- const w = () => {
698
+ const N = () => {
683
699
  if (!o.value) return;
684
- const n = u.value.find((a) => a.id === f.value);
700
+ const n = y.value.find((l) => l.id === w.value);
685
701
  n && o.value.setLabelStyle(n.color);
686
- const s = u.value.filter((a) => a.visible).map((a) => a.name);
702
+ const s = y.value.filter((l) => l.visible).map((l) => l.name);
687
703
  o.value.setVisibleLabels(s);
688
- }, S = () => {
704
+ }, x = () => {
689
705
  var n;
690
706
  if (o.value)
691
- if (C.value = "", e.batchImages.length > 0) {
692
- const s = e.batchImages[p.value];
707
+ if (A.value = "", requestAnimationFrame(() => {
708
+ var s;
709
+ (s = o.value) == null || s.resize();
710
+ }), e.batchImages.length > 0) {
711
+ const s = e.batchImages[u.value];
693
712
  o.value.loadImage(s.imageUrl), s.annotations ? o.value.setAnnotations(s.annotations) : o.value.setAnnotations([]);
694
713
  } else (n = e.image) != null && n.url && o.value.loadImage(e.image.url);
695
- }, U = (n) => {
696
- var s, a;
697
- if (h.value = n, C.value = "", n !== "pan" && n !== "select" && u.value.length === 0) {
714
+ }, b = (n) => {
715
+ var s, l;
716
+ if (h.value = n, A.value = "", n !== "pan" && n !== "select" && y.value.length === 0) {
698
717
  alert("请先创建标签!");
699
718
  return;
700
719
  }
701
- n === "pan" || n === "select" ? (s = o.value) == null || s.setTool(n) : (a = o.value) == null || a.setTool(n), l("tool:change", { meta: R(), tool: n });
702
- }, rt = () => {
720
+ n === "pan" || n === "select" ? (s = o.value) == null || s.setTool(n) : (l = o.value) == null || l.setTool(n), a("tool:change", { meta: E(), tool: n });
721
+ }, M = () => {
703
722
  var n;
704
723
  (n = o.value) != null && n.activeAnnotation && o.value.deleteAnnotation(o.value.activeAnnotation.id);
705
- }, ct = () => {
706
- o.value && l("viewport:change", {
707
- meta: R(),
724
+ }, W = () => {
725
+ o.value && a("viewport:change", {
726
+ meta: E(),
708
727
  scale: o.value.scale,
709
728
  offset: { ...o.value.offset }
710
729
  });
711
- }, yt = () => {
730
+ }, ht = () => {
712
731
  var n;
713
- (n = o.value) == null || n.zoom(1), ct();
732
+ (n = o.value) == null || n.zoom(1), W();
714
733
  }, pt = () => {
715
734
  var n;
716
- (n = o.value) == null || n.zoom(-1), ct();
735
+ (n = o.value) == null || n.zoom(-1), W();
717
736
  }, xt = () => {
718
- T.value = { name: "", color: "#2196F3" }, A.value = !0;
719
- }, ht = () => {
720
- A.value = !1;
737
+ C.value = { name: "", color: "#2196F3" }, I.value = !0;
738
+ }, dt = () => {
739
+ I.value = !1;
721
740
  }, bt = () => {
722
- if (!T.value.name.trim()) {
741
+ if (!C.value.name.trim()) {
723
742
  alert("请输入标签名称");
724
743
  return;
725
744
  }
726
745
  const s = {
727
746
  id: Date.now().toString(),
728
- name: T.value.name,
729
- color: T.value.color,
747
+ name: C.value.name,
748
+ color: C.value.color,
730
749
  visible: !0
731
750
  };
732
- u.value.push(s), l("labelChange", u.value), u.value.length === 1 && W(s), ht();
733
- }, W = (n) => {
751
+ y.value.push(s), a("labelChange", y.value), y.value.length === 1 && j(s), dt();
752
+ }, j = (n) => {
734
753
  var s;
735
- f.value = n.id, (s = o.value) == null || s.setLabelStyle(n.color);
754
+ w.value = n.id, (s = o.value) == null || s.setLabelStyle(n.color);
736
755
  }, wt = (n, s) => {
737
756
  if (!n.startsWith("#")) return n;
738
- let a = 0, d = 0, v = 0;
739
- return n.length === 4 ? (a = parseInt(n[1] + n[1], 16), d = parseInt(n[2] + n[2], 16), v = parseInt(n[3] + n[3], 16)) : n.length === 7 && (a = parseInt(n.slice(1, 3), 16), d = parseInt(n.slice(3, 5), 16), v = parseInt(n.slice(5, 7), 16)), `rgba(${a}, ${d}, ${v}, ${s})`;
757
+ let l = 0, d = 0, m = 0;
758
+ return n.length === 4 ? (l = parseInt(n[1] + n[1], 16), d = parseInt(n[2] + n[2], 16), m = parseInt(n[3] + n[3], 16)) : n.length === 7 && (l = parseInt(n.slice(1, 3), 16), d = parseInt(n.slice(3, 5), 16), m = parseInt(n.slice(5, 7), 16)), `rgba(${l}, ${d}, ${m}, ${s})`;
740
759
  }, Ct = (n) => {
741
760
  var s;
742
- if (n.id === f.value && ((s = o.value) == null || s.setLabelStyle(n.color)), o.value) {
743
- const a = o.value.getAnnotations();
761
+ if (n.id === w.value && ((s = o.value) == null || s.setLabelStyle(n.color)), o.value) {
762
+ const l = o.value.getAnnotations();
744
763
  let d = !1;
745
- a.forEach((v) => {
746
- v.label === n.name && (v.style || (v.style = {}), v.style.strokeColor = n.color, v.style.fillColor = wt(n.color, 0.2), d = !0);
764
+ l.forEach((m) => {
765
+ m.label === n.name && (m.style || (m.style = {}), m.style.strokeColor = n.color, m.style.fillColor = wt(n.color, 0.2), d = !0);
747
766
  }), d && o.value.render();
748
767
  }
749
- l("labelChange", u.value);
750
- }, _t = (n) => {
751
- n.visible = !n.visible, w();
768
+ a("labelChange", y.value);
752
769
  }, At = (n) => {
753
- const s = u.value.findIndex((a) => a.id === n);
754
- s > -1 && (u.value.splice(s, 1), l("labelChange", u.value), f.value === n && (f.value = u.value.length > 0 ? u.value[0].id : "", f.value && W(u.value[0])), w());
770
+ n.visible = !n.visible, N();
771
+ }, _t = (n) => {
772
+ const s = y.value.findIndex((l) => l.id === n);
773
+ s > -1 && (y.value.splice(s, 1), a("labelChange", y.value), w.value === n && (w.value = y.value.length > 0 ? y.value[0].id : "", w.value && j(y.value[0])), N());
755
774
  };
756
- J(() => e.labels, (n) => {
775
+ Y(() => e.labels, (n) => {
757
776
  const s = JSON.parse(JSON.stringify(n || []));
758
- if (u.value = s, u.value.length > 0)
759
- if (!f.value || !u.value.find((a) => a.id === f.value))
760
- W(u.value[0]);
777
+ if (y.value = s, y.value.length > 0)
778
+ if (!w.value || !y.value.find((l) => l.id === w.value))
779
+ j(y.value[0]);
761
780
  else {
762
- const a = u.value.find((d) => d.id === f.value);
763
- a && W(a);
781
+ const l = y.value.find((d) => d.id === w.value);
782
+ l && j(l);
764
783
  }
765
784
  else
766
- f.value = "";
767
- w();
785
+ w.value = "";
786
+ N();
768
787
  }, { immediate: !0, deep: !0 });
769
788
  const It = () => {
770
- p.value > 0 && (nt(), p.value--, S(), st());
789
+ u.value > 0 && (ot(), u.value--, x(), at());
771
790
  }, kt = () => {
772
- p.value < e.batchImages.length - 1 && (nt(), p.value++, S(), st());
773
- }, nt = () => {
791
+ u.value < e.batchImages.length - 1 && (ot(), u.value++, x(), at());
792
+ }, ot = () => {
774
793
  if (o.value) {
775
794
  const n = o.value.getAnnotations();
776
- e.batchImages[p.value].annotations = n;
795
+ e.batchImages[u.value].annotations = n;
777
796
  }
778
- }, st = () => {
779
- const n = e.batchImages[p.value];
780
- l("batchChange", {
781
- currentIndex: p.value,
797
+ }, at = () => {
798
+ const n = e.batchImages[u.value];
799
+ a("batchChange", {
800
+ currentIndex: u.value,
782
801
  total: e.batchImages.length,
783
802
  currentImageUrl: n.imageUrl,
784
803
  currentAnnotations: n.annotations || []
785
804
  });
786
- }, dt = (n = []) => {
787
- var v;
805
+ }, gt = (n = []) => {
806
+ var m;
788
807
  if (!o.value) return;
789
808
  if (D.value = JSON.parse(JSON.stringify(n)), D.value.length === 0) {
790
809
  B.value = "none";
791
810
  return;
792
811
  }
793
812
  B.value = "loaded";
794
- const a = (o.value.getAnnotations() || []).filter((_) => !_.predictionId), d = D.value.map((_) => {
795
- const M = JSON.parse(JSON.stringify(_.annotation));
796
- return M.id = M.id || `pred-${_.id}`, M.predictionId = _.id, M.modelRunId = _.modelRunId || M.modelRunId, M.confidence = _.confidence ?? M.confidence, M.reviewStatus = M.reviewStatus || "draft", M;
813
+ const l = (o.value.getAnnotations() || []).filter((_) => !_.predictionId), d = D.value.map((_) => {
814
+ const z = JSON.parse(JSON.stringify(_.annotation));
815
+ return z.id = z.id || `pred-${_.id}`, z.predictionId = _.id, z.modelRunId = _.modelRunId || z.modelRunId, z.confidence = _.confidence ?? z.confidence, z.reviewStatus = z.reviewStatus || "draft", z;
797
816
  });
798
- o.value.setAnnotations([...a, ...d]), l("prediction:loaded", {
799
- meta: R(),
800
- modelRunId: (v = D.value[0]) == null ? void 0 : v.modelRunId,
817
+ o.value.setAnnotations([...l, ...d]), a("prediction:loaded", {
818
+ meta: E(),
819
+ modelRunId: (m = D.value[0]) == null ? void 0 : m.modelRunId,
801
820
  candidates: D.value
802
821
  });
803
822
  }, St = (n, s) => {
804
- var v;
823
+ var m;
805
824
  if (!o.value) return [];
806
825
  B.value = "applying";
807
826
  const d = (o.value.getAnnotations() || []).filter((_) => _.predictionId && n.includes(_.predictionId));
808
827
  return d.forEach((_) => {
809
828
  _.reviewStatus = "accepted";
810
- }), B.value = "applied", l("prediction:apply", {
811
- meta: R(),
812
- modelRunId: (v = d[0]) == null ? void 0 : v.modelRunId,
829
+ }), B.value = "applied", a("prediction:apply", {
830
+ meta: E(),
831
+ modelRunId: (m = d[0]) == null ? void 0 : m.modelRunId,
813
832
  candidateIds: n,
814
833
  threshold: s,
815
834
  acceptedAnnotations: d
816
835
  }), o.value.render(), d;
817
836
  }, Mt = (n, s) => {
818
- var v;
837
+ var m;
819
838
  if (!o.value) return;
820
- const a = o.value.getAnnotations() || [], d = a.filter((_) => !(_.predictionId && n.includes(_.predictionId)));
821
- o.value.setAnnotations(d), l("prediction:reject", {
822
- meta: R(),
823
- modelRunId: (v = a.find((_) => _.predictionId && n.includes(_.predictionId))) == null ? void 0 : v.modelRunId,
839
+ const l = o.value.getAnnotations() || [], d = l.filter((_) => !(_.predictionId && n.includes(_.predictionId)));
840
+ o.value.setAnnotations(d), a("prediction:reject", {
841
+ meta: E(),
842
+ modelRunId: (m = l.find((_) => _.predictionId && n.includes(_.predictionId))) == null ? void 0 : m.modelRunId,
824
843
  candidateIds: n,
825
844
  reason: s
826
845
  });
@@ -829,84 +848,84 @@ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
829
848
  }, $t = (n) => {
830
849
  var s;
831
850
  (s = o.value) == null || s.setAnnotations(n);
832
- }, gt = () => {
851
+ }, ut = () => {
833
852
  var n;
834
853
  return ((n = o.value) == null ? void 0 : n.getAnnotations()) || [];
835
854
  }, Tt = (n = "json") => {
836
- var a, d;
837
- const s = gt();
855
+ var l, d;
856
+ const s = ut();
838
857
  return {
839
858
  format: n,
840
- image: ((a = e.batchImages[p.value]) == null ? void 0 : a.imageUrl) || ((d = e.image) == null ? void 0 : d.url) || "",
859
+ image: ((l = e.batchImages[u.value]) == null ? void 0 : l.imageUrl) || ((d = e.image) == null ? void 0 : d.url) || "",
841
860
  annotations: s
842
861
  };
843
- }, ut = (n) => {
844
- n >= 0 && n < e.batchImages.length && (nt(), p.value = n, S(), st());
862
+ }, vt = (n) => {
863
+ n >= 0 && n < e.batchImages.length && (ot(), u.value = n, x(), at());
845
864
  }, Pt = (n) => {
846
865
  var s;
847
- return n === p.value && o.value ? o.value.getAnnotations() || [] : ((s = e.batchImages[n]) == null ? void 0 : s.annotations) || [];
848
- }, Ht = (n) => n.type === "rectangle", Lt = (n) => n.type === "polygon", Bt = (n) => n.type === "point", Dt = (n) => n.type === "rotatedRect", Y = (n) => {
849
- var a, d;
850
- const s = (a = u.value.find((v) => v.name === n.label)) == null ? void 0 : a.color;
866
+ return n === u.value && o.value ? o.value.getAnnotations() || [] : ((s = e.batchImages[n]) == null ? void 0 : s.annotations) || [];
867
+ }, Ht = (n) => n.type === "rectangle", Lt = (n) => n.type === "polygon", Rt = (n) => n.type === "point", Bt = (n) => n.type === "rotatedRect", q = (n) => {
868
+ var l, d;
869
+ const s = (l = y.value.find((m) => m.name === n.label)) == null ? void 0 : l.color;
851
870
  return ((d = n.style) == null ? void 0 : d.strokeColor) || s || "#409eff";
852
- }, vt = (n) => {
871
+ }, mt = (n) => {
853
872
  const s = n.coordinates;
854
873
  return (s == null ? void 0 : s.points) || [];
855
- }, q = (n) => {
874
+ }, G = (n) => {
856
875
  const s = e.batchImages[n];
857
876
  if (s != null && s.width && (s != null && s.height))
858
877
  return { width: s.width, height: s.height };
859
- const a = s != null && s.imageUrl ? E.value[s.imageUrl] : void 0;
860
- return a || (s != null && s.imageUrl && Z(s.imageUrl), { width: 1, height: 1 });
861
- }, Rt = (n) => {
878
+ const l = s != null && s.imageUrl ? L.value[s.imageUrl] : void 0;
879
+ return l || (s != null && s.imageUrl && J(s.imageUrl), { width: 1, height: 1 });
880
+ }, Dt = (n) => {
862
881
  const s = e.batchImages[n];
863
- return s != null && s.width && (s != null && s.height) ? !0 : s != null && s.imageUrl ? !!E.value[s.imageUrl] : !1;
882
+ return s != null && s.width && (s != null && s.height) ? !0 : s != null && s.imageUrl ? !!L.value[s.imageUrl] : !1;
864
883
  }, Ut = (n, s) => {
865
- const a = s.coordinates, d = q(n), v = Y(s), _ = Math.min(a.x1, a.x2), M = Math.min(a.y1, a.y2), Nt = Math.max(a.x1, a.x2), Wt = Math.max(a.y1, a.y2);
884
+ const l = s.coordinates, d = G(n), m = q(s), _ = Math.min(l.x1, l.x2), z = Math.min(l.y1, l.y2), Nt = Math.max(l.x1, l.x2), Wt = Math.max(l.y1, l.y2);
866
885
  return {
867
886
  left: `${_ / d.width * 100}%`,
868
- top: `${M / d.height * 100}%`,
887
+ top: `${z / d.height * 100}%`,
869
888
  width: `${(Nt - _) / d.width * 100}%`,
870
- height: `${(Wt - M) / d.height * 100}%`,
871
- borderColor: v,
872
- backgroundColor: `${v}22`
889
+ height: `${(Wt - z) / d.height * 100}%`,
890
+ borderColor: m,
891
+ backgroundColor: `${m}22`
873
892
  };
874
893
  }, Ft = (n, s) => {
875
- const a = q(n);
876
- return vt(s).map((d) => `${d.x / a.width * 100},${d.y / a.height * 100}`).join(" ");
894
+ const l = G(n);
895
+ return mt(s).map((d) => `${d.x / l.width * 100},${d.y / l.height * 100}`).join(" ");
877
896
  }, Et = (n) => {
878
- const s = Y(n);
897
+ const s = q(n);
879
898
  return {
880
899
  fill: `${s}33`,
881
900
  stroke: s,
882
901
  strokeWidth: "1.4"
883
902
  };
884
- }, Ot = (n, s, a) => {
885
- const d = q(n), v = Y(a);
903
+ }, Ot = (n, s, l) => {
904
+ const d = G(n), m = q(l);
886
905
  return {
887
906
  left: `${s.x / d.width * 100}%`,
888
907
  top: `${s.y / d.height * 100}%`,
889
- backgroundColor: v
908
+ backgroundColor: m
890
909
  };
891
910
  }, Vt = (n, s) => {
892
- const a = s.coordinates, d = q(n), v = Y(s), _ = Math.abs(a.width), M = Math.abs(a.height);
911
+ const l = s.coordinates, d = G(n), m = q(s), _ = Math.abs(l.width), z = Math.abs(l.height);
893
912
  return {
894
- left: `${(a.x - _ / 2) / d.width * 100}%`,
895
- top: `${(a.y - M / 2) / d.height * 100}%`,
913
+ left: `${(l.x - _ / 2) / d.width * 100}%`,
914
+ top: `${(l.y - z / 2) / d.height * 100}%`,
896
915
  width: `${_ / d.width * 100}%`,
897
- height: `${M / d.height * 100}%`,
898
- transform: `rotate(${a.angle || 0}deg)`,
899
- borderColor: v,
900
- backgroundColor: `${v}22`
916
+ height: `${z / d.height * 100}%`,
917
+ transform: `rotate(${l.angle || 0}deg)`,
918
+ borderColor: m,
919
+ backgroundColor: `${m}22`
901
920
  };
902
921
  };
903
922
  return t({
904
- jumpTo: ut,
923
+ jumpTo: vt,
905
924
  setImage: zt,
906
925
  setAnnotations: $t,
907
- getAnnotations: gt,
908
- selectTool: U,
909
- loadPredictionCandidates: dt,
926
+ getAnnotations: ut,
927
+ selectTool: b,
928
+ loadPredictionCandidates: gt,
910
929
  applyPredictions: St,
911
930
  rejectPredictions: Mt,
912
931
  exportAnnotations: Tt,
@@ -918,102 +937,102 @@ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
918
937
  }];
919
938
  },
920
939
  getCurrentAnnotation: () => {
921
- var n, s, a;
940
+ var n, s, l;
922
941
  return {
923
- imageUrl: ((n = e.batchImages[p.value]) == null ? void 0 : n.imageUrl) || ((s = e.image) == null ? void 0 : s.url) || "",
924
- annotations: ((a = o.value) == null ? void 0 : a.getAnnotations()) || []
942
+ imageUrl: ((n = e.batchImages[u.value]) == null ? void 0 : n.imageUrl) || ((s = e.image) == null ? void 0 : s.url) || "",
943
+ annotations: ((l = o.value) == null ? void 0 : l.getAnnotations()) || []
925
944
  };
926
945
  }
927
- }), J(() => {
946
+ }), Y(() => {
928
947
  var n;
929
948
  return (n = e.image) == null ? void 0 : n.url;
930
949
  }, () => {
931
950
  var n;
932
- e.batchImages.length === 0 && ((n = e.image) != null && n.url) && S();
933
- }), J(() => e.predictionCandidates, (n) => {
934
- n && dt(n);
935
- }, { immediate: !0, deep: !0 }), J(
951
+ e.batchImages.length === 0 && ((n = e.image) != null && n.url) && x();
952
+ }), Y(() => e.predictionCandidates, (n) => {
953
+ n && gt(n);
954
+ }, { immediate: !0, deep: !0 }), Y(
936
955
  () => e.batchImages.map((n) => `${n.imageUrl}:${n.width || ""}x${n.height || ""}`),
937
956
  () => {
938
- X();
957
+ tt();
939
958
  },
940
959
  { immediate: !0 }
941
- ), (n, s) => (y(), x("div", {
942
- class: V(["annotation-container", m.theme])
960
+ ), (n, s) => (f(), p("div", {
961
+ class: V(["annotation-container", v.theme])
943
962
  }, [
944
- m.batchImages && m.batchImages.length > 0 ? (y(), x("div", fe, [
945
- g("div", ye, "批量图片(" + $(m.batchImages.length) + ")", 1),
946
- g("div", pe, [
947
- (y(!0), x(L, null, F(m.batchImages, (a, d) => (y(), x("button", {
948
- key: `${a.imageUrl}-${d}`,
949
- class: V(["image-list-item", { active: d === p.value }]),
950
- onClick: (v) => ut(d)
963
+ v.batchImages && v.batchImages.length > 0 ? (f(), p("div", ye, [
964
+ g("div", pe, "批量图片(" + T(v.batchImages.length) + ")", 1),
965
+ g("div", xe, [
966
+ (f(!0), p(R, null, F(v.batchImages, (l, d) => (f(), p("button", {
967
+ key: `${l.imageUrl}-${d}`,
968
+ class: V(["image-list-item", { active: d === u.value }]),
969
+ onClick: (m) => vt(d)
951
970
  }, [
952
- g("div", be, [
971
+ g("div", we, [
953
972
  g("img", {
954
- src: a.imageUrl,
973
+ src: l.imageUrl,
955
974
  alt: `第${d + 1}张`,
956
975
  class: "image-list-thumb"
957
- }, null, 8, we),
958
- Rt(d) ? (y(), x("div", Ce, [
959
- (y(!0), x(L, null, F(Pt(d), (v) => (y(), x(L, {
960
- key: v.id
976
+ }, null, 8, Ce),
977
+ Dt(d) ? (f(), p("div", Ae, [
978
+ (f(!0), p(R, null, F(Pt(d), (m) => (f(), p(R, {
979
+ key: m.id
961
980
  }, [
962
- Ht(v) ? (y(), x("div", {
981
+ Ht(m) ? (f(), p("div", {
963
982
  key: 0,
964
983
  class: "thumb-overlay-rect",
965
- style: N(Ut(d, v))
966
- }, null, 4)) : Lt(v) ? (y(), x("svg", _e, [
984
+ style: O(Ut(d, m))
985
+ }, null, 4)) : Lt(m) ? (f(), p("svg", _e, [
967
986
  g("polygon", {
968
- points: Ft(d, v),
969
- style: N(Et(v))
970
- }, null, 12, Ae)
971
- ])) : Bt(v) ? (y(!0), x(L, { key: 2 }, F(vt(v), (_, M) => (y(), x("div", {
972
- key: `${v.id}-${M}`,
987
+ points: Ft(d, m),
988
+ style: O(Et(m))
989
+ }, null, 12, Ie)
990
+ ])) : Rt(m) ? (f(!0), p(R, { key: 2 }, F(mt(m), (_, z) => (f(), p("div", {
991
+ key: `${m.id}-${z}`,
973
992
  class: "thumb-overlay-point",
974
- style: N(Ot(d, _, v))
975
- }, null, 4))), 128)) : Dt(v) ? (y(), x("div", {
993
+ style: O(Ot(d, _, m))
994
+ }, null, 4))), 128)) : Bt(m) ? (f(), p("div", {
976
995
  key: 3,
977
996
  class: "thumb-overlay-rotated",
978
- style: N(Vt(d, v))
979
- }, null, 4)) : z("", !0)
997
+ style: O(Vt(d, m))
998
+ }, null, 4)) : $("", !0)
980
999
  ], 64))), 128))
981
- ])) : z("", !0)
1000
+ ])) : $("", !0)
982
1001
  ]),
983
- g("span", Ie, "第 " + $(d + 1) + " 张", 1)
984
- ], 10, xe))), 128))
1002
+ g("span", ke, "第 " + T(d + 1) + " 张", 1)
1003
+ ], 10, be))), 128))
985
1004
  ])
986
- ])) : z("", !0),
987
- m.readOnly ? z("", !0) : (y(), x("div", ke, [
1005
+ ])) : $("", !0),
1006
+ v.readOnly ? $("", !0) : (f(), p("div", Se, [
988
1007
  g("div", {
989
1008
  class: V(["tool-btn", { active: h.value === "pan" }]),
990
- onClick: s[0] || (s[0] = (a) => U("pan")),
1009
+ onClick: s[0] || (s[0] = (l) => b("pan")),
991
1010
  title: "拖动"
992
1011
  }, [
993
1012
  H(P, { name: "rank" })
994
1013
  ], 2),
995
1014
  g("div", {
996
1015
  class: V(["tool-btn", { active: h.value === "select" }]),
997
- onClick: s[1] || (s[1] = (a) => U("select")),
1016
+ onClick: s[1] || (s[1] = (l) => b("select")),
998
1017
  title: "选择"
999
1018
  }, [
1000
1019
  H(P, { name: "pointer" })
1001
1020
  ], 2),
1002
- s[4] || (s[4] = g("div", { class: "divider" }, null, -1)),
1003
- (y(!0), x(L, null, F(tt.value, (a) => (y(), x("div", {
1004
- key: a,
1005
- class: V(["tool-btn", { active: h.value === a }]),
1006
- onClick: (d) => U(a),
1007
- title: b(a)
1021
+ s[5] || (s[5] = g("div", { class: "divider" }, null, -1)),
1022
+ (f(!0), p(R, null, F(nt.value, (l) => (f(), p("div", {
1023
+ key: l,
1024
+ class: V(["tool-btn", { active: h.value === l }]),
1025
+ onClick: (d) => b(l),
1026
+ title: it(l)
1008
1027
  }, [
1009
1028
  H(P, {
1010
- name: et(a)
1029
+ name: st(l)
1011
1030
  }, null, 8, ["name"])
1012
- ], 10, Se))), 128)),
1013
- s[5] || (s[5] = g("div", { class: "divider" }, null, -1)),
1031
+ ], 10, Me))), 128)),
1032
+ s[6] || (s[6] = g("div", { class: "divider" }, null, -1)),
1014
1033
  g("div", {
1015
1034
  class: "tool-btn",
1016
- onClick: yt,
1035
+ onClick: ht,
1017
1036
  title: "放大"
1018
1037
  }, [
1019
1038
  H(P, { name: "zoom-in" })
@@ -1025,145 +1044,147 @@ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
1025
1044
  }, [
1026
1045
  H(P, { name: "zoom-out" })
1027
1046
  ]),
1028
- s[6] || (s[6] = g("div", { class: "divider" }, null, -1)),
1029
- lt.value ? (y(), x("div", {
1047
+ s[7] || (s[7] = g("div", { class: "divider" }, null, -1)),
1048
+ Q.value ? (f(), p("div", {
1030
1049
  key: 0,
1031
1050
  class: "tool-btn",
1032
- onClick: rt,
1051
+ onClick: M,
1033
1052
  title: "删除选中"
1034
1053
  }, [
1035
1054
  H(P, { name: "delete" })
1036
- ])) : z("", !0)
1055
+ ])) : $("", !0)
1037
1056
  ])),
1038
- g("div", Me, [
1039
- m.readOnly ? z("", !0) : (y(), x("div", ze, [
1040
- g("div", $e, [
1041
- s[7] || (s[7] = g("span", { class: "label-text" }, "当前标签:", -1)),
1042
- g("div", Te, [
1043
- (y(!0), x(L, null, F(u.value, (a) => (y(), x("div", {
1044
- key: a.id,
1045
- class: V(["tag-chip", { active: f.value === a.id }]),
1046
- style: N({ backgroundColor: a.color, borderColor: a.color }),
1047
- onClick: (d) => W(a)
1048
- }, $(a.name), 15, Pe))), 128)),
1049
- u.value.length === 0 ? (y(), x("div", He, "请在右侧创建标签")) : z("", !0)
1057
+ g("div", ze, [
1058
+ v.readOnly ? $("", !0) : (f(), p("div", $e, [
1059
+ g("div", Te, [
1060
+ s[8] || (s[8] = g("span", { class: "label-text" }, "当前标签:", -1)),
1061
+ g("div", Pe, [
1062
+ (f(!0), p(R, null, F(y.value, (l) => (f(), p("div", {
1063
+ key: l.id,
1064
+ class: V(["tag-chip", { active: w.value === l.id }]),
1065
+ style: O({ backgroundColor: l.color, borderColor: l.color }),
1066
+ onClick: (d) => j(l)
1067
+ }, T(l.name), 15, He))), 128)),
1068
+ y.value.length === 0 ? (f(), p("div", Le, "请在右侧创建标签")) : $("", !0)
1050
1069
  ])
1051
1070
  ])
1052
1071
  ])),
1053
1072
  g("div", {
1054
1073
  class: "canvas-wrapper",
1055
1074
  ref_key: "canvasWrapper",
1056
- ref: c
1075
+ ref: c,
1076
+ onWheel: s[2] || (s[2] = qt(() => {
1077
+ }, ["prevent"]))
1057
1078
  }, [
1058
1079
  g("canvas", {
1059
1080
  ref_key: "canvasRef",
1060
1081
  ref: r
1061
1082
  }, null, 512)
1062
- ], 512),
1063
- m.batchImages && m.batchImages.length > 0 ? (y(), x("div", Le, [
1083
+ ], 544),
1084
+ v.batchImages && v.batchImages.length > 0 ? (f(), p("div", Re, [
1064
1085
  g("button", {
1065
1086
  onClick: It,
1066
- disabled: p.value <= 0
1087
+ disabled: u.value <= 0
1067
1088
  }, [
1068
1089
  H(P, { name: "back" }),
1069
- s[8] || (s[8] = j(" 上一张 ", -1))
1090
+ s[9] || (s[9] = X(" 上一张 ", -1))
1070
1091
  ], 8, Be),
1071
- g("span", null, $(p.value + 1) + " / " + $(m.batchImages.length), 1),
1092
+ g("span", null, T(u.value + 1) + " / " + T(v.batchImages.length), 1),
1072
1093
  g("button", {
1073
1094
  onClick: kt,
1074
- disabled: p.value >= m.batchImages.length - 1
1095
+ disabled: u.value >= v.batchImages.length - 1
1075
1096
  }, [
1076
- s[9] || (s[9] = j(" 下一张 ", -1)),
1097
+ s[10] || (s[10] = X(" 下一张 ", -1)),
1077
1098
  H(P, { name: "right" })
1078
1099
  ], 8, De)
1079
- ])) : z("", !0)
1100
+ ])) : $("", !0)
1080
1101
  ]),
1081
- m.readOnly ? z("", !0) : (y(), x("div", Re, [
1102
+ v.readOnly ? $("", !0) : (f(), p("div", Ue, [
1082
1103
  g("div", { class: "sidebar-header" }, [
1083
- s[10] || (s[10] = g("h3", null, "标签管理", -1)),
1104
+ s[11] || (s[11] = g("h3", null, "标签管理", -1)),
1084
1105
  g("button", {
1085
1106
  class: "add-btn",
1086
1107
  onClick: xt
1087
1108
  }, "添加标签")
1088
1109
  ]),
1089
- g("div", Ue, [
1090
- (y(!0), x(L, null, F(u.value, (a) => (y(), x("div", {
1091
- key: a.id,
1110
+ g("div", Fe, [
1111
+ (f(!0), p(R, null, F(y.value, (l) => (f(), p("div", {
1112
+ key: l.id,
1092
1113
  class: "label-item"
1093
1114
  }, [
1094
- g("div", Fe, [
1115
+ g("div", Ee, [
1095
1116
  g("label", {
1096
1117
  class: "color-wrapper",
1097
- style: N({ backgroundColor: a.color })
1118
+ style: O({ backgroundColor: l.color })
1098
1119
  }, [
1099
- it(g("input", {
1120
+ lt(g("input", {
1100
1121
  type: "color",
1101
- "onUpdate:modelValue": (d) => a.color = d,
1102
- onChange: (d) => Ct(a),
1122
+ "onUpdate:modelValue": (d) => l.color = d,
1123
+ onChange: (d) => Ct(l),
1103
1124
  style: { visibility: "hidden", width: "0", height: "0" }
1104
- }, null, 40, Ee), [
1105
- [ot, a.color]
1125
+ }, null, 40, Oe), [
1126
+ [rt, l.color]
1106
1127
  ])
1107
1128
  ], 4),
1108
1129
  g("span", {
1109
1130
  class: "label-name",
1110
- title: a.name
1111
- }, $(a.name), 9, Oe),
1131
+ title: l.name
1132
+ }, T(l.name), 9, Ve),
1112
1133
  g("span", {
1113
1134
  class: "action-icon eye",
1114
- onClick: (d) => _t(a)
1135
+ onClick: (d) => At(l)
1115
1136
  }, [
1116
- a.visible ? (y(), mt(P, {
1137
+ l.visible ? (f(), ft(P, {
1117
1138
  key: 0,
1118
1139
  name: "view"
1119
- })) : (y(), mt(P, {
1140
+ })) : (f(), ft(P, {
1120
1141
  key: 1,
1121
1142
  name: "hide"
1122
1143
  }))
1123
- ], 8, Ve),
1124
- g("div", Ne, [
1125
- s[11] || (s[11] = g("span", { class: "dots" }, "•••", -1)),
1144
+ ], 8, Ne),
1145
+ g("div", We, [
1146
+ s[12] || (s[12] = g("span", { class: "dots" }, "•••", -1)),
1126
1147
  g("span", {
1127
1148
  class: "delete-btn",
1128
- onClick: (d) => At(a.id),
1149
+ onClick: (d) => _t(l.id),
1129
1150
  title: "删除"
1130
1151
  }, [
1131
1152
  H(P, { name: "delete" })
1132
- ], 8, We)
1153
+ ], 8, Je)
1133
1154
  ])
1134
1155
  ])
1135
1156
  ]))), 128))
1136
1157
  ])
1137
1158
  ])),
1138
- A.value ? (y(), x("div", Je, [
1139
- g("div", je, [
1140
- s[14] || (s[14] = g("h3", null, "新增标签", -1)),
1159
+ I.value ? (f(), p("div", je, [
1160
+ g("div", Ye, [
1161
+ s[15] || (s[15] = g("h3", null, "新增标签", -1)),
1141
1162
  g("div", Xe, [
1142
- s[12] || (s[12] = g("label", null, "名称", -1)),
1143
- it(g("input", {
1144
- "onUpdate:modelValue": s[2] || (s[2] = (a) => T.value.name = a),
1163
+ s[13] || (s[13] = g("label", null, "名称", -1)),
1164
+ lt(g("input", {
1165
+ "onUpdate:modelValue": s[3] || (s[3] = (l) => C.value.name = l),
1145
1166
  placeholder: "请输入标签名称",
1146
1167
  class: "modal-input"
1147
1168
  }, null, 512), [
1148
- [ot, T.value.name]
1169
+ [rt, C.value.name]
1149
1170
  ])
1150
1171
  ]),
1151
- g("div", Ye, [
1152
- s[13] || (s[13] = g("label", null, "颜色", -1)),
1153
- g("div", qe, [
1154
- it(g("input", {
1172
+ g("div", qe, [
1173
+ s[14] || (s[14] = g("label", null, "颜色", -1)),
1174
+ g("div", Ge, [
1175
+ lt(g("input", {
1155
1176
  type: "color",
1156
- "onUpdate:modelValue": s[3] || (s[3] = (a) => T.value.color = a),
1177
+ "onUpdate:modelValue": s[4] || (s[4] = (l) => C.value.color = l),
1157
1178
  class: "modal-color-picker"
1158
1179
  }, null, 512), [
1159
- [ot, T.value.color]
1180
+ [rt, C.value.color]
1160
1181
  ]),
1161
- g("span", null, $(T.value.color), 1)
1182
+ g("span", null, T(C.value.color), 1)
1162
1183
  ])
1163
1184
  ]),
1164
1185
  g("div", { class: "modal-actions" }, [
1165
1186
  g("button", {
1166
- onClick: ht,
1187
+ onClick: dt,
1167
1188
  class: "cancel-btn"
1168
1189
  }, "取消"),
1169
1190
  g("button", {
@@ -1172,105 +1193,107 @@ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
1172
1193
  }, "确认")
1173
1194
  ])
1174
1195
  ])
1175
- ])) : z("", !0)
1196
+ ])) : $("", !0)
1176
1197
  ], 2));
1177
1198
  }
1178
- }), Ke = /* @__PURE__ */ K(Ge, [["__scopeId", "data-v-22c2957b"]]), Ze = {
1199
+ }), Ze = /* @__PURE__ */ Z(Ke, [["__scopeId", "data-v-79777e6e"]]), Qe = {
1179
1200
  class: "thumbnail-wrapper",
1180
1201
  ref: "wrapper"
1181
- }, Qe = ["src", "alt"], tn = ["viewBox"], en = ["x", "y", "width", "height", "stroke"], nn = ["points", "stroke"], sn = ["x", "y", "fill"], on = {
1202
+ }, tn = ["src", "alt"], en = ["viewBox", "preserveAspectRatio"], nn = ["x", "y", "width", "height", "stroke"], sn = ["points", "stroke"], on = ["x", "y", "fill"], an = {
1182
1203
  key: 1,
1183
1204
  class: "loading-placeholder"
1184
- }, an = /* @__PURE__ */ G({
1205
+ }, ln = /* @__PURE__ */ K({
1185
1206
  __name: "AnnotationThumbnail",
1186
1207
  props: {
1187
1208
  src: {},
1188
1209
  annotations: {},
1189
1210
  alt: {},
1190
- labels: {}
1211
+ labels: {},
1212
+ fit: {}
1191
1213
  },
1192
- setup(m) {
1193
- const t = m, i = k(null), e = k(!1), l = k(0), r = k(0), c = () => {
1194
- i.value && (l.value = i.value.naturalWidth, r.value = i.value.naturalHeight, e.value = !0);
1195
- }, o = (u) => {
1196
- var f;
1197
- if ((f = u.style) != null && f.strokeColor) return u.style.strokeColor;
1214
+ setup(v) {
1215
+ const t = v, i = S(null), e = S(!1), a = S(0), r = S(0), c = () => {
1216
+ i.value && (a.value = i.value.naturalWidth, r.value = i.value.naturalHeight, e.value = !0);
1217
+ }, o = U(() => t.fit === "contain" ? "xMidYMid meet" : "xMidYMid slice"), h = (w) => {
1218
+ var I;
1219
+ if ((I = w.style) != null && I.strokeColor) return w.style.strokeColor;
1198
1220
  if (t.labels) {
1199
- const A = t.labels.find((T) => T.name === u.label);
1200
- if (A) return A.color;
1221
+ const C = t.labels.find((B) => B.name === w.label);
1222
+ if (C) return C.color;
1201
1223
  }
1202
1224
  return "#FF0000";
1203
- }, h = (u) => {
1204
- const f = u.coordinates, A = Math.min(f.x1, f.x2), T = Math.min(f.y1, f.y2), B = Math.abs(f.x1 - f.x2), D = Math.abs(f.y1 - f.y2);
1205
- return { x: A, y: T, width: B, height: D };
1206
- }, p = (u) => u.coordinates.points.map((A) => `${A.x},${A.y}`).join(" "), C = (u) => {
1207
- if (u.type === "rectangle") {
1208
- const f = h(u);
1209
- return { x: f.x, y: f.y - 5 };
1210
- } else if (u.type === "polygon") {
1211
- const f = u.coordinates.points;
1212
- if (f.length > 0) return { x: f[0].x, y: f[0].y - 5 };
1225
+ }, u = (w) => {
1226
+ const I = w.coordinates, C = Math.min(I.x1, I.x2), B = Math.min(I.y1, I.y2), D = Math.abs(I.x1 - I.x2), L = Math.abs(I.y1 - I.y2);
1227
+ return { x: C, y: B, width: D, height: L };
1228
+ }, A = (w) => w.coordinates.points.map((C) => `${C.x},${C.y}`).join(" "), y = (w) => {
1229
+ if (w.type === "rectangle") {
1230
+ const I = u(w);
1231
+ return { x: I.x, y: I.y - 5 };
1232
+ } else if (w.type === "polygon") {
1233
+ const I = w.coordinates.points;
1234
+ if (I.length > 0) return { x: I[0].x, y: I[0].y - 5 };
1213
1235
  }
1214
1236
  return { x: 0, y: 0 };
1215
1237
  };
1216
- return (u, f) => (y(), x("div", Ze, [
1238
+ return (w, I) => (f(), p("div", Qe, [
1217
1239
  g("img", {
1218
1240
  ref_key: "img",
1219
1241
  ref: i,
1220
- src: m.src,
1242
+ src: v.src,
1221
1243
  class: "thumbnail-image",
1244
+ style: O({ objectFit: v.fit }),
1222
1245
  onLoad: c,
1223
- alt: m.alt
1224
- }, null, 40, Qe),
1225
- e.value ? (y(), x("svg", {
1246
+ alt: v.alt
1247
+ }, null, 44, tn),
1248
+ e.value ? (f(), p("svg", {
1226
1249
  key: 0,
1227
1250
  class: "annotation-overlay",
1228
- viewBox: `0 0 ${l.value} ${r.value}`,
1229
- preserveAspectRatio: "none"
1251
+ viewBox: `0 0 ${a.value} ${r.value}`,
1252
+ preserveAspectRatio: o.value
1230
1253
  }, [
1231
- (y(!0), x(L, null, F(m.annotations, (A) => (y(), x(L, {
1232
- key: A.id
1254
+ (f(!0), p(R, null, F(v.annotations, (C) => (f(), p(R, {
1255
+ key: C.id
1233
1256
  }, [
1234
- A.type === "rectangle" ? (y(), x("rect", {
1257
+ C.type === "rectangle" ? (f(), p("rect", {
1235
1258
  key: 0,
1236
- x: h(A).x,
1237
- y: h(A).y,
1238
- width: h(A).width,
1239
- height: h(A).height,
1240
- stroke: o(A),
1259
+ x: u(C).x,
1260
+ y: u(C).y,
1261
+ width: u(C).width,
1262
+ height: u(C).height,
1263
+ stroke: h(C),
1241
1264
  "stroke-width": "2",
1242
1265
  fill: "transparent"
1243
- }, null, 8, en)) : z("", !0),
1244
- A.type === "polygon" ? (y(), x("polygon", {
1266
+ }, null, 8, nn)) : $("", !0),
1267
+ C.type === "polygon" ? (f(), p("polygon", {
1245
1268
  key: 1,
1246
- points: p(A),
1247
- stroke: o(A),
1269
+ points: A(C),
1270
+ stroke: h(C),
1248
1271
  "stroke-width": "2",
1249
1272
  fill: "transparent"
1250
- }, null, 8, nn)) : z("", !0),
1251
- A.label ? (y(), x("text", {
1273
+ }, null, 8, sn)) : $("", !0),
1274
+ C.label ? (f(), p("text", {
1252
1275
  key: 2,
1253
- x: C(A).x,
1254
- y: C(A).y,
1255
- fill: o(A),
1276
+ x: y(C).x,
1277
+ y: y(C).y,
1278
+ fill: h(C),
1256
1279
  "font-size": "14",
1257
1280
  "font-weight": "bold",
1258
1281
  class: "anno-label"
1259
- }, $(A.label), 9, sn)) : z("", !0)
1282
+ }, T(C.label), 9, on)) : $("", !0)
1260
1283
  ], 64))), 128))
1261
- ], 8, tn)) : (y(), x("div", on, "Loading..."))
1284
+ ], 8, en)) : (f(), p("div", an, "Loading..."))
1262
1285
  ], 512));
1263
1286
  }
1264
- }), ln = /* @__PURE__ */ K(an, [["__scopeId", "data-v-78bcbe0c"]]), rn = { class: "batch-annotator" }, cn = {
1287
+ }), rn = /* @__PURE__ */ Z(ln, [["__scopeId", "data-v-c77b0958"]]), cn = {
1265
1288
  key: 0,
1266
1289
  class: "gallery-view"
1267
- }, hn = { class: "gallery-header" }, dn = { class: "label-summary" }, gn = { class: "gallery-grid" }, un = ["onClick"], vn = { class: "thumbnail-wrapper" }, mn = { class: "img-meta" }, fn = { class: "img-index" }, yn = { class: "anno-count" }, pn = {
1290
+ }, hn = { class: "gallery-header" }, dn = { class: "label-summary" }, gn = ["onClick"], un = { class: "thumbnail-wrapper" }, vn = { class: "img-meta" }, mn = { class: "img-index" }, fn = { class: "anno-count" }, yn = {
1268
1291
  key: 0,
1269
1292
  class: "bottom-bar"
1270
- }, xn = {
1293
+ }, pn = {
1271
1294
  key: 1,
1272
1295
  class: "editor-view"
1273
- }, bn = { class: "editor-header" }, wn = { class: "header-left" }, Cn = { class: "editor-title" }, _n = { class: "editor-content" }, An = /* @__PURE__ */ G({
1296
+ }, xn = { class: "editor-header" }, bn = { class: "header-left" }, wn = { class: "editor-title" }, Cn = { class: "editor-content" }, An = /* @__PURE__ */ K({
1274
1297
  __name: "BatchAnnotator",
1275
1298
  props: {
1276
1299
  images: {},
@@ -1279,144 +1302,156 @@ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
1279
1302
  clickToEnterEditor: { type: Boolean }
1280
1303
  },
1281
1304
  emits: ["export", "update:images", "imageClick"],
1282
- setup(m, { expose: t, emit: i }) {
1283
- const e = m, l = i, r = k("gallery"), c = k([]), o = k(0), h = k(null), p = O(() => {
1284
- var b, w;
1285
- return ((w = (b = e.actionBar) == null ? void 0 : b.annotateButton) == null ? void 0 : w.show) === !0;
1286
- }), C = O(() => {
1287
- var b, w;
1288
- return ((w = (b = e.actionBar) == null ? void 0 : b.exportButton) == null ? void 0 : w.show) === !0;
1289
- }), u = O(() => p.value || C.value), f = O(() => {
1290
- var b, w;
1291
- return ((w = (b = e.actionBar) == null ? void 0 : b.annotateButton) == null ? void 0 : w.text) || "手动标注";
1292
- }), A = O(() => {
1293
- var b, w;
1294
- return ((w = (b = e.actionBar) == null ? void 0 : b.exportButton) == null ? void 0 : w.text) || "导出";
1295
- }), T = O(() => e.clickToEnterEditor !== !1);
1296
- J(() => e.images, (b) => {
1297
- c.value = JSON.parse(JSON.stringify(b));
1305
+ setup(v, { expose: t, emit: i }) {
1306
+ const e = v, a = i, r = S("gallery"), c = S([]), o = S(0), h = S(null), u = S(null), A = S(null), y = U(() => {
1307
+ var x, b;
1308
+ return ((b = (x = e.actionBar) == null ? void 0 : x.annotateButton) == null ? void 0 : b.show) === !0;
1309
+ }), w = U(() => {
1310
+ var x, b;
1311
+ return ((b = (x = e.actionBar) == null ? void 0 : x.exportButton) == null ? void 0 : b.show) === !0;
1312
+ }), I = U(() => y.value || w.value), C = U(() => {
1313
+ var x, b;
1314
+ return ((b = (x = e.actionBar) == null ? void 0 : x.annotateButton) == null ? void 0 : b.text) || "手动标注";
1315
+ }), B = U(() => {
1316
+ var x, b;
1317
+ return ((b = (x = e.actionBar) == null ? void 0 : x.exportButton) == null ? void 0 : b.text) || "导出";
1318
+ }), D = U(() => e.clickToEnterEditor !== !1);
1319
+ Y(() => e.images, (x) => {
1320
+ c.value = JSON.parse(JSON.stringify(x));
1298
1321
  }, { immediate: !0, deep: !0 });
1299
- const B = (b) => {
1300
- o.value = b, r.value = "editor", qt(() => {
1301
- h.value && h.value.jumpTo && h.value.jumpTo(b);
1322
+ const L = (x) => {
1323
+ o.value = x, r.value = "editor", A.value && (A.value.scrollTop = 0), Gt(() => {
1324
+ u.value && (u.value.scrollTop = 0), window.scrollTo(0, 0), requestAnimationFrame(() => {
1325
+ var b, M;
1326
+ (M = (b = h.value) == null ? void 0 : b.jumpTo) == null || M.call(b, x);
1327
+ });
1302
1328
  });
1303
- }, D = (b, w) => {
1304
- if (T.value) {
1305
- B(b);
1329
+ }, Q = (x, b) => {
1330
+ if (D.value) {
1331
+ L(x);
1306
1332
  return;
1307
1333
  }
1308
- l("imageClick", { index: b, imageId: w.id, image: w });
1309
- }, E = (b) => c.value.findIndex((w) => w.id === b);
1334
+ a("imageClick", { index: x, imageId: b.id, image: b });
1335
+ }, J = (x) => c.value.findIndex((b) => b.id === x);
1310
1336
  t({
1311
- openImageById: (b) => {
1312
- const w = E(b);
1313
- return w < 0 ? !1 : (B(w), !0);
1337
+ openImageById: (x) => {
1338
+ const b = J(x);
1339
+ return b < 0 ? !1 : (L(b), !0);
1314
1340
  },
1315
- triggerImageClickById: (b) => {
1316
- const w = E(b);
1317
- if (w < 0)
1341
+ triggerImageClickById: (x) => {
1342
+ const b = J(x);
1343
+ if (b < 0)
1318
1344
  return !1;
1319
- const S = c.value[w];
1320
- return S ? (l("imageClick", { index: w, imageId: S.id, image: S }), !0) : !1;
1345
+ const M = c.value[b];
1346
+ return M ? (a("imageClick", { index: b, imageId: M.id, image: M }), !0) : !1;
1321
1347
  }
1322
1348
  });
1323
- const X = () => {
1349
+ const et = () => {
1324
1350
  if (h.value && h.value.getCurrentAnnotation) {
1325
- const b = h.value.getCurrentAnnotation();
1326
- c.value[o.value] && (c.value[o.value].annotations = b.annotations);
1351
+ const x = h.value.getCurrentAnnotation();
1352
+ c.value[o.value] && (c.value[o.value].annotations = x.annotations);
1327
1353
  }
1328
1354
  r.value = "gallery";
1329
- }, R = () => {
1330
- l("export", c.value);
1331
- }, Q = (b) => {
1332
- o.value = b.currentIndex, c.value[b.currentIndex] && (c.value[b.currentIndex].annotations = b.currentAnnotations);
1333
- }, tt = (b) => {
1355
+ }, nt = () => {
1356
+ a("export", c.value);
1357
+ }, st = (x) => {
1358
+ o.value = x.currentIndex, c.value[x.currentIndex] && (c.value[x.currentIndex].annotations = x.currentAnnotations);
1359
+ }, it = (x) => {
1334
1360
  if (h.value && h.value.getCurrentAnnotation) {
1335
- const w = h.value.getCurrentAnnotation();
1336
- c.value[o.value] && (c.value[o.value].annotations = w.annotations, l("update:images", c.value));
1361
+ const b = h.value.getCurrentAnnotation();
1362
+ c.value[o.value] && (c.value[o.value].annotations = b.annotations, a("update:images", c.value));
1337
1363
  }
1338
- }, et = (b) => {
1364
+ }, N = (x) => {
1339
1365
  };
1340
- return (b, w) => (y(), x("div", rn, [
1341
- r.value === "gallery" ? (y(), x("div", cn, [
1366
+ return (x, b) => (f(), p("div", {
1367
+ ref_key: "batchRootRef",
1368
+ ref: u,
1369
+ class: "batch-annotator"
1370
+ }, [
1371
+ r.value === "gallery" ? (f(), p("div", cn, [
1342
1372
  g("div", hn, [
1343
- g("h3", null, "批量查看与标注 (" + $(c.value.length) + " 张)", 1),
1373
+ g("h3", null, "批量查看与标注 (" + T(c.value.length) + " 张)", 1),
1344
1374
  g("div", dn, [
1345
- (y(!0), x(L, null, F(m.labels, (S) => (y(), x("span", {
1346
- key: S.id,
1375
+ (f(!0), p(R, null, F(v.labels, (M) => (f(), p("span", {
1376
+ key: M.id,
1347
1377
  class: "label-badge",
1348
- style: N({ backgroundColor: S.color })
1349
- }, $(S.name), 5))), 128))
1378
+ style: O({ backgroundColor: M.color })
1379
+ }, T(M.name), 5))), 128))
1350
1380
  ])
1351
1381
  ]),
1352
- g("div", gn, [
1353
- (y(!0), x(L, null, F(c.value, (S, U) => (y(), x("div", {
1354
- key: U,
1382
+ g("div", {
1383
+ ref_key: "galleryGridRef",
1384
+ ref: A,
1385
+ class: "gallery-grid"
1386
+ }, [
1387
+ (f(!0), p(R, null, F(c.value, (M, W) => (f(), p("div", {
1388
+ key: W,
1355
1389
  class: "gallery-item",
1356
- onClick: (rt) => D(U, S)
1390
+ onClick: (ht) => Q(W, M)
1357
1391
  }, [
1358
- g("div", vn, [
1359
- H(ln, {
1360
- src: S.imageUrl,
1361
- annotations: S.annotations || [],
1362
- labels: m.labels
1392
+ g("div", un, [
1393
+ H(rn, {
1394
+ src: M.imageUrl,
1395
+ annotations: M.annotations || [],
1396
+ labels: v.labels,
1397
+ fit: "cover"
1363
1398
  }, null, 8, ["src", "annotations", "labels"])
1364
1399
  ]),
1365
- g("div", mn, [
1366
- g("span", fn, "#" + $(U + 1), 1),
1367
- g("span", yn, $((S.annotations || []).length) + " 标注", 1)
1400
+ g("div", vn, [
1401
+ g("span", mn, "#" + T(W + 1), 1),
1402
+ g("span", fn, T((M.annotations || []).length) + " 标注", 1)
1368
1403
  ])
1369
- ], 8, un))), 128))
1370
- ]),
1371
- u.value ? (y(), x("div", pn, [
1372
- p.value ? (y(), x("button", {
1404
+ ], 8, gn))), 128))
1405
+ ], 512),
1406
+ I.value ? (f(), p("div", yn, [
1407
+ y.value ? (f(), p("button", {
1373
1408
  key: 0,
1374
1409
  class: "action-btn primary",
1375
- onClick: w[0] || (w[0] = (S) => B(0))
1410
+ onClick: b[0] || (b[0] = (M) => L(0))
1376
1411
  }, [
1377
1412
  H(P, { name: "edit" }),
1378
- j(" " + $(f.value), 1)
1379
- ])) : z("", !0),
1380
- C.value ? (y(), x("button", {
1413
+ X(" " + T(C.value), 1)
1414
+ ])) : $("", !0),
1415
+ w.value ? (f(), p("button", {
1381
1416
  key: 1,
1382
1417
  class: "action-btn success",
1383
- onClick: R
1418
+ onClick: nt
1384
1419
  }, [
1385
1420
  H(P, { name: "download" }),
1386
- j(" " + $(A.value), 1)
1387
- ])) : z("", !0)
1388
- ])) : z("", !0)
1389
- ])) : (y(), x("div", xn, [
1390
- g("div", bn, [
1391
- g("div", wn, [
1421
+ X(" " + T(B.value), 1)
1422
+ ])) : $("", !0)
1423
+ ])) : $("", !0)
1424
+ ])) : (f(), p("div", pn, [
1425
+ g("div", xn, [
1426
+ g("div", bn, [
1392
1427
  g("button", {
1393
1428
  class: "back-btn",
1394
- onClick: X
1429
+ onClick: et
1395
1430
  }, [
1396
1431
  H(P, { name: "back" }),
1397
- w[1] || (w[1] = j(" 返回列表 ", -1))
1432
+ b[1] || (b[1] = X(" 返回列表 ", -1))
1398
1433
  ]),
1399
- g("span", Cn, "正在标注: " + $(o.value + 1) + " / " + $(c.value.length), 1)
1434
+ g("span", wn, "正在标注: " + T(o.value + 1) + " / " + T(c.value.length), 1)
1400
1435
  ])
1401
1436
  ]),
1402
- g("div", _n, [
1403
- H(Ke, {
1437
+ g("div", Cn, [
1438
+ H(Ze, {
1404
1439
  ref_key: "annotatorRef",
1405
1440
  ref: h,
1406
1441
  batchImages: c.value,
1407
- labels: m.labels,
1442
+ labels: v.labels,
1408
1443
  annotationTypes: ["rectangle", "polygon", "point", "rotatedRect"],
1409
- onBatchChange: Q,
1410
- onAnnotationChange: tt,
1411
- onLabelChange: et
1444
+ onBatchChange: st,
1445
+ onAnnotationChange: it,
1446
+ onLabelChange: N
1412
1447
  }, null, 8, ["batchImages", "labels"])
1413
1448
  ])
1414
1449
  ]))
1415
- ]));
1450
+ ], 512));
1416
1451
  }
1417
- }), Sn = /* @__PURE__ */ K(An, [["__scopeId", "data-v-d19b4a14"]]);
1452
+ }), kn = /* @__PURE__ */ Z(An, [["__scopeId", "data-v-16638a5c"]]);
1418
1453
  export {
1419
- Sn as BatchAnnotator,
1420
- Ke as ImageAnnotator,
1421
- Sn as default
1454
+ kn as BatchAnnotator,
1455
+ Ze as ImageAnnotator,
1456
+ kn as default
1422
1457
  };