@design.estate/dees-document 2.2.0 → 2.2.2

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 (52) hide show
  1. package/dist_ts_web/00_commitinfo_data.js +1 -1
  2. package/dist_ts_web/elements/contentinvoice.d.ts +6 -0
  3. package/dist_ts_web/elements/contentinvoice.js +39 -3
  4. package/dist_ts_web/elements/document.d.ts +21 -0
  5. package/dist_ts_web/elements/document.js +73 -4
  6. package/dist_ts_web/elements/page.d.ts +1 -0
  7. package/dist_ts_web/elements/page.js +19 -4
  8. package/dist_ts_web/elements/viewer.d.ts +117 -4
  9. package/dist_ts_web/elements/viewer.js +1347 -17
  10. package/package.json +1 -1
  11. package/dist_ts_web/ts_shared/translation.d.ts +0 -82
  12. package/dist_ts_web/ts_shared/translation.js +0 -134
  13. package/dist_ts_web/ts_web/00_commitinfo_data.d.ts +0 -8
  14. package/dist_ts_web/ts_web/00_commitinfo_data.js +0 -9
  15. package/dist_ts_web/ts_web/elements/contentinvoice.d.ts +0 -47
  16. package/dist_ts_web/ts_web/elements/contentinvoice.js +0 -502
  17. package/dist_ts_web/ts_web/elements/document.d.ts +0 -48
  18. package/dist_ts_web/ts_web/elements/document.demo.d.ts +0 -1
  19. package/dist_ts_web/ts_web/elements/document.demo.js +0 -9
  20. package/dist_ts_web/ts_web/elements/document.js +0 -375
  21. package/dist_ts_web/ts_web/elements/index.d.ts +0 -10
  22. package/dist_ts_web/ts_web/elements/index.js +0 -11
  23. package/dist_ts_web/ts_web/elements/letterheader.d.ts +0 -18
  24. package/dist_ts_web/ts_web/elements/letterheader.js +0 -224
  25. package/dist_ts_web/ts_web/elements/page.d.ts +0 -26
  26. package/dist_ts_web/ts_web/elements/page.js +0 -350
  27. package/dist_ts_web/ts_web/elements/pagecontainer.d.ts +0 -14
  28. package/dist_ts_web/ts_web/elements/pagecontainer.js +0 -114
  29. package/dist_ts_web/ts_web/elements/pagecontent.d.ts +0 -19
  30. package/dist_ts_web/ts_web/elements/pagecontent.js +0 -177
  31. package/dist_ts_web/ts_web/elements/pagefooter.d.ts +0 -17
  32. package/dist_ts_web/ts_web/elements/pagefooter.js +0 -234
  33. package/dist_ts_web/ts_web/elements/pageheader.d.ts +0 -17
  34. package/dist_ts_web/ts_web/elements/pageheader.js +0 -165
  35. package/dist_ts_web/ts_web/elements/paymentcode.d.ts +0 -19
  36. package/dist_ts_web/ts_web/elements/paymentcode.js +0 -162
  37. package/dist_ts_web/ts_web/elements/viewer.d.ts +0 -128
  38. package/dist_ts_web/ts_web/elements/viewer.demo.d.ts +0 -1
  39. package/dist_ts_web/ts_web/elements/viewer.demo.js +0 -9
  40. package/dist_ts_web/ts_web/elements/viewer.js +0 -1480
  41. package/dist_ts_web/ts_web/index.d.ts +0 -1
  42. package/dist_ts_web/ts_web/index.js +0 -2
  43. package/dist_ts_web/ts_web/pages/index.d.ts +0 -2
  44. package/dist_ts_web/ts_web/pages/index.js +0 -3
  45. package/dist_ts_web/ts_web/pages/page1.d.ts +0 -1
  46. package/dist_ts_web/ts_web/pages/page1.js +0 -21
  47. package/dist_ts_web/ts_web/pages/page2.d.ts +0 -1
  48. package/dist_ts_web/ts_web/pages/page2.js +0 -18
  49. package/dist_ts_web/ts_web/plugins.d.ts +0 -9
  50. package/dist_ts_web/ts_web/plugins.js +0 -14
  51. package/dist_ts_web/ts_web/style.d.ts +0 -1
  52. package/dist_ts_web/ts_web/style.js +0 -38
@@ -33,8 +33,28 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
33
33
  return useValue ? value : void 0;
34
34
  };
35
35
  import * as plugins from "../plugins.js";
36
- import { DeesElement, css, cssManager, customElement, html, property, } from "@design.estate/dees-element";
36
+ import { DeesElement, css, cssManager, customElement, html, property, state, } from "@design.estate/dees-element";
37
37
  import { demoFunc } from "./viewer.demo.js";
