hazo_pdf 1.5.5 → 1.5.7
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 +148 -1
- package/config/hazo_pdf_config.ini +45 -0
- package/dist/chunk-AOSHQP7D.js +12 -0
- package/dist/{chunk-GFRC6LEG.js → chunk-CXHR3TT6.js} +11 -8
- package/dist/{chunk-GFRC6LEG.js.map → chunk-CXHR3TT6.js.map} +1 -1
- package/dist/{chunk-HT7OPS2V.js → chunk-FMZPXAJT.js} +147 -5
- package/dist/chunk-FMZPXAJT.js.map +1 -0
- package/dist/chunk-FXOJ3DPX.js +71 -0
- package/dist/chunk-FXOJ3DPX.js.map +1 -0
- package/dist/{chunk-3LPXEBPN.js → chunk-RQOQLZRS.js} +2 -2
- package/dist/index.d.ts +87 -21
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/{pdf_saver-IOWST6TO.js → pdf_saver-JXAIRQVL.js} +4 -3
- package/dist/pdf_viewer-ZZLO5MVA.js +12 -0
- package/dist/pdf_viewer-ZZLO5MVA.js.map +1 -0
- package/dist/text_search-GW2VYMU6.js +9 -0
- package/dist/text_search-GW2VYMU6.js.map +1 -0
- package/package.json +5 -3
- package/dist/chunk-HT7OPS2V.js.map +0 -1
- package/dist/pdf_viewer-ZJG52QDR.js +0 -11
- /package/dist/{pdf_saver-IOWST6TO.js.map → chunk-AOSHQP7D.js.map} +0 -0
- /package/dist/{chunk-3LPXEBPN.js.map → chunk-RQOQLZRS.js.map} +0 -0
- /package/dist/{pdf_viewer-ZJG52QDR.js.map → pdf_saver-JXAIRQVL.js.map} +0 -0
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ A React component library for viewing and annotating PDF documents with support
|
|
|
6
6
|
|
|
7
7
|
- 📄 **PDF Viewing** - Render PDF documents with customizable zoom levels
|
|
8
8
|
- ✏️ **Annotations** - Square and FreeText annotation tools
|
|
9
|
+
- ✨ **Auto-Highlighting** - Automatically highlight extracted field values in PDFs
|
|
9
10
|
- 🔍 **Programmatic Highlights** - Ref-based API for creating and managing highlights programmatically
|
|
10
11
|
- 🎨 **Customizable Styling** - Extensive configuration options via INI file
|
|
11
12
|
- ⏰ **Timestamp Support** - Automatic timestamp appending to annotations
|
|
@@ -516,9 +517,155 @@ See `config/hazo_pdf_config.ini` in the project root for all available configura
|
|
|
516
517
|
|
|
517
518
|
---
|
|
518
519
|
|
|
520
|
+
## Auto-Highlighting
|
|
521
|
+
|
|
522
|
+
The PDF viewer can automatically highlight extracted field values in your PDFs. Simply provide field names and values via the `highlight_fields_info` prop, and the viewer will search for and highlight them automatically.
|
|
523
|
+
|
|
524
|
+
### Basic Usage
|
|
525
|
+
|
|
526
|
+
```tsx
|
|
527
|
+
import { PdfViewer } from 'hazo_pdf';
|
|
528
|
+
import 'hazo_pdf/styles.css';
|
|
529
|
+
|
|
530
|
+
function AutoHighlightExample() {
|
|
531
|
+
const extracted_data = {
|
|
532
|
+
document_date: '30 June 2024',
|
|
533
|
+
total_amount: '$29,696.60',
|
|
534
|
+
vendor_name: 'ACME Corporation',
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
return (
|
|
538
|
+
<div style={{ width: '100%', height: '800px' }}>
|
|
539
|
+
<PdfViewer
|
|
540
|
+
url="/invoice.pdf"
|
|
541
|
+
highlight_fields_info={[
|
|
542
|
+
{ field_name: 'document_date', value: '30 June 2024', page_index: 0 },
|
|
543
|
+
{ field_name: 'total_amount', value: '$29,696.60', page_index: 0 },
|
|
544
|
+
{ field_name: 'vendor_name', value: 'ACME Corporation', page_index: 0 },
|
|
545
|
+
]}
|
|
546
|
+
show_file_info_button={true}
|
|
547
|
+
/>
|
|
548
|
+
</div>
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**That's it!** The viewer will:
|
|
554
|
+
1. Search for each value in the PDF text layer
|
|
555
|
+
2. Create visual highlight boxes at the found positions
|
|
556
|
+
3. Display field names and values in the File Info sidepanel
|
|
557
|
+
|
|
558
|
+
### How It Works
|
|
559
|
+
|
|
560
|
+
- **Smart Text Search**: Exact match first, then partial match with normalization (removes commas/spaces)
|
|
561
|
+
- **Automatic Cleanup**: Highlights are removed when the PDF changes or component unmounts
|
|
562
|
+
- **Non-Blocking**: Text search runs asynchronously without freezing the UI
|
|
563
|
+
- **Configurable**: Customize colors, opacity, padding, and search behavior
|
|
564
|
+
|
|
565
|
+
### HighlightFieldInfo Type
|
|
566
|
+
|
|
567
|
+
```typescript
|
|
568
|
+
interface HighlightFieldInfo {
|
|
569
|
+
field_name: string; // Field identifier (auto-formatted to Title Case in sidepanel)
|
|
570
|
+
value: string; // The text to search for and highlight
|
|
571
|
+
page_index?: number; // Page to search on (0-based, default: 0)
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Customization Options
|
|
576
|
+
|
|
577
|
+
#### Custom Highlight Colors
|
|
578
|
+
|
|
579
|
+
```tsx
|
|
580
|
+
<PdfViewer
|
|
581
|
+
url="/document.pdf"
|
|
582
|
+
highlight_fields_info={highlight_fields}
|
|
583
|
+
auto_highlight_options={{
|
|
584
|
+
border_color: '#0066CC',
|
|
585
|
+
background_color: '#E6F2FF',
|
|
586
|
+
background_opacity: 0.4,
|
|
587
|
+
border_width: 2,
|
|
588
|
+
}}
|
|
589
|
+
/>
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
#### Custom Search Options
|
|
593
|
+
|
|
594
|
+
```tsx
|
|
595
|
+
<PdfViewer
|
|
596
|
+
url="/document.pdf"
|
|
597
|
+
highlight_fields_info={highlight_fields}
|
|
598
|
+
auto_highlight_search_options={{
|
|
599
|
+
normalize: false, // Disable text normalization (exact match only)
|
|
600
|
+
padding_x: 5, // More horizontal padding
|
|
601
|
+
padding_y: 2, // More vertical padding
|
|
602
|
+
y_offset: -5, // Adjust vertical position
|
|
603
|
+
}}
|
|
604
|
+
/>
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
#### Disable Auto-Highlighting (Sidepanel Only)
|
|
608
|
+
|
|
609
|
+
```tsx
|
|
610
|
+
<PdfViewer
|
|
611
|
+
url="/document.pdf"
|
|
612
|
+
highlight_fields_info={highlight_fields}
|
|
613
|
+
auto_highlight_enabled={false} // Only show in sidepanel, no visual highlights
|
|
614
|
+
/>
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Configuration via INI File
|
|
618
|
+
|
|
619
|
+
You can set default auto-highlight styling in your config file:
|
|
620
|
+
|
|
621
|
+
```ini
|
|
622
|
+
[auto_highlight]
|
|
623
|
+
auto_highlight_border_color = #FF6B00
|
|
624
|
+
auto_highlight_background_color = #FFF3E0
|
|
625
|
+
auto_highlight_background_opacity = 0.3
|
|
626
|
+
auto_highlight_border_width = 1
|
|
627
|
+
auto_highlight_normalize_text = true
|
|
628
|
+
auto_highlight_padding_x = 2
|
|
629
|
+
auto_highlight_padding_y = 1
|
|
630
|
+
auto_highlight_y_offset = -3
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
### Props
|
|
634
|
+
|
|
635
|
+
| Prop | Type | Default | Description |
|
|
636
|
+
|------|------|---------|-------------|
|
|
637
|
+
| `highlight_fields_info` | `HighlightFieldInfo[]` | `undefined` | Fields to highlight and display in sidepanel |
|
|
638
|
+
| `auto_highlight_enabled` | `boolean` | `true` | Enable/disable auto-highlighting feature |
|
|
639
|
+
| `auto_highlight_options` | `HighlightOptions` | From config | Custom highlight styling |
|
|
640
|
+
| `auto_highlight_search_options` | `Partial<TextSearchOptions>` | From config | Custom search behavior |
|
|
641
|
+
|
|
642
|
+
### Advanced: Custom Text Search
|
|
643
|
+
|
|
644
|
+
For advanced use cases, you can use the text search utility directly:
|
|
645
|
+
|
|
646
|
+
```tsx
|
|
647
|
+
import { find_text_in_pdf, type TextSearchOptions } from 'hazo_pdf';
|
|
648
|
+
|
|
649
|
+
const search_result = await find_text_in_pdf(pdf_document, 'Invoice #12345', {
|
|
650
|
+
page_index: 0,
|
|
651
|
+
normalize: true,
|
|
652
|
+
padding_x: 10,
|
|
653
|
+
padding_y: 5,
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
if (search_result) {
|
|
657
|
+
console.log('Found at:', search_result.x, search_result.y);
|
|
658
|
+
console.log('Match type:', search_result.match_type); // 'exact' | 'partial'
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
---
|
|
663
|
+
|
|
519
664
|
## Programmatic Highlight API
|
|
520
665
|
|
|
521
|
-
The PDF viewer exposes a ref-based API for programmatically creating, removing, and managing highlights. This
|
|
666
|
+
The PDF viewer also exposes a ref-based API for programmatically creating, removing, and managing highlights. This is useful when you need manual control over highlights or want to create highlights from coordinates.
|
|
667
|
+
|
|
668
|
+
**Note**: For most use cases, the [Auto-Highlighting](#auto-highlighting) feature is recommended as it's simpler and requires less code.
|
|
522
669
|
|
|
523
670
|
### Basic Usage
|
|
524
671
|
|
|
@@ -615,6 +615,51 @@ toolbar_show_metadata_button = false
|
|
|
615
615
|
# Default: 36 (0.5 inch)
|
|
616
616
|
# margin = 36
|
|
617
617
|
|
|
618
|
+
# =============================================================================
|
|
619
|
+
# [auto_highlight] - Auto-highlighting configuration
|
|
620
|
+
# =============================================================================
|
|
621
|
+
[auto_highlight]
|
|
622
|
+
|
|
623
|
+
# Border color for auto-created highlights (hex format: #RRGGBB)
|
|
624
|
+
# Color of the highlight border when using auto-highlighting feature
|
|
625
|
+
# Default: "#FF6B00" (orange)
|
|
626
|
+
# auto_highlight_border_color = #FF6B00
|
|
627
|
+
|
|
628
|
+
# Background color for auto-created highlights (hex format: #RRGGBB)
|
|
629
|
+
# Fill color inside the highlight box
|
|
630
|
+
# Default: "#FFF3E0" (light orange)
|
|
631
|
+
# auto_highlight_background_color = #FFF3E0
|
|
632
|
+
|
|
633
|
+
# Background opacity for auto-created highlights (0.0 to 1.0)
|
|
634
|
+
# Transparency level of the highlight background
|
|
635
|
+
# Default: 0.3
|
|
636
|
+
# auto_highlight_background_opacity = 0.3
|
|
637
|
+
|
|
638
|
+
# Border width for auto-created highlights in pixels
|
|
639
|
+
# Thickness of the highlight border
|
|
640
|
+
# Default: 1
|
|
641
|
+
# auto_highlight_border_width = 1
|
|
642
|
+
|
|
643
|
+
# Whether to normalize text during search (true/false)
|
|
644
|
+
# When enabled, removes commas and spaces from text before matching
|
|
645
|
+
# Default: true
|
|
646
|
+
# auto_highlight_normalize_text = true
|
|
647
|
+
|
|
648
|
+
# Horizontal padding around highlighted text (in PDF units)
|
|
649
|
+
# Extra space to add on left/right sides of the text box
|
|
650
|
+
# Default: 2
|
|
651
|
+
# auto_highlight_padding_x = 2
|
|
652
|
+
|
|
653
|
+
# Vertical padding around highlighted text (in PDF units)
|
|
654
|
+
# Extra space to add on top/bottom of the text box
|
|
655
|
+
# Default: 1
|
|
656
|
+
# auto_highlight_padding_y = 1
|
|
657
|
+
|
|
658
|
+
# Y-axis offset to adjust highlight position (in PDF units)
|
|
659
|
+
# Negative values move highlight down, positive values move up
|
|
660
|
+
# Default: -3
|
|
661
|
+
# auto_highlight_y_offset = -3
|
|
662
|
+
|
|
618
663
|
# =============================================================================
|
|
619
664
|
# [file_button] - File manager button configuration
|
|
620
665
|
# =============================================================================
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
__require
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=chunk-AOSHQP7D.js.map
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
-
}) : x)(function(x) {
|
|
5
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
-
});
|
|
8
2
|
|
|
9
3
|
// src/config/default_config.ts
|
|
10
4
|
var default_config = {
|
|
@@ -137,6 +131,16 @@ var default_config = {
|
|
|
137
131
|
image_fit: "fit",
|
|
138
132
|
margin: 36
|
|
139
133
|
},
|
|
134
|
+
auto_highlight: {
|
|
135
|
+
auto_highlight_border_color: "#FF6B00",
|
|
136
|
+
auto_highlight_background_color: "#FFF3E0",
|
|
137
|
+
auto_highlight_background_opacity: 0.3,
|
|
138
|
+
auto_highlight_border_width: 1,
|
|
139
|
+
auto_highlight_normalize_text: true,
|
|
140
|
+
auto_highlight_padding_x: 2,
|
|
141
|
+
auto_highlight_padding_y: 1,
|
|
142
|
+
auto_highlight_y_offset: -3
|
|
143
|
+
},
|
|
140
144
|
file_button: {
|
|
141
145
|
icon_size: 24,
|
|
142
146
|
icon_color: "#6b7280",
|
|
@@ -148,7 +152,6 @@ var default_config = {
|
|
|
148
152
|
};
|
|
149
153
|
|
|
150
154
|
export {
|
|
151
|
-
__require,
|
|
152
155
|
default_config
|
|
153
156
|
};
|
|
154
|
-
//# sourceMappingURL=chunk-
|
|
157
|
+
//# sourceMappingURL=chunk-CXHR3TT6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/default_config.ts"],"sourcesContent":["/**\n * Default configuration values for hazo_pdf\n * All styling defaults organized by category\n */\n\nimport type { PdfViewerConfig } from '../types/config';\n\n/**\n * Default PDF Viewer Configuration\n * These values are used when no config file is provided or when values are missing\n */\nexport const default_config: PdfViewerConfig = {\n fonts: {\n freetext_font_family: 'Arial, sans-serif',\n freetext_font_size_min: 12,\n freetext_font_size_max: 24,\n freetext_font_size_default: 14,\n font_foreground_color: '#000000', // Black by default\n },\n\n highlight_annotation: {\n highlight_fill_color: '#FFFF00',\n highlight_fill_opacity: 0.3,\n highlight_border_color: '#FFD700',\n highlight_border_color_hover: '#FFD700',\n highlight_fill_opacity_hover: 0.4,\n },\n\n square_annotation: {\n square_fill_color: '#FF0000',\n square_fill_opacity: 0.2,\n square_border_color: '#FF0000',\n square_border_color_hover: '#CC0000',\n square_fill_opacity_hover: 0.3,\n },\n\n freetext_annotation: {\n freetext_text_color: '#000000',\n freetext_text_color_hover: '#000000',\n freetext_border_color: '#003366',\n freetext_border_width: 1,\n freetext_background_color: '#E6F3FF',\n freetext_background_opacity: 0.1,\n freetext_font_weight: 'normal',\n freetext_font_style: 'normal',\n freetext_text_decoration: 'none',\n freetext_padding_horizontal: 4,\n freetext_padding_vertical: 2,\n },\n\n page_styling: {\n page_border_color: '#999999',\n page_box_shadow: '0 2px 8px rgba(0, 0, 0, 0.3)',\n page_background_color: '#ffffff',\n },\n\n viewer: {\n viewer_background_color: '#2d2d2d',\n append_timestamp_to_text_edits: false,\n annotation_text_suffix_fixed_text: '',\n add_enclosing_brackets_to_suffixes: true,\n suffix_enclosing_brackets: '[]',\n suffix_text_position: 'below_multi_line',\n },\n\n context_menu: {\n context_menu_background_color: '#ffffff',\n context_menu_border_color: '#d1d5db',\n context_menu_item_hover_background: '#f3f4f6',\n context_menu_item_disabled_opacity: 0.5,\n right_click_custom_stamps: '', // Empty string means no custom stamps\n },\n\n dialog: {\n dialog_backdrop_opacity: 0.2,\n dialog_background_color: '#ffffff',\n dialog_border_color: '#d1d5db',\n dialog_button_submit_color: '#16a34a',\n dialog_button_submit_color_hover: '#15803d',\n dialog_button_cancel_color: '#6b7280',\n dialog_button_cancel_color_hover: '#4b5563',\n dialog_button_disabled_opacity: 0.4,\n },\n\n toolbar: {\n toolbar_background_color: '#f9fafb',\n toolbar_border_color: '#e5e7eb',\n toolbar_font_family: 'system-ui, -apple-system, sans-serif',\n toolbar_font_size: 14,\n toolbar_font_color: '#111827',\n toolbar_button_background_color: '#ffffff',\n toolbar_button_background_color_hover: '#f3f4f6',\n toolbar_button_text_color: '#374151',\n toolbar_button_active_background_color: '#3b82f6',\n toolbar_button_active_text_color: '#ffffff',\n toolbar_button_save_background_color: '#10b981',\n toolbar_button_save_background_color_hover: '#059669',\n toolbar_button_save_text_color: '#ffffff',\n toolbar_button_disabled_opacity: 0.5,\n toolbar_show_zoom_controls: true,\n toolbar_show_rotation_controls: true,\n toolbar_show_square_button: true,\n toolbar_show_undo_button: true,\n toolbar_show_redo_button: true,\n toolbar_show_save_button: true,\n toolbar_show_metadata_button: true,\n toolbar_show_annotate_button: true,\n toolbar_show_file_info_button: true,\n toolbar_show_extract_button: true,\n toolbar_zoom_out_label: '−',\n toolbar_zoom_in_label: '+',\n toolbar_zoom_reset_label: 'Reset',\n toolbar_square_label: 'Square',\n toolbar_undo_label: 'Undo',\n toolbar_redo_label: 'Redo',\n toolbar_save_label: 'Save',\n toolbar_saving_label: 'Saving...',\n toolbar_metadata_label: 'Metadata',\n },\n\n file_manager: {\n file_manager_enabled: false,\n show_file_list: true,\n allow_delete: true,\n show_popout_button: true,\n file_list_height: 60,\n selected_color: '#3b82f6',\n file_list_background_color: '#f9fafb',\n file_list_border_color: '#e5e7eb',\n },\n\n file_upload: {\n upload_enabled: true,\n allowed_types: 'application/pdf,image/jpeg,image/png,image/gif,image/webp,text/plain,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel',\n max_file_size: 10485760, // 10MB\n max_files: 10,\n show_add_button: true,\n dropzone_border_color: '#d1d5db',\n dropzone_border_color_active: '#3b82f6',\n dropzone_background_color: '#f9fafb',\n },\n\n pdf_conversion: {\n conversion_enabled: true,\n page_size: 'letter',\n image_quality: 0.85,\n image_fit: 'fit',\n margin: 36,\n },\n\n file_button: {\n icon_size: 24,\n icon_color: '#6b7280',\n icon_color_hover: '#374151',\n icon_color_with_files: '#3b82f6',\n badge_background: '#3b82f6',\n badge_text_color: '#ffffff',\n },\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/config/default_config.ts"],"sourcesContent":["/**\n * Default configuration values for hazo_pdf\n * All styling defaults organized by category\n */\n\nimport type { PdfViewerConfig } from '../types/config';\n\n/**\n * Default PDF Viewer Configuration\n * These values are used when no config file is provided or when values are missing\n */\nexport const default_config: PdfViewerConfig = {\n fonts: {\n freetext_font_family: 'Arial, sans-serif',\n freetext_font_size_min: 12,\n freetext_font_size_max: 24,\n freetext_font_size_default: 14,\n font_foreground_color: '#000000', // Black by default\n },\n\n highlight_annotation: {\n highlight_fill_color: '#FFFF00',\n highlight_fill_opacity: 0.3,\n highlight_border_color: '#FFD700',\n highlight_border_color_hover: '#FFD700',\n highlight_fill_opacity_hover: 0.4,\n },\n\n square_annotation: {\n square_fill_color: '#FF0000',\n square_fill_opacity: 0.2,\n square_border_color: '#FF0000',\n square_border_color_hover: '#CC0000',\n square_fill_opacity_hover: 0.3,\n },\n\n freetext_annotation: {\n freetext_text_color: '#000000',\n freetext_text_color_hover: '#000000',\n freetext_border_color: '#003366',\n freetext_border_width: 1,\n freetext_background_color: '#E6F3FF',\n freetext_background_opacity: 0.1,\n freetext_font_weight: 'normal',\n freetext_font_style: 'normal',\n freetext_text_decoration: 'none',\n freetext_padding_horizontal: 4,\n freetext_padding_vertical: 2,\n },\n\n page_styling: {\n page_border_color: '#999999',\n page_box_shadow: '0 2px 8px rgba(0, 0, 0, 0.3)',\n page_background_color: '#ffffff',\n },\n\n viewer: {\n viewer_background_color: '#2d2d2d',\n append_timestamp_to_text_edits: false,\n annotation_text_suffix_fixed_text: '',\n add_enclosing_brackets_to_suffixes: true,\n suffix_enclosing_brackets: '[]',\n suffix_text_position: 'below_multi_line',\n },\n\n context_menu: {\n context_menu_background_color: '#ffffff',\n context_menu_border_color: '#d1d5db',\n context_menu_item_hover_background: '#f3f4f6',\n context_menu_item_disabled_opacity: 0.5,\n right_click_custom_stamps: '', // Empty string means no custom stamps\n },\n\n dialog: {\n dialog_backdrop_opacity: 0.2,\n dialog_background_color: '#ffffff',\n dialog_border_color: '#d1d5db',\n dialog_button_submit_color: '#16a34a',\n dialog_button_submit_color_hover: '#15803d',\n dialog_button_cancel_color: '#6b7280',\n dialog_button_cancel_color_hover: '#4b5563',\n dialog_button_disabled_opacity: 0.4,\n },\n\n toolbar: {\n toolbar_background_color: '#f9fafb',\n toolbar_border_color: '#e5e7eb',\n toolbar_font_family: 'system-ui, -apple-system, sans-serif',\n toolbar_font_size: 14,\n toolbar_font_color: '#111827',\n toolbar_button_background_color: '#ffffff',\n toolbar_button_background_color_hover: '#f3f4f6',\n toolbar_button_text_color: '#374151',\n toolbar_button_active_background_color: '#3b82f6',\n toolbar_button_active_text_color: '#ffffff',\n toolbar_button_save_background_color: '#10b981',\n toolbar_button_save_background_color_hover: '#059669',\n toolbar_button_save_text_color: '#ffffff',\n toolbar_button_disabled_opacity: 0.5,\n toolbar_show_zoom_controls: true,\n toolbar_show_rotation_controls: true,\n toolbar_show_square_button: true,\n toolbar_show_undo_button: true,\n toolbar_show_redo_button: true,\n toolbar_show_save_button: true,\n toolbar_show_metadata_button: true,\n toolbar_show_annotate_button: true,\n toolbar_show_file_info_button: true,\n toolbar_show_extract_button: true,\n toolbar_zoom_out_label: '−',\n toolbar_zoom_in_label: '+',\n toolbar_zoom_reset_label: 'Reset',\n toolbar_square_label: 'Square',\n toolbar_undo_label: 'Undo',\n toolbar_redo_label: 'Redo',\n toolbar_save_label: 'Save',\n toolbar_saving_label: 'Saving...',\n toolbar_metadata_label: 'Metadata',\n },\n\n file_manager: {\n file_manager_enabled: false,\n show_file_list: true,\n allow_delete: true,\n show_popout_button: true,\n file_list_height: 60,\n selected_color: '#3b82f6',\n file_list_background_color: '#f9fafb',\n file_list_border_color: '#e5e7eb',\n },\n\n file_upload: {\n upload_enabled: true,\n allowed_types: 'application/pdf,image/jpeg,image/png,image/gif,image/webp,text/plain,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel',\n max_file_size: 10485760, // 10MB\n max_files: 10,\n show_add_button: true,\n dropzone_border_color: '#d1d5db',\n dropzone_border_color_active: '#3b82f6',\n dropzone_background_color: '#f9fafb',\n },\n\n pdf_conversion: {\n conversion_enabled: true,\n page_size: 'letter',\n image_quality: 0.85,\n image_fit: 'fit',\n margin: 36,\n },\n\n auto_highlight: {\n auto_highlight_border_color: '#FF6B00',\n auto_highlight_background_color: '#FFF3E0',\n auto_highlight_background_opacity: 0.3,\n auto_highlight_border_width: 1,\n auto_highlight_normalize_text: true,\n auto_highlight_padding_x: 2,\n auto_highlight_padding_y: 1,\n auto_highlight_y_offset: -3,\n },\n\n file_button: {\n icon_size: 24,\n icon_color: '#6b7280',\n icon_color_hover: '#374151',\n icon_color_with_files: '#3b82f6',\n badge_background: '#3b82f6',\n badge_text_color: '#ffffff',\n },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
|
-
__require,
|
|
4
3
|
default_config
|
|
5
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CXHR3TT6.js";
|
|
5
|
+
import {
|
|
6
|
+
__require
|
|
7
|
+
} from "./chunk-AOSHQP7D.js";
|
|
6
8
|
|
|
7
9
|
// src/components/pdf_viewer/pdf_viewer.tsx
|
|
8
10
|
import { useState as useState13, useEffect as useEffect10, useRef as useRef11, useCallback as useCallback4, forwardRef, useImperativeHandle } from "react";
|
|
@@ -2790,6 +2792,40 @@ function build_config_from_ini(get_value) {
|
|
|
2790
2792
|
default_config.pdf_conversion.margin
|
|
2791
2793
|
)
|
|
2792
2794
|
},
|
|
2795
|
+
auto_highlight: {
|
|
2796
|
+
auto_highlight_border_color: parse_color(
|
|
2797
|
+
get_value("auto_highlight", "auto_highlight_border_color"),
|
|
2798
|
+
default_config.auto_highlight.auto_highlight_border_color
|
|
2799
|
+
),
|
|
2800
|
+
auto_highlight_background_color: parse_color(
|
|
2801
|
+
get_value("auto_highlight", "auto_highlight_background_color"),
|
|
2802
|
+
default_config.auto_highlight.auto_highlight_background_color
|
|
2803
|
+
),
|
|
2804
|
+
auto_highlight_background_opacity: parse_opacity(
|
|
2805
|
+
get_value("auto_highlight", "auto_highlight_background_opacity"),
|
|
2806
|
+
default_config.auto_highlight.auto_highlight_background_opacity
|
|
2807
|
+
),
|
|
2808
|
+
auto_highlight_border_width: parse_number(
|
|
2809
|
+
get_value("auto_highlight", "auto_highlight_border_width"),
|
|
2810
|
+
default_config.auto_highlight.auto_highlight_border_width
|
|
2811
|
+
),
|
|
2812
|
+
auto_highlight_normalize_text: parse_boolean(
|
|
2813
|
+
get_value("auto_highlight", "auto_highlight_normalize_text"),
|
|
2814
|
+
default_config.auto_highlight.auto_highlight_normalize_text
|
|
2815
|
+
),
|
|
2816
|
+
auto_highlight_padding_x: parse_number(
|
|
2817
|
+
get_value("auto_highlight", "auto_highlight_padding_x"),
|
|
2818
|
+
default_config.auto_highlight.auto_highlight_padding_x
|
|
2819
|
+
),
|
|
2820
|
+
auto_highlight_padding_y: parse_number(
|
|
2821
|
+
get_value("auto_highlight", "auto_highlight_padding_y"),
|
|
2822
|
+
default_config.auto_highlight.auto_highlight_padding_y
|
|
2823
|
+
),
|
|
2824
|
+
auto_highlight_y_offset: parse_number(
|
|
2825
|
+
get_value("auto_highlight", "auto_highlight_y_offset"),
|
|
2826
|
+
default_config.auto_highlight.auto_highlight_y_offset
|
|
2827
|
+
)
|
|
2828
|
+
},
|
|
2793
2829
|
file_button: {
|
|
2794
2830
|
icon_size: parse_number(
|
|
2795
2831
|
get_value("file_button", "icon_size"),
|
|
@@ -4434,7 +4470,11 @@ var PdfViewer = forwardRef(({
|
|
|
4434
4470
|
save_path,
|
|
4435
4471
|
// File info sidepanel data props
|
|
4436
4472
|
doc_data,
|
|
4437
|
-
highlight_fields_info
|
|
4473
|
+
highlight_fields_info,
|
|
4474
|
+
// Auto-highlight props
|
|
4475
|
+
auto_highlight_enabled,
|
|
4476
|
+
auto_highlight_options,
|
|
4477
|
+
auto_highlight_search_options
|
|
4438
4478
|
}, ref) => {
|
|
4439
4479
|
const [pdf_document, setPdfDocument] = useState13(null);
|
|
4440
4480
|
const [loading, setLoading] = useState13(true);
|
|
@@ -4451,6 +4491,7 @@ var PdfViewer = forwardRef(({
|
|
|
4451
4491
|
const [file_info_sidepanel_open, setFileInfoSidepanelOpen] = useState13(false);
|
|
4452
4492
|
const [file_info_sidepanel_width, setFileInfoSidepanelWidth] = useState13(300);
|
|
4453
4493
|
const [hazo_files_available, setHazoFilesAvailable] = useState13(null);
|
|
4494
|
+
const [auto_highlight_ids, setAutoHighlightIds] = useState13(/* @__PURE__ */ new Set());
|
|
4454
4495
|
const [page_rotations, setPageRotations] = useState13(/* @__PURE__ */ new Map());
|
|
4455
4496
|
const [current_visible_page, setCurrentVisiblePage] = useState13(0);
|
|
4456
4497
|
const [current_file, setCurrentFile] = useState13(
|
|
@@ -5099,6 +5140,107 @@ ${suffix_line}`;
|
|
|
5099
5140
|
console.error("PdfViewer: Failed to popout:", err);
|
|
5100
5141
|
}
|
|
5101
5142
|
}, [files, current_file, viewer_title, on_popout, popout_route]);
|
|
5143
|
+
useEffect10(() => {
|
|
5144
|
+
const should_auto_highlight = auto_highlight_enabled !== false && // Default true
|
|
5145
|
+
highlight_fields_info && highlight_fields_info.length > 0 && pdf_document;
|
|
5146
|
+
if (!should_auto_highlight) {
|
|
5147
|
+
return;
|
|
5148
|
+
}
|
|
5149
|
+
const logger2 = get_logger();
|
|
5150
|
+
auto_highlight_ids.forEach((id) => {
|
|
5151
|
+
const annotation = annotations.find((a) => a.id === id);
|
|
5152
|
+
if (annotation) {
|
|
5153
|
+
handle_annotation_delete(id);
|
|
5154
|
+
}
|
|
5155
|
+
});
|
|
5156
|
+
setAutoHighlightIds(/* @__PURE__ */ new Set());
|
|
5157
|
+
const perform_auto_highlights = async () => {
|
|
5158
|
+
const { find_text_in_pdf } = await import("./text_search-GW2VYMU6.js");
|
|
5159
|
+
const new_ids = /* @__PURE__ */ new Set();
|
|
5160
|
+
const auto_config = config_ref.current?.auto_highlight || default_config.auto_highlight;
|
|
5161
|
+
const search_opts = {
|
|
5162
|
+
normalize: auto_config.auto_highlight_normalize_text,
|
|
5163
|
+
padding_x: auto_config.auto_highlight_padding_x,
|
|
5164
|
+
padding_y: auto_config.auto_highlight_padding_y,
|
|
5165
|
+
y_offset: auto_config.auto_highlight_y_offset,
|
|
5166
|
+
...auto_highlight_search_options
|
|
5167
|
+
};
|
|
5168
|
+
const highlight_opts = auto_highlight_options || {
|
|
5169
|
+
border_color: auto_config.auto_highlight_border_color,
|
|
5170
|
+
background_color: auto_config.auto_highlight_background_color,
|
|
5171
|
+
background_opacity: auto_config.auto_highlight_background_opacity,
|
|
5172
|
+
border_width: auto_config.auto_highlight_border_width
|
|
5173
|
+
};
|
|
5174
|
+
for (const field of highlight_fields_info) {
|
|
5175
|
+
try {
|
|
5176
|
+
const page_idx = field.page_index ?? 0;
|
|
5177
|
+
const result = await find_text_in_pdf(pdf_document, field.value, {
|
|
5178
|
+
page_index: page_idx,
|
|
5179
|
+
...search_opts
|
|
5180
|
+
});
|
|
5181
|
+
if (result) {
|
|
5182
|
+
logger2.debug("[AutoHighlight] Found text", {
|
|
5183
|
+
field: field.field_name,
|
|
5184
|
+
value: field.value,
|
|
5185
|
+
match_type: result.match_type,
|
|
5186
|
+
position: { x: result.x, y: result.y }
|
|
5187
|
+
});
|
|
5188
|
+
const rect = [
|
|
5189
|
+
result.x,
|
|
5190
|
+
result.y,
|
|
5191
|
+
result.x + result.width,
|
|
5192
|
+
result.y + result.height
|
|
5193
|
+
];
|
|
5194
|
+
const highlight_config = config_ref.current?.highlight_annotation || default_config.highlight_annotation;
|
|
5195
|
+
const annotation = {
|
|
5196
|
+
id: `auto_highlight_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
5197
|
+
type: "Highlight",
|
|
5198
|
+
page_index: page_idx,
|
|
5199
|
+
rect,
|
|
5200
|
+
author: "AutoHighlight",
|
|
5201
|
+
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5202
|
+
contents: field.field_name,
|
|
5203
|
+
// Store field name in contents
|
|
5204
|
+
color: highlight_opts.background_color || highlight_config.highlight_fill_color,
|
|
5205
|
+
flags: "api_highlight"
|
|
5206
|
+
// Marker to identify API-created highlights
|
|
5207
|
+
};
|
|
5208
|
+
annotation.subject = JSON.stringify({
|
|
5209
|
+
border_color: highlight_opts.border_color,
|
|
5210
|
+
background_color: highlight_opts.background_color,
|
|
5211
|
+
background_opacity: highlight_opts.background_opacity,
|
|
5212
|
+
border_width: highlight_opts.border_width
|
|
5213
|
+
});
|
|
5214
|
+
handle_annotation_create(annotation);
|
|
5215
|
+
new_ids.add(annotation.id);
|
|
5216
|
+
} else {
|
|
5217
|
+
logger2.warn("[AutoHighlight] Text not found in PDF", {
|
|
5218
|
+
field: field.field_name,
|
|
5219
|
+
value: field.value,
|
|
5220
|
+
page: page_idx
|
|
5221
|
+
});
|
|
5222
|
+
}
|
|
5223
|
+
} catch (err) {
|
|
5224
|
+
logger2.error("[AutoHighlight] Search failed", {
|
|
5225
|
+
field: field.field_name,
|
|
5226
|
+
error: err instanceof Error ? err.message : String(err)
|
|
5227
|
+
});
|
|
5228
|
+
}
|
|
5229
|
+
}
|
|
5230
|
+
setAutoHighlightIds(new_ids);
|
|
5231
|
+
};
|
|
5232
|
+
perform_auto_highlights();
|
|
5233
|
+
}, [pdf_document, highlight_fields_info, auto_highlight_enabled]);
|
|
5234
|
+
useEffect10(() => {
|
|
5235
|
+
return () => {
|
|
5236
|
+
auto_highlight_ids.forEach((id) => {
|
|
5237
|
+
const annotation = annotations.find((a) => a.id === id);
|
|
5238
|
+
if (annotation) {
|
|
5239
|
+
handle_annotation_delete(id);
|
|
5240
|
+
}
|
|
5241
|
+
});
|
|
5242
|
+
};
|
|
5243
|
+
}, []);
|
|
5102
5244
|
const has_changes_to_save = annotations.length > 0 || page_rotations.size > 0;
|
|
5103
5245
|
const handle_save = async () => {
|
|
5104
5246
|
if (!has_changes_to_save) {
|
|
@@ -5115,7 +5257,7 @@ ${suffix_line}`;
|
|
|
5115
5257
|
const original_filename = is_multi_file_mode && current_file ? current_file.name : effective_url.split("/").pop() || "document.pdf";
|
|
5116
5258
|
const filename_without_ext = original_filename.replace(/\.pdf$/i, "");
|
|
5117
5259
|
const output_filename = `${filename_without_ext}_annotated.pdf`;
|
|
5118
|
-
const { save_annotations_to_pdf, download_pdf } = await import("./pdf_saver-
|
|
5260
|
+
const { save_annotations_to_pdf, download_pdf } = await import("./pdf_saver-JXAIRQVL.js");
|
|
5119
5261
|
const pdf_source = cached_pdf_data || effective_url;
|
|
5120
5262
|
logger2.debug("[PdfViewer] Saving PDF", { source_type: cached_pdf_data ? "cached ArrayBuffer" : "URL" });
|
|
5121
5263
|
const pdf_bytes = await save_annotations_to_pdf(pdf_source, annotations, output_filename, config_ref.current, page_rotations);
|
|
@@ -5995,4 +6137,4 @@ export {
|
|
|
5995
6137
|
PdfViewer,
|
|
5996
6138
|
pdf_viewer_default
|
|
5997
6139
|
};
|
|
5998
|
-
//# sourceMappingURL=chunk-
|
|
6140
|
+
//# sourceMappingURL=chunk-FMZPXAJT.js.map
|