@dssp/supervision 1.0.0-alpha.47 → 1.0.0-alpha.49

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 (23) hide show
  1. package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.d.ts +57 -0
  2. package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js +800 -0
  3. package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js.map +1 -0
  4. package/dist-client/pages/building-inspection/building-inspection-detail-camera.d.ts +6 -33
  5. package/dist-client/pages/building-inspection/building-inspection-detail-camera.js +58 -427
  6. package/dist-client/pages/building-inspection/building-inspection-detail-camera.js.map +1 -1
  7. package/dist-client/pages/building-inspection/component/building-inspection-detail-header.d.ts +3 -0
  8. package/dist-client/pages/building-inspection/component/building-inspection-detail-header.js +77 -8
  9. package/dist-client/pages/building-inspection/component/building-inspection-detail-header.js.map +1 -1
  10. package/dist-client/pages/building-inspection/component/inspection-document/photo-album-popup.js +21 -6
  11. package/dist-client/pages/building-inspection/component/inspection-document/photo-album-popup.js.map +1 -1
  12. package/dist-client/route.d.ts +1 -1
  13. package/dist-client/route.js +3 -0
  14. package/dist-client/route.js.map +1 -1
  15. package/dist-client/tsconfig.tsbuildinfo +1 -1
  16. package/dist-server/service/checklist/checklist-query.d.ts +1 -0
  17. package/dist-server/service/checklist/checklist-query.js +20 -0
  18. package/dist-server/service/checklist/checklist-query.js.map +1 -1
  19. package/dist-server/service/checklist-template-item/index.d.ts +1 -1
  20. package/dist-server/service/index.d.ts +1 -1
  21. package/dist-server/tsconfig.tsbuildinfo +1 -1
  22. package/package.json +3 -2
  23. package/things-factory.config.js +1 -0
@@ -1,7 +1,5 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import '@material/web/icon/icon.js';
3
- import '@operato/input/ox-input-switch.js';
4
- import '@operato/mini-map/ox-zoomable-image.js';
5
3
  import '@material/web/progress/circular-progress.js';
6
4
  import gql from 'graphql-tag';
7
5
  import { css, html } from 'lit';
@@ -9,77 +7,17 @@ import { customElement, state, query } from 'lit/decorators.js';
9
7
  import { PageView } from '@operato/shell';
10
8
  import { CommonGristStyles, ScrollbarStyles } from '@operato/styles';
11
9
  import { client } from '@operato/graphql';
10
+ import { notify } from '@operato/layout';
12
11
  import './component/building-inspection-detail-header';
13
12
  let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
14
13
  constructor() {
15
14
  super(...arguments);
16
- this.KEYPOINT_RULER_API_BASE_URL = 'https://hatiolab-korea-uni.ettisoft.com';
17
15
  this.project = {};
18
16
  this.buildingInspection = {};
19
17
  this.buildingInspectionId = '';
20
- this.capturedVideoUrl = null;
21
- this.videoFile = null;
22
- this.frame = null;
23
- this.analyzing = false;
24
- this.selectedPoints = {
25
- x1: null,
26
- y1: null,
27
- x2: null,
28
- y2: null
29
- };
30
- this.frameNaturalWidth = 0;
31
- this.frameNaturalHeight = 0;
32
- this.displayedImageRect = null;
33
- this.distance = null;
34
- this.unit = null;
35
- this._onImageLoad = () => {
36
- if (!this.frameImageEl || !this.imageWrapperEl)
37
- return;
38
- const img = this.frameImageEl;
39
- const wrapperRect = this.imageWrapperEl.getBoundingClientRect();
40
- const imgRect = img.getBoundingClientRect();
41
- this.frameNaturalWidth = img.naturalWidth;
42
- this.frameNaturalHeight = img.naturalHeight;
43
- this.displayedImageRect = {
44
- width: imgRect.width,
45
- height: imgRect.height,
46
- left: imgRect.left - wrapperRect.left,
47
- top: imgRect.top - wrapperRect.top
48
- };
49
- };
50
- this._onImageClick = (event) => {
51
- if (!this.frameImageEl || !this.imageWrapperEl)
52
- return;
53
- const imgRect = this.frameImageEl.getBoundingClientRect();
54
- const wrapperRect = this.imageWrapperEl.getBoundingClientRect();
55
- const clientX = event.clientX;
56
- const clientY = event.clientY;
57
- // Ignore clicks outside the displayed image area
58
- if (clientX < imgRect.left || clientX > imgRect.right || clientY < imgRect.top || clientY > imgRect.bottom) {
59
- return;
60
- }
61
- const relativeX = clientX - imgRect.left;
62
- const relativeY = clientY - imgRect.top;
63
- const xOnNatural = Math.round((relativeX * this.frameNaturalWidth) / imgRect.width);
64
- const yOnNatural = Math.round((relativeY * this.frameNaturalHeight) / imgRect.height);
65
- if (this.selectedPoints.x1 === null || this.selectedPoints.y1 === null) {
66
- this.selectedPoints = Object.assign(Object.assign({}, this.selectedPoints), { x1: xOnNatural, y1: yOnNatural });
67
- }
68
- else if (this.selectedPoints.x2 === null || this.selectedPoints.y2 === null) {
69
- this.selectedPoints = Object.assign(Object.assign({}, this.selectedPoints), { x2: xOnNatural, y2: yOnNatural });
70
- }
71
- else {
72
- // 세 번째 클릭부터는 초기화 후 첫 점으로 설정
73
- this.selectedPoints = { x1: xOnNatural, y1: yOnNatural, x2: null, y2: null };
74
- }
75
- // Update displayed rect cache (in case layout changed)
76
- this.displayedImageRect = {
77
- width: imgRect.width,
78
- height: imgRect.height,
79
- left: imgRect.left - wrapperRect.left,
80
- top: imgRect.top - wrapperRect.top
81
- };
82
- };
18
+ this.capturedImageUrl = null;
19
+ this.imageFile = null;
20
+ this.isSaved = false;
83
21
  }