38
+ import { DeDocument } from "./document.js";
39
+ import "./page.js"; // Import DePage for thumbnail rendering
40
+ import "./contentinvoice.js"; // Import DeContentInvoice for thumbnail content
41
+ import "@design.estate/dees-catalog";
42
+ const ZOOM_PRESETS = [
43
+ { label: "Auto Fit", value: "auto" },
44
+ { label: "Fit Width", value: "fit-width" },
45
+ { label: "Fit Page", value: "fit-page" },
46
+ { label: "50%", value: 50 },
47
+ { label: "75%", value: 75 },
48
+ { label: "100%", value: 100 },
49
+ { label: "125%", value: 125 },
50
+ { label: "150%", value: 150 },
51
+ { label: "200%", value: 200 },
52
+ ];
53
+ const SPACING_PRESETS = [
54
+ { label: "Compact", value: 8, icon: "lucide:minimize2" },
55
+ { label: "Normal", value: 16, icon: "lucide:minus" },
56
+ { label: "Comfortable", value: 32, icon: "lucide:maximize2" },
57
+ ];
38
58
  let DeDocumentViewer = (() => {
39
59
  let _classDecorators = [customElement("dedocument-viewer")];
40
60
  let _classDescriptor;
@@ -47,6 +67,45 @@ let DeDocumentViewer = (() => {
47
67
  let _documentSettings_decorators;
48
68
  let _documentSettings_initializers = [];
49
69
  let _documentSettings_extraInitializers = [];
70
+ let _initialZoom_decorators;
71
+ let _initialZoom_initializers = [];
72
+ let _initialZoom_extraInitializers = [];
73
+ let _initialPageGap_decorators;
74
+ let _initialPageGap_initializers = [];
75
+ let _initialPageGap_extraInitializers = [];
76
+ let _zoomMode_decorators;
77
+ let _zoomMode_initializers = [];
78
+ let _zoomMode_extraInitializers = [];
79
+ let _zoomLevel_decorators;
80
+ let _zoomLevel_initializers = [];
81
+ let _zoomLevel_extraInitializers = [];
82
+ let _pageGap_decorators;
83
+ let _pageGap_initializers = [];
84
+ let _pageGap_extraInitializers = [];
85
+ let _showZoomDropdown_decorators;
86
+ let _showZoomDropdown_initializers = [];
87
+ let _showZoomDropdown_extraInitializers = [];
88
+ let _displayZoom_decorators;
89
+ let _displayZoom_initializers = [];
90
+ let _displayZoom_extraInitializers = [];
91
+ let _currentPageDisplay_decorators;
92
+ let _currentPageDisplay_initializers = [];
93
+ let _currentPageDisplay_extraInitializers = [];
94
+ let _showThumbnails_decorators;
95
+ let _showThumbnails_initializers = [];
96
+ let _showThumbnails_extraInitializers = [];
97
+ let _sidebarWidth_decorators;
98
+ let _sidebarWidth_initializers = [];
99
+ let _sidebarWidth_extraInitializers = [];
100
+ let _isResizingSidebar_decorators;
101
+ let _isResizingSidebar_initializers = [];
102
+ let _isResizingSidebar_extraInitializers = [];
103
+ let _thumbnailPages_decorators;
104
+ let _thumbnailPages_initializers = [];
105
+ let _thumbnailPages_extraInitializers = [];
106
+ let _paginationInfo_decorators;
107
+ let _paginationInfo_initializers = [];
108
+ let _paginationInfo_extraInitializers = [];
50
109
  var DeDocumentViewer = class extends _classSuper {
51
110
  static { _classThis = this; }
52
111
  static {
@@ -59,8 +118,34 @@ let DeDocumentViewer = (() => {
59
118
  type: Object,
60
119
  reflect: true,
61
120
  })];
121
+ _initialZoom_decorators = [property({ type: Number })];
122
+ _initialPageGap_decorators = [property({ type: Number })];
123
+ _zoomMode_decorators = [state()];
124
+ _zoomLevel_decorators = [state()];
125
+ _pageGap_decorators = [state()];
126
+ _showZoomDropdown_decorators = [state()];
127
+ _displayZoom_decorators = [state()];
128
+ _currentPageDisplay_decorators = [state()];
129
+ _showThumbnails_decorators = [state()];
130
+ _sidebarWidth_decorators = [state()];
131
+ _isResizingSidebar_decorators = [state()];
132
+ _thumbnailPages_decorators = [state()];
133
+ _paginationInfo_decorators = [state()];
62
134
  __esDecorate(this, null, _letterData_decorators, { kind: "accessor", name: "letterData", static: false, private: false, access: { has: obj => "letterData" in obj, get: obj => obj.letterData, set: (obj, value) => { obj.letterData = value; } }, metadata: _metadata }, _letterData_initializers, _letterData_extraInitializers);
63
135
  __esDecorate(this, null, _documentSettings_decorators, { kind: "accessor", name: "documentSettings", static: false, private: false, access: { has: obj => "documentSettings" in obj, get: obj => obj.documentSettings, set: (obj, value) => { obj.documentSettings = value; } }, metadata: _metadata }, _documentSettings_initializers, _documentSettings_extraInitializers);
136
+ __esDecorate(this, null, _initialZoom_decorators, { kind: "accessor", name: "initialZoom", static: false, private: false, access: { has: obj => "initialZoom" in obj, get: obj => obj.initialZoom, set: (obj, value) => { obj.initialZoom = value; } }, metadata: _metadata }, _initialZoom_initializers, _initialZoom_extraInitializers);
137
+ __esDecorate(this, null, _initialPageGap_decorators, { kind: "accessor", name: "initialPageGap", static: false, private: false, access: { has: obj => "initialPageGap" in obj, get: obj => obj.initialPageGap, set: (obj, value) => { obj.initialPageGap = value; } }, metadata: _metadata }, _initialPageGap_initializers, _initialPageGap_extraInitializers);
138
+ __esDecorate(this, null, _zoomMode_decorators, { kind: "accessor", name: "zoomMode", static: false, private: false, access: { has: obj => "zoomMode" in obj, get: obj => obj.zoomMode, set: (obj, value) => { obj.zoomMode = value; } }, metadata: _metadata }, _zoomMode_initializers, _zoomMode_extraInitializers);
139
+ __esDecorate(this, null, _zoomLevel_decorators, { kind: "accessor", name: "zoomLevel", static: false, private: false, access: { has: obj => "zoomLevel" in obj, get: obj => obj.zoomLevel, set: (obj, value) => { obj.zoomLevel = value; } }, metadata: _metadata }, _zoomLevel_initializers, _zoomLevel_extraInitializers);
140
+ __esDecorate(this, null, _pageGap_decorators, { kind: "accessor", name: "pageGap", static: false, private: false, access: { has: obj => "pageGap" in obj, get: obj => obj.pageGap, set: (obj, value) => { obj.pageGap = value; } }, metadata: _metadata }, _pageGap_initializers, _pageGap_extraInitializers);
141
+ __esDecorate(this, null, _showZoomDropdown_decorators, { kind: "accessor", name: "showZoomDropdown", static: false, private: false, access: { has: obj => "showZoomDropdown" in obj, get: obj => obj.showZoomDropdown, set: (obj, value) => { obj.showZoomDropdown = value; } }, metadata: _metadata }, _showZoomDropdown_initializers, _showZoomDropdown_extraInitializers);
142
+ __esDecorate(this, null, _displayZoom_decorators, { kind: "accessor", name: "displayZoom", static: false, private: false, access: { has: obj => "displayZoom" in obj, get: obj => obj.displayZoom, set: (obj, value) => { obj.displayZoom = value; } }, metadata: _metadata }, _displayZoom_initializers, _displayZoom_extraInitializers);
143
+ __esDecorate(this, null, _currentPageDisplay_decorators, { kind: "accessor", name: "currentPageDisplay", static: false, private: false, access: { has: obj => "currentPageDisplay" in obj, get: obj => obj.currentPageDisplay, set: (obj, value) => { obj.currentPageDisplay = value; } }, metadata: _metadata }, _currentPageDisplay_initializers, _currentPageDisplay_extraInitializers);
144
+ __esDecorate(this, null, _showThumbnails_decorators, { kind: "accessor", name: "showThumbnails", static: false, private: false, access: { has: obj => "showThumbnails" in obj, get: obj => obj.showThumbnails, set: (obj, value) => { obj.showThumbnails = value; } }, metadata: _metadata }, _showThumbnails_initializers, _showThumbnails_extraInitializers);
145
+ __esDecorate(this, null, _sidebarWidth_decorators, { kind: "accessor", name: "sidebarWidth", static: false, private: false, access: { has: obj => "sidebarWidth" in obj, get: obj => obj.sidebarWidth, set: (obj, value) => { obj.sidebarWidth = value; } }, metadata: _metadata }, _sidebarWidth_initializers, _sidebarWidth_extraInitializers);
146
+ __esDecorate(this, null, _isResizingSidebar_decorators, { kind: "accessor", name: "isResizingSidebar", static: false, private: false, access: { has: obj => "isResizingSidebar" in obj, get: obj => obj.isResizingSidebar, set: (obj, value) => { obj.isResizingSidebar = value; } }, metadata: _metadata }, _isResizingSidebar_initializers, _isResizingSidebar_extraInitializers);
147
+ __esDecorate(this, null, _thumbnailPages_decorators, { kind: "accessor", name: "thumbnailPages", static: false, private: false, access: { has: obj => "thumbnailPages" in obj, get: obj => obj.thumbnailPages, set: (obj, value) => { obj.thumbnailPages = value; } }, metadata: _metadata }, _thumbnailPages_initializers, _thumbnailPages_extraInitializers);
148
+ __esDecorate(this, null, _paginationInfo_decorators, { kind: "accessor", name: "paginationInfo", static: false, private: false, access: { has: obj => "paginationInfo" in obj, get: obj => obj.paginationInfo, set: (obj, value) => { obj.paginationInfo = value; } }, metadata: _metadata }, _paginationInfo_initializers, _paginationInfo_extraInitializers);
64
149
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
65
150
  DeDocumentViewer = _classThis = _classDescriptor.value;
66
151
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -74,72 +159,1317 @@ let DeDocumentViewer = (() => {
74
159
  #documentSettings_accessor_storage = (__runInitializers(this, _letterData_extraInitializers), __runInitializers(this, _documentSettings_initializers, void 0));
75
160
  get documentSettings() { return this.#documentSettings_accessor_storage; }
76
161
  set documentSettings(value) { this.#documentSettings_accessor_storage = value; }
162
+ #initialZoom_accessor_storage = (__runInitializers(this, _documentSettings_extraInitializers), __runInitializers(this, _initialZoom_initializers, null));
163
+ // External configuration properties
164
+ get initialZoom() { return this.#initialZoom_accessor_storage; } // Initial zoom % (null = auto)
165
+ set initialZoom(value) { this.#initialZoom_accessor_storage = value; }
166
+ #initialPageGap_accessor_storage = (__runInitializers(this, _initialZoom_extraInitializers), __runInitializers(this, _initialPageGap_initializers, 16));
167
+ get initialPageGap() { return this.#initialPageGap_accessor_storage; } // Initial page gap in pixels
168
+ set initialPageGap(value) { this.#initialPageGap_accessor_storage = value; }
169
+ #zoomMode_accessor_storage = (__runInitializers(this, _initialPageGap_extraInitializers), __runInitializers(this, _zoomMode_initializers, "auto"));
170
+ // Internal state
171
+ get zoomMode() { return this.#zoomMode_accessor_storage; }
172
+ set zoomMode(value) { this.#zoomMode_accessor_storage = value; }
173
+ #zoomLevel_accessor_storage = (__runInitializers(this, _zoomMode_extraInitializers), __runInitializers(this, _zoomLevel_initializers, null));
174
+ get zoomLevel() { return this.#zoomLevel_accessor_storage; } // null = auto, otherwise percentage
175
+ set zoomLevel(value) { this.#zoomLevel_accessor_storage = value; }
176
+ #pageGap_accessor_storage = (__runInitializers(this, _zoomLevel_extraInitializers), __runInitializers(this, _pageGap_initializers, 16));
177
+ get pageGap() { return this.#pageGap_accessor_storage; }
178
+ set pageGap(value) { this.#pageGap_accessor_storage = value; }
179
+ #showZoomDropdown_accessor_storage = (__runInitializers(this, _pageGap_extraInitializers), __runInitializers(this, _showZoomDropdown_initializers, false));
180
+ get showZoomDropdown() { return this.#showZoomDropdown_accessor_storage; }
181
+ set showZoomDropdown(value) { this.#showZoomDropdown_accessor_storage = value; }
182
+ #displayZoom_accessor_storage = (__runInitializers(this, _showZoomDropdown_extraInitializers), __runInitializers(this, _displayZoom_initializers, 100));
183
+ get displayZoom() { return this.#displayZoom_accessor_storage; }
184
+ set displayZoom(value) { this.#displayZoom_accessor_storage = value; }
185
+ #currentPageDisplay_accessor_storage = (__runInitializers(this, _displayZoom_extraInitializers), __runInitializers(this, _currentPageDisplay_initializers, "1 / 1"));
186
+ get currentPageDisplay() { return this.#currentPageDisplay_accessor_storage; }
187
+ set currentPageDisplay(value) { this.#currentPageDisplay_accessor_storage = value; }
188
+ #showThumbnails_accessor_storage = (__runInitializers(this, _currentPageDisplay_extraInitializers), __runInitializers(this, _showThumbnails_initializers, true));
189
+ // Sidebar state
190
+ get showThumbnails() { return this.#showThumbnails_accessor_storage; }
191
+ set showThumbnails(value) { this.#showThumbnails_accessor_storage = value; }
192
+ #sidebarWidth_accessor_storage = (__runInitializers(this, _showThumbnails_extraInitializers), __runInitializers(this, _sidebarWidth_initializers, 140));
193
+ get sidebarWidth() { return this.#sidebarWidth_accessor_storage; }
194
+ set sidebarWidth(value) { this.#sidebarWidth_accessor_storage = value; }
195
+ #isResizingSidebar_accessor_storage = (__runInitializers(this, _sidebarWidth_extraInitializers), __runInitializers(this, _isResizingSidebar_initializers, false));
196
+ get isResizingSidebar() { return this.#isResizingSidebar_accessor_storage; }
197
+ set isResizingSidebar(value) { this.#isResizingSidebar_accessor_storage = value; }
198
+ #thumbnailPages_accessor_storage = (__runInitializers(this, _isResizingSidebar_extraInitializers), __runInitializers(this, _thumbnailPages_initializers, []));
199
+ get thumbnailPages() { return this.#thumbnailPages_accessor_storage; }
200
+ set thumbnailPages(value) { this.#thumbnailPages_accessor_storage = value; }
201
+ #paginationInfo_accessor_storage = (__runInitializers(this, _thumbnailPages_extraInitializers), __runInitializers(this, _paginationInfo_initializers, []));
202
+ get paginationInfo() { return this.#paginationInfo_accessor_storage; }
203
+ set paginationInfo(value) { this.#paginationInfo_accessor_storage = value; }
204
+ // Zoom animation
205
+ zoomAnimationId = (__runInitializers(this, _paginationInfo_extraInitializers), null);
77
206
  static styles = [
78
207
  cssManager.defaultStyles,
79
208
  css `
209
+ :host {
210
+ --toolbar-height: 40px;
211
+ --toolbar-bg: ${cssManager.bdTheme("rgba(250, 250, 250, 0.95)", "rgba(24, 24, 24, 0.95)")};
212
+ --toolbar-border: ${cssManager.bdTheme("rgba(0, 0, 0, 0.1)", "rgba(255, 255, 255, 0.1)")};
213
+ --button-hover: ${cssManager.bdTheme("rgba(0, 0, 0, 0.08)", "rgba(255, 255, 255, 0.08)")};
214
+ --button-active: ${cssManager.bdTheme("rgba(0, 0, 0, 0.12)", "rgba(255, 255, 255, 0.15)")};
215
+ --text-primary: ${cssManager.bdTheme("#1a1a1a", "#e5e5e5")};
216
+ --text-secondary: ${cssManager.bdTheme("#666", "#999")};
217
+ --accent-color: ${cssManager.bdTheme("#0066cc", "#4d9fff")};
218
+ --dropdown-bg: ${cssManager.bdTheme("#fff", "#1e1e1e")};
219
+ --dropdown-shadow: ${cssManager.bdTheme("0 4px 16px rgba(0,0,0,0.15)", "0 4px 16px rgba(0,0,0,0.4)")};
220
+ --slider-track: ${cssManager.bdTheme("#ddd", "#444")};
221
+ --slider-fill: ${cssManager.bdTheme("#0066cc", "#4d9fff")};
222
+ --sidebar-min-width: 100px;
223
+ --sidebar-max-width: 300px;
224
+ }
225
+
226
+ /* Sidebar Styles */
227
+ .sidebar {
228
+ position: absolute;
229
+ left: 0;
230
+ top: var(--toolbar-height);
231
+ bottom: 0;
232
+ background: var(--toolbar-bg);
233
+ backdrop-filter: blur(12px);
234
+ -webkit-backdrop-filter: blur(12px);
235
+ border-right: 1px solid var(--toolbar-border);
236
+ display: flex;
237
+ flex-direction: column;
238
+ z-index: 50;
239
+ box-sizing: border-box;
240
+ transition: width 0.2s ease;
241
+ }
242
+
243
+ .sidebar--collapsed {
244
+ width: 0 !important;
245
+ overflow: hidden;
246
+ border-right: none;
247
+ }
248
+
249
+ .sidebar--resizing {
250
+ transition: none !important;
251
+ user-select: none;
252
+ }
253
+
254
+ .sidebar__header {
255
+ padding: 10px 12px;
256
+ font-size: 11px;
257
+ font-weight: 600;
258
+ color: var(--text-secondary);
259
+ border-bottom: 1px solid var(--toolbar-border);
260
+ text-transform: uppercase;
261
+ letter-spacing: 0.5px;
262
+ flex-shrink: 0;
263
+ }
264
+
265
+ .sidebar__thumbnails {
266
+ flex: 1;
267
+ overflow-y: auto;
268
+ overflow-x: hidden;
269
+ padding: 8px;
270
+ display: flex;
271
+ flex-direction: column;
272
+ gap: 12px;
273
+ }
274
+
275
+ .thumbnail {
276
+ display: flex;
277
+ flex-direction: column;
278
+ align-items: center;
279
+ gap: 4px;
280
+ cursor: pointer;
281
+ padding: 4px;
282
+ border-radius: 6px;
283
+ transition: background 0.15s ease;
284
+ flex-shrink: 0;
285
+ }
286
+
287
+ .thumbnail:hover {
288
+ background: var(--button-hover);
289
+ }
290
+
291
+ .thumbnail--active {
292
+ background: var(--button-active);
293
+ }
294
+
295
+ .thumbnail--active .thumbnail__preview {
296
+ outline: 2px solid var(--accent-color);
297
+ outline-offset: 2px;
298
+ }
299
+
300
+ .thumbnail__preview {
301
+ width: 100%;
302
+ aspect-ratio: 210 / 297;
303
+ background: ${cssManager.bdTheme("#fff", "#2a2a2a")};
304
+ box-shadow: ${cssManager.bdTheme("0 1px 4px rgba(0,0,0,0.15)", "0 1px 4px rgba(0,0,0,0.4)")};
305
+ border-radius: 2px;
306
+ overflow: hidden;
307
+ position: relative;
308
+ }
309
+
310
+ .thumbnail__label {
311
+ font-size: 11px;
312
+ color: var(--text-secondary);
313
+ font-weight: 500;
314
+ }
315
+
316
+ .sidebar__resize-handle {
317
+ position: absolute;
318
+ top: 0;
319
+ right: -4px;
320
+ bottom: 0;
321
+ width: 8px;
322
+ cursor: ew-resize;
323
+ background: transparent;
324
+ z-index: 60;
325
+ }
326
+
327
+ .sidebar__resize-handle::after {
328
+ content: '';
329
+ position: absolute;
330
+ top: 0;
331
+ left: 3px;
332
+ bottom: 0;
333
+ width: 2px;
334
+ background: transparent;
335
+ transition: background 0.15s ease;
336
+ }
337
+
338
+ .sidebar__resize-handle:hover::after,
339
+ .sidebar--resizing .sidebar__resize-handle::after {
340
+ background: var(--accent-color);
341
+ }
342
+
80
343
  .maincontainer {
81
344
  position: relative;
82
345
  height: 100%;
83
346
  width: 100%;
84
347
  background: ${cssManager.bdTheme("#eeeeeb", "#111")};
85
348
  }
349
+
86
350
  .controls {
351
+ position: absolute;
87
352
  top: 0px;
88
353
  right: 0px;
89
354
  left: 0px;
90
- position: absolute;
355
+ height: var(--toolbar-height);
356
+ background: var(--toolbar-bg);
357
+ backdrop-filter: blur(12px);
358
+ -webkit-backdrop-filter: blur(12px);
359
+ border-bottom: 1px solid var(--toolbar-border);
360
+ display: flex;
361
+ align-items: center;
362
+ justify-content: space-between;
363
+ padding: 0 12px;
364
+ z-index: 100;
365
+ box-sizing: border-box;
366
+ }
367
+
368
+ .controls__section {
369
+ display: flex;
370
+ align-items: center;
371
+ gap: 4px;
372
+ }
373
+
374
+ .controls__divider {
375
+ width: 1px;
376
+ height: 20px;
377
+ background: var(--toolbar-border);
378
+ margin: 0 8px;
379
+ }
380
+
381
+ .controls__button {
382
+ display: flex;
383
+ align-items: center;
384
+ justify-content: center;
385
+ width: 32px;
91
386
  height: 32px;
387
+ border: none;
388
+ background: transparent;
389
+ border-radius: 6px;
390
+ cursor: pointer;
391
+ color: var(--text-primary);
392
+ transition: background 0.15s ease;
393
+ }
394
+
395
+ .controls__button:hover {
396
+ background: var(--button-hover);
397
+ }
398
+
399
+ .controls__button:active {
400
+ background: var(--button-active);
401
+ }
402
+
403
+ .controls__button--active {
404
+ background: var(--button-active);
405
+ color: var(--accent-color);
406
+ }
407
+
408
+ .controls__button dees-icon {
409
+ font-size: 16px;
410
+ }
411
+
412
+ .zoom-control {
413
+ position: relative;
414
+ display: flex;
415
+ align-items: center;
416
+ gap: 2px;
417
+ }
418
+
419
+ .zoom-dropdown-trigger {
420
+ display: flex;
421
+ align-items: center;
422
+ gap: 4px;
423
+ padding: 4px 8px;
424
+ border: 1px solid var(--toolbar-border);
425
+ background: transparent;
426
+ border-radius: 6px;
427
+ cursor: pointer;
428
+ color: var(--text-primary);
429
+ font-size: 13px;
430
+ font-weight: 500;
431
+ width: 90px; /* Fixed width to prevent reflow - fits "Fit Width" */
432
+ justify-content: space-between;
433
+ transition: all 0.15s ease;
434
+ }
435
+
436
+ .zoom-dropdown-trigger:hover {
437
+ background: var(--button-hover);
438
+ border-color: var(--text-secondary);
439
+ }
440
+
441
+ .zoom-dropdown-trigger dees-icon {
442
+ font-size: 12px;
443
+ opacity: 0.6;
444
+ transition: transform 0.2s ease;
445
+ }
446
+
447
+ .zoom-dropdown-trigger--open dees-icon {
448
+ transform: rotate(180deg);
449
+ }
450
+
451
+ .zoom-dropdown {
452
+ position: absolute;
453
+ top: calc(100% + 4px);
454
+ left: 50%;
455
+ transform: translateX(-50%);
456
+ background: var(--dropdown-bg);
457
+ border: 1px solid var(--toolbar-border);
458
+ border-radius: 8px;
459
+ box-shadow: var(--dropdown-shadow);
460
+ min-width: 140px;
461
+ padding: 4px;
462
+ z-index: 1000;
463
+ opacity: 0;
464
+ visibility: hidden;
465
+ transform: translateX(-50%) translateY(-8px);
466
+ transition: all 0.2s ease;
467
+ }
468
+
469
+ .zoom-dropdown--visible {
470
+ opacity: 1;
471
+ visibility: visible;
472
+ transform: translateX(-50%) translateY(0);
473
+ }
474
+
475
+ .zoom-dropdown__item {
476
+ display: flex;
477
+ align-items: center;
478
+ padding: 8px 12px;
479
+ border: none;
480
+ background: transparent;
92
481
  width: 100%;
93
- background: ${cssManager.bdTheme("#eeeeeb", "#111111ee")};
94
- box-shadow: 0px 2px 8px 0px #000000;
482
+ text-align: left;
483
+ cursor: pointer;
484
+ border-radius: 4px;
485
+ color: var(--text-primary);
486
+ font-size: 13px;
487
+ transition: background 0.1s ease;
488
+ }
489
+
490
+ .zoom-dropdown__item:hover {
491
+ background: var(--button-hover);
492
+ }
493
+
494
+ .zoom-dropdown__item--active {
495
+ color: var(--accent-color);
496
+ font-weight: 500;
497
+ }
498
+
499
+ .zoom-slider-container {
500
+ display: flex;
501
+ align-items: center;
502
+ gap: 8px;
503
+ padding: 0 4px;
504
+ }
505
+
506
+ .zoom-slider {
507
+ width: 80px;
508
+ height: 4px;
509
+ -webkit-appearance: none;
510
+ appearance: none;
511
+ background: var(--slider-track);
512
+ border-radius: 2px;
513
+ outline: none;
514
+ cursor: pointer;
515
+ }
516
+
517
+ .zoom-slider::-webkit-slider-thumb {
518
+ -webkit-appearance: none;
519
+ appearance: none;
520
+ width: 14px;
521
+ height: 14px;
522
+ background: var(--slider-fill);
523
+ border-radius: 50%;
524
+ cursor: pointer;
525
+ transition: transform 0.15s ease;
526
+ }
527
+
528
+ .zoom-slider::-webkit-slider-thumb:hover {
529
+ transform: scale(1.15);
530
+ }
531
+
532
+ .zoom-slider::-moz-range-thumb {
533
+ width: 14px;
534
+ height: 14px;
535
+ background: var(--slider-fill);
536
+ border: none;
537
+ border-radius: 50%;
538
+ cursor: pointer;
539
+ }
540
+
541
+ .spacing-control {
542
+ display: flex;
543
+ align-items: center;
544
+ gap: 4px;
545
+ }
546
+
547
+ .spacing-label {
548
+ font-size: 12px;
549
+ color: var(--text-secondary);
550
+ margin-right: 4px;
551
+ }
552
+
553
+ .spacing-presets {
554
+ display: flex;
555
+ align-items: center;
556
+ gap: 2px;
95
557
  }
558
+
559
+ .fit-buttons {
560
+ display: flex;
561
+ align-items: center;
562
+ gap: 2px;
563
+ }
564
+
565
+ .page-nav {
566
+ display: flex;
567
+ align-items: center;
568
+ gap: 2px;
569
+ }
570
+
571
+ .page-indicator {
572
+ font-size: 12px;
573
+ color: var(--text-secondary);
574
+ min-width: 45px;
575
+ text-align: center;
576
+ }
577
+
578
+ .spacing-slider-container {
579
+ display: flex;
580
+ align-items: center;
581
+ gap: 6px;
582
+ }
583
+
584
+ .spacing-slider {
585
+ width: 60px;
586
+ height: 4px;
587
+ -webkit-appearance: none;
588
+ appearance: none;
589
+ background: var(--slider-track);
590
+ border-radius: 2px;
591
+ outline: none;
592
+ cursor: pointer;
593
+ }
594
+
595
+ .spacing-slider::-webkit-slider-thumb {
596
+ -webkit-appearance: none;
597
+ appearance: none;
598
+ width: 12px;
599
+ height: 12px;
600
+ background: var(--slider-fill);
601
+ border-radius: 50%;
602
+ cursor: pointer;
603
+ }
604
+
605
+ .spacing-slider::-moz-range-thumb {
606
+ width: 12px;
607
+ height: 12px;
608
+ background: var(--slider-fill);
609
+ border: none;
610
+ border-radius: 50%;
611
+ cursor: pointer;
612
+ }
613
+
614
+ .spacing-value {
615
+ font-size: 11px;
616
+ color: var(--text-secondary);
617
+ min-width: 28px;
618
+ text-align: right;
619
+ }
620
+
96
621
  .controlsShadow {
97
622
  position: absolute;
98
- top: 32px;
623
+ top: var(--toolbar-height);
99
624
  right: 0px;
100
625
  left: 0px;
101
626
  height: 16px;
102
- width: 100%;
103
- position: absolute;
104
- background: linear-gradient(to bottom, #111111cc 0%, #11111100 100%);
627
+ background: ${cssManager.bdTheme("linear-gradient(to bottom, rgba(0,0,0,0.08) 0%, transparent 100%)", "linear-gradient(to bottom, rgba(0,0,0,0.3) 0%, transparent 100%)")};
628
+ pointer-events: none;
629
+ z-index: 99;
105
630
  }
106
631
 
107
632
  .viewport {
108
633
  position: absolute;
109
634
  padding: 16px;
110
- padding-top: 48px;
635
+ padding-top: calc(var(--toolbar-height) + 16px);
111
636
  padding-bottom: 0px;
112
637
  top: 0px;
113
638
  left: 0px;
114
639
  right: 0px;
115
640
  bottom: 0px;
116
641
  overflow-y: scroll;
642
+ overflow-x: auto;
117
643
  overscroll-behavior: contain;
644
+ transition: left 0.2s ease;
645
+ }
646
+
647
+ .viewport--resizing {
648
+ transition: none !important;
649
+ }
650
+
651
+ .viewport--with-sidebar {
652
+ left: var(--current-sidebar-width, 140px);
653
+ }
654
+
655
+ .viewport--centered {
656
+ display: flex;
657
+ flex-direction: column;
658
+ align-items: center;
118
659
  }
119
660
  `,
661
+ // Tablet styles
662
+ cssManager.cssForTablet(css `
663
+ .zoom-slider-container {
664
+ display: none;
665
+ }
666
+ .spacing-slider-container {
667
+ display: none;
668
+ }
669
+ /* Collapse sidebar by default on tablet */
670
+ .sidebar {
671
+ width: 0 !important;
672
+ }
673
+ .sidebar--collapsed {
674
+ width: 0 !important;
675
+ }
676
+ .viewport--with-sidebar {
677
+ left: 0 !important;
678
+ }
679
+ `),
680
+ // Phone styles
681
+ cssManager.cssForPhone(css `
682
+ .zoom-slider-container {
683
+ display: none;
684
+ }
685
+ .fit-buttons {
686
+ display: none;
687
+ }
688
+ .spacing-label {
689
+ display: none;
690
+ }
691
+ .spacing-presets {
692
+ display: none;
693
+ }
694
+ .controls__divider {
695
+ display: none;
696
+ }
697
+ .controls {
698
+ padding: 0 8px;
699
+ }
700
+ .controls__section {
701
+ gap: 2px;
702
+ }
703
+ /* Hide sidebar and toggle on phone */
704
+ .sidebar {
705
+ display: none !important;
706
+ }
707
+ .sidebar-toggle {
708
+ display: none !important;
709
+ }
710
+ .viewport--with-sidebar {
711
+ left: 0 !important;
712
+ }
713
+ `),
120
714
  ];
121
- render = (__runInitializers(this, _documentSettings_extraInitializers), () => {
715
+ render() {
716
+ const viewportClasses = [
717
+ "viewport",
718
+ this.zoomMode !== "auto" ? "viewport--centered" : "",
719
+ this.showThumbnails ? "viewport--with-sidebar" : "",
720
+ this.isResizingSidebar ? "viewport--resizing" : "",
721
+ ].filter(Boolean).join(" ");
122
722
  return html `
123
- <div class="maincontainer">
124
- <div class="viewport">
723
+ <div class="maincontainer" style="--current-sidebar-width: ${this.sidebarWidth}px;">
724
+ ${this.renderSidebar()}
725
+ <div class="${viewportClasses}">
125
726
  ${this.letterData
126
727
  ? html `
127
728
  <dedocument-dedocument
128
729
  .letterData=${this.letterData}
129
730
  .documentSettings=${this.documentSettings}
731
+ .zoomLevel=${this.zoomLevel}
732
+ .pageGap=${this.pageGap}
130
733
  ></dedocument-dedocument>
131
734
  `
132
735
  : html ``}
133
736
  </div>
134
- <div class="controls"></div>
737
+ <div class="controls">
738
+ ${this.renderZoomControls()}
739
+ ${this.renderSpacingControls()}
740
+ </div>
741
+ <div class="controlsShadow"></div>
742
+ </div>
743
+ `;
744
+ }
745
+ renderSidebar() {
746
+ const sidebarClasses = [
747
+ "sidebar",
748
+ !this.showThumbnails ? "sidebar--collapsed" : "",
749
+ this.isResizingSidebar ? "sidebar--resizing" : "",
750
+ ].filter(Boolean).join(" ");
751
+ const thumbnailScale = this.getThumbnailScale();
752
+ const currentPage = this.getCurrentPage();
753
+ return html `
754
+ <div class="${sidebarClasses}" style="width: ${this.sidebarWidth}px;">
755
+ <div class="sidebar__header">Pages</div>
756
+ <div class="sidebar__thumbnails">
757
+ ${this.thumbnailPages.map((_, i) => {
758
+ const pageInfo = this.paginationInfo[i];
759
+ return html `
760
+ <div
761
+ class="thumbnail ${currentPage === i + 1 ? "thumbnail--active" : ""}"
762
+ @click=${() => this.scrollToPage(i + 1)}
763
+ >
764
+ <div
765
+ class="thumbnail__preview"
766
+ style="--thumbnail-scale: ${thumbnailScale};"
767
+ >
768
+ <div style="
769
+ width: ${plugins.shared.A4_WIDTH}px;
770
+ height: ${plugins.shared.A4_HEIGHT}px;
771
+ transform: scale(${thumbnailScale});
772
+ transform-origin: top left;
773
+ pointer-events: none;
774
+ ">
775
+ <dedocument-page
776
+ .letterData=${this.letterData}
777
+ .documentSettings=${this.documentSettings}
778
+ .pageNumber=${i + 1}
779
+ .pageTotalNumber=${this.thumbnailPages.length}
780
+ >${pageInfo ? html `
781
+ <dedocument-contentinvoice
782
+ .letterData=${this.letterData}
783
+ .documentSettings=${this.documentSettings}
784
+ .renderStartOffset=${pageInfo.startOffset}
785
+ .renderContentLength=${pageInfo.contentLength}
786
+ ></dedocument-contentinvoice>
787
+ ` : null}</dedocument-page>
788
+ </div>
789
+ </div>
790
+ <span class="thumbnail__label">${i + 1}</span>
791
+ </div>
792
+ `;
793
+ })}
794
+ </div>
795
+ <div
796
+ class="sidebar__resize-handle"
797
+ @mousedown=${this.startSidebarResize}
798
+ ></div>
135
799
  </div>
136
800
  `;
137
- });
138
- updated = (changedProperties) => {
801
+ }
802
+ getThumbnailScale() {
803
+ const previewWidth = this.sidebarWidth - 24; // Account for padding
804
+ return previewWidth / plugins.shared.A4_WIDTH;
805
+ }
806
+ renderZoomControls() {
807
+ return html `
808
+ <div class="controls__section">
809
+ <!-- Sidebar Toggle Button -->
810
+ <button
811
+ class="controls__button sidebar-toggle ${this.showThumbnails ? "controls__button--active" : ""}"
812
+ @click=${() => this.toggleThumbnails()}
813
+ title="Toggle Thumbnails"
814
+ >
815
+ <dees-icon icon="lucide:panelLeft"></dees-icon>
816
+ </button>
817
+
818
+ <div class="controls__divider sidebar-toggle"></div>
819
+
820
+ <!-- Zoom Out Button -->
821
+ <button
822
+ class="controls__button"
823
+ @click=${() => this.handleZoomStep(-10)}
824
+ title="Zoom Out"
825
+ >
826
+ <dees-icon icon="lucide:minus"></dees-icon>
827
+ </button>
828
+
829
+ <!-- Zoom Dropdown -->
830
+ <div class="zoom-control">
831
+ <button
832
+ class="zoom-dropdown-trigger ${this.showZoomDropdown ? "zoom-dropdown-trigger--open" : ""}"
833
+ @click=${() => this.toggleZoomDropdown()}
834
+ >
835
+ <span>${this.getZoomDisplayText()}</span>
836
+ <dees-icon icon="lucide:chevronDown"></dees-icon>
837
+ </button>
838
+ <div class="zoom-dropdown ${this.showZoomDropdown ? "zoom-dropdown--visible" : ""}">
839
+ ${ZOOM_PRESETS.map((preset) => html `
840
+ <button
841
+ class="zoom-dropdown__item ${this.isActivePreset(preset.value) ? "zoom-dropdown__item--active" : ""}"
842
+ @click=${() => this.handleZoomPreset(preset.value)}
843
+ >
844
+ ${preset.label}
845
+ </button>
846
+ `)}
847
+ </div>
848
+ </div>
849
+
850
+ <!-- Zoom In Button -->
851
+ <button
852
+ class="controls__button"
853
+ @click=${() => this.handleZoomStep(10)}
854
+ title="Zoom In"
855
+ >
856
+ <dees-icon icon="lucide:plus"></dees-icon>
857
+ </button>
858
+
859
+ <div class="controls__divider"></div>
860
+
861
+ <!-- Fit Buttons -->
862
+ <div class="fit-buttons">
863
+ <!-- Fit Width Button -->
864
+ <button
865
+ class="controls__button ${this.zoomMode === "fit-width" ? "controls__button--active" : ""}"
866
+ @click=${() => this.handleZoomPreset("fit-width")}
867
+ title="Fit Width"
868
+ >
869
+ <dees-icon icon="lucide:arrowLeftRight"></dees-icon>
870
+ </button>
871
+
872
+ <!-- Fit Page Button -->
873
+ <button
874
+ class="controls__button ${this.zoomMode === "fit-page" ? "controls__button--active" : ""}"
875
+ @click=${() => this.handleZoomPreset("fit-page")}
876
+ title="Fit Page"
877
+ >
878
+ <dees-icon icon="lucide:expand"></dees-icon>
879
+ </button>
880
+ </div>
881
+
882
+ <div class="controls__divider"></div>
883
+
884
+ <!-- Zoom Slider -->
885
+ <div class="zoom-slider-container">
886
+ <input
887
+ type="range"
888
+ class="zoom-slider"
889
+ min="25"
890
+ max="400"
891
+ .value=${String(this.displayZoom)}
892
+ @input=${this.handleZoomSlider}
893
+ />
894
+ </div>
895
+ </div>
896
+ `;
897
+ }
898
+ renderSpacingControls() {
899
+ return html `
900
+ <div class="controls__section">
901
+ <span class="spacing-label">Spacing</span>
902
+
903
+ <!-- Spacing Presets -->
904
+ <div class="spacing-presets">
905
+ ${SPACING_PRESETS.map((preset) => html `
906
+ <button
907
+ class="controls__button ${this.pageGap === preset.value ? "controls__button--active" : ""}"
908
+ @click=${() => this.handleSpacingPreset(preset.value)}
909
+ title="${preset.label} (${preset.value}px)"
910
+ >
911
+ <dees-icon icon="${preset.icon}"></dees-icon>
912
+ </button>
913
+ `)}
914
+ </div>
915
+
916
+ <div class="controls__divider"></div>
917
+
918
+ <!-- Spacing Slider -->
919
+ <div class="spacing-slider-container">
920
+ <input
921
+ type="range"
922
+ class="spacing-slider"
923
+ min="0"
924
+ max="64"
925
+ .value=${String(this.pageGap)}
926
+ @input=${this.handleSpacingSlider}
927
+ />
928
+ <span class="spacing-value">${this.pageGap}px</span>
929
+ </div>
930
+
931
+ <div class="controls__divider"></div>
932
+
933
+ <!-- Page Navigation -->
934
+ <div class="page-nav">
935
+ <button
936
+ class="controls__button"
937
+ @click=${() => this.handlePreviousPage()}
938
+ title="Previous Page"
939
+ >
940
+ <dees-icon icon="lucide:chevronUp"></dees-icon>
941
+ </button>
942
+ <span class="page-indicator">${this.currentPageDisplay}</span>
943
+ <button
944
+ class="controls__button"
945
+ @click=${() => this.handleNextPage()}
946
+ title="Next Page"
947
+ >
948
+ <dees-icon icon="lucide:chevronDown"></dees-icon>
949
+ </button>
950
+ </div>
951
+
952
+ <div class="controls__divider"></div>
953
+
954
+ <!-- Print Button -->
955
+ <button
956
+ class="controls__button"
957
+ @click=${() => this.handlePrint()}
958
+ title="Print Document"
959
+ >
960
+ <dees-icon icon="lucide:printer"></dees-icon>
961
+ </button>
962
+ </div>
963
+ `;
964
+ }
965
+ getZoomDisplayText() {
966
+ if (this.zoomMode === "auto")
967
+ return "Auto";
968
+ if (this.zoomMode === "fit-width")
969
+ return "Fit Width";
970
+ if (this.zoomMode === "fit-page")
971
+ return "Fit Page";
972
+ return `${this.displayZoom}%`;
973
+ }
974
+ isActivePreset(value) {
975
+ if (typeof value === "string") {
976
+ return this.zoomMode === value;
977
+ }
978
+ return this.zoomMode === value || (typeof this.zoomMode === "number" && this.zoomMode === value);
979
+ }
980
+ toggleZoomDropdown() {
981
+ this.showZoomDropdown = !this.showZoomDropdown;
982
+ if (this.showZoomDropdown) {
983
+ // Close dropdown when clicking outside
984
+ const closeHandler = (e) => {
985
+ const target = e.target;
986
+ if (!target.closest(".zoom-control")) {
987
+ this.showZoomDropdown = false;
988
+ document.removeEventListener("click", closeHandler);
989
+ }
990
+ };
991
+ setTimeout(() => document.addEventListener("click", closeHandler), 0);
992
+ }
993
+ }
994
+ handleZoomPreset(value) {
995
+ this.showZoomDropdown = false;
996
+ this.zoomMode = value;
997
+ if (value === "auto") {
998
+ this.zoomLevel = null;
999
+ this.updateDisplayZoom();
1000
+ }
1001
+ else if (value === "fit-width") {
1002
+ // Calculate zoom to fit page width to viewport width
1003
+ this.calculateFitWidth(true);
1004
+ }
1005
+ else if (value === "fit-page") {
1006
+ // Calculate zoom to fit entire page in viewport
1007
+ this.calculateFitPage(true);
1008
+ }
1009
+ else {
1010
+ // Animate to numeric preset
1011
+ this.animateZoomTo(value);
1012
+ }
1013
+ }
1014
+ handleZoomStep(delta) {
1015
+ const current = this.zoomLevel ?? this.displayZoom;
1016
+ const newZoom = Math.min(400, Math.max(25, current + delta));
1017
+ this.animateZoomTo(newZoom);
1018
+ this.zoomMode = newZoom;
1019
+ }
1020
+ handleZoomSlider(e) {
1021
+ // Cancel any running animation when user takes manual control
1022
+ if (this.zoomAnimationId !== null) {
1023
+ cancelAnimationFrame(this.zoomAnimationId);
1024
+ this.zoomAnimationId = null;
1025
+ }
1026
+ const value = parseInt(e.target.value, 10);
1027
+ this.zoomLevel = value;
1028
+ this.displayZoom = value;
1029
+ this.zoomMode = value;
1030
+ }
1031
+ /**
1032
+ * Animate zoom level to target value
1033
+ * @param targetZoom - Target zoom percentage
1034
+ * @param duration - Animation duration in ms (default: 200)
1035
+ */
1036
+ animateZoomTo(targetZoom, duration = 200) {
1037
+ // Cancel any existing animation
1038
+ if (this.zoomAnimationId !== null) {
1039
+ cancelAnimationFrame(this.zoomAnimationId);
1040
+ }
1041
+ const startZoom = this.zoomLevel ?? this.displayZoom;
1042
+ const startTime = performance.now();
1043
+ const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
1044
+ const animate = (currentTime) => {
1045
+ const elapsed = currentTime - startTime;
1046
+ const progress = Math.min(elapsed / duration, 1);
1047
+ const easedProgress = easeOutCubic(progress);
1048
+ const currentZoom = startZoom + (targetZoom - startZoom) * easedProgress;
1049
+ this.zoomLevel = Math.round(currentZoom);
1050
+ this.displayZoom = this.zoomLevel;
1051
+ if (progress < 1) {
1052
+ this.zoomAnimationId = requestAnimationFrame(animate);
1053
+ }
1054
+ else {
1055
+ this.zoomAnimationId = null;
1056
+ }
1057
+ };
1058
+ this.zoomAnimationId = requestAnimationFrame(animate);
1059
+ }
1060
+ handleSpacingPreset(value) {
1061
+ this.pageGap = value;
1062
+ }
1063
+ handleSpacingSlider(e) {
1064
+ this.pageGap = parseInt(e.target.value, 10);
1065
+ }
1066
+ // ============================================
1067
+ // SIDEBAR METHODS
1068
+ // ============================================
1069
+ startSidebarResize(e) {
1070
+ e.preventDefault();
1071
+ this.isResizingSidebar = true;
1072
+ const startX = e.clientX;
1073
+ const startWidth = this.sidebarWidth;
1074
+ const onMouseMove = (moveEvent) => {
1075
+ const delta = moveEvent.clientX - startX;
1076
+ const newWidth = Math.min(300, Math.max(100, startWidth + delta));
1077
+ this.sidebarWidth = newWidth;
1078
+ };
1079
+ const onMouseUp = () => {
1080
+ this.isResizingSidebar = false;
1081
+ document.removeEventListener("mousemove", onMouseMove);
1082
+ document.removeEventListener("mouseup", onMouseUp);
1083
+ document.body.style.cursor = "";
1084
+ document.body.style.userSelect = "";
1085
+ };
1086
+ document.addEventListener("mousemove", onMouseMove, { passive: true });
1087
+ document.addEventListener("mouseup", onMouseUp);
1088
+ document.body.style.cursor = "ew-resize";
1089
+ document.body.style.userSelect = "none";
1090
+ }
1091
+ updateThumbnailPages() {
1092
+ const pageCount = this.getPageCount();
1093
+ if (pageCount !== this.thumbnailPages.length) {
1094
+ this.thumbnailPages = Array.from({ length: pageCount }, (_, i) => i);
1095
+ }
1096
+ }
1097
+ handlePreviousPage() {
1098
+ const current = this.getCurrentPage();
1099
+ if (current > 1) {
1100
+ this.scrollToPage(current - 1);
1101
+ }
1102
+ }
1103
+ handleNextPage() {
1104
+ const current = this.getCurrentPage();
1105
+ const total = this.getPageCount();
1106
+ if (current < total) {
1107
+ this.scrollToPage(current + 1);
1108
+ }
1109
+ }
1110
+ updatePageIndicator() {
1111
+ const current = this.getCurrentPage();
1112
+ const total = this.getPageCount();
1113
+ this.currentPageDisplay = `${current} / ${total || 1}`;
1114
+ }
1115
+ async handlePrint() {
1116
+ // Create a print-specific container - hidden on screen, visible only in print
1117
+ const printContainer = document.createElement("div");
1118
+ printContainer.className = "dedocument-print-container";
1119
+ printContainer.style.cssText = `
1120
+ position: absolute;
1121
+ left: -9999px;
1122
+ top: 0;
1123
+ width: 210mm;
1124
+ height: auto;
1125
+ visibility: hidden;
1126
+ pointer-events: none;
1127
+ `;
1128
+ // Create a document element in print mode
1129
+ const printDoc = document.createElement("dedocument-dedocument");
1130
+ printDoc.letterData = this.letterData;
1131
+ printDoc.documentSettings = this.documentSettings;
1132
+ printDoc.printMode = true;
1133
+ printDoc.pageGap = 0;
1134
+ printContainer.appendChild(printDoc);
1135
+ document.body.appendChild(printContainer);
1136
+ // Add print styles - hide everything except print container during print
1137
+ const printStyles = document.createElement("style");
1138
+ printStyles.id = "dedocument-print-styles";
1139
+ printStyles.textContent = `
1140
+ @media print {
1141
+ body > *:not(.dedocument-print-container) {
1142
+ display: none !important;
1143
+ }
1144
+ .dedocument-print-container {
1145
+ position: static !important;
1146
+ left: auto !important;
1147
+ width: auto !important;
1148
+ height: auto !important;
1149
+ visibility: visible !important;
1150
+ pointer-events: auto !important;
1151
+ }
1152
+ dedocument-dedocument {
1153
+ display: block !important;
1154
+ }
1155
+ dedocument-page {
1156
+ page-break-after: always;
1157
+ page-break-inside: avoid;
1158
+ break-after: page;
1159
+ break-inside: avoid;
1160
+ }
1161
+ dedocument-page:last-child {
1162
+ page-break-after: auto;
1163
+ break-after: auto;
1164
+ }
1165
+ @page {
1166
+ size: A4;
1167
+ margin: 0;
1168
+ }
1169
+ }
1170
+ `;
1171
+ document.head.appendChild(printStyles);
1172
+ // Wait for the document to render
1173
+ await new Promise((resolve) => setTimeout(resolve, 500));
1174
+ // Cleanup function
1175
+ const cleanup = () => {
1176
+ if (document.body.contains(printContainer)) {
1177
+ printContainer.remove();
1178
+ }
1179
+ if (document.head.contains(printStyles)) {
1180
+ printStyles.remove();
1181
+ }
1182
+ window.removeEventListener("afterprint", cleanup);
1183
+ };
1184
+ // Listen for print dialog close
1185
+ window.addEventListener("afterprint", cleanup);
1186
+ // Trigger print
1187
+ window.print();
1188
+ // Fallback: also clean up immediately after print() returns
1189
+ // (some browsers return from print() after dialog closes)
1190
+ setTimeout(cleanup, 100);
1191
+ }
1192
+ calculateFitWidth(animate = false) {
1193
+ const viewport = this.shadowRoot?.querySelector(".viewport");
1194
+ if (!viewport)
1195
+ return;
1196
+ // Account for padding and scrollbar width
1197
+ const viewportWidth = viewport.clientWidth - 32 - 16;
1198
+ const scale = viewportWidth / plugins.shared.A4_WIDTH;
1199
+ const targetZoom = Math.round(scale * 100);
1200
+ if (animate) {
1201
+ this.animateZoomTo(targetZoom);
1202
+ }
1203
+ else {
1204
+ this.zoomLevel = targetZoom;
1205
+ this.displayZoom = targetZoom;
1206
+ }
1207
+ }
1208
+ calculateFitPage(animate = false) {
1209
+ const viewport = this.shadowRoot?.querySelector(".viewport");
1210
+ if (!viewport)
1211
+ return;
1212
+ // Account for padding: top = toolbar (40px) + 16px, bottom = 16px margin for visibility
1213
+ const topPadding = 40 + 16; // toolbar height + padding
1214
+ const bottomPadding = 16; // some margin at bottom
1215
+ const sidePadding = 32; // 16px each side
1216
+ const viewportHeight = viewport.clientHeight - topPadding - bottomPadding;
1217
+ const viewportWidth = viewport.clientWidth - sidePadding;
1218
+ const scaleByHeight = viewportHeight / plugins.shared.A4_HEIGHT;
1219
+ const scaleByWidth = viewportWidth / plugins.shared.A4_WIDTH;
1220
+ const scale = Math.min(scaleByHeight, scaleByWidth);
1221
+ const targetZoom = Math.round(scale * 100);
1222
+ if (animate) {
1223
+ this.animateZoomTo(targetZoom);
1224
+ }
1225
+ else {
1226
+ this.zoomLevel = targetZoom;
1227
+ this.displayZoom = targetZoom;
1228
+ }
1229
+ }
1230
+ updateDisplayZoom() {
1231
+ // Update display zoom based on current auto scale
1232
+ requestAnimationFrame(() => {
1233
+ const doc = this.shadowRoot?.querySelector("dedocument-dedocument");
1234
+ if (doc) {
1235
+ this.displayZoom = doc.getEffectiveZoom();
1236
+ }
1237
+ });
1238
+ }
1239
+ updated(changedProperties) {
139
1240
  super.updated(changedProperties);
140
1241
  if (changedProperties.has("letterData")) {
1242
+ // Update display zoom, page indicator, and thumbnails after document renders
1243
+ setTimeout(() => {
1244
+ this.updateDisplayZoom();
1245
+ this.updatePageIndicator();
1246
+ this.updateThumbnailPages();
1247
+ }, 100);
1248
+ // Additional delay to ensure all pages are rendered
1249
+ setTimeout(() => {
1250
+ this.updateThumbnailPages();
1251
+ }, 500);
1252
+ }
1253
+ }
1254
+ firstUpdated() {
1255
+ // Apply initial settings if provided
1256
+ if (this.initialPageGap !== 16) {
1257
+ this.pageGap = this.initialPageGap;
1258
+ }
1259
+ if (this.initialZoom !== null) {
1260
+ this.zoomLevel = this.initialZoom;
1261
+ this.displayZoom = this.initialZoom;
1262
+ this.zoomMode = this.initialZoom;
1263
+ }
1264
+ else {
1265
+ // Update display zoom initially for auto mode
1266
+ setTimeout(() => this.updateDisplayZoom(), 200);
1267
+ }
1268
+ // Listen for pagination-complete event from DeDocument
1269
+ this.addEventListener('pagination-complete', (e) => {
1270
+ this.paginationInfo = e.detail.paginationInfo;
1271
+ const pageCount = e.detail.pageCount;
1272
+ if (pageCount !== this.thumbnailPages.length) {
1273
+ this.thumbnailPages = Array.from({ length: pageCount }, (_, i) => i);
1274
+ }
1275
+ });
1276
+ // Handle viewport resize and scroll
1277
+ const viewport = this.shadowRoot?.querySelector(".viewport");
1278
+ if (viewport) {
1279
+ // Resize observer for zoom updates
1280
+ const resizeObserver = new ResizeObserver(() => {
1281
+ if (this.zoomMode === "auto" || this.zoomMode === "fit-width") {
1282
+ this.updateDisplayZoom();
1283
+ }
1284
+ });
1285
+ resizeObserver.observe(viewport);
1286
+ this.registerGarbageFunction(() => resizeObserver.disconnect());
1287
+ // Scroll listener for page indicator and thumbnail highlighting
1288
+ const scrollHandler = () => {
1289
+ this.updatePageIndicator();
1290
+ // Trigger re-render to update active thumbnail
1291
+ this.requestUpdate();
1292
+ };
1293
+ viewport.addEventListener("scroll", scrollHandler, { passive: true });
1294
+ this.registerGarbageFunction(() => viewport.removeEventListener("scroll", scrollHandler));
141
1295
  }
142
- };
1296
+ // Initial page indicator and thumbnail update
1297
+ setTimeout(() => {
1298
+ this.updatePageIndicator();
1299
+ this.updateThumbnailPages();
1300
+ }, 300);
1301
+ }
1302
+ // ============================================
1303
+ // PUBLIC API METHODS
1304
+ // ============================================
1305
+ /**
1306
+ * Set the zoom level programmatically
1307
+ * @param level - Zoom percentage (25-400), or 'auto', 'fit-width', 'fit-page'
1308
+ */
1309
+ setZoom(level) {
1310
+ if (level === "auto") {
1311
+ this.handleZoomPreset("auto");
1312
+ }
1313
+ else if (level === "fit-width") {
1314
+ this.handleZoomPreset("fit-width");
1315
+ }
1316
+ else if (level === "fit-page") {
1317
+ this.handleZoomPreset("fit-page");
1318
+ }
1319
+ else {
1320
+ const clampedZoom = Math.min(400, Math.max(25, level));
1321
+ this.zoomLevel = clampedZoom;
1322
+ this.displayZoom = clampedZoom;
1323
+ this.zoomMode = clampedZoom;
1324
+ }
1325
+ }
1326
+ /**
1327
+ * Get the current zoom percentage
1328
+ */
1329
+ getZoom() {
1330
+ return this.displayZoom;
1331
+ }
1332
+ /**
1333
+ * Set the page gap (spacing between pages)
1334
+ * @param gap - Gap in pixels (0-64)
1335
+ */
1336
+ setPageGap(gap) {
1337
+ this.pageGap = Math.min(64, Math.max(0, gap));
1338
+ }
1339
+ /**
1340
+ * Get the current page gap in pixels
1341
+ */
1342
+ getPageGap() {
1343
+ return this.pageGap;
1344
+ }
1345
+ /**
1346
+ * Get the total number of pages in the document
1347
+ */
1348
+ getPageCount() {
1349
+ const doc = this.shadowRoot?.querySelector("dedocument-dedocument");
1350
+ if (!doc)
1351
+ return 0;
1352
+ const pages = doc.shadowRoot?.querySelectorAll("dedocument-page");
1353
+ return pages?.length ?? 0;
1354
+ }
1355
+ /**
1356
+ * Get the currently visible page number (1-indexed)
1357
+ */
1358
+ getCurrentPage() {
1359
+ const viewport = this.shadowRoot?.querySelector(".viewport");
1360
+ const doc = this.shadowRoot?.querySelector("dedocument-dedocument");
1361
+ if (!viewport || !doc)
1362
+ return 1;
1363
+ const pages = doc.shadowRoot?.querySelectorAll("dedocument-page");
1364
+ if (!pages || pages.length === 0)
1365
+ return 1;
1366
+ const viewportRect = viewport.getBoundingClientRect();
1367
+ const viewportCenter = viewportRect.top + viewportRect.height / 2;
1368
+ let currentPage = 1;
1369
+ for (let i = 0; i < pages.length; i++) {
1370
+ const pageRect = pages[i].getBoundingClientRect();
1371
+ if (pageRect.top <= viewportCenter && pageRect.bottom >= viewportCenter) {
1372
+ currentPage = i + 1;
1373
+ break;
1374
+ }
1375
+ if (pageRect.top > viewportCenter) {
1376
+ currentPage = Math.max(1, i);
1377
+ break;
1378
+ }
1379
+ currentPage = i + 1;
1380
+ }
1381
+ return currentPage;
1382
+ }
1383
+ /**
1384
+ * Scroll to a specific page
1385
+ * @param pageNumber - Page number (1-indexed)
1386
+ * @param smooth - Whether to use smooth scrolling (default: true)
1387
+ */
1388
+ scrollToPage(pageNumber, smooth = true) {
1389
+ const viewport = this.shadowRoot?.querySelector(".viewport");
1390
+ const doc = this.shadowRoot?.querySelector("dedocument-dedocument");
1391
+ if (!viewport || !doc)
1392
+ return;
1393
+ const pages = doc.shadowRoot?.querySelectorAll("dedocument-page");
1394
+ if (!pages || pages.length === 0)
1395
+ return;
1396
+ const targetIndex = Math.min(Math.max(0, pageNumber - 1), pages.length - 1);
1397
+ const targetPage = pages[targetIndex];
1398
+ if (targetPage) {
1399
+ // Calculate scroll position relative to viewport
1400
+ // Account for the document's position within the viewport
1401
+ const docRect = doc.getBoundingClientRect();
1402
+ const pageRect = targetPage.getBoundingClientRect();
1403
+ const pageOffsetFromDoc = pageRect.top - docRect.top;
1404
+ // Scroll to the page position with fast custom animation
1405
+ if (smooth) {
1406
+ this.animateScrollTo(viewport, pageOffsetFromDoc, 250);
1407
+ }
1408
+ else {
1409
+ viewport.scrollTop = pageOffsetFromDoc;
1410
+ }
1411
+ }
1412
+ }
1413
+ /**
1414
+ * Animate scroll to target position
1415
+ * @param element - The scrollable element
1416
+ * @param targetTop - Target scroll position
1417
+ * @param duration - Animation duration in ms (default: 150)
1418
+ */
1419
+ animateScrollTo(element, targetTop, duration = 150) {
1420
+ const startTop = element.scrollTop;
1421
+ const distance = targetTop - startTop;
1422
+ const startTime = performance.now();
1423
+ const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
1424
+ const step = (currentTime) => {
1425
+ const elapsed = currentTime - startTime;
1426
+ const progress = Math.min(elapsed / duration, 1);
1427
+ const easedProgress = easeOutCubic(progress);
1428
+ element.scrollTop = startTop + distance * easedProgress;
1429
+ if (progress < 1) {
1430
+ requestAnimationFrame(step);
1431
+ }
1432
+ };
1433
+ requestAnimationFrame(step);
1434
+ }
1435
+ /**
1436
+ * Trigger the print dialog
1437
+ */
1438
+ async print() {
1439
+ await this.handlePrint();
1440
+ }
1441
+ /**
1442
+ * Toggle the thumbnails sidebar visibility
1443
+ */
1444
+ toggleThumbnails() {
1445
+ this.showThumbnails = !this.showThumbnails;
1446
+ }
1447
+ /**
1448
+ * Set whether the thumbnails sidebar is visible
1449
+ * @param visible - Whether the sidebar should be visible
1450
+ */
1451
+ setThumbnailsVisible(visible) {
1452
+ this.showThumbnails = visible;
1453
+ }
1454
+ /**
1455
+ * Get whether the thumbnails sidebar is visible
1456
+ */
1457
+ getThumbnailsVisible() {
1458
+ return this.showThumbnails;
1459
+ }
1460
+ /**
1461
+ * Set the sidebar width
1462
+ * @param width - Width in pixels (100-300)
1463
+ */
1464
+ setSidebarWidth(width) {
1465
+ this.sidebarWidth = Math.min(300, Math.max(100, width));
1466
+ }
1467
+ /**
1468
+ * Get the current sidebar width
1469
+ */
1470
+ getSidebarWidth() {
1471
+ return this.sidebarWidth;
1472
+ }
143
1473
  static {
144
1474
  __runInitializers(_classThis, _classExtraInitializers);
145
1475
  }
@@ -147,4 +1477,4 @@ let DeDocumentViewer = (() => {
147
1477
  return DeDocumentViewer = _classThis;
148
1478
  })();
149
1479
  export { DeDocumentViewer };
150
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHNfd2ViL2VsZW1lbnRzL3ZpZXdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUNMLFdBQVcsRUFDWCxHQUFHLEVBQ0gsVUFBVSxFQUNWLGFBQWEsRUFDYixJQUFJLEVBQ0osUUFBUSxHQUNULE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0lBUy9CLGdCQUFnQjs0QkFENUIsYUFBYSxDQUFDLG1CQUFtQixDQUFDOzs7O3NCQUNHLFdBQVc7Ozs7Ozs7Z0NBQW5CLFNBQVEsV0FBVzs7OztzQ0FLOUMsUUFBUSxDQUFDO29CQUNSLElBQUksRUFBRSxNQUFNO29CQUNaLE9BQU8sRUFBRSxJQUFJO2lCQUNkLENBQUM7NENBR0QsUUFBUSxDQUFDO29CQUNSLElBQUksRUFBRSxNQUFNO29CQUNaLE9BQU8sRUFBRSxJQUFJO2lCQUNkLENBQUM7WUFMRixtTEFBUyxVQUFVLDZCQUFWLFVBQVUsK0ZBQTBDO1lBTTdELHFNQUFTLGdCQUFnQiw2QkFBaEIsZ0JBQWdCLDJHQUE4QztZQWZ6RSw2S0F1RkM7Ozs7UUF0RkMsT0FBTztRQUNBLE1BQU0sQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDO1FBTzlCLGlGQUF3RCxJQUFJLEVBQUM7UUFMN0QsV0FBVztRQUtYLElBQVMsVUFBVSxnREFBMEM7UUFBN0QsSUFBUyxVQUFVLHNEQUEwQztRQU03RCwrSkFBdUU7UUFBdkUsSUFBUyxnQkFBZ0Isc0RBQThDO1FBQXZFLElBQVMsZ0JBQWdCLDREQUE4QztRQUVoRSxNQUFNLENBQUMsTUFBTSxHQUFHO1lBQ3JCLFVBQVUsQ0FBQyxhQUFhO1lBQ3hCLEdBQUcsQ0FBQTs7Ozs7c0JBS2UsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDOzs7Ozs7Ozs7c0JBU3JDLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0EwQjNEO1NBQ0YsQ0FBQztRQUVLLE1BQU0sa0VBQUcsR0FBRyxFQUFFO1lBQ25CLE9BQU8sSUFBSSxDQUFBOzs7WUFHSCxJQUFJLENBQUMsVUFBVTtnQkFDZixDQUFDLENBQUMsSUFBSSxDQUFBOztnQ0FFYyxJQUFJLENBQUMsVUFBVTtzQ0FDVCxJQUFJLENBQUMsZ0JBQWdCOztlQUU1QztnQkFDSCxDQUFDLENBQUMsSUFBSSxDQUFBLEVBQUU7Ozs7S0FJZixDQUFDO1FBQ0osQ0FBQyxFQUFDO1FBRUssT0FBTyxHQUFHLENBQ2YsaUJBQXlELEVBQ3pELEVBQUU7WUFDRixLQUFLLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDakMsSUFBSSxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUMxQyxDQUFDO1FBQ0gsQ0FBQyxDQUFDOztZQXRGUyx1REFBZ0I7Ozs7O1NBQWhCLGdCQUFnQiJ9
1480
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHNfd2ViL2VsZW1lbnRzL3ZpZXdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUNMLFdBQVcsRUFDWCxHQUFHLEVBQ0gsVUFBVSxFQUNWLGFBQWEsRUFDYixJQUFJLEVBQ0osUUFBUSxFQUNSLEtBQUssR0FFTixNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsVUFBVSxFQUE0QixNQUFNLGVBQWUsQ0FBQztBQUNyRSxPQUFPLFdBQVcsQ0FBQyxDQUFDLHdDQUF3QztBQUM1RCxPQUFPLHFCQUFxQixDQUFDLENBQUMsZ0RBQWdEO0FBRTlFLE9BQU8sNkJBQTZCLENBQUM7QUFnQnJDLE1BQU0sWUFBWSxHQUE0QztJQUM1RCxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtJQUNwQyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRTtJQUMxQyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRTtJQUN4QyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtJQUMzQixFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtJQUMzQixFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRTtJQUM3QixFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRTtJQUM3QixFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRTtJ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