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

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 +56 -0
  2. package/dist-client/pages/building-inspection/building-inspection-detail-ai-measurement.js +789 -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 +57 -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>
@@ -171,20 +77,12 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
171
77
  id
172
78
  status
173
79
  requestDate
174
- drawingMarker
175
80
  checklist {
176
- location
177
- inspectionDrawingType
81
+ id
178
82
  }
179
83
  buildingLevel {
180
84
  id
181
85
  floor
182
- mainDrawing {
183
- id
184
- name
185
- fullpath
186
- }
187
- mainDrawingImage
188
86
  building {
189
87
  id
190
88
  name
@@ -223,163 +121,62 @@ let BuildingInspectionCamera = class BuildingInspectionCamera extends PageView {
223
121
  return;
224
122
  this.project = response.data.project;
225
123
  }
226
- _onVideoSelected(event) {
124
+ _onImageSelected(event) {
227
125
  var _a;
228
126
  const input = event.target;
229
127
  const file = (_a = input === null || input === void 0 ? void 0 : input.files) === null || _a === void 0 ? void 0 : _a[0];
230
128
  if (!file)
231
129
  return;
232
130
  // Only allow video files
233
- if (!file.type.startsWith('video/')) {
234
- console.warn('선택된 파일이 동영상이 아닙니다.');
131
+ if (!file.type.startsWith('image/')) {
132
+ console.warn('선택된 파일이 이미지가 아닙니다.');
235
133
  return;
236
134
  }
237
135
  // 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;
136
+ if (this.capturedImageUrl) {
137
+ URL.revokeObjectURL(this.capturedImageUrl);
272
138
  }
139
+ this.imageFile = file;
140
+ this.capturedImageUrl = URL.createObjectURL(file);
141
+ this.isSaved = false; // 새 이미지 선택 시 저장 상태 초기화
273
142
  }
274
143
  _onRetry() {
275
144
  // Clear current selection and reopen camera
276
- if (this.capturedVideoUrl) {
277
- URL.revokeObjectURL(this.capturedVideoUrl);
145
+ if (this.capturedImageUrl) {
146
+ URL.revokeObjectURL(this.capturedImageUrl);
278
147
  }
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
- `;
148
+ this.capturedImageUrl = null;
149
+ this.imageFile = null;
150
+ this.isSaved = false; // 초기화 시 저장 상태도 리셋
151
+ this.imageInputEl.value = '';
345
152
  }
346
- async _onAnalyzePhoto() {
347
- if (!this.frame) {
348
- console.warn('분석할 사진이 없습니다.');
153
+ async _savePhoto() {
154
+ var _a, _b, _c;
155
+ if (!this.imageFile) {
156
+ notify({ message: '사진을 선택한 후 저장할 수 있습니다.', level: 'warn' });
349
157
  return;
350
158
  }
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);
159
+ const checklistId = (_b = (_a = this.buildingInspection) === null || _a === void 0 ? void 0 : _a.checklist) === null || _b === void 0 ? void 0 : _b.id;
160
+ const file = this.imageFile;
161
+ const response = await client.mutate({
162
+ mutation: gql `
163
+ mutation ($attachments: [NewAttachment!]!) {
164
+ createAttachments(attachments: $attachments) {
165
+ id
166
+ }
379
167
  }
380
- finally {
381
- this.analyzing = false;
168
+ `,
169
+ variables: {
170
+ attachments: [{ file, refBy: checklistId, refType: 'Checklist', description: (_c = this.buildingInspection) === null || _c === void 0 ? void 0 : _c.status }]
171
+ },
172
+ context: { hasUpload: true }
173
+ });
174
+ if (!response.errors) {
175
+ notify({ message: '사진 대지를 저장하였습니다.', level: 'info' });
176
+ this.isSaved = true; // 저장 성공 시 상태 업데이트
177
+ return;
382
178
  }
179
+ return response.data.createAttachments;
383
180
  }
384
181
  };
385
182
  BuildingInspectionCamera.styles = [
@@ -431,119 +228,12 @@ BuildingInspectionCamera.styles = [
431
228
  --md-icon-size: 160px;
432
229
  }
433
230
 
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
231
  .image-wrapper {
507
232
  position: relative;
508
233
  width: 100%;
509
234
  height: 100%;
510
235
  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;
236
+ text-align: center;
547
237
  }
548
238
 
549
239
  div[controls] {
@@ -561,20 +251,6 @@ BuildingInspectionCamera.styles = [
561
251
  gap: 15px;
562
252
  }
563
253
 
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
254
  .camera-shutter {
579
255
  display: flex;
580
256
  justify-content: center;
@@ -627,16 +303,6 @@ BuildingInspectionCamera.styles = [
627
303
  background-color: #f0ad4e;
628
304
  color: white;
629
305
  }
630
-
631
- button.photo {
632
- background-color: #1e88e5;
633
- color: white;
634
-
635
- &:disabled {
636
- background-color: #ccc;
637
- cursor: default;
638
- }
639
- }
640
306
  `
641
307
  ];
642
308
  __decorate([
@@ -654,55 +320,19 @@ __decorate([
654
320
  __decorate([
655
321
  state(),
656
322
  __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);
323
+ ], BuildingInspectionCamera.prototype, "capturedImageUrl", void 0);
662
324
  __decorate([
663
325
  state(),
664
326
  __metadata("design:type", Object)
665
- ], BuildingInspectionCamera.prototype, "frame", void 0);
327
+ ], BuildingInspectionCamera.prototype, "imageFile", void 0);
666
328
  __decorate([
667
329
  state(),
668
330
  __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);
331
+ ], BuildingInspectionCamera.prototype, "isSaved", void 0);
702
332
  __decorate([
703
- query('#cameraInput'),
333
+ query('#imageInput'),
704
334
  __metadata("design:type", HTMLInputElement)
705
- ], BuildingInspectionCamera.prototype, "cameraInputEl", void 0);
335
+ ], BuildingInspectionCamera.prototype, "imageInputEl", void 0);
706
336
  BuildingInspectionCamera = __decorate([
707
337
  customElement('building-inspection-detail-camera')
708
338
  ], BuildingInspectionCamera);