84
22
  get context() {
85
23
  return {
@@ -87,7 +25,7 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
87
25
  };
88
26
  }
89
27
  render() {
90
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
28
+ var _a, _b, _c, _d, _e, _f, _g, _h;
91
29
  return html `
92
30
  <building-inspection-detail-header
93
31
  .buildingInspectionId=${(_a = this.buildingInspection) === null || _a === void 0 ? void 0 : _a.id}
@@ -98,57 +36,25 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
98
36
  ></building-inspection-detail-header>
99
37
 
100
38
  <div body>
101
- <!-- Preview selected or recorded video -->
102
39
  <div preview>
103
- <!-- analyzing 로딩 중일 때 -->
104
- ${this.analyzing
105
- ? html `<div class="loading-container">
106
- <md-circular-progress indeterminate></md-circular-progress>
107
- <div class="loading-text">분석 중...</div>
108
- </div>`
109
- : // 동영상 분석 완료 단일 프레임 표시
110
- this.frame
111
- ? html `
112
- <div class="image-wrapper" @click=${this._onImageClick}>
113
- <img
114
- id="frameImage"
115
- src="${this.KEYPOINT_RULER_API_BASE_URL + ((_j = this.frame) === null || _j === void 0 ? void 0 : _j.download_url)}"
116
- alt="frame"
117
- loading="eager"
118
- @load=${this._onImageLoad}
119
- />
120
- ${this._renderMarkers()}
121
- </div>
122
- `
123
- : // 동영상 선택 후 동영상 프리뷰
124
- this.capturedVideoUrl
125
- ? html `<video src=${this.capturedVideoUrl} controls playsinline></video>`
126
- : // 초기 상태, 동영상 선택 전
127
- html `<md-icon>videocam</md-icon>`}
40
+ <div class="image-wrapper">
41
+ ${this.capturedImageUrl
42
+ ? html `<img id="imageImage" src="${this.capturedImageUrl}" alt="image" />`
43
+ : html `<md-icon>add_a_photo</md-icon>`}
44
+ </div>
128
45
  </div>
129
46
 
130
47
  <div controls>
131
- <span class="controls-title">동영상 촬영</span>
48
+ <span class="controls-title">사진 촬영</span>
132
49
 
133
- <!-- Camera shutter button (record video) -->
134
50
  <div class="camera-shutter">
135
51
  <md-icon>camera</md-icon>
136
- <input id="cameraInput" type="file" accept="video/*" capture @change="${this._onVideoSelected}" />
52
+ <input id="imageInput" type="file" accept="image/*" @change="${this._onImageSelected}" />
137
53
  </div>
138
54
 
139
55
  <!-- Action buttons -->
140
56
  <div action-buttons>
141
- ${this.frame
142
- ? html `
143
- <button class="photo" ?disabled=${this.analyzing || !this._hasTwoPoints()} @click=${this._onAnalyzePhoto}>
144
- 사진 분석
145
- </button>
146
- `
147
- : html `
148
- <button class="save" ?disabled=${this.analyzing || !this.capturedVideoUrl} @click=${this._onAnalyzeVideo}>
149
- 동영상 분석
150
- </button>
151
- `}
57
+ <button class="save" ?disabled=${!this.imageFile || this.isSaved} @click=${this._savePhoto}>사진 저장</button>
152
58
  <button class="retry" @click=${this._onRetry}>초기화</button>
153
59
  </div>
154
60
  </div>
@@ -158,6 +64,7 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
158
64
  async updated(changes) { }
159
65
  async pageUpdated(changes, lifecycle) {
160
66
  if (this.active) {
67
+ this._onRetry();
161
68
  this.buildingInspectionId = lifecycle.resourceId || '';
162
69
  await this.initBuildingInspection(this.buildingInspectionId);
163
70
  }
@@ -171,20 +78,12 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
171
78
  id
172
79
  status
173
80
  requestDate
174
- drawingMarker
175
81
  checklist {
176
- location
177
- inspectionDrawingType
82
+ id
178
83
  }
179
84
  buildingLevel {
180
85
  id
181
86
  floor
182
- mainDrawing {
183
- id
184
- name
185
- fullpath
186
- }
187
- mainDrawingImage
188
87
  building {
189
88
  id
190
89
  name
@@ -223,163 +122,62 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
223
122
  return;
224
123
  this.project = response.data.project;
225
124
  }
226
- _onVideoSelected(event) {
125
+ _onImageSelected(event) {
227
126
  var _a;
228
127
  const input = event.target;
229
128
  const file = (_a = input === null || input === void 0 ? void 0 : input.files) === null || _a === void 0 ? void 0 : _a[0];
230
129
  if (!file)
231
130
  return;
232
131
  // Only allow video files
233
- if (!file.type.startsWith('video/')) {
234
- console.warn('선택된 파일이 동영상이 아닙니다.');
132
+ if (!file.type.startsWith('image/')) {
133
+ console.warn('선택된 파일이 이미지가 아닙니다.');
235
134
  return;
236
135
  }
237
136
  // Revoke old object URL if exists
238
- if (this.capturedVideoUrl) {
239
- URL.revokeObjectURL(this.capturedVideoUrl);
240
- }
241
- this.videoFile = file;
242
- this.capturedVideoUrl = URL.createObjectURL(file);
243
- }
244
- async _onAnalyzeVideo() {
245
- var _a, _b, _c, _d, _e, _f, _g;
246
- if (!this.videoFile) {
247
- console.warn('선택된 동영상이 없습니다.');
248
- return;
249
- }
250
- try {
251
- this.analyzing = true;
252
- const form = new FormData();
253
- form.append('files', this.videoFile, this.videoFile.name);
254
- const response = await fetch(`${this.KEYPOINT_RULER_API_BASE_URL}/api/run/keypoint-ruler`, {
255
- method: 'POST',
256
- headers: { Authorization: `Basic ${btoa('admin:admin1234')}` },
257
- body: form
258
- });
259
- const data = await response.json();
260
- this.frame = {
261
- file_id: (_b = (_a = data === null || data === void 0 ? void 0 : data.result) === null || _a === void 0 ? void 0 : _a.output_files[0]) === null || _b === void 0 ? void 0 : _b.file_id,
262
- download_url: (_d = (_c = data === null || data === void 0 ? void 0 : data.result) === null || _c === void 0 ? void 0 : _c.output_files[0]) === null || _d === void 0 ? void 0 : _d.download_url,
263
- file_path: (_f = (_e = data === null || data === void 0 ? void 0 : data.result) === null || _e === void 0 ? void 0 : _e.frames[0]) === null || _f === void 0 ? void 0 : _f.file_path,
264
- calibration: (_g = data === null || data === void 0 ? void 0 : data.result) === null || _g === void 0 ? void 0 : _g.calibration
265
- };
266
- }
267
- catch (error) {
268
- console.error('동영상 업로드 실패:', error);
269
- }
270
- finally {
271
- this.analyzing = false;
137
+ if (this.capturedImageUrl) {
138
+ URL.revokeObjectURL(this.capturedImageUrl);
272
139
  }
140
+ this.imageFile = file;
141
+ this.capturedImageUrl = URL.createObjectURL(file);
142
+ this.isSaved = false; // 새 이미지 선택 시 저장 상태 초기화
273
143
  }
274
144
  _onRetry() {
275
145
  // Clear current selection and reopen camera
276
- if (this.capturedVideoUrl) {
277
- URL.revokeObjectURL(this.capturedVideoUrl);
146
+ if (this.capturedImageUrl) {
147
+ URL.revokeObjectURL(this.capturedImageUrl);
278
148
  }
279
- this.capturedVideoUrl = null;
280
- this.videoFile = null;
281
- this.frame = null;
282
- this.selectedPoints = { x1: null, y1: null, x2: null, y2: null };
283
- this.displayedImageRect = null;
284
- this.frameNaturalWidth = 0;
285
- this.frameNaturalHeight = 0;
286
- this.cameraInputEl.value = '';
287
- this.distance = null;
288
- this.unit = null;
289
- }
290
- _hasTwoPoints() {
291
- const { x1, y1, x2, y2 } = this.selectedPoints;
292
- return x1 !== null && y1 !== null && x2 !== null && y2 !== null;
293
- }
294
- _renderMarkers() {
295
- if (!this.displayedImageRect)
296
- return html ``;
297
- const { left, top, width, height } = this.displayedImageRect;
298
- const { x1, y1, x2, y2 } = this.selectedPoints;
299
- const toDisplay = (x, y) => {
300
- const dx = left + (x * width) / (this.frameNaturalWidth || 1);
301
- const dy = top + (y * height) / (this.frameNaturalHeight || 1);
302
- return { dx, dy };
303
- };
304
- return html `
305
- ${x1 !== null && y1 !== null
306
- ? (() => {
307
- const p = toDisplay(x1, y1);
308
- return html `<div class="point-marker point-1" style="left:${p.dx}px; top:${p.dy}px;"></div>`;
309
- })()
310
- : ''}
311
- ${x2 !== null && y2 !== null
312
- ? (() => {
313
- const p = toDisplay(x2, y2);
314
- return html `<div class="point-marker point-2" style="left:${p.dx}px; top:${p.dy}px;"></div>`;
315
- })()
316
- : ''}
317
- ${this._hasTwoPoints()
318
- ? (() => {
319
- const p1 = toDisplay(x1, y1);
320
- const p2 = toDisplay(x2, y2);
321
- const x = Math.min(p1.dx, p2.dx);
322
- const y = Math.min(p1.dy, p2.dy);
323
- const w = Math.abs(p1.dx - p2.dx);
324
- const h = Math.abs(p1.dy - p2.dy);
325
- const cx = (p1.dx + p2.dx) / 2;
326
- const cy = (p1.dy + p2.dy) / 2;
327
- return html `
328
- <svg class="line-overlay" style="left:${x}px; top:${y}px; width:${w}px; height:${h}px;">
329
- <line
330
- x1=${p1.dx < p2.dx ? 0 : w}
331
- y1=${p1.dy < p2.dy ? 0 : h}
332
- x2=${p1.dx < p2.dx ? w : 0}
333
- y2=${p1.dy < p2.dy ? h : 0}
334
- stroke="#ff9800"
335
- stroke-width="3"
336
- />
337
- </svg>
338
- ${this.distance !== null && this.unit
339
- ? html `<div class="distance-label" style="left:${cx}px; top:${cy}px;">${this.distance} ${this.unit}</div>`
340
- : ''}
341
- `;
342
- })()
343
- : ''}
344
- `;
149
+ this.capturedImageUrl = null;
150
+ this.imageFile = null;
151
+ this.isSaved = false; // 초기화 시 저장 상태도 리셋
152
+ this.imageInputEl.value = '';
345
153
  }
346
- async _onAnalyzePhoto() {
347
- if (!this.frame) {
348
- console.warn('분석할 사진이 없습니다.');
154
+ async _savePhoto() {
155
+ var _a, _b, _c;
156
+ if (!this.imageFile) {
157
+ notify({ message: '사진을 선택한 후 저장할 수 있습니다.', level: 'warn' });
349
158
  return;
350
159
  }
351
- if (!this._hasTwoPoints()) {
352
- console.warn('두 점을 먼저 선택해 주세요.');
353
- return;
354
- }
355
- try {
356
- this.analyzing = true;
357
- const payload = {
358
- x1: this.selectedPoints.x1,
359
- y1: this.selectedPoints.y1,
360
- x2: this.selectedPoints.x2,
361
- y2: this.selectedPoints.y2,
362
- file_path: this.frame.file_path,
363
- calibration: this.frame.calibration
364
- };
365
- const form = new FormData();
366
- form.append('input', JSON.stringify(payload));
367
- const response = await fetch(`${this.KEYPOINT_RULER_API_BASE_URL}/api/run/keypoint-ruler`, {
368
- method: 'POST',
369
- headers: { Authorization: `Basic ${btoa('admin:admin1234')}` },
370
- body: form
371
- });
372
- const result = await response.json();
373
- const { distance, unit } = result.result || {};
374
- this.distance = distance;
375
- this.unit = unit;
376
- }
377
- catch (error) {
378
- console.error('사진 분석 실패:', error);
160
+ const checklistId = (_b = (_a = this.buildingInspection) === null || _a === void 0 ? void 0 : _a.checklist) === null || _b === void 0 ? void 0 : _b.id;
161
+ const file = this.imageFile;
162
+ const response = await client.mutate({
163
+ mutation: gql `
164
+ mutation ($attachments: [NewAttachment!]!) {
165
+ createAttachments(attachments: $attachments) {
166
+ id
167
+ }
379
168
  }
380
- finally {
381
- this.analyzing = false;
169
+ `,
170
+ variables: {
171
+ attachments: [{ file, refBy: checklistId, refType: 'Checklist', description: (_c = this.buildingInspection) === null || _c === void 0 ? void 0 : _c.status }]
172
+ },
173
+ context: { hasUpload: true }
174
+ });
175
+ if (!response.errors) {
176
+ notify({ message: '사진 대지를 저장하였습니다.', level: 'info' });
177
+ this.isSaved = true; // 저장 성공 시 상태 업데이트
178
+ return;
382
179
  }
180
+ return response.data.createAttachments;
383
181
  }
384
182
  };
385
183
  BuildingInspectionCamera.styles = [
@@ -431,119 +229,12 @@ BuildingInspectionCamera.styles = [
431
229
  --md-icon-size: 160px;
432
230
  }
433
231
 
434
- .loading-container {
435
- display: flex;
436
- flex-direction: column;
437
- align-items: center;
438
- justify-content: center;
439
- gap: 12px;
440
- }
441
-
442
- .loading-text {
443
- font-size: 14px;
444
- color: #666;
445
- }
446
-
447
- .frame-container {
448
- width: 100%;
449
- height: 100%;
450
- max-height: 100%;
451
- min-height: 0;
452
- overflow-y: auto;
453
- display: flex;
454
- flex-direction: column;
455
- gap: 12px;
456
- padding: 12px;
457
- }
458
-
459
- .frames-header {
460
- display: flex;
461
- align-items: center;
462
- justify-content: center;
463
- gap: 12px;
464
- font-size: 20px;
465
- font-weight: 700;
466
- color: #333;
467
- text-align: center;
468
- padding-block: 8px;
469
- }
470
-
471
- .frames-count {
472
- font-size: 16px;
473
- color: #777;
474
- font-weight: 600;
475
- }
476
-
477
- .frames-grid {
478
- display: grid;
479
- grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
480
- gap: 12px;
481
- }
482
-
483
- .frame-item {
484
- border: 1px solid #ddd;
485
- border-radius: 8px;
486
- overflow: hidden;
487
- background: #fff;
488
- cursor: pointer;
489
- transition:
490
- box-shadow 0.2s,
491
- transform 0.1s;
492
- }
493
-
494
- .frame-item:hover {
495
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
496
- transform: translateY(-1px);
497
- }
498
-
499
- .frame-item img {
500
- display: block;
501
- width: 100%;
502
- height: 120px;
503
- object-fit: cover;
504
- }
505
-
506
232
  .image-wrapper {
507
233
  position: relative;
508
234
  width: 100%;
509
235
  height: 100%;
510
236
  align-content: center;
511
- }
512
-
513
- .point-marker {
514
- position: absolute;
515
- width: 14px;
516
- height: 14px;
517
- border-radius: 50%;
518
- border: 2px solid #fff;
519
- transform: translate(-50%, -50%);
520
- pointer-events: none;
521
- box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25);
522
- }
523
-
524
- .point-1 {
525
- background-color: #e53935;
526
- }
527
-
528
- .point-2 {
529
- background-color: #1e88e5;
530
- }
531
-
532
- .line-overlay {
533
- position: absolute;
534
- pointer-events: none;
535
- }
536
-
537
- .distance-label {
538
- position: absolute;
539
- background: rgba(0, 0, 0, 0.7);
540
- color: #fff;
541
- font-size: 14px;
542
- padding: 2px 6px;
543
- border-radius: 4px;
544
- transform: translate(-50%, -120%);
545
- pointer-events: none;
546
- white-space: nowrap;
237
+ text-align: center;
547
238
  }
548
239
 
549
240
  div[controls] {
@@ -561,20 +252,6 @@ BuildingInspectionCamera.styles = [
561
252
  gap: 15px;
562
253
  }
563
254
 
564
- .switch-container {
565
- display: flex;
566
- align-items: center;
567
- gap: 10px;
568
- font-size: 24px;
569
- font-weight: bold;
570
- }
571
-
572
- ox-input-switch {
573
- --ox-simple-switch-fullwidth: 68px;
574
- --ox-simple-switch-fullheight: 34px;
575
- --ox-simple-switch-thumbnail-size: 34px;
576
- }
577
-
578
255
  .camera-shutter {
579
256
  display: flex;
580
257
  justify-content: center;
@@ -627,16 +304,6 @@ BuildingInspectionCamera.styles = [
627
304
  background-color: #f0ad4e;
628
305
  color: white;
629
306
  }
630
-
631
- button.photo {
632
- background-color: #1e88e5;
633
- color: white;
634
-
635
- &:disabled {
636
- background-color: #ccc;
637
- cursor: default;
638
- }
639
- }
640
307
  `
641
308
  ];
642
309
  __decorate([
@@ -654,55 +321,19 @@ __decorate([
654
321
  __decorate([
655
322
  state(),
656
323
  __metadata("design:type", Object)
657
- ], BuildingInspectionCamera.prototype, "capturedVideoUrl", void 0);
658
- __decorate([
659
- state(),
660
- __metadata("design:type", Object)
661
- ], BuildingInspectionCamera.prototype, "videoFile", void 0);
324
+ ], BuildingInspectionCamera.prototype, "capturedImageUrl", void 0);
662
325
  __decorate([
663
326
  state(),
664
327
  __metadata("design:type", Object)
665
- ], BuildingInspectionCamera.prototype, "frame", void 0);
328
+ ], BuildingInspectionCamera.prototype, "imageFile", void 0);
666
329
  __decorate([
667
330
  state(),
668
331
  __metadata("design:type", Boolean)
669
- ], BuildingInspectionCamera.prototype, "analyzing", void 0);
670
- __decorate([
671
- state(),
672
- __metadata("design:type", Object)
673
- ], BuildingInspectionCamera.prototype, "selectedPoints", void 0);
674
- __decorate([
675
- state(),
676
- __metadata("design:type", Number)
677
- ], BuildingInspectionCamera.prototype, "frameNaturalWidth", void 0);
678
- __decorate([
679
- state(),
680
- __metadata("design:type", Number)
681
- ], BuildingInspectionCamera.prototype, "frameNaturalHeight", void 0);
682
- __decorate([
683
- state(),
684
- __metadata("design:type", Object)
685
- ], BuildingInspectionCamera.prototype, "displayedImageRect", void 0);
686
- __decorate([
687
- state(),
688
- __metadata("design:type", Object)
689
- ], BuildingInspectionCamera.prototype, "distance", void 0);
690
- __decorate([
691
- state(),
692
- __metadata("design:type", Object)
693
- ], BuildingInspectionCamera.prototype, "unit", void 0);
694
- __decorate([
695
- query('img#frameImage'),
696
- __metadata("design:type", HTMLImageElement)
697
- ], BuildingInspectionCamera.prototype, "frameImageEl", void 0);
698
- __decorate([
699
- query('div.image-wrapper'),
700
- __metadata("design:type", HTMLDivElement)
701
- ], BuildingInspectionCamera.prototype, "imageWrapperEl", void 0);
332
+ ], BuildingInspectionCamera.prototype, "isSaved", void 0);
702
333
  __decorate([
703
- query('#cameraInput'),
334
+ query('#imageInput'),
704
335
  __metadata("design:type", HTMLInputElement)
705
- ], BuildingInspectionCamera.prototype, "cameraInputEl", void 0);
336
+ ], BuildingInspectionCamera.prototype, "imageInputEl", void 0);
706
337
  BuildingInspectionCamera = __decorate([
707
338
  customElement('building-inspection-detail-camera')
708
339
  ], BuildingInspectionCamera);