Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
363 lines (341 loc) · 32 KB
/
Copy pathindex.html
File metadata and controls
363 lines (341 loc) · 32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Takeoff — Plan Measurement Tool</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Sora:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./app/styles.css?v=scale-source-spacing-1" />
</head>
<body class="no-document">
<header>
<div class="brand">
<div class="dot"></div>
<div>Takeoff</div>
</div>
<div class="tab-strip">
<div id="docTabs" class="doc-tabs" role="tablist" aria-label="Open documents"></div>
<button id="uploadButton" class="add-doc-tab" type="button" aria-label="Upload Image/PDF">
<svg viewBox="0 0 12 12" aria-hidden="true"><path d="M6 2v8M2 6h8"/></svg>
</button>
</div>
<div class="top-actions" aria-label="View labels and edit history"><button id="measurementLabelsToggle" class="top-action" type="button" title="Hide measurement labels" aria-label="Hide measurement labels" aria-pressed="true"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 18h6"/><path d="M10 22h4"/><path d="M8.4 14.5A7 7 0 1 1 15.6 14.5C14.6 15.3 14 16.1 14 18h-4c0-1.9-.6-2.7-1.6-3.5Z"/></svg></button>
<button id="undoButton" class="top-action" type="button" title="Undo" aria-label="Undo" disabled>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 14 4 9l5-5"/><path d="M4 9h10a6 6 0 0 1 0 12h-2"/></svg>
</button>
<button id="redoButton" class="top-action" type="button" title="Redo" aria-label="Redo" disabled>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m15 14 5-5-5-5"/><path d="M20 9H10a6 6 0 0 0 0 12h2"/></svg>
</button>
</div>
<input type="file" id="fileInput" class="file-picker" accept="application/pdf,image/*" aria-label="Upload Image/PDF" />
</header>
<nav id="leftRail" class="left-rail" aria-label="Document tools">
<div class="toolbar tools-center" aria-label="Drawing tools">
<button id="btn-pan" class="tool-btn" aria-label="Pan" data-tooltip="Pan">
<svg viewBox="0 0 400 400" aria-hidden="true">
<path fill="currentColor" fill-rule="evenodd" d="M201.563 35.655 C 192.086 36.975,185.612 42.795,182.674 52.637 C 182.451 53.383,182.360 55.132,182.288 60.059 C 182.236 63.604,182.129 66.571,182.052 66.652 C 181.974 66.734,181.363 66.106,180.694 65.258 C 173.853 56.572,163.261 54.190,153.381 59.114 C 148.517 61.538,144.715 65.978,142.864 71.394 C 141.478 75.451,141.558 71.251,141.712 131.857 C 141.804 168.099,141.785 186.507,141.656 186.587 C 141.549 186.654,140.482 185.326,139.284 183.637 C 138.086 181.948,137.018 180.459,136.910 180.328 C 136.802 180.197,135.789 178.791,134.659 177.203 C 132.941 174.790,129.883 170.546,129.342 169.824 C 120.994 158.685,112.938 153.857,102.637 153.821 C 91.825 153.782,83.654 159.479,79.685 169.824 C 78.665 172.482,78.139 178.774,78.717 181.408 C 78.827 181.912,79.014 182.764,79.131 183.301 C 79.818 186.439,81.414 189.911,83.549 192.909 C 84.070 193.640,85.510 195.732,86.749 197.559 C 91.079 203.939,93.804 207.939,96.396 211.719 C 97.832 213.813,100.370 217.549,102.036 220.020 C 103.703 222.490,105.822 225.610,106.745 226.953 C 107.669 228.296,109.224 230.581,110.202 232.031 C 111.180 233.481,112.961 236.118,114.161 237.891 C 115.361 239.663,117.266 242.476,118.393 244.141 C 122.105 249.623,125.792 255.091,129.785 261.035 C 141.936 279.126,142.201 279.510,144.847 282.910 C 156.975 298.489,175.007 308.545,195.508 311.164 C 198.444 311.539,235.091 311.544,238.086 311.170 C 273.732 306.715,300.448 279.867,305.854 243.066 C 306.662 237.571,306.665 237.258,306.600 171.777 L 306.537 108.691 306.105 107.084 C 301.418 89.678,281.028 83.819,268.700 96.336 C 267.646 97.406,266.955 97.974,266.900 97.816 C 266.851 97.674,266.781 92.549,266.745 86.426 C 266.667 73.377,266.635 73.134,264.324 68.447 C 257.183 53.965,235.698 52.413,227.185 65.764 C 226.229 67.263,226.172 67.048,226.172 61.955 C 226.172 54.850,225.570 51.257,223.791 47.754 C 219.471 39.243,210.573 34.400,201.563 35.655 M208.203 44.316 C 212.546 45.677,216.089 49.607,217.289 54.395 C 217.723 56.125,217.685 52.167,217.858 114.063 C 217.978 156.919,218.048 165.714,218.273 166.646 C 219.734 172.678,228.647 173.153,230.831 167.316 L 231.251 166.194 231.356 121.915 C 231.466 75.407,231.454 75.987,232.370 73.633 C 236.906 61.985,253.119 61.994,257.484 73.647 C 258.428 76.169,258.391 74.206,258.395 122.016 L 258.398 166.786 258.859 167.827 C 261.125 172.952,268.744 172.575,270.276 167.262 C 270.450 166.660,270.512 159.526,270.524 138.845 C 270.533 123.657,270.613 110.747,270.702 110.156 C 272.736 96.607,290.751 93.510,296.657 105.694 C 298.411 109.311,298.262 102.672,298.192 174.121 C 298.122 245.075,298.270 237.924,296.683 246.777 C 294.757 257.517,288.536 270.356,280.877 279.395 C 270.681 291.428,256.108 299.820,241.052 302.328 C 235.864 303.193,235.050 303.223,216.895 303.223 C 199.787 303.223,196.849 303.136,193.945 302.543 C 193.462 302.445,192.319 302.225,191.406 302.055 C 177.113 299.394,162.253 290.785,153.308 279.980 C 149.904 275.870,149.386 275.155,144.109 267.285 C 142.020 264.170,138.212 258.501,135.647 254.688 C 133.082 250.874,128.799 244.502,126.131 240.527 C 123.462 236.553,120.111 231.587,118.684 229.492 C 117.257 227.397,115.136 224.277,113.971 222.559 C 112.806 220.840,111.186 218.467,110.371 217.285 C 109.555 216.104,107.833 213.580,106.544 211.678 C 103.295 206.884,99.567 201.423,97.173 197.949 C 88.996 186.083,88.138 184.688,87.450 182.129 C 83.528 167.533,98.770 156.741,112.184 164.616 C 116.998 167.442,119.249 170.005,129.004 183.767 C 131.689 187.555,134.824 191.961,135.969 193.556 C 137.114 195.152,139.467 198.437,141.199 200.856 C 144.588 205.591,145.060 206.069,146.487 206.206 C 147.782 206.331,148.702 205.970,149.526 205.015 L 150.231 204.199 150.178 140.332 C 150.129 80.359,150.147 76.389,150.463 75.228 C 154.167 61.641,172.647 61.455,176.252 74.969 L 176.739 76.793 176.942 120.867 C 177.054 145.108,177.191 165.409,177.248 165.980 C 177.781 171.379,185.472 173.441,188.901 169.104 C 189.514 168.330,189.705 167.996,190.168 166.895 C 190.258 166.680,190.380 141.499,190.440 110.938 C 190.555 51.244,190.486 55.358,191.425 52.734 C 193.790 46.124,201.551 42.230,208.203 44.316"/>
</svg>
<span class="sr-only">Pan</span>
</button>
<button id="btn-selection" class="tool-btn" aria-label="Select" data-tooltip="Select">
<svg viewBox="0 0 400 400" aria-hidden="true">
<path fill="currentColor" fill-rule="evenodd" d="M138.362 70.475 C 136.808 70.975,135.296 72.094,134.546 73.302 L 133.812 74.482 133.730 178.897 C 133.650 281.217,133.661 283.340,134.260 284.695 C 135.387 287.242,138.686 288.618,141.509 287.720 C 142.506 287.403,146.949 283.130,164.662 265.450 C 176.718 253.417,186.651 243.642,186.735 243.726 C 186.819 243.810,188.133 246.315,189.655 249.292 C 195.872 261.453,204.766 278.723,208.131 285.167 C 214.081 296.561,223.670 314.888,224.571 316.587 C 225.866 319.029,227.592 320.096,230.251 320.096 C 232.571 320.096,230.749 320.888,259.958 307.185 C 272.932 301.099,273.163 304.009,257.088 271.132 C 253.013 262.799,248.639 253.828,247.367 251.196 C 246.095 248.565,243.727 243.684,242.104 240.351 C 235.743 227.281,233.174 221.908,233.174 221.674 C 233.174 221.392,235.631 221.205,245.455 220.737 C 249.314 220.553,256.419 220.184,261.244 219.917 C 266.069 219.649,275.160 219.168,281.446 218.848 L 292.876 218.265 294.172 217.346 C 296.551 215.660,297.424 212.092,296.127 209.359 C 295.609 208.267,289.834 202.767,275.917 190.112 C 272.155 186.691,268.069 182.957,266.835 181.814 C 265.602 180.671,261.651 177.083,258.054 173.840 C 249.697 166.306,231.375 149.715,227.432 146.112 C 224.783 143.690,212.712 132.817,200.319 121.686 C 198.126 119.717,187.719 110.365,177.193 100.904 C 147.236 73.979,144.735 71.771,143.439 71.095 C 142.034 70.362,139.628 70.068,138.362 70.475 M160.016 102.095 C 167.533 108.861,178.206 118.465,183.732 123.437 C 189.258 128.409,195.646 134.160,197.927 136.216 C 200.207 138.273,206.595 144.015,212.121 148.976 C 239.627 173.670,275.917 206.679,275.917 207.004 C 275.917 207.140,273.800 207.346,271.212 207.463 C 268.624 207.580,265.215 207.748,263.636 207.837 C 260.838 207.994,253.513 208.374,232.695 209.444 C 221.408 210.024,220.548 210.196,219.042 212.169 C 217.059 214.770,217.269 216.500,220.355 222.970 C 223.985 230.583,236.396 256.175,242.149 267.910 C 245.107 273.944,247.528 278.929,247.528 278.986 C 247.528 279.044,249.399 282.846,251.686 287.435 C 253.973 292.023,255.793 295.829,255.731 295.891 C 255.524 296.098,233.158 306.539,232.925 306.538 C 232.729 306.537,213.208 268.870,198.134 239.408 C 192.538 228.470,191.593 227.341,188.038 227.341 C 185.358 227.341,184.870 227.775,165.009 247.792 L 145.807 267.145 145.790 178.363 C 145.780 125.947,145.891 89.624,146.060 89.686 C 146.218 89.745,152.498 95.329,160.016 102.095"/>
</svg>
<span class="sr-only">Select</span>
</button>
<button id="btn-calibrate" class="tool-btn" aria-label="Calibrate" data-tooltip="Calibrate">
<svg viewBox="0 0 24 24"><path d="M3 12h18M3 8v8M21 8v8"/></svg>
<span class="sr-only">Calibrate</span>
</button>
<div id="measureSplit" class="measure-split">
<button id="btn-measure" class="tool-btn" aria-label="Measure" data-tooltip="Measure">
<svg viewBox="0 0 24 24"><path d="M4 20l6-6 4 4 6-10"/><circle cx="4" cy="20" r="1.5"/><circle cx="10" cy="14" r="1.5"/><circle cx="14" cy="18" r="1.5"/><circle cx="20" cy="8" r="1.5"/></svg>
<span class="sr-only">Measure</span>
</button>
<button id="measureModeToggle" class="measure-menu-toggle" type="button" aria-label="Measure mode" aria-haspopup="true" aria-expanded="false" title="Measure mode">
<svg viewBox="0 0 12 12" aria-hidden="true"><path d="M4.5 3 7.5 6 4.5 9"/></svg>
</button>
</div>
<div id="circleSplit" class="measure-split"><button id="btn-circle" class="tool-btn" aria-label="Circle" data-tooltip="Circle"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="7"/><path d="M12 12h7"/></svg><span class="sr-only">Circle</span></button><button id="circleModeToggle" class="measure-menu-toggle" type="button" aria-label="Circle mode" aria-haspopup="true" aria-expanded="false" title="Circle mode"><svg viewBox="0 0 12 12" aria-hidden="true"><path d="M4.5 3 7.5 6 4.5 9"/></svg></button></div>
<div id="arcSplit" class="measure-split"><button id="btn-arc" class="tool-btn" aria-label="Arc" data-tooltip="Arc"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 17a7 7 0 0 1 14 0"/><circle cx="5" cy="17" r="1.5"/><circle cx="19" cy="17" r="1.5"/></svg><span class="sr-only">Arc</span></button><button id="arcModeToggle" class="measure-menu-toggle" type="button" aria-label="Arc mode" aria-haspopup="true" aria-expanded="false" title="Arc mode"><svg viewBox="0 0 12 12" aria-hidden="true"><path d="M4.5 3 7.5 6 4.5 9"/></svg></button></div>
<button id="btn-count" class="tool-btn" aria-label="Count" data-tooltip="Count"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="7.5"/><circle cx="12" cy="12" r="2.4" fill="currentColor" stroke="none"/></svg><span class="sr-only">Count</span></button>
<button id="btn-erase" class="tool-btn" aria-label="Erase" data-tooltip="Erase">
<svg viewBox="0 0 24 24" aria-hidden="true">
<g transform="rotate(-90 12 12)">
<g transform="rotate(-45 12 12)">
<rect x="7" y="4" width="10" height="16" rx="2" />
<line x1="7" y1="10" x2="17" y2="10" />
</g>
</g>
</svg>
<span class="sr-only">Erase</span>
</button>
</div>
<div class="toolbar-spacer"></div>
<div class="toolbar utility">
<div class="viewer-controls" aria-label="View controls">
<div class="control-cluster zoom-group">
<button id="zoomOut" class="control-btn" aria-label="Zoom out">−</button>
<span class="pill control-value" id="zoomLabel"><strong>100%</strong></span>
<button id="zoomIn" class="control-btn" aria-label="Zoom in">+</button>
</div>
<div class="control-divider"></div>
<div class="control-cluster page-group-control">
<button id="prevPage" class="control-btn" disabled aria-label="Previous page">
<svg viewBox="0 0 12 12" aria-hidden="true"><path d="M2.5 7.5 6 4l3.5 3.5"/></svg>
</button>
<span class="pill control-value" id="pageLabel" aria-label="No page loaded"><span class="page-current">—</span><span class="page-sep">·</span><span>—</span></span>
<button id="nextPage" class="control-btn" disabled aria-label="Next page">
<svg viewBox="0 0 12 12" aria-hidden="true"><path d="M2.5 4.5 6 8l3.5-3.5"/></svg>
</button>
</div>
<div class="control-divider"></div>
<button id="continuousScrollToggle" class="control-btn continuous-scroll-toggle" type="button" aria-label="Continuous scroll needs a multi-page PDF." aria-pressed="false" title="Continuous scroll needs a multi-page PDF." data-tooltip="Continuous scroll needs a multi-page PDF." hidden>
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="7" y="3" width="10" height="5" rx="1"/><rect x="7" y="9.5" width="10" height="5" rx="1"/><rect x="7" y="16" width="10" height="5" rx="1"/></svg>
</button>
<div class="control-divider continuous-scroll-divider" hidden></div>
<div id="fitSplit" class="fit-split">
<button id="zoomFit" class="fit-control" type="button" title="Fit page" aria-label="Fit page">
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="6" y="3" width="12" height="18" rx="1.5"/><path d="M9 7h6M9 11h6M9 15h4"/></svg>
</button>
<button id="fitMenuToggle" class="fit-menu-toggle" type="button" title="Fit options" aria-label="Fit options" aria-haspopup="true" aria-expanded="false">
<svg viewBox="0 0 12 12" aria-hidden="true"><path d="M4.5 3 7.5 6 4.5 9"/></svg>
</button>
</div>
</div>
<button id="resetScale" disabled title="Reset calibration for the current page only">Reset</button>
</div>
</nav>
<div id="toolTip" class="tool-tip" role="tooltip"></div>
<div id="measureModeMenu" class="measure-mode-menu" role="menu" aria-label="Measure mode">
<button class="measure-mode-option active" type="button" role="menuitemradio" aria-checked="true" data-value="line">Line</button>
<button class="measure-mode-option" type="button" role="menuitemradio" aria-checked="false" data-value="freehand">Freehand</button>
<button class="measure-mode-option" type="button" role="menuitemradio" aria-checked="false" data-value="area">Area</button>
</div>
<div id="circleModeMenu" class="measure-mode-menu" role="menu" aria-label="Circle mode"><button class="measure-mode-option active" type="button" role="menuitemradio" aria-checked="true" data-value="circle-radius">Radius</button><button class="measure-mode-option" type="button" role="menuitemradio" aria-checked="false" data-value="circle-diameter">Diameter</button><button class="measure-mode-option" type="button" role="menuitemradio" aria-checked="false" data-value="circle-2p">2 point</button><button class="measure-mode-option" type="button" role="menuitemradio" aria-checked="false" data-value="circle-3p">3 point</button></div>
<div id="arcModeMenu" class="measure-mode-menu" role="menu" aria-label="Arc mode"><button class="measure-mode-option active" type="button" role="menuitemradio" aria-checked="true" data-value="arc-3p">3 point</button><button class="measure-mode-option" type="button" role="menuitemradio" aria-checked="false" data-value="arc-center">Center, start, end</button></div>
<div id="fitMenu" class="fit-menu" role="menu" aria-label="Fit options">
<button class="fit-menu-option" type="button" data-fit="page" role="menuitem">Fit page</button>
<button class="fit-menu-option" type="button" data-fit="width" role="menuitem">Fit width</button>
<button class="fit-menu-option" type="button" data-fit="height" role="menuitem">Fit height</button>
</div>
<main>
<div id="stage">
<div id="viewport">
<div id="continuousBasePages" hidden></div>
<canvas id="baseCanvas"></canvas>
<canvas id="pdfDetailCanvas"></canvas>
<canvas id="drawCanvas"></canvas>
<svg id="drawSvg" aria-hidden="true"></svg>
</div>
<div class="empty" id="empty">
<div class="home-shell">
<nav class="home-sidebar" aria-label="Home navigation"><p>Workspace</p><button id="homeIndexTab" class="home-nav-item active" type="button" role="tab" aria-selected="true" aria-controls="homeIndexPanel" data-home-tab="index"><span>Index</span><span>00</span></button><button id="homeTemplatesTab" class="home-nav-item" type="button" role="tab" aria-selected="false" aria-controls="homeTemplatesPanel" data-home-tab="templates"><span>Templates</span><span id="homeTemplateCount">01</span></button></nav>
<div class="home-main">
<section id="homeIndexPanel" class="home-panel active" role="tabpanel" aria-labelledby="homeIndexTab" data-home-panel="index" tabindex="0"><section class="home-hero" aria-label="Takeoff start"><div class="home-copy"><p class="home-eyebrow">Takeoff</p><h2>Drop in a floor plan to begin.</h2><p class="home-deck">Upload a PDF or image, calibrate the scale against a known dimension, then trace your takeoff measurements.</p></div><section class="home-upload-panel" aria-label="Open a floor plan"><button id="emptyUploadButton" class="empty-upload" type="button"><span class="home-upload-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 3v12m0 0l-4-4m4 4l4-4M5 21h14"/></svg></span><span class="home-upload-copy"><strong>Upload Image/PDF</strong><span>or drop a file anywhere on the canvas</span></span><span class="home-file-types" aria-hidden="true"><span>PDF</span><span>Image</span><span>Multi-page</span></span></button></section></section><section class="home-lower" aria-label="Takeoff setup"><div class="home-steps" aria-label="Takeoff workflow"><div class="home-step"><span>01</span><div><h2>Upload Image/PDF</h2><p>Pick a floor plan file or drop one onto the canvas.</p></div></div><div class="home-step"><span>02</span><div><h2>Calibrate</h2><p>Draw a line on a known dimension and enter its real length.</p></div></div><div class="home-step"><span>03</span><div><h2>Measure</h2><p>Click point-to-point to trace a path. Double-click to finish.</p></div></div></div></section></section>
<section id="homeTemplatesPanel" class="home-panel" role="tabpanel" aria-labelledby="homeTemplatesTab" data-home-panel="templates" tabindex="0" hidden><section id="pathTemplatesHome" class="path-template-home" aria-label="Path templates"></section></section>
</div>
</div>
</div>
<div id="pathDockRoot" class="path-dock-root" hidden></div>
<div class="status" id="status"></div>
<div id="draftPrompt" class="draft-prompt" aria-live="polite" hidden><div class="draft-prompt-title"></div><div class="draft-prompt-step"></div><div class="draft-prompt-metric"></div></div>
<div class="hud">
<span class="pill cursor-hud">
<span id="cursorPos">
<span class="hud-part">scale: <strong>—</strong></span>
<span class="hud-part">x: <strong>—</strong></span>
<span class="hud-part">y: <strong>—</strong></span>
</span>
<button id="polarLock" class="snap-toggle" type="button" aria-label="45° lock" aria-pressed="true" data-tooltip="45° lock" data-tooltip-placement="above"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 20V8M4 20h12"/><path d="M4 20 16 8"/></svg></button>
<button id="snapToPaths" class="snap-toggle" type="button" aria-label="Snap to Paths" aria-pressed="false" data-tooltip="Snap to Paths" data-tooltip-placement="above">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path fill="currentColor" d="M1 12h1v1H1zm4 0H4v1h1zm17 0v1h1v-1zm-3 1h1v-1h-1zm-3-1H8v-1H7v3h1v-1h8v1h1v-3h-1zm1-5.05V10h-1V6.95a2.5 2.5 0 1 1 1 0zm1-2.45A1.5 1.5 0 1 0 16.5 6 1.502 1.502 0 0 0 18 4.5zm-8 16a2.5 2.5 0 1 1-3-2.45V15h1v3.05a2.5 2.5 0 0 1 2 2.45zm-1 0A1.5 1.5 0 1 0 7.5 22 1.502 1.502 0 0 0 9 20.5z"/>
</svg>
</button>
</span>
</div>
</div>
</main>
<aside>
<div class="side-h">
<div class="side-h-top">
<h3 id="totalHeading">This Page Total</h3>
<div class="export-wrap" id="exportWrap">
<button id="exportButton" class="export-trigger" type="button" title="Export" aria-label="Export" aria-haspopup="menu" aria-expanded="false" disabled>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3v12"/><path d="m7 10 5 5 5-5"/><path d="M5 21h14"/></svg>
</button>
<div id="exportMenu" class="export-menu" role="menu" aria-label="Export">
<button id="exportXlsx" type="button" role="menuitem" disabled>Excel</button>
<button id="copySummary" type="button" role="menuitem" disabled>Copy summary</button>
<button id="exportCsv" type="button" role="menuitem" disabled>CSV</button>
</div>
</div>
</div>
<div class="total"><span id="totalLen">0.00</span><span class="unit" id="totalUnit">ft</span></div>
<div id="entireTotal" class="entire-total" hidden>Total: 0.00 ft</div>
<div class="sub"><span id="runCount">0 runs</span><span id="averageMetric" class="average-metric"></span></div>
</div>
<div id="scopeTabs" class="tabs">
<button class="tab active" data-tab="page">This page</button>
<button class="tab" data-tab="categories">Categories</button>
<button class="tab" data-tab="all">All pages</button>
<button class="tab" data-tab="report">Report</button>
</div>
<div class="meas-list" id="measList"></div>
<div class="footer">
<div class="select-wrap">
<button id="unitSelectButton" class="unit-select-button" type="button" aria-haspopup="listbox" aria-expanded="false">feet (ft)</button>
<div id="unitMenu" class="unit-menu" role="listbox" aria-label="Measurement unit">
<button class="unit-option active" type="button" role="option" data-value="ft" aria-selected="true">feet (ft)</button>
<button class="unit-option" type="button" role="option" data-value="yd" aria-selected="false">yards (yd)</button>
<button class="unit-option" type="button" role="option" data-value="in" aria-selected="false">inches (in)</button>
<button class="unit-option" type="button" role="option" data-value="m" aria-selected="false">meters (m)</button>
<button class="unit-option" type="button" role="option" data-value="cm" aria-selected="false">centimeters (cm)</button>
</div>
<select id="unitSelect" class="unit-select-native" aria-label="Measurement unit">
<option value="ft">feet (ft)</option>
<option value="yd">yards (yd)</option>
<option value="in">inches (in)</option>
<option value="m">meters (m)</option>
<option value="cm">centimeters (cm)</option>
</select>
</div>
<button id="clearAll" class="danger">Clear All</button>
</div>
</aside>
<div id="contextMenu" class="context-menu" role="menu">
<button type="button" data-action="add-anchor">Add anchor</button>
<button type="button" data-action="remove-anchor">Remove anchor</button>
<button type="button" data-action="continue-path" hidden>Continue Path</button>
<button type="button" data-action="cut">Cut</button>
<button type="button" data-action="copy">Copy</button>
<button type="button" data-action="paste">Paste</button>
<button type="button" data-action="rotate">Rotate</button>
<button type="button" data-action="toggle-lock" hidden>Lock</button><button type="button" data-action="toggle-area" hidden>Area</button>
<button type="button" data-action="toggle-path-visibility" hidden>Hide path</button>
<button type="button" data-action="toggle-category-visibility" hidden>Hide category</button>
<button type="button" data-action="convert-to-line" hidden>Convert to Line</button>
<button type="button" data-action="convert-to-freehand" hidden>Convert to Freehand</button>
<button type="button" data-action="merge-paths" hidden>Merge Paths</button>
<button type="button" data-action="unmerge-paths" hidden>Unmerge Paths</button>
</div>
<div id="rotationPill" class="rotation-pill">
<input id="rotationInput" type="text" inputmode="numeric" aria-label="Rotation degrees" />
<span>°</span>
</div>
<div class="modal-bg" id="calibModal">
<div class="modal">
<h3>Set scale</h3>
<p>How long is the line you just drew, in real-world units?</p>
<div class="field">
<input type="text" id="calibValue" inputmode="decimal" autocomplete="off" placeholder="e.g. 10" autofocus />
<select id="calibUnit">
<option value="ft">ft</option>
<option value="yd">yd</option>
<option value="in">in</option>
<option value="m">m</option>
<option value="cm">cm</option>
</select>
</div>
<div class="field calibration-source-field" id="calibSourceField" hidden>
<input type="hidden" id="calibSource" value="new" />
<div class="calib-source-control" id="calibSourceCombo">
<button id="calibSourceDisplay" class="calib-source-display" type="button" aria-label="Match calibration from" aria-haspopup="menu" aria-expanded="false" aria-controls="calibSourceOptions">
<span class="calib-source-main">
<span id="calibSourceTitle" class="calib-source-title">New calibration</span>
<span id="calibSourceScale" class="calib-source-badge" hidden></span>
<span id="calibSourceCount" class="calib-source-badge" hidden></span>
</span>
</button>
<div class="calib-source-options" id="calibSourceOptions" role="menu"></div>
<div class="calib-source-helper" id="calibSourceHelper" hidden></div>
</div>
</div>
<div class="field calibration-apply-field">
<label for="calibRange">Apply</label>
<div class="calib-scope-combo" id="calibScopeCombo" data-scope="this">
<input type="hidden" id="calibScope" value="this" />
<button class="calib-scope-display" id="calibScopeDisplay" type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="calibScopeOptions">Apply to the current page</button>
<input type="text" id="calibRange" class="calib-scope-range" inputmode="numeric" autocomplete="off" placeholder="e.g. 1, 3, 5-7" aria-label="Selected pages" />
<button class="calib-scope-menu" id="calibScopeMenu" type="button" aria-label="Change apply option" aria-haspopup="menu" aria-expanded="false" aria-controls="calibScopeOptions"></button>
<div class="calib-scope-options" id="calibScopeOptions" role="menu">
<button class="calib-scope-option active" type="button" role="menuitemradio" aria-checked="true" data-scope="this">Apply to the current page</button>
<button class="calib-scope-option" type="button" role="menuitemradio" aria-checked="false" data-scope="all">Apply to all pages</button>
<button class="calib-scope-option" type="button" role="menuitemradio" aria-checked="false" data-scope="custom">Apply to a selected group of pages</button>
</div>
</div>
</div>
<p id="calibVerdict" class="calib-verdict" hidden></p>
<div class="actions">
<button id="calibCancel">Cancel</button>
<button id="calibCheck" type="button" title="Check the current scale without changing it" aria-label="Check current scale">Check</button>
<button id="calibOk" class="primary">Set Scale</button>
</div>
</div>
</div>
<div class="modal-bg" id="pasteChoiceModal">
<div class="modal">
<h3>Paste run</h3>
<p>This run came from a page with a different calibration. Choose how it should land on this page.</p>
<div class="actions" style="display:grid; gap:8px; grid-template-columns:1fr; justify-content:stretch">
<button id="pasteVisualSize" class="primary">Keep visual size</button>
<button id="pasteRealLength">Keep measured length</button>
<button id="pasteCancel">Cancel</button>
</div>
</div>
</div>
<div class="modal-bg" id="unmergePathModal"><div class="modal unmerge-path-modal" role="dialog" aria-labelledby="unmergePathTitle" aria-modal="true"><h3 id="unmergePathTitle">Unmerge Paths</h3><p>Choose how to split this Path.</p><div class="unmerge-actions"><button id="unmergeOriginal" class="primary" type="button">Unmerge to original</button><button id="unmergeMaintain" type="button">Unmerge and maintain edits</button><p id="unmergeMaintainReason" class="modal-help" hidden></p><button id="unmergeCancel" type="button">Cancel</button></div></div></div>
<div class="modal-bg" id="pathSettingsModal">
<div class="modal path-settings-modal" role="dialog" aria-labelledby="pathSettingsTitle" aria-modal="true">
<h3 id="pathSettingsTitle">Path Settings</h3>
<p id="pathSettingsSummary">Update this Path.</p>
<div id="pathSettingsPreview" class="path-settings-preview" aria-hidden="true"></div>
<label class="path-settings-field path-settings-field-full"><span>Path name</span><input id="pathSettingsName" type="text" autocomplete="off" /></label>
<div class="path-settings-grid">
<label class="path-settings-field"><span>Category</span><select id="pathSettingsCategory"></select></label>
<label id="pathSettingsNewCategoryField" class="path-settings-field" hidden><span>New category</span><input id="pathSettingsNewCategory" type="text" autocomplete="off" /></label>
<label class="path-settings-field path-settings-field-full">
<span>Apply</span>
<select id="pathSettingsScope"><option value="run">Current run</option><option value="page">Current page</option><option value="document">Same Path across document</option><option value="template">Future template default</option></select>
</label>
</div>
<div class="path-settings-sections">
<section class="path-settings-section" aria-label="Line styling">
<h4>Line</h4>
<div class="path-settings-grid">
<label class="path-settings-field"><span>Line fill</span><input id="pathSettingsLineColor" type="color" /></label>
<label class="path-settings-field"><span>Line border</span><input id="pathSettingsLineBorder" type="color" /></label>
<label class="path-settings-check path-settings-field-full"><input id="pathSettingsLineBorderMatches" type="checkbox" /><span>Match line border to fill</span></label>
<label class="path-settings-field">
<span>Line style</span>
<select id="pathSettingsLineStyle"><option value="solid">Solid</option><option value="dashed">Dashed</option><option value="dotted">Dotted</option></select>
</label>
</div>
</section>
<section class="path-settings-section" aria-label="Takeoff quantities">
<h4>Takeoff</h4>
<div class="path-settings-grid">
<label class="path-settings-field"><span>Kind</span><select id="pathSettingsRole"><option value="linear">Length</option><option value="area">Area</option><option value="count">Count</option></select></label>
<label class="path-settings-field"><span>Waste %</span><input id="pathSettingsWaste" type="text" inputmode="decimal" autocomplete="off" /></label>
<label class="path-settings-field"><span>Multiplier</span><input id="pathSettingsMultiplier" type="text" inputmode="decimal" autocomplete="off" /></label>
</div>
</section>
<section class="path-settings-section" aria-label="Anchor styling">
<h4>Anchor</h4>
<div class="path-settings-grid">
<label class="path-settings-field"><span>Anchor fill</span><input id="pathSettingsAnchorFill" type="color" /></label>
<label class="path-settings-field"><span>Anchor border</span><input id="pathSettingsAnchorBorder" type="color" /></label>
<label class="path-settings-check path-settings-field-full"><input id="pathSettingsAnchorBorderMatches" type="checkbox" /><span>Match anchor border to Line color</span></label>
</div>
</section>
</div>
<div class="actions"><button id="pathSettingsCancel" type="button">Cancel</button><button id="pathSettingsApply" class="primary" type="button">Apply</button></div>
</div>
</div>
<script type="module" src="./src/main.js?v=kal-96-lock-2"></script>
</body>
</html>