@edgepdf/viewer-js 0.0.32 → 0.0.34

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.
package/README.md CHANGED
@@ -8,18 +8,19 @@ Core JavaScript library for the EdgePDF viewer, providing Leaflet map integratio
8
8
  npm install @edgepdf/viewer-js
9
9
  # or
10
10
  pnpm add @edgepdf/viewer-js
11
+ # or
12
+ yarn add @edgepdf/viewer-js
11
13
  ```
12
14
 
13
15
  **Note:** Leaflet is bundled with this library, so you don't need to install it separately. **CSS styles are automatically injected** when you import the library - no manual CSS import needed!
14
16
 
15
- ## Usage
17
+ ## Quick Start
16
18
 
17
19
  ### Basic Example
18
20
 
19
21
  ```typescript
20
22
  import { EdgePdfViewer } from '@edgepdf/viewer-js';
21
23
  import type { ViewerConfig } from '@edgepdf/types';
22
- // CSS is automatically injected - no need to import styles manually!
23
24
 
24
25
  // Get container element
25
26
  const container = document.getElementById('map-container');
@@ -40,6 +41,16 @@ const config: ViewerConfig = {
40
41
  const viewer = new EdgePdfViewer({ container, config });
41
42
  viewer.initialize();
42
43
 
44
+ // Access marker manager
45
+ const markerManager = viewer.getMarkerManager();
46
+ if (markerManager) {
47
+ // Create a marker
48
+ const marker = markerManager.createMarker({
49
+ position: [1500, 1000], // [lat, lng] in Leaflet coordinates
50
+ label: 'My Marker',
51
+ });
52
+ }
53
+
43
54
  // Cleanup when done
44
55
  viewer.dispose();
45
56
  ```
@@ -49,7 +60,6 @@ viewer.dispose();
49
60
  ```typescript
50
61
  import { EdgePdfViewer } from '@edgepdf/viewer-js';
51
62
  import type { ViewerConfig, MapOptions } from '@edgepdf/types';
52
- // CSS is automatically injected - no need to import styles manually!
53
63
 
54
64
  const config: ViewerConfig = {
55
65
  tileUrl: 'https://example.com/tiles/{z}/{x}/{y}.png',
@@ -129,10 +139,448 @@ Checks if the map is initialized.
129
139
 
130
140
  **Returns:** `true` if map is initialized, `false` otherwise
131
141
 
142
+ ##### `getTileLayerManager(): TileLayerManager | null`
143
+
144
+ Gets the tile layer manager instance.
145
+
146
+ **Returns:** The tile layer manager, or `null` if not created
147
+
148
+ ##### `getCoordinateMapper(): CoordinateMapper | null`
149
+
150
+ Gets the coordinate mapper instance.
151
+
152
+ **Returns:** The coordinate mapper, or `null` if not created
153
+
154
+ ##### `getZoomController(): ZoomController | null`
155
+
156
+ Gets the zoom controller instance.
157
+
158
+ **Returns:** The zoom controller, or `null` if not created
159
+
160
+ ##### `getMarkerManager(): MarkerManager | null`
161
+
162
+ Gets the marker manager instance.
163
+
164
+ **Returns:** The marker manager, or `null` if not created
165
+
166
+ ##### `focusMarker(markerOrId: string | Marker, options?: FocusOptions): boolean`
167
+
168
+ Focuses on a marker by panning and zooming to its position.
169
+
170
+ **Parameters:**
171
+
172
+ - `markerOrId` - Marker ID string or Marker object
173
+ - `options` - Optional focus options
174
+ - `zoom?: number` - Target zoom level (uses marker's zoom or default if not provided)
175
+ - `animate?: boolean` - Whether to animate the transition (default: true)
176
+ - `duration?: number` - Animation duration in seconds (default: 0.5)
177
+ - `offsetLeft?: number` - Pixel offset to move focus marker to the left (default: 0)
178
+ - `offsetRight?: number` - Pixel offset to move focus marker to the right (default: 0)
179
+ - `offsetTop?: number` - Pixel offset to move focus marker upward (default: 0)
180
+ - `offsetBottom?: number` - Pixel offset to move focus marker downward (default: 0)
181
+
182
+ **Returns:** `true` if focus was successful, `false` if marker not found or viewer not initialized
183
+
184
+ **Example:**
185
+ ```typescript
186
+ // Focus with offset to account for overlay
187
+ viewer.focusMarker('marker-123', { offsetLeft: 100, offsetTop: 50 });
188
+ ```
189
+
132
190
  ##### `dispose(): void`
133
191
 
134
192
  Disposes of the map instance and cleans up resources. This should be called when the viewer is no longer needed to prevent memory leaks and event listener issues.
135
193
 
194
+ ---
195
+
196
+ ### MarkerManager
197
+
198
+ Manages markers on the Leaflet map. Access via `viewer.getMarkerManager()`.
199
+
200
+ #### Methods
201
+
202
+ ##### `createMarker(options: CreateMarkerOptions): Marker`
203
+
204
+ Creates a new marker from coordinates.
205
+
206
+ **Parameters:**
207
+
208
+ - `options.position?: LeafletCoords` - Leaflet coordinates [lat, lng]
209
+ - `options.imageCoords?: ImageCoords` - Image pixel coordinates {x, y}
210
+ - `options.label?: string` - Marker label/tooltip text
211
+ - `options.description?: string` - Marker description
212
+ - `options.href?: string` - Link URL (optional)
213
+ - `options.target?: string` - Link target (optional)
214
+ - `options.showLabel?: boolean` - Show label/tooltip
215
+ - `options.id?: string` - Custom marker ID (auto-generated if not provided)
216
+ - `options.iconType?: 'pin-gray' | 'pin-yellow'` - Icon type for the marker
217
+ - `options.referenceId?: string` - Reference ID for linking to external systems
218
+ - `options.draggable?: boolean` - Enable dragging for this specific marker
219
+ - `options.editable?: boolean` - Enable editing for this specific marker
220
+ - `options.deletable?: boolean` - Enable deleting for this specific marker
221
+
222
+ **Returns:** The created marker
223
+
224
+ **Throws:**
225
+
226
+ - `Error` if neither position nor imageCoords is provided
227
+ - `Error` if coordinates are invalid or out of bounds
228
+
229
+ ##### `getMarker(id: string): Marker | null`
230
+
231
+ Gets a marker by ID.
232
+
233
+ **Returns:** The marker, or `null` if not found
234
+
235
+ ##### `getAllMarkers(): Marker[]`
236
+
237
+ Gets all markers.
238
+
239
+ **Returns:** Array of all markers
240
+
241
+ ##### `getMarkerCount(): number`
242
+
243
+ Gets the total number of markers.
244
+
245
+ **Returns:** Number of markers
246
+
247
+ ##### `hasMarker(id: string): boolean`
248
+
249
+ Checks if a marker exists.
250
+
251
+ **Returns:** `true` if marker exists, `false` otherwise
252
+
253
+ ##### `updateMarker(id: string, updates: Partial<Marker>): boolean`
254
+
255
+ Updates a marker's properties.
256
+
257
+ **Parameters:**
258
+
259
+ - `id` - Marker ID
260
+ - `updates` - Partial marker object with properties to update
261
+
262
+ **Returns:** `true` if marker was updated, `false` if not found
263
+
264
+ ##### `updateMarkerPosition(id: string, position: LeafletCoords): boolean`
265
+
266
+ Updates a marker's position.
267
+
268
+ **Parameters:**
269
+
270
+ - `id` - Marker ID
271
+ - `position` - New Leaflet coordinates [lat, lng]
272
+
273
+ **Returns:** `true` if marker was updated, `false` if not found
274
+
275
+ ##### `updateMarkerIcon(id: string, iconType: 'pin-gray' | 'pin-yellow'): boolean`
276
+
277
+ Updates the icon type for a specific marker.
278
+
279
+ **Returns:** `true` if marker was updated, `false` if not found
280
+
281
+ ##### `updateAllMarkerIcons(iconType: 'pin-gray' | 'pin-yellow'): void`
282
+
283
+ Updates all markers to use a new icon type.
284
+
285
+ ##### `removeMarker(id: string): boolean`
286
+
287
+ Removes a marker by ID.
288
+
289
+ **Returns:** `true` if marker was removed, `false` if not found
290
+
291
+ ##### `removeAllMarkers(): void`
292
+
293
+ Removes all markers.
294
+
295
+ ##### `deleteMarker(id: string): boolean`
296
+
297
+ Deletes a marker by ID (triggers delete event).
298
+
299
+ **Returns:** `true` if marker was deleted, `false` if not found
300
+
301
+ ##### `exportMarkers(): MarkerData`
302
+
303
+ Exports all markers as JSON data.
304
+
305
+ **Returns:** MarkerData object containing all markers and metadata
306
+
307
+ ##### `importMarkers(data: MarkerData, options?: ImportOptions): ImportResult`
308
+
309
+ Imports markers from MarkerData.
310
+
311
+ **Parameters:**
312
+
313
+ - `data` - MarkerData object to import
314
+ - `options` - Import options
315
+ - `clearExisting?: boolean` - If true, removes all existing markers before import (default: false)
316
+ - `validateCoordinates?: boolean` - If true, validates coordinates are within bounds (default: true)
317
+
318
+ **Returns:** Import result with success status and details
319
+
320
+ ##### `setInteractionConfig(config: Partial<MarkerInteractionConfig>): void`
321
+
322
+ Sets marker interaction configuration.
323
+
324
+ **Parameters:**
325
+
326
+ - `config.draggable?: boolean` - Enable dragging markers
327
+ - `config.selectable?: boolean` - Enable selecting markers
328
+ - `config.showTooltips?: boolean` - Show tooltips on hover
329
+ - `config.showPopups?: boolean` - Show popups on click
330
+ - `config.multiSelect?: boolean` - Allow multiple marker selection
331
+ - `config.showEditButton?: boolean` - Show edit button in popups
332
+ - `config.showDeleteButton?: boolean` - Show delete button in popups
333
+ - `config.onEdit?: (marker: Marker) => Promise<Marker | null>` - Custom edit handler
334
+ - `config.onDelete?: (marker: Marker) => Promise<boolean>` - Custom delete handler
335
+ - `config.onActiveMarkerChange?: (marker: Marker | null) => void` - Active marker change callback
336
+
337
+ ##### `getInteractionConfig(): MarkerInteractionConfig`
338
+
339
+ Gets the current interaction configuration.
340
+
341
+ **Returns:** Current interaction configuration
342
+
343
+ ##### `selectMarker(id: string): boolean`
344
+
345
+ Selects a marker.
346
+
347
+ **Returns:** `true` if marker was selected, `false` if not found
348
+
349
+ ##### `deselectMarker(id: string): boolean`
350
+
351
+ Deselects a marker.
352
+
353
+ **Returns:** `true` if marker was deselected, `false` if not found
354
+
355
+ ##### `deselectAllMarkers(): void`
356
+
357
+ Deselects all markers.
358
+
359
+ ##### `getSelectionState(): MarkerSelectionState`
360
+
361
+ Gets the current selection state.
362
+
363
+ **Returns:** Selection state object with selected IDs and count
364
+
365
+ ##### `isMarkerSelected(id: string): boolean`
366
+
367
+ Checks if a marker is selected.
368
+
369
+ **Returns:** `true` if marker is selected, `false` otherwise
370
+
371
+ ##### `setActiveMarker(id: string | null): boolean`
372
+
373
+ Sets the active marker (for popup management).
374
+
375
+ **Returns:** `true` if active marker was set, `false` if marker not found
376
+
377
+ ##### `getActiveMarker(): Marker | null`
378
+
379
+ Gets the currently active marker.
380
+
381
+ **Returns:** The active marker, or `null` if no marker is active
382
+
383
+ ##### `focusMarker(markerOrId: string | Marker, options?: FocusOptions): boolean`
384
+
385
+ Focuses on a marker by panning and zooming to its position.
386
+
387
+ **Parameters:**
388
+
389
+ - `markerOrId` - Marker ID string or Marker object
390
+ - `options` - Optional focus options
391
+ - `zoom?: number` - Target zoom level
392
+ - `animate?: boolean` - Whether to animate (default: true)
393
+ - `duration?: number` - Animation duration in seconds (default: 0.5)
394
+ - `offsetLeft?: number` - Pixel offset to move focus marker to the left (default: 0)
395
+ - `offsetRight?: number` - Pixel offset to move focus marker to the right (default: 0)
396
+ - `offsetTop?: number` - Pixel offset to move focus marker upward (default: 0)
397
+ - `offsetBottom?: number` - Pixel offset to move focus marker downward (default: 0)
398
+
399
+ **Returns:** `true` if focus was successful, `false` if marker not found
400
+
401
+ **Example:**
402
+ ```typescript
403
+ // Focus with offset to account for overlay
404
+ markerManager.focusMarker('marker-123', { offsetLeft: 100, offsetTop: 50 });
405
+ ```
406
+
407
+ ##### `setDefaultIconType(iconType: 'pin-gray' | 'pin-yellow'): void`
408
+
409
+ Sets the default icon type for new markers.
410
+
411
+ ##### `getDefaultIconType(): 'pin-gray' | 'pin-yellow'`
412
+
413
+ Gets the current default icon type.
414
+
415
+ **Returns:** Current default icon type
416
+
417
+ ##### `setIconBasePath(basePath: string): void`
418
+
419
+ Sets the base path for marker icons.
420
+
421
+ **Example:**
422
+
423
+ ```typescript
424
+ // Use library's built-in icons (default)
425
+ markerManager.setIconBasePath('./images/');
426
+
427
+ // Use custom icons from public folder
428
+ markerManager.setIconBasePath('/');
429
+
430
+ // Use icons from a CDN
431
+ markerManager.setIconBasePath('https://cdn.example.com/icons/');
432
+ ```
433
+
434
+ ##### `getIconBasePath(): string`
435
+
436
+ Gets the current base path for marker icons.
437
+
438
+ **Returns:** The current icon base path
439
+
440
+ ##### `on(eventType: MarkerEventType, callback: (event: MarkerEvent) => void): () => void`
441
+
442
+ Registers an event listener.
443
+
444
+ **Parameters:**
445
+
446
+ - `eventType` - Event type: 'click' | 'dragstart' | 'drag' | 'dragend' | 'edit' | 'delete'
447
+ - `callback` - Callback function
448
+
449
+ **Returns:** Unsubscribe function
450
+
451
+ **Example:**
452
+
453
+ ```typescript
454
+ const unsubscribe = markerManager.on('click', (event) => {
455
+ console.log('Marker clicked:', event.marker.id);
456
+ });
457
+
458
+ // Later, to unsubscribe:
459
+ unsubscribe();
460
+ ```
461
+
462
+ ##### `off(eventType: MarkerEventType, callback: (event: MarkerEvent) => void): void`
463
+
464
+ Unregisters an event listener.
465
+
466
+ ##### `removeAllListeners(eventType?: MarkerEventType): void`
467
+
468
+ Removes all event listeners for a specific event type, or all events if no type is provided.
469
+
470
+ ##### `dispose(): void`
471
+
472
+ Disposes of the marker manager and cleans up resources.
473
+
474
+ ---
475
+
476
+ ### ZoomController
477
+
478
+ Manages zoom state and operations. Access via `viewer.getZoomController()`.
479
+
480
+ #### Methods
481
+
482
+ ##### `zoomIn(options?: { animate?: boolean }): boolean`
483
+
484
+ Zooms in by one level.
485
+
486
+ **Parameters:**
487
+
488
+ - `options.animate?: boolean` - Whether to animate the zoom (default: true)
489
+
490
+ **Returns:** `true` if zoomed in, `false` if already at max zoom
491
+
492
+ ##### `zoomOut(options?: { animate?: boolean }): boolean`
493
+
494
+ Zooms out by one level.
495
+
496
+ **Parameters:**
497
+
498
+ - `options.animate?: boolean` - Whether to animate the zoom (default: true)
499
+
500
+ **Returns:** `true` if zoomed out, `false` if already at min zoom
501
+
502
+ ##### `setZoom(zoom: number, options?: { animate?: boolean }): void`
503
+
504
+ Sets a specific zoom level.
505
+
506
+ **Parameters:**
507
+
508
+ - `zoom` - Target zoom level
509
+ - `options.animate?: boolean` - Whether to animate the zoom (default: true)
510
+
511
+ **Throws:**
512
+
513
+ - `Error` if zoom is not a finite number
514
+
515
+ ##### `getZoom(): number`
516
+
517
+ Gets the current zoom level.
518
+
519
+ **Returns:** Current zoom level
520
+
521
+ ##### `getZoomState(): ZoomState`
522
+
523
+ Gets the current zoom state.
524
+
525
+ **Returns:** Zoom state object with currentZoom, minZoom, maxZoom
526
+
527
+ ##### `getMinZoom(): number`
528
+
529
+ Gets the minimum zoom level.
530
+
531
+ **Returns:** Minimum zoom level
532
+
533
+ ##### `getMaxZoom(): number`
534
+
535
+ Gets the maximum zoom level.
536
+
537
+ **Returns:** Maximum zoom level
538
+
539
+ ##### `canZoomIn(): boolean`
540
+
541
+ Checks if can zoom in.
542
+
543
+ **Returns:** `true` if can zoom in, `false` otherwise
544
+
545
+ ##### `canZoomOut(): boolean`
546
+
547
+ Checks if can zoom out.
548
+
549
+ **Returns:** `true` if can zoom out, `false` otherwise
550
+
551
+ ##### `onZoomChange(listener: (state: ZoomState) => void): () => void`
552
+
553
+ Registers a zoom change listener.
554
+
555
+ **Returns:** Unsubscribe function
556
+
557
+ ##### `removeAllListeners(): void`
558
+
559
+ Removes all zoom change listeners.
560
+
561
+ ##### `dispose(): void`
562
+
563
+ Disposes of the zoom controller and cleans up resources.
564
+
565
+ ---
566
+
567
+ ### Utility Functions
568
+
569
+ #### `createZoomControls(container: HTMLElement, zoomController: ZoomController, options?: ZoomControlsOptions): HTMLElement`
570
+
571
+ Creates zoom control buttons (zoom in/out) in the specified container.
572
+
573
+ **Parameters:**
574
+
575
+ - `container` - Container element
576
+ - `zoomController` - Zoom controller instance
577
+ - `options` - Optional configuration
578
+ - `position?: ZoomControlsPosition` - Position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' (default: 'top-right')
579
+
580
+ **Returns:** The created controls element
581
+
582
+ ---
583
+
136
584
  ## Configuration
137
585
 
138
586
  ### ViewerConfig
@@ -229,16 +677,77 @@ The viewer uses Leaflet's `CRS.Simple` coordinate system, which treats coordinat
229
677
  - Y-axis: vertical pixel position (0 to image height)
230
678
  - Origin: top-left corner (0, 0)
231
679
 
232
- ## Building
680
+ ## Examples
681
+
682
+ ### Working with Markers
683
+
684
+ ```typescript
685
+ const viewer = new EdgePdfViewer({ container, config });
686
+ viewer.initialize();
687
+
688
+ const markerManager = viewer.getMarkerManager();
689
+ if (!markerManager) return;
690
+
691
+ // Create a marker
692
+ const marker = markerManager.createMarker({
693
+ position: [1500, 1000],
694
+ label: 'My Marker',
695
+ description: 'This is a marker description',
696
+ iconType: 'pin-yellow',
697
+ });
698
+
699
+ // Update marker
700
+ markerManager.updateMarker(marker.id, {
701
+ label: 'Updated Label',
702
+ description: 'Updated description',
703
+ });
704
+
705
+ // Listen to marker events
706
+ markerManager.on('click', (event) => {
707
+ console.log('Marker clicked:', event.marker);
708
+ });
233
709
 
234
- Run `nx build viewer-js` to build the library.
710
+ markerManager.on('dragend', (event) => {
711
+ console.log('Marker dragged to:', event.marker.position);
712
+ });
235
713
 
236
- ## Running Tests
714
+ // Export markers
715
+ const markerData = markerManager.exportMarkers();
716
+ console.log(JSON.stringify(markerData, null, 2));
237
717
 
238
- Run `nx test viewer-js` to execute the unit tests via [Jest](https://jestjs.io).
718
+ // Import markers
719
+ markerManager.importMarkers(markerData, {
720
+ clearExisting: true,
721
+ validateCoordinates: true,
722
+ });
723
+ ```
239
724
 
240
- Run `nx test viewer-js --coverage` to generate coverage reports.
725
+ ### Working with Zoom
241
726
 
242
- ## License
727
+ ```typescript
728
+ const viewer = new EdgePdfViewer({ container, config });
729
+ viewer.initialize();
243
730
 
244
- MIT
731
+ const zoomController = viewer.getZoomController();
732
+ if (!zoomController) return;
733
+
734
+ // Zoom in
735
+ zoomController.zoomIn();
736
+
737
+ // Zoom out
738
+ zoomController.zoomOut();
739
+
740
+ // Set specific zoom level
741
+ zoomController.setZoom(3);
742
+
743
+ // Get zoom state
744
+ const zoomState = zoomController.getZoomState();
745
+ console.log('Current zoom:', zoomState.currentZoom);
746
+ console.log('Min zoom:', zoomState.minZoom);
747
+ console.log('Max zoom:', zoomState.maxZoom);
748
+
749
+ // Listen to zoom changes
750
+ zoomController.onZoomChange((state) => {
751
+ console.log('Zoom changed to:', state.currentZoom);
752
+ });
753
+ ```
package/dist/index.css CHANGED
@@ -1,3 +1,5 @@
1
+ @import "https://fonts.googleapis.com/css2?family=Lato:wght@300;400;500;600;700&display=swap";
2
+
1
3
  /* node_modules/.pnpm/leaflet@1.9.4/node_modules/leaflet/dist/leaflet.css */
2
4
  .leaflet-pane,
3
5
  .leaflet-tile,
@@ -673,6 +675,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
673
675
  display: flex;
674
676
  align-items: center;
675
677
  justify-content: center;
678
+ font-family: "Lato", sans-serif;
676
679
  }
677
680
  .edgepdf-marker-edit-popup-overlay {
678
681
  position: absolute;
@@ -680,14 +683,15 @@ svg.leaflet-image-layer.leaflet-interactive path {
680
683
  left: 0;
681
684
  right: 0;
682
685
  bottom: 0;
683
- background-color: rgba(0, 0, 0, 0.5);
686
+ background-color: rgba(0, 0, 0, 0.7);
684
687
  cursor: pointer;
685
688
  }
686
689
  .edgepdf-marker-edit-popup-content {
687
690
  position: relative;
688
- background-color: #fff;
691
+ background-color: #1a1a1a;
689
692
  border-radius: 8px;
690
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
693
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
694
+ border: 1px solid #333;
691
695
  width: 90%;
692
696
  max-width: 500px;
693
697
  max-height: 90vh;
@@ -699,20 +703,20 @@ svg.leaflet-image-layer.leaflet-interactive path {
699
703
  justify-content: space-between;
700
704
  align-items: center;
701
705
  padding: 16px 20px;
702
- border-bottom: 1px solid #e0e0e0;
706
+ border-bottom: 1px solid #333;
703
707
  }
704
708
  .edgepdf-marker-edit-popup-header h3 {
705
709
  margin: 0;
706
710
  font-size: 18px;
707
711
  font-weight: 600;
708
- color: #333;
712
+ color: #fff;
709
713
  }
710
714
  .edgepdf-marker-edit-popup-close {
711
715
  background: none;
712
716
  border: none;
713
717
  font-size: 24px;
714
718
  line-height: 1;
715
- color: #666;
719
+ color: #fff;
716
720
  cursor: pointer;
717
721
  padding: 0;
718
722
  width: 32px;
@@ -724,8 +728,8 @@ svg.leaflet-image-layer.leaflet-interactive path {
724
728
  transition: background-color 0.2s ease;
725
729
  }
726
730
  .edgepdf-marker-edit-popup-close:hover {
727
- background-color: #f0f0f0;
728
- color: #333;
731
+ background-color: #333;
732
+ color: #ffa500;
729
733
  }
730
734
  .edgepdf-marker-edit-popup-body {
731
735
  padding: 20px;
@@ -741,52 +745,57 @@ svg.leaflet-image-layer.leaflet-interactive path {
741
745
  margin-bottom: 8px;
742
746
  font-size: 14px;
743
747
  font-weight: 500;
744
- color: #333;
748
+ color: #fff;
745
749
  }
746
750
  .edgepdf-marker-edit-input {
747
751
  width: 100%;
748
752
  padding: 10px 12px;
749
- border: 1px solid #ccc;
753
+ border: 1px solid #444;
750
754
  border-radius: 4px;
751
755
  font-size: 14px;
756
+ background-color: #2a2a2a;
757
+ color: #fff;
752
758
  box-sizing: border-box;
753
759
  transition: border-color 0.2s ease;
754
760
  }
755
761
  .edgepdf-marker-edit-input:focus {
756
762
  outline: none;
757
- border-color: #1976d2;
758
- box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);
763
+ border-color: #ffa500;
764
+ box-shadow: 0 0 0 2px rgba(255, 165, 0, 0.2);
765
+ }
766
+ .edgepdf-marker-edit-input::placeholder {
767
+ color: #888;
759
768
  }
760
769
  .edgepdf-marker-edit-popup-footer {
761
770
  display: flex;
762
771
  justify-content: flex-end;
763
772
  gap: 12px;
764
773
  padding: 16px 20px;
765
- border-top: 1px solid #e0e0e0;
774
+ border-top: 1px solid #333;
766
775
  }
767
776
  .edgepdf-marker-edit-button {
768
777
  padding: 10px 20px;
769
- border: 1px solid #ccc;
778
+ border: 1px solid #444;
770
779
  border-radius: 4px;
771
- background-color: #fff;
772
- color: #333;
780
+ background-color: #2a2a2a;
781
+ color: #fff;
773
782
  cursor: pointer;
774
783
  font-size: 14px;
775
784
  font-weight: 500;
776
785
  transition: all 0.2s ease;
777
786
  }
778
787
  .edgepdf-marker-edit-button-cancel:hover {
779
- background-color: #f0f0f0;
780
- border-color: #999;
788
+ background-color: #333;
789
+ border-color: #555;
781
790
  }
782
791
  .edgepdf-marker-edit-button-save {
783
- background-color: #1976d2;
784
- color: #fff;
785
- border-color: #1976d2;
792
+ background-color: #ffa500;
793
+ color: #000;
794
+ border-color: #ffa500;
786
795
  }
787
796
  .edgepdf-marker-edit-button-save:hover {
788
- background-color: #1565c0;
789
- border-color: #1565c0;
797
+ background-color: #ffd700;
798
+ border-color: #ffd700;
790
799
  }
791
800
  .edgepdf-marker-delete-popup {
792
801
  position: fixed;
@@ -798,6 +807,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
798
807
  display: flex;
799
808
  align-items: center;
800
809
  justify-content: center;
810
+ font-family: "Lato", sans-serif;
801
811
  }
802
812
  .edgepdf-marker-delete-popup-overlay {
803
813
  position: absolute;
@@ -805,14 +815,15 @@ svg.leaflet-image-layer.leaflet-interactive path {
805
815
  left: 0;
806
816
  right: 0;
807
817
  bottom: 0;
808
- background-color: rgba(0, 0, 0, 0.5);
818
+ background-color: rgba(0, 0, 0, 0.7);
809
819
  cursor: pointer;
810
820
  }
811
821
  .edgepdf-marker-delete-popup-content {
812
822
  position: relative;
813
- background-color: #fff;
823
+ background-color: #1a1a1a;
814
824
  border-radius: 8px;
815
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
825
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
826
+ border: 1px solid #333;
816
827
  width: 90%;
817
828
  max-width: 500px;
818
829
  max-height: 90vh;
@@ -824,20 +835,20 @@ svg.leaflet-image-layer.leaflet-interactive path {
824
835
  justify-content: space-between;
825
836
  align-items: center;
826
837
  padding: 16px 20px;
827
- border-bottom: 1px solid #e0e0e0;
838
+ border-bottom: 1px solid #333;
828
839
  }
829
840
  .edgepdf-marker-delete-popup-header h3 {
830
841
  margin: 0;
831
842
  font-size: 18px;
832
843
  font-weight: 600;
833
- color: #333;
844
+ color: #fff;
834
845
  }
835
846
  .edgepdf-marker-delete-popup-close {
836
847
  background: none;
837
848
  border: none;
838
849
  font-size: 24px;
839
850
  line-height: 1;
840
- color: #666;
851
+ color: #fff;
841
852
  cursor: pointer;
842
853
  padding: 0;
843
854
  width: 32px;
@@ -849,8 +860,8 @@ svg.leaflet-image-layer.leaflet-interactive path {
849
860
  transition: background-color 0.2s ease;
850
861
  }
851
862
  .edgepdf-marker-delete-popup-close:hover {
852
- background-color: #f0f0f0;
853
- color: #333;
863
+ background-color: #333;
864
+ color: #ffa500;
854
865
  }
855
866
  .edgepdf-marker-delete-popup-body {
856
867
  padding: 20px;
@@ -858,43 +869,43 @@ svg.leaflet-image-layer.leaflet-interactive path {
858
869
  .edgepdf-marker-delete-popup-body p {
859
870
  margin: 0;
860
871
  font-size: 14px;
861
- color: #333;
872
+ color: #fff;
862
873
  line-height: 1.5;
863
874
  }
864
875
  .edgepdf-marker-delete-popup-body strong {
865
876
  font-weight: 600;
866
- color: #d32f2f;
877
+ color: #ffa500;
867
878
  }
868
879
  .edgepdf-marker-delete-popup-footer {
869
880
  display: flex;
870
881
  justify-content: flex-end;
871
882
  gap: 12px;
872
883
  padding: 16px 20px;
873
- border-top: 1px solid #e0e0e0;
884
+ border-top: 1px solid #333;
874
885
  }
875
886
  .edgepdf-marker-delete-button {
876
887
  padding: 10px 20px;
877
- border: 1px solid #ccc;
888
+ border: 1px solid #444;
878
889
  border-radius: 4px;
879
- background-color: #fff;
880
- color: #333;
890
+ background-color: #2a2a2a;
891
+ color: #fff;
881
892
  cursor: pointer;
882
893
  font-size: 14px;
883
894
  font-weight: 500;
884
895
  transition: all 0.2s ease;
885
896
  }
886
897
  .edgepdf-marker-delete-button-cancel:hover {
887
- background-color: #f0f0f0;
888
- border-color: #999;
898
+ background-color: #333;
899
+ border-color: #555;
889
900
  }
890
901
  .edgepdf-marker-delete-button-confirm {
891
- background-color: #d32f2f;
892
- color: #fff;
893
- border-color: #d32f2f;
902
+ background-color: #ffa500;
903
+ color: #000;
904
+ border-color: #ffa500;
894
905
  }
895
906
  .edgepdf-marker-delete-button-confirm:hover {
896
- background-color: #b71c1c;
897
- border-color: #b71c1c;
907
+ background-color: #ffd700;
908
+ border-color: #ffd700;
898
909
  }
899
910
  .edgepdf-marker-icon-overlay-container {
900
911
  background: transparent !important;
package/dist/index.js CHANGED
@@ -9589,6 +9589,12 @@ var S3_PREFIX = {
9589
9589
  PROCESSED: "processed"
9590
9590
  };
9591
9591
  var MAX_ZOOM_LEVEL = 4;
9592
+ var MARKER_SPEC = {
9593
+ WIDTH: 30,
9594
+ HEIGHT: 40,
9595
+ ANCHOR_X: 16,
9596
+ ANCHOR_Y: 36
9597
+ };
9592
9598
  function calculateTileCount(imageSize, tileSize, zoom) {
9593
9599
  if (imageSize <= 0 || tileSize <= 0 || zoom < 0) {
9594
9600
  return 0;
@@ -11290,6 +11296,98 @@ var MarkerManager = class {
11290
11296
  this.updateMarkerIcon(id, iconType);
11291
11297
  });
11292
11298
  }
11299
+ /**
11300
+ * Focuses on a marker by panning and zooming to its position
11301
+ *
11302
+ * This method smoothly animates the map view to center on the specified marker
11303
+ * and optionally sets a specific zoom level. If no zoom level is provided,
11304
+ * it uses the marker's saved zoom level or a reasonable default.
11305
+ *
11306
+ * @param markerOrId - Marker ID string or Marker object
11307
+ * @param options - Optional focus options
11308
+ * @param options.zoom - Target zoom level (uses marker's zoom or default if not provided)
11309
+ * @param options.animate - Whether to animate the transition (default: true)
11310
+ * @param options.duration - Animation duration in seconds (default: 0.5)
11311
+ * @param options.offsetLeft - Pixel offset to move focus marker to the left (default: 0)
11312
+ * @param options.offsetRight - Pixel offset to move focus marker to the right (default: 0)
11313
+ * @param options.offsetTop - Pixel offset to move focus marker upward (default: 0)
11314
+ * @param options.offsetBottom - Pixel offset to move focus marker downward (default: 0)
11315
+ * @returns True if focus was successful, false if marker not found
11316
+ *
11317
+ * @example
11318
+ * ```typescript
11319
+ * // Focus on marker by ID
11320
+ * markerManager.focusMarker('marker-123');
11321
+ *
11322
+ * // Focus with specific zoom level
11323
+ * markerManager.focusMarker('marker-123', { zoom: 3 });
11324
+ *
11325
+ * // Focus without animation
11326
+ * markerManager.focusMarker('marker-123', { animate: false });
11327
+ *
11328
+ * // Focus with custom duration
11329
+ * markerManager.focusMarker('marker-123', { zoom: 2, duration: 1.0 });
11330
+ *
11331
+ * // Focus with offset to account for overlay
11332
+ * markerManager.focusMarker('marker-123', { offsetLeft: 100, offsetTop: 50 });
11333
+ * ```
11334
+ */
11335
+ focusMarker(markerOrId, options) {
11336
+ let marker = null;
11337
+ if (typeof markerOrId === "string") {
11338
+ marker = this.getMarker(markerOrId);
11339
+ } else {
11340
+ marker = markerOrId;
11341
+ }
11342
+ if (!marker) {
11343
+ console.warn(`Marker not found: ${markerOrId}`);
11344
+ return false;
11345
+ }
11346
+ const targetZoom = options?.zoom ?? marker.zoom ?? 2;
11347
+ const minZoom = this.imageInfo.minZoom ?? 0;
11348
+ const maxZoom = this.imageInfo.maxZoom ?? 5;
11349
+ const constrainedZoom = Math.max(minZoom, Math.min(maxZoom, targetZoom));
11350
+ const position = [
11351
+ marker.position[0],
11352
+ marker.position[1]
11353
+ ];
11354
+ const animate = options?.animate !== false;
11355
+ const duration = options?.duration ?? 0.5;
11356
+ const offsetX = (options?.offsetRight ?? 0) - (options?.offsetLeft ?? 0);
11357
+ const offsetY = (options?.offsetBottom ?? 0) - (options?.offsetTop ?? 0);
11358
+ if (offsetX !== 0 || offsetY !== 0) {
11359
+ const currentZoom = this.map.getZoom();
11360
+ const needsZoomChange = currentZoom !== constrainedZoom;
11361
+ if (needsZoomChange) {
11362
+ this.map.setZoom(constrainedZoom, { animate: false });
11363
+ }
11364
+ const markerPoint = this.map.latLngToContainerPoint(position);
11365
+ const offsetPoint = import_leaflet3.default.point(
11366
+ markerPoint.x + offsetX,
11367
+ markerPoint.y + offsetY
11368
+ );
11369
+ const offsetLatLng = this.map.containerPointToLatLng(offsetPoint);
11370
+ if (needsZoomChange && animate) {
11371
+ this.map.setZoom(currentZoom, { animate: false });
11372
+ }
11373
+ if (animate) {
11374
+ this.map.flyTo(offsetLatLng, constrainedZoom, {
11375
+ duration
11376
+ });
11377
+ } else {
11378
+ this.map.setView(offsetLatLng, constrainedZoom);
11379
+ }
11380
+ } else {
11381
+ if (animate) {
11382
+ this.map.flyTo(position, constrainedZoom, {
11383
+ duration
11384
+ });
11385
+ } else {
11386
+ this.map.setView(position, constrainedZoom);
11387
+ }
11388
+ }
11389
+ return true;
11390
+ }
11293
11391
  /**
11294
11392
  * Disposes of the marker manager and cleans up resources
11295
11393
  *
@@ -11312,10 +11410,9 @@ var MarkerManager = class {
11312
11410
  const iconUrl = `${this.iconBasePath}${iconType}.png`;
11313
11411
  return import_leaflet3.default.icon({
11314
11412
  iconUrl,
11315
- iconSize: [30, 40],
11316
- // Default marker size
11317
- iconAnchor: [16, 36],
11318
- // Point of the icon which will correspond to marker's location
11413
+ iconSize: [MARKER_SPEC.WIDTH, MARKER_SPEC.HEIGHT],
11414
+ iconAnchor: [MARKER_SPEC.ANCHOR_X, MARKER_SPEC.ANCHOR_Y],
11415
+ // Anchor point aligns with marker location
11319
11416
  popupAnchor: [0, 0],
11320
11417
  // Point from which the popup should open relative to the iconAnchor
11321
11418
  shadowUrl: void 0,
@@ -11445,8 +11542,8 @@ var MarkerManager = class {
11445
11542
  }
11446
11543
  const overlaySize = 40;
11447
11544
  const borderWidth = 1;
11448
- const overlayAnchorX = 20;
11449
- const overlayAnchorY = 35;
11545
+ const overlayAnchorX = overlaySize / 2 + (MARKER_SPEC.WIDTH / 2 - MARKER_SPEC.ANCHOR_X);
11546
+ const overlayAnchorY = overlaySize / 2 + (MARKER_SPEC.HEIGHT / 2 - MARKER_SPEC.ANCHOR_Y);
11450
11547
  const overlayHTML = `
11451
11548
  <div style="
11452
11549
  width: ${overlaySize}px;
@@ -12407,6 +12504,41 @@ var EdgePdfViewer = class {
12407
12504
  getMarkerManager() {
12408
12505
  return this.markerManager;
12409
12506
  }
12507
+ /**
12508
+ * Focuses on a marker by panning and zooming to its position
12509
+ *
12510
+ * This is a convenience method that delegates to the marker manager's focusMarker method.
12511
+ *
12512
+ * @param markerOrId - Marker ID string or Marker object
12513
+ * @param options - Optional focus options
12514
+ * @param options.zoom - Target zoom level (uses marker's zoom or default if not provided)
12515
+ * @param options.animate - Whether to animate the transition (default: true)
12516
+ * @param options.duration - Animation duration in seconds (default: 0.5)
12517
+ * @param options.offsetLeft - Pixel offset to move focus marker to the left (default: 0)
12518
+ * @param options.offsetRight - Pixel offset to move focus marker to the right (default: 0)
12519
+ * @param options.offsetTop - Pixel offset to move focus marker upward (default: 0)
12520
+ * @param options.offsetBottom - Pixel offset to move focus marker downward (default: 0)
12521
+ * @returns True if focus was successful, false if marker not found or viewer not initialized
12522
+ *
12523
+ * @example
12524
+ * ```typescript
12525
+ * // Focus on marker by ID
12526
+ * viewer.focusMarker('marker-123');
12527
+ *
12528
+ * // Focus with specific zoom level
12529
+ * viewer.focusMarker('marker-123', { zoom: 3 });
12530
+ *
12531
+ * // Focus with offset to account for overlay
12532
+ * viewer.focusMarker('marker-123', { offsetLeft: 100, offsetTop: 50 });
12533
+ * ```
12534
+ */
12535
+ focusMarker(markerOrId, options) {
12536
+ if (!this.markerManager) {
12537
+ console.warn("Marker manager not available");
12538
+ return false;
12539
+ }
12540
+ return this.markerManager.focusMarker(markerOrId, options);
12541
+ }
12410
12542
  /**
12411
12543
  * Disposes of the map instance and cleans up resources
12412
12544
  *
@@ -373,6 +373,51 @@ export declare class MarkerManager {
373
373
  * @param iconType - Icon type to apply to all markers
374
374
  */
375
375
  updateAllMarkerIcons(iconType: 'pin-gray' | 'pin-yellow'): void;
376
+ /**
377
+ * Focuses on a marker by panning and zooming to its position
378
+ *
379
+ * This method smoothly animates the map view to center on the specified marker
380
+ * and optionally sets a specific zoom level. If no zoom level is provided,
381
+ * it uses the marker's saved zoom level or a reasonable default.
382
+ *
383
+ * @param markerOrId - Marker ID string or Marker object
384
+ * @param options - Optional focus options
385
+ * @param options.zoom - Target zoom level (uses marker's zoom or default if not provided)
386
+ * @param options.animate - Whether to animate the transition (default: true)
387
+ * @param options.duration - Animation duration in seconds (default: 0.5)
388
+ * @param options.offsetLeft - Pixel offset to move focus marker to the left (default: 0)
389
+ * @param options.offsetRight - Pixel offset to move focus marker to the right (default: 0)
390
+ * @param options.offsetTop - Pixel offset to move focus marker upward (default: 0)
391
+ * @param options.offsetBottom - Pixel offset to move focus marker downward (default: 0)
392
+ * @returns True if focus was successful, false if marker not found
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * // Focus on marker by ID
397
+ * markerManager.focusMarker('marker-123');
398
+ *
399
+ * // Focus with specific zoom level
400
+ * markerManager.focusMarker('marker-123', { zoom: 3 });
401
+ *
402
+ * // Focus without animation
403
+ * markerManager.focusMarker('marker-123', { animate: false });
404
+ *
405
+ * // Focus with custom duration
406
+ * markerManager.focusMarker('marker-123', { zoom: 2, duration: 1.0 });
407
+ *
408
+ * // Focus with offset to account for overlay
409
+ * markerManager.focusMarker('marker-123', { offsetLeft: 100, offsetTop: 50 });
410
+ * ```
411
+ */
412
+ focusMarker(markerOrId: string | Marker, options?: {
413
+ zoom?: number;
414
+ animate?: boolean;
415
+ duration?: number;
416
+ offsetLeft?: number;
417
+ offsetRight?: number;
418
+ offsetTop?: number;
419
+ offsetBottom?: number;
420
+ }): boolean;
376
421
  /**
377
422
  * Disposes of the marker manager and cleans up resources
378
423
  *
@@ -1 +1 @@
1
- {"version":3,"file":"marker-manager.d.ts","sourceRoot":"","sources":["../../src/lib/marker-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"marker-manager.d.ts","sourceRoot":"","sources":["../../src/lib/marker-manager.ts"],"names":[],"mappings":"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"}
@@ -124,6 +124,43 @@ export declare class EdgePdfViewer {
124
124
  * @returns The marker manager, or null if not created
125
125
  */
126
126
  getMarkerManager(): MarkerManager | null;
127
+ /**
128
+ * Focuses on a marker by panning and zooming to its position
129
+ *
130
+ * This is a convenience method that delegates to the marker manager's focusMarker method.
131
+ *
132
+ * @param markerOrId - Marker ID string or Marker object
133
+ * @param options - Optional focus options
134
+ * @param options.zoom - Target zoom level (uses marker's zoom or default if not provided)
135
+ * @param options.animate - Whether to animate the transition (default: true)
136
+ * @param options.duration - Animation duration in seconds (default: 0.5)
137
+ * @param options.offsetLeft - Pixel offset to move focus marker to the left (default: 0)
138
+ * @param options.offsetRight - Pixel offset to move focus marker to the right (default: 0)
139
+ * @param options.offsetTop - Pixel offset to move focus marker upward (default: 0)
140
+ * @param options.offsetBottom - Pixel offset to move focus marker downward (default: 0)
141
+ * @returns True if focus was successful, false if marker not found or viewer not initialized
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * // Focus on marker by ID
146
+ * viewer.focusMarker('marker-123');
147
+ *
148
+ * // Focus with specific zoom level
149
+ * viewer.focusMarker('marker-123', { zoom: 3 });
150
+ *
151
+ * // Focus with offset to account for overlay
152
+ * viewer.focusMarker('marker-123', { offsetLeft: 100, offsetTop: 50 });
153
+ * ```
154
+ */
155
+ focusMarker(markerOrId: string | import('@edgepdf/types').Marker, options?: {
156
+ zoom?: number;
157
+ animate?: boolean;
158
+ duration?: number;
159
+ offsetLeft?: number;
160
+ offsetRight?: number;
161
+ offsetTop?: number;
162
+ offsetBottom?: number;
163
+ }): boolean;
127
164
  /**
128
165
  * Disposes of the map instance and cleans up resources
129
166
  *
@@ -1 +1 @@
1
- {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/lib/viewer.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,SAAS,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAA8B;IAEnD;;;;;;;;;;OAUG;gBACS,OAAO,EAAE;QACnB,SAAS,EAAE,WAAW,CAAC;QACvB,MAAM,EAAE,YAAY,CAAC;QACrB,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;IAmBD;;;;;;;OAOG;IACH,UAAU,IAAI,IAAI;IA6FlB;;;;;;OAMG;IACH,OAAO,CAAC,2BAA2B;IAmBnC;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;;;OAIG;IACH,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,IAAI;IAItB;;;;OAIG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAwBpB;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C;;;;OAIG;IACH,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAIxC;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CA0BhB"}
1
+ {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/lib/viewer.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,SAAS,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAA8B;IAEnD;;;;;;;;;;OAUG;gBACS,OAAO,EAAE;QACnB,SAAS,EAAE,WAAW,CAAC;QACvB,MAAM,EAAE,YAAY,CAAC;QACrB,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;IAmBD;;;;;;;OAOG;IACH,UAAU,IAAI,IAAI;IA6FlB;;;;;;OAMG;IACH,OAAO,CAAC,2BAA2B;IAmBnC;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;;;OAIG;IACH,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,IAAI;IAItB;;;;OAIG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAwBpB;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C;;;;OAIG;IACH,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAIxC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,WAAW,CACT,UAAU,EAAE,MAAM,GAAG,OAAO,gBAAgB,EAAE,MAAM,EACpD,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GACA,OAAO;IASV;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CA0BhB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgepdf/viewer-js",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "description": "EdgePDF Viewer - JavaScript library for viewing PDF documents with interactive markers and zoom controls",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",