@aquera/ngx-smart-table 0.0.2-alpha
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 +152 -0
- package/aquera-ngx-smart-table.d.ts +5 -0
- package/esm2020/aquera-ngx-smart-table.mjs +5 -0
- package/esm2020/lib/builder/components/builder-preview/builder-preview.component.mjs +63 -0
- package/esm2020/lib/builder/components/builder-toolbar/builder-toolbar.component.mjs +115 -0
- package/esm2020/lib/builder/components/column-editor/column-editor.component.mjs +206 -0
- package/esm2020/lib/builder/components/column-list/column-list.component.mjs +125 -0
- package/esm2020/lib/builder/components/definition-builder/definition-builder.component.mjs +105 -0
- package/esm2020/lib/builder/components/table-config-editor/table-config-editor.component.mjs +132 -0
- package/esm2020/lib/builder/definition-builder.module.mjs +70 -0
- package/esm2020/lib/builder/models/builder-state.interface.mjs +5 -0
- package/esm2020/lib/builder/services/definition-builder.service.mjs +251 -0
- package/esm2020/lib/builder/services/definition-export.service.mjs +167 -0
- package/esm2020/lib/builder/services/definition-import.service.mjs +193 -0
- package/esm2020/lib/builder/services/sample-data-generator.service.mjs +126 -0
- package/esm2020/lib/builder/utils/config-validator.util.mjs +165 -0
- package/esm2020/lib/builder/utils/typescript-generator.util.mjs +206 -0
- package/esm2020/lib/editors/index.mjs +9 -0
- package/esm2020/lib/editors/nile-autocomplete-editor.mjs +228 -0
- package/esm2020/lib/editors/nile-calendar-editor.mjs +214 -0
- package/esm2020/lib/editors/nile-date-picker-editor.mjs +227 -0
- package/esm2020/lib/editors/nile-input-editor.mjs +235 -0
- package/esm2020/lib/editors/nile-select-editor.mjs +317 -0
- package/esm2020/lib/factories/column-config.factory.mjs +231 -0
- package/esm2020/lib/models/autosave-config.interface.mjs +8 -0
- package/esm2020/lib/models/base-column-config.class.mjs +253 -0
- package/esm2020/lib/models/cell-strategies.interface.mjs +6 -0
- package/esm2020/lib/models/cell-types.mjs +147 -0
- package/esm2020/lib/models/column-action.interface.mjs +6 -0
- package/esm2020/lib/models/column-config.interface.mjs +43 -0
- package/esm2020/lib/models/column-config.utils.mjs +101 -0
- package/esm2020/lib/models/row-action.interface.mjs +5 -0
- package/esm2020/lib/models/row-validator.interface.mjs +2 -0
- package/esm2020/lib/models/schema-validation.interface.mjs +2 -0
- package/esm2020/lib/models/sheet-action.interface.mjs +5 -0
- package/esm2020/lib/models/sheet-config.interface.mjs +5 -0
- package/esm2020/lib/models/table-config.interface.mjs +106 -0
- package/esm2020/lib/models/table-validator.interface.mjs +2 -0
- package/esm2020/lib/models/workbook-action.interface.mjs +5 -0
- package/esm2020/lib/models/workbook-config.interface.mjs +5 -0
- package/esm2020/lib/renderer/components/st-add-column-button/st-add-column-button.component.mjs +24 -0
- package/esm2020/lib/renderer/components/st-cell/st-cell.component.mjs +391 -0
- package/esm2020/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.mjs +103 -0
- package/esm2020/lib/renderer/components/st-column-filter/st-column-filter.component.mjs +383 -0
- package/esm2020/lib/renderer/components/st-column-menu/st-column-menu.component.mjs +232 -0
- package/esm2020/lib/renderer/components/st-column-visibility/st-column-visibility.component.mjs +97 -0
- package/esm2020/lib/renderer/components/st-header/st-header.component.mjs +157 -0
- package/esm2020/lib/renderer/components/st-pagination/st-pagination.component.mjs +87 -0
- package/esm2020/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.mjs +167 -0
- package/esm2020/lib/renderer/components/st-sheet/st-sheet.component.mjs +165 -0
- package/esm2020/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.mjs +112 -0
- package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +1246 -0
- package/esm2020/lib/renderer/components/st-table-actions/st-table-actions.component.mjs +171 -0
- package/esm2020/lib/renderer/components/st-workbook/st-workbook.component.mjs +489 -0
- package/esm2020/lib/renderer/directives/click-outside.directive.mjs +28 -0
- package/esm2020/lib/renderer/directives/st-column-resize.directive.mjs +108 -0
- package/esm2020/lib/renderer/directives/st-keyboard-navigation.directive.mjs +73 -0
- package/esm2020/lib/renderer/models/cell-state.interface.mjs +66 -0
- package/esm2020/lib/renderer/models/cell.class.mjs +389 -0
- package/esm2020/lib/renderer/models/row-validation-state.interface.mjs +7 -0
- package/esm2020/lib/renderer/models/sheet-state.class.mjs +90 -0
- package/esm2020/lib/renderer/models/sheet-state.interface.mjs +5 -0
- package/esm2020/lib/renderer/models/table-state.class.mjs +841 -0
- package/esm2020/lib/renderer/models/table-state.interface.mjs +5 -0
- package/esm2020/lib/renderer/models/table-types.mjs +29 -0
- package/esm2020/lib/renderer/models/table-validation-state.interface.mjs +7 -0
- package/esm2020/lib/renderer/models/workbook-state.class.mjs +174 -0
- package/esm2020/lib/renderer/models/workbook-state.interface.mjs +5 -0
- package/esm2020/lib/renderer/models/z-index.enum.mjs +55 -0
- package/esm2020/lib/schemas/table-config.schema.mjs +472 -0
- package/esm2020/lib/services/autosave.service.mjs +92 -0
- package/esm2020/lib/services/custom-validation-rules.util.mjs +124 -0
- package/esm2020/lib/services/json-schema-validator.service.mjs +216 -0
- package/esm2020/lib/services/row-validation.service.mjs +42 -0
- package/esm2020/lib/services/validation-logger.service.mjs +177 -0
- package/esm2020/lib/services/virtual-scroll.service.mjs +52 -0
- package/esm2020/lib/shared/shared-table-components.module.mjs +35 -0
- package/esm2020/lib/smart-table.module.mjs +124 -0
- package/esm2020/lib/strategies/default-editors.mjs +433 -0
- package/esm2020/lib/strategies/default-formatters.mjs +238 -0
- package/esm2020/lib/strategies/default-validators.mjs +327 -0
- package/esm2020/public-api.mjs +146 -0
- package/fesm2015/aquera-ngx-smart-table.mjs +11860 -0
- package/fesm2015/aquera-ngx-smart-table.mjs.map +1 -0
- package/fesm2020/aquera-ngx-smart-table.mjs +11897 -0
- package/fesm2020/aquera-ngx-smart-table.mjs.map +1 -0
- package/lib/builder/components/builder-preview/builder-preview.component.d.ts +31 -0
- package/lib/builder/components/builder-toolbar/builder-toolbar.component.d.ts +53 -0
- package/lib/builder/components/column-editor/column-editor.component.d.ts +69 -0
- package/lib/builder/components/column-list/column-list.component.d.ts +65 -0
- package/lib/builder/components/definition-builder/definition-builder.component.d.ts +58 -0
- package/lib/builder/components/table-config-editor/table-config-editor.component.d.ts +32 -0
- package/lib/builder/definition-builder.module.d.ts +15 -0
- package/lib/builder/models/builder-state.interface.d.ts +93 -0
- package/lib/builder/services/definition-builder.service.d.ts +80 -0
- package/lib/builder/services/definition-export.service.d.ts +59 -0
- package/lib/builder/services/definition-import.service.d.ts +31 -0
- package/lib/builder/services/sample-data-generator.service.d.ts +41 -0
- package/lib/builder/utils/config-validator.util.d.ts +32 -0
- package/lib/builder/utils/typescript-generator.util.d.ts +29 -0
- package/lib/editors/index.d.ts +8 -0
- package/lib/editors/nile-autocomplete-editor.d.ts +102 -0
- package/lib/editors/nile-calendar-editor.d.ts +89 -0
- package/lib/editors/nile-date-picker-editor.d.ts +95 -0
- package/lib/editors/nile-input-editor.d.ts +67 -0
- package/lib/editors/nile-select-editor.d.ts +109 -0
- package/lib/factories/column-config.factory.d.ts +73 -0
- package/lib/models/autosave-config.interface.d.ts +23 -0
- package/lib/models/base-column-config.class.d.ts +115 -0
- package/lib/models/cell-strategies.interface.d.ts +181 -0
- package/lib/models/cell-types.d.ts +337 -0
- package/lib/models/column-action.interface.d.ts +86 -0
- package/lib/models/column-config.interface.d.ts +272 -0
- package/lib/models/column-config.utils.d.ts +37 -0
- package/lib/models/row-action.interface.d.ts +86 -0
- package/lib/models/row-validator.interface.d.ts +37 -0
- package/lib/models/schema-validation.interface.d.ts +42 -0
- package/lib/models/sheet-action.interface.d.ts +59 -0
- package/lib/models/sheet-config.interface.d.ts +41 -0
- package/lib/models/table-config.interface.d.ts +245 -0
- package/lib/models/table-validator.interface.d.ts +40 -0
- package/lib/models/workbook-action.interface.d.ts +90 -0
- package/lib/models/workbook-config.interface.d.ts +107 -0
- package/lib/renderer/components/st-add-column-button/st-add-column-button.component.d.ts +9 -0
- package/lib/renderer/components/st-cell/st-cell.component.d.ts +69 -0
- package/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.d.ts +39 -0
- package/lib/renderer/components/st-column-filter/st-column-filter.component.d.ts +139 -0
- package/lib/renderer/components/st-column-menu/st-column-menu.component.d.ts +81 -0
- package/lib/renderer/components/st-column-visibility/st-column-visibility.component.d.ts +44 -0
- package/lib/renderer/components/st-header/st-header.component.d.ts +93 -0
- package/lib/renderer/components/st-pagination/st-pagination.component.d.ts +42 -0
- package/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.d.ts +67 -0
- package/lib/renderer/components/st-sheet/st-sheet.component.d.ts +98 -0
- package/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.d.ts +58 -0
- package/lib/renderer/components/st-table/st-table.component.d.ts +349 -0
- package/lib/renderer/components/st-table-actions/st-table-actions.component.d.ts +77 -0
- package/lib/renderer/components/st-workbook/st-workbook.component.d.ts +235 -0
- package/lib/renderer/directives/click-outside.directive.d.ts +10 -0
- package/lib/renderer/directives/st-column-resize.directive.d.ts +44 -0
- package/lib/renderer/directives/st-keyboard-navigation.directive.d.ts +15 -0
- package/lib/renderer/models/cell-state.interface.d.ts +118 -0
- package/lib/renderer/models/cell.class.d.ts +174 -0
- package/lib/renderer/models/row-validation-state.interface.d.ts +27 -0
- package/lib/renderer/models/sheet-state.class.d.ts +67 -0
- package/lib/renderer/models/sheet-state.interface.d.ts +55 -0
- package/lib/renderer/models/table-state.class.d.ts +313 -0
- package/lib/renderer/models/table-state.interface.d.ts +18 -0
- package/lib/renderer/models/table-types.d.ts +228 -0
- package/lib/renderer/models/table-validation-state.interface.d.ts +34 -0
- package/lib/renderer/models/workbook-state.class.d.ts +117 -0
- package/lib/renderer/models/workbook-state.interface.d.ts +71 -0
- package/lib/renderer/models/z-index.enum.d.ts +44 -0
- package/lib/schemas/table-config.schema.d.ts +455 -0
- package/lib/services/autosave.service.d.ts +73 -0
- package/lib/services/custom-validation-rules.util.d.ts +12 -0
- package/lib/services/json-schema-validator.service.d.ts +49 -0
- package/lib/services/row-validation.service.d.ts +17 -0
- package/lib/services/validation-logger.service.d.ts +87 -0
- package/lib/services/virtual-scroll.service.d.ts +44 -0
- package/lib/shared/shared-table-components.module.d.ts +9 -0
- package/lib/smart-table.module.d.ts +26 -0
- package/lib/strategies/default-editors.d.ts +109 -0
- package/lib/strategies/default-formatters.d.ts +116 -0
- package/lib/strategies/default-validators.d.ts +113 -0
- package/package.json +42 -0
- package/public-api.d.ts +70 -0
- package/src/lib/builder/README.md +30 -0
- package/src/lib/editors/README.md +303 -0
- package/src/lib/renderer/components/st-column-filter/README.md +286 -0
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# NgxSmartTable
|
|
2
|
+
|
|
3
|
+
A powerful, feature-rich Angular smart table library with inline editing, validation, sorting, pagination, filtering, sticky columns, keyboard navigation, and more.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Inline Cell Editing** - Click to edit with multiple editor types
|
|
8
|
+
- ✅ **Column-Level Filtering** - Multiple operators and custom dropdown filters
|
|
9
|
+
- ✅ **Sorting & Pagination** - Server-side and client-side support
|
|
10
|
+
- ✅ **Sticky/Pinned Columns** - Pin columns left or right with user controls
|
|
11
|
+
- ✅ **Column Management** - Resize, reorder, show/hide, and pin columns
|
|
12
|
+
- ✅ **Keyboard Navigation** - Excel-like arrow key navigation and editing
|
|
13
|
+
- ✅ **Virtual Scrolling** - Handle millions of rows efficiently
|
|
14
|
+
- ✅ **Configuration Builder** - Visual UI for building table configurations
|
|
15
|
+
- ✅ **Type-Safe** - Full TypeScript support with comprehensive interfaces
|
|
16
|
+
- ✅ **Reactive** - Event-driven architecture with RxJS
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @your-org/ngx-smart-table
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { Component } from '@angular/core';
|
|
28
|
+
import { TableConfig } from '@your-org/ngx-smart-table';
|
|
29
|
+
|
|
30
|
+
@Component({
|
|
31
|
+
selector: 'app-my-table',
|
|
32
|
+
template: `
|
|
33
|
+
<st-table [config]="tableConfig" [data]="data"></st-table>
|
|
34
|
+
`
|
|
35
|
+
})
|
|
36
|
+
export class MyTableComponent {
|
|
37
|
+
tableConfig: TableConfig = {
|
|
38
|
+
columns: [
|
|
39
|
+
{ key: 'id', header: 'ID', width: 80 },
|
|
40
|
+
{ key: 'name', header: 'Name', sortable: true, filterable: true },
|
|
41
|
+
{ key: 'email', header: 'Email', filterable: true }
|
|
42
|
+
],
|
|
43
|
+
pagination: { enabled: true, pageSize: 25 },
|
|
44
|
+
sorting: { enabled: true, mode: 'server' },
|
|
45
|
+
features: {
|
|
46
|
+
keyboardNavigation: { enabled: true }
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
data = [
|
|
51
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com' },
|
|
52
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Documentation
|
|
58
|
+
|
|
59
|
+
For complete documentation, see the [documentation folder](../../docs/README.md):
|
|
60
|
+
|
|
61
|
+
- [Column Configuration Guide](../../docs/COLUMN_CONFIG.md) - All column properties and features
|
|
62
|
+
- [Table Configuration Guide](../../docs/TABLE_CONFIG.md) - Table-level settings
|
|
63
|
+
- [Keyboard Navigation Guide](../../docs/KEYBOARD_NAVIGATION.md) - Excel-like navigation
|
|
64
|
+
- [Architecture Overview](../../docs/ARCHITECTURE.md) - System design and patterns
|
|
65
|
+
|
|
66
|
+
## Column Configuration
|
|
67
|
+
|
|
68
|
+
### New Features
|
|
69
|
+
|
|
70
|
+
- **`movable`**: Control if column can be reordered (default: `true`)
|
|
71
|
+
- **`pinnable`**: Control if column can be pinned/unpinned (default: `true`)
|
|
72
|
+
- **`enableMenu`**: Control if column menu button appears (default: `true`)
|
|
73
|
+
|
|
74
|
+
### Example
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const columns = [
|
|
78
|
+
{
|
|
79
|
+
key: 'id',
|
|
80
|
+
header: 'ID',
|
|
81
|
+
width: 80,
|
|
82
|
+
sticky: 'left', // Pin to left
|
|
83
|
+
movable: false, // Cannot reorder
|
|
84
|
+
pinnable: false, // Cannot unpin
|
|
85
|
+
enableMenu: false // No menu button
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: 'name',
|
|
89
|
+
header: 'Name',
|
|
90
|
+
sortable: true,
|
|
91
|
+
filterable: true,
|
|
92
|
+
movable: true, // Can reorder
|
|
93
|
+
pinnable: true // Can pin/unpin
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
key: 'actions',
|
|
97
|
+
header: 'Actions',
|
|
98
|
+
width: 100,
|
|
99
|
+
sticky: 'right', // Pin to right
|
|
100
|
+
sortable: false,
|
|
101
|
+
enableMenu: false
|
|
102
|
+
}
|
|
103
|
+
];
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Keyboard Navigation
|
|
107
|
+
|
|
108
|
+
Enable Excel-like keyboard navigation:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
{
|
|
112
|
+
features: {
|
|
113
|
+
keyboardNavigation: {
|
|
114
|
+
enabled: true
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Keyboard Shortcuts:**
|
|
121
|
+
- Arrow keys: Navigate cells
|
|
122
|
+
- Tab/Shift+Tab: Move between cells
|
|
123
|
+
- Enter: Edit/save and move down
|
|
124
|
+
- Escape: Cancel editing
|
|
125
|
+
- Alphanumeric keys: Start editing
|
|
126
|
+
|
|
127
|
+
## Column Menu
|
|
128
|
+
|
|
129
|
+
The column menu (⋮) provides quick access to:
|
|
130
|
+
- Sort ascending/descending
|
|
131
|
+
- Clear sort
|
|
132
|
+
- Filter (with multiple operators)
|
|
133
|
+
- Pin left/right
|
|
134
|
+
- Unpin
|
|
135
|
+
- Move left/right
|
|
136
|
+
|
|
137
|
+
Menu options automatically show/hide based on column configuration.
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
MIT
|
|
142
|
+
|
|
143
|
+
## Links
|
|
144
|
+
|
|
145
|
+
- [GitHub Repository](https://github.com/your-org/ngx-smart-table)
|
|
146
|
+
- [Documentation](../../docs/README.md)
|
|
147
|
+
- [Demo Application](../../projects/demo)
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
**Built with ❤️ using Angular and TypeScript**
|
|
152
|
+
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXF1ZXJhLW5neC1zbWFydC10YWJsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9hcXVlcmEtbmd4LXNtYXJ0LXRhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG4iXX0=
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builder Preview Component
|
|
3
|
+
* Live preview of table using st-table component
|
|
4
|
+
*/
|
|
5
|
+
import { Component, Input } from '@angular/core';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "../../services/sample-data-generator.service";
|
|
8
|
+
import * as i2 from "../../../renderer/components/st-table/st-table.component";
|
|
9
|
+
import * as i3 from "@angular/common";
|
|
10
|
+
export class BuilderPreviewComponent {
|
|
11
|
+
constructor(sampleDataGenerator) {
|
|
12
|
+
this.sampleDataGenerator = sampleDataGenerator;
|
|
13
|
+
this.sampleData = [];
|
|
14
|
+
this.isLoading = false;
|
|
15
|
+
}
|
|
16
|
+
ngOnInit() {
|
|
17
|
+
this.generatePreviewData();
|
|
18
|
+
}
|
|
19
|
+
ngOnChanges(changes) {
|
|
20
|
+
if (changes['tableConfig'] && !changes['tableConfig'].firstChange) {
|
|
21
|
+
this.generatePreviewData();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generate sample data for preview
|
|
26
|
+
*/
|
|
27
|
+
generatePreviewData() {
|
|
28
|
+
if (!this.tableConfig || !this.tableConfig?.columns || this.tableConfig?.columns.length === 0) {
|
|
29
|
+
this.sampleData = [];
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this.isLoading = true;
|
|
33
|
+
// Generate sample data based on columns
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
this.sampleData = this.sampleDataGenerator.generateSampleData(this.tableConfig.columns, 5 // Generate 5 sample rows
|
|
36
|
+
);
|
|
37
|
+
this.isLoading = false;
|
|
38
|
+
}, 100);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Refresh preview
|
|
42
|
+
*/
|
|
43
|
+
refreshPreview() {
|
|
44
|
+
this.generatePreviewData();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Handle state change from preview table
|
|
48
|
+
*/
|
|
49
|
+
onStateChange(event) {
|
|
50
|
+
// Preview is read-only, so we don't need to handle state changes
|
|
51
|
+
// But we can log them for debugging
|
|
52
|
+
console.log('Preview state change:', event);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
BuilderPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BuilderPreviewComponent, deps: [{ token: i1.SampleDataGeneratorService }], target: i0.ɵɵFactoryTarget.Component });
|
|
56
|
+
BuilderPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: BuilderPreviewComponent, selector: "st-builder-preview", inputs: { tableConfig: "tableConfig" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"builder-preview\">\n <div class=\"preview-header\">\n <h3>Live Preview</h3>\n <button class=\"refresh-btn\" (click)=\"refreshPreview()\" title=\"Refresh Preview\">\n \u21BB Refresh\n </button>\n </div>\n\n <div class=\"preview-content\">\n <div *ngIf=\"isLoading\" class=\"loading\">\n <p>Generating preview...</p>\n </div>\n\n <div *ngIf=\"!isLoading && tableConfig?.columns?.length === 0\" class=\"empty-state\">\n <p>Add columns to see preview</p>\n </div>\n <ng-container *ngIf=\"tableConfig\">\n <st-table\n *ngIf=\"!isLoading && tableConfig!.columns!.length > 0\"\n [tableConfig]=\"tableConfig\"\n [data]=\"sampleData\"\n (stateChange)=\"onStateChange($event)\">\n </st-table>\n </ng-container>\n\n </div>\n</div>\n\n", styles: [".builder-preview{height:100%}.preview-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.preview-header h3{margin:0;font-size:1rem;font-weight:600;color:#333}.refresh-btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.refresh-btn:hover{background-color:#f5f5f5}.preview-content{overflow:auto}.loading,.empty-state{display:flex;align-items:center;justify-content:center;height:200px;color:#999;font-size:.875rem}\n"], components: [{ type: i2.StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
57
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BuilderPreviewComponent, decorators: [{
|
|
58
|
+
type: Component,
|
|
59
|
+
args: [{ selector: 'st-builder-preview', template: "<div class=\"builder-preview\">\n <div class=\"preview-header\">\n <h3>Live Preview</h3>\n <button class=\"refresh-btn\" (click)=\"refreshPreview()\" title=\"Refresh Preview\">\n \u21BB Refresh\n </button>\n </div>\n\n <div class=\"preview-content\">\n <div *ngIf=\"isLoading\" class=\"loading\">\n <p>Generating preview...</p>\n </div>\n\n <div *ngIf=\"!isLoading && tableConfig?.columns?.length === 0\" class=\"empty-state\">\n <p>Add columns to see preview</p>\n </div>\n <ng-container *ngIf=\"tableConfig\">\n <st-table\n *ngIf=\"!isLoading && tableConfig!.columns!.length > 0\"\n [tableConfig]=\"tableConfig\"\n [data]=\"sampleData\"\n (stateChange)=\"onStateChange($event)\">\n </st-table>\n </ng-container>\n\n </div>\n</div>\n\n", styles: [".builder-preview{height:100%}.preview-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.preview-header h3{margin:0;font-size:1rem;font-weight:600;color:#333}.refresh-btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.refresh-btn:hover{background-color:#f5f5f5}.preview-content{overflow:auto}.loading,.empty-state{display:flex;align-items:center;justify-content:center;height:200px;color:#999;font-size:.875rem}\n"] }]
|
|
60
|
+
}], ctorParameters: function () { return [{ type: i1.SampleDataGeneratorService }]; }, propDecorators: { tableConfig: [{
|
|
61
|
+
type: Input
|
|
62
|
+
}] } });
|
|
63
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci1wcmV2aWV3LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvYnVpbGRlci9jb21wb25lbnRzL2J1aWxkZXItcHJldmlldy9idWlsZGVyLXByZXZpZXcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtdGFibGUvc3JjL2xpYi9idWlsZGVyL2NvbXBvbmVudHMvYnVpbGRlci1wcmV2aWV3L2J1aWxkZXItcHJldmlldy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBb0MsTUFBTSxlQUFlLENBQUM7Ozs7O0FBU25GLE1BQU0sT0FBTyx1QkFBdUI7SUFNbEMsWUFDVSxtQkFBK0M7UUFBL0Msd0JBQW1CLEdBQW5CLG1CQUFtQixDQUE0QjtRQUp6RCxlQUFVLEdBQVUsRUFBRSxDQUFDO1FBQ3ZCLGNBQVMsR0FBRyxLQUFLLENBQUM7SUFJZixDQUFDO0lBRUosUUFBUTtRQUNOLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxPQUFPLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUMsV0FBVyxFQUFFO1lBQ2pFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1NBQzVCO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssbUJBQW1CO1FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUM3RixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztZQUNyQixPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUV0Qix3Q0FBd0M7UUFDeEMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGtCQUFrQixDQUMzRCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFDeEIsQ0FBQyxDQUFDLHlCQUF5QjthQUM1QixDQUFDO1lBQ0YsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDekIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsQ0FBQztJQUVEOztPQUVHO0lBQ0gsY0FBYztRQUNaLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRDs7T0FFRztJQUNILGFBQWEsQ0FBQyxLQUFVO1FBQ3RCLGlFQUFpRTtRQUNqRSxvQ0FBb0M7UUFDcEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM5QyxDQUFDOztvSEF2RFUsdUJBQXVCO3dHQUF2Qix1QkFBdUIsdUhDZHBDLHN6QkE0QkE7MkZEZGEsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLG9CQUFvQjtpSEFLckIsV0FBVztzQkFBbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQnVpbGRlciBQcmV2aWV3IENvbXBvbmVudFxuICogTGl2ZSBwcmV2aWV3IG9mIHRhYmxlIHVzaW5nIHN0LXRhYmxlIGNvbXBvbmVudFxuICovXG5cbmltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUYWJsZUNvbmZpZyB9IGZyb20gJy4uLy4uLy4uL21vZGVscy90YWJsZS1jb25maWcuaW50ZXJmYWNlJztcbmltcG9ydCB7IFNhbXBsZURhdGFHZW5lcmF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvc2FtcGxlLWRhdGEtZ2VuZXJhdG9yLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzdC1idWlsZGVyLXByZXZpZXcnLFxuICB0ZW1wbGF0ZVVybDogJy4vYnVpbGRlci1wcmV2aWV3LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYnVpbGRlci1wcmV2aWV3LmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQnVpbGRlclByZXZpZXdDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIHRhYmxlQ29uZmlnITogVGFibGVDb25maWc7XG5cbiAgc2FtcGxlRGF0YTogYW55W10gPSBbXTtcbiAgaXNMb2FkaW5nID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzYW1wbGVEYXRhR2VuZXJhdG9yOiBTYW1wbGVEYXRhR2VuZXJhdG9yU2VydmljZSxcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZ2VuZXJhdGVQcmV2aWV3RGF0YSgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWyd0YWJsZUNvbmZpZyddICYmICFjaGFuZ2VzWyd0YWJsZUNvbmZpZyddLmZpcnN0Q2hhbmdlKSB7XG4gICAgICB0aGlzLmdlbmVyYXRlUHJldmlld0RhdGEoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgc2FtcGxlIGRhdGEgZm9yIHByZXZpZXdcbiAgICovXG4gIHByaXZhdGUgZ2VuZXJhdGVQcmV2aWV3RGF0YSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudGFibGVDb25maWcgfHwgIXRoaXMudGFibGVDb25maWc/LmNvbHVtbnMgfHwgdGhpcy50YWJsZUNvbmZpZz8uY29sdW1ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuc2FtcGxlRGF0YSA9IFtdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcbiAgICBcbiAgICAvLyBHZW5lcmF0ZSBzYW1wbGUgZGF0YSBiYXNlZCBvbiBjb2x1bW5zXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnNhbXBsZURhdGEgPSB0aGlzLnNhbXBsZURhdGFHZW5lcmF0b3IuZ2VuZXJhdGVTYW1wbGVEYXRhKFxuICAgICAgICB0aGlzLnRhYmxlQ29uZmlnLmNvbHVtbnMsXG4gICAgICAgIDUgLy8gR2VuZXJhdGUgNSBzYW1wbGUgcm93c1xuICAgICAgKTtcbiAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgfSwgMTAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZyZXNoIHByZXZpZXdcbiAgICovXG4gIHJlZnJlc2hQcmV2aWV3KCk6IHZvaWQge1xuICAgIHRoaXMuZ2VuZXJhdGVQcmV2aWV3RGF0YSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBzdGF0ZSBjaGFuZ2UgZnJvbSBwcmV2aWV3IHRhYmxlXG4gICAqL1xuICBvblN0YXRlQ2hhbmdlKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICAvLyBQcmV2aWV3IGlzIHJlYWQtb25seSwgc28gd2UgZG9uJ3QgbmVlZCB0byBoYW5kbGUgc3RhdGUgY2hhbmdlc1xuICAgIC8vIEJ1dCB3ZSBjYW4gbG9nIHRoZW0gZm9yIGRlYnVnZ2luZ1xuICAgIGNvbnNvbGUubG9nKCdQcmV2aWV3IHN0YXRlIGNoYW5nZTonLCBldmVudCk7XG4gIH1cbn1cblxuIiwiPGRpdiBjbGFzcz1cImJ1aWxkZXItcHJldmlld1wiPlxuICA8ZGl2IGNsYXNzPVwicHJldmlldy1oZWFkZXJcIj5cbiAgICA8aDM+TGl2ZSBQcmV2aWV3PC9oMz5cbiAgICA8YnV0dG9uIGNsYXNzPVwicmVmcmVzaC1idG5cIiAoY2xpY2spPVwicmVmcmVzaFByZXZpZXcoKVwiIHRpdGxlPVwiUmVmcmVzaCBQcmV2aWV3XCI+XG4gICAgICDihrsgUmVmcmVzaFxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwicHJldmlldy1jb250ZW50XCI+XG4gICAgPGRpdiAqbmdJZj1cImlzTG9hZGluZ1wiIGNsYXNzPVwibG9hZGluZ1wiPlxuICAgICAgPHA+R2VuZXJhdGluZyBwcmV2aWV3Li4uPC9wPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdJZj1cIiFpc0xvYWRpbmcgJiYgdGFibGVDb25maWc/LmNvbHVtbnM/Lmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwiZW1wdHktc3RhdGVcIj5cbiAgICAgIDxwPkFkZCBjb2x1bW5zIHRvIHNlZSBwcmV2aWV3PC9wPlxuICAgIDwvZGl2PlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0YWJsZUNvbmZpZ1wiPlxuICAgICAgPHN0LXRhYmxlXG4gICAgICAgICpuZ0lmPVwiIWlzTG9hZGluZyAmJiB0YWJsZUNvbmZpZyEuY29sdW1ucyEubGVuZ3RoID4gMFwiXG4gICAgICAgIFt0YWJsZUNvbmZpZ109XCJ0YWJsZUNvbmZpZ1wiXG4gICAgICAgIFtkYXRhXT1cInNhbXBsZURhdGFcIlxuICAgICAgICAoc3RhdGVDaGFuZ2UpPVwib25TdGF0ZUNoYW5nZSgkZXZlbnQpXCI+XG4gICAgICA8L3N0LXRhYmxlPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gIDwvZGl2PlxuPC9kaXY+XG5cbiJdfQ==
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builder Toolbar Component
|
|
3
|
+
* Handles file operations and actions
|
|
4
|
+
*/
|
|
5
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "../../services/definition-builder.service";
|
|
8
|
+
import * as i2 from "../../services/definition-export.service";
|
|
9
|
+
import * as i3 from "../../services/definition-import.service";
|
|
10
|
+
import * as i4 from "@angular/common";
|
|
11
|
+
export class BuilderToolbarComponent {
|
|
12
|
+
constructor(builderService, exportService, importService) {
|
|
13
|
+
this.builderService = builderService;
|
|
14
|
+
this.exportService = exportService;
|
|
15
|
+
this.importService = importService;
|
|
16
|
+
this.hasUnsavedChanges = false;
|
|
17
|
+
this.newDefinition = new EventEmitter();
|
|
18
|
+
this.saved = new EventEmitter();
|
|
19
|
+
this.previewToggled = new EventEmitter();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Handle new definition button click
|
|
23
|
+
*/
|
|
24
|
+
onNewDefinition() {
|
|
25
|
+
this.newDefinition.emit();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Handle open file button click
|
|
29
|
+
*/
|
|
30
|
+
onOpenFile() {
|
|
31
|
+
const input = document.createElement('input');
|
|
32
|
+
input.type = 'file';
|
|
33
|
+
input.accept = '.json';
|
|
34
|
+
input.onchange = (event) => {
|
|
35
|
+
const file = event.target.files[0];
|
|
36
|
+
if (file) {
|
|
37
|
+
this.importService.importFromFile(file).then(result => {
|
|
38
|
+
if (result.success && result.tableConfig) {
|
|
39
|
+
this.builderService.initialize(result.tableConfig);
|
|
40
|
+
this.saved.emit();
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
alert(`Failed to import: ${result.error}`);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
input.click();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Handle save button click
|
|
52
|
+
*/
|
|
53
|
+
onSave() {
|
|
54
|
+
const state = this.builderService.getState();
|
|
55
|
+
this.exportService.saveToLocalStorage(state.tableConfig);
|
|
56
|
+
this.saved.emit();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Handle load from localStorage button click
|
|
60
|
+
*/
|
|
61
|
+
onLoad() {
|
|
62
|
+
const config = this.exportService.loadFromLocalStorage();
|
|
63
|
+
if (config) {
|
|
64
|
+
this.builderService.initialize(config);
|
|
65
|
+
this.saved.emit();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
alert('No saved configuration found');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Handle export JSON button click
|
|
73
|
+
*/
|
|
74
|
+
onExportJSON() {
|
|
75
|
+
const state = this.builderService.getState();
|
|
76
|
+
this.exportService.downloadAsJSON(state.tableConfig);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Handle export TypeScript button click
|
|
80
|
+
*/
|
|
81
|
+
onExportTypeScript() {
|
|
82
|
+
const state = this.builderService.getState();
|
|
83
|
+
this.exportService.downloadAsTypeScript(state.tableConfig, 'table-config', {
|
|
84
|
+
includeComments: true,
|
|
85
|
+
variableName: 'tableConfig'
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Handle import JSON button click
|
|
90
|
+
*/
|
|
91
|
+
onImportJSON() {
|
|
92
|
+
this.onOpenFile();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Handle preview toggle button click
|
|
96
|
+
*/
|
|
97
|
+
onTogglePreview() {
|
|
98
|
+
this.previewToggled.emit();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
BuilderToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BuilderToolbarComponent, deps: [{ token: i1.DefinitionBuilderService }, { token: i2.DefinitionExportService }, { token: i3.DefinitionImportService }], target: i0.ɵɵFactoryTarget.Component });
|
|
102
|
+
BuilderToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: BuilderToolbarComponent, selector: "st-builder-toolbar", inputs: { hasUnsavedChanges: "hasUnsavedChanges" }, outputs: { newDefinition: "newDefinition", saved: "saved", previewToggled: "previewToggled" }, ngImport: i0, template: "<div class=\"builder-toolbar\">\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onNewDefinition()\" title=\"New Definition\">\n <span>New</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onOpenFile()\" title=\"Open File\">\n <span>Open</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onSave()\" title=\"Save to LocalStorage\" [class.has-changes]=\"hasUnsavedChanges\">\n <span>Save</span>\n <span *ngIf=\"hasUnsavedChanges\" class=\"unsaved-indicator\">\u25CF</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onLoad()\" title=\"Load from LocalStorage\">\n <span>Load</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onImportJSON()\" title=\"Import JSON\">\n <span>Import JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportJSON()\" title=\"Export JSON\">\n <span>Export JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportTypeScript()\" title=\"Export TypeScript\">\n <span>Export TS</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onTogglePreview()\" title=\"Toggle Preview\">\n <span>Preview</span>\n </button>\n </div>\n</div>\n\n", styles: [".builder-toolbar{display:flex;align-items:center;gap:1rem;padding:.75rem 1rem;background-color:#fff;border-bottom:1px solid #e0e0e0;box-shadow:0 2px 4px #0000000d}.toolbar-section{display:flex;align-items:center;gap:.5rem}.toolbar-section:not(:last-child):after{content:\"\";width:1px;height:24px;background-color:#e0e0e0;margin-left:.5rem}.toolbar-btn{display:flex;align-items:center;gap:.25rem;padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.toolbar-btn:hover{background-color:#f5f5f5;border-color:#b0b0b0}.toolbar-btn:active{background-color:#e8e8e8}.toolbar-btn.has-changes{border-color:#ff9800;background-color:#fff3e0}.toolbar-btn .unsaved-indicator{color:#ff9800;font-size:.75rem;margin-left:.25rem}\n"], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
103
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BuilderToolbarComponent, decorators: [{
|
|
104
|
+
type: Component,
|
|
105
|
+
args: [{ selector: 'st-builder-toolbar', template: "<div class=\"builder-toolbar\">\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onNewDefinition()\" title=\"New Definition\">\n <span>New</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onOpenFile()\" title=\"Open File\">\n <span>Open</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onSave()\" title=\"Save to LocalStorage\" [class.has-changes]=\"hasUnsavedChanges\">\n <span>Save</span>\n <span *ngIf=\"hasUnsavedChanges\" class=\"unsaved-indicator\">\u25CF</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onLoad()\" title=\"Load from LocalStorage\">\n <span>Load</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onImportJSON()\" title=\"Import JSON\">\n <span>Import JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportJSON()\" title=\"Export JSON\">\n <span>Export JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportTypeScript()\" title=\"Export TypeScript\">\n <span>Export TS</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onTogglePreview()\" title=\"Toggle Preview\">\n <span>Preview</span>\n </button>\n </div>\n</div>\n\n", styles: [".builder-toolbar{display:flex;align-items:center;gap:1rem;padding:.75rem 1rem;background-color:#fff;border-bottom:1px solid #e0e0e0;box-shadow:0 2px 4px #0000000d}.toolbar-section{display:flex;align-items:center;gap:.5rem}.toolbar-section:not(:last-child):after{content:\"\";width:1px;height:24px;background-color:#e0e0e0;margin-left:.5rem}.toolbar-btn{display:flex;align-items:center;gap:.25rem;padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.toolbar-btn:hover{background-color:#f5f5f5;border-color:#b0b0b0}.toolbar-btn:active{background-color:#e8e8e8}.toolbar-btn.has-changes{border-color:#ff9800;background-color:#fff3e0}.toolbar-btn .unsaved-indicator{color:#ff9800;font-size:.75rem;margin-left:.25rem}\n"] }]
|
|
106
|
+
}], ctorParameters: function () { return [{ type: i1.DefinitionBuilderService }, { type: i2.DefinitionExportService }, { type: i3.DefinitionImportService }]; }, propDecorators: { hasUnsavedChanges: [{
|
|
107
|
+
type: Input
|
|
108
|
+
}], newDefinition: [{
|
|
109
|
+
type: Output
|
|
110
|
+
}], saved: [{
|
|
111
|
+
type: Output
|
|
112
|
+
}], previewToggled: [{
|
|
113
|
+
type: Output
|
|
114
|
+
}] } });
|
|
115
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci10b29sYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvYnVpbGRlci9jb21wb25lbnRzL2J1aWxkZXItdG9vbGJhci9idWlsZGVyLXRvb2xiYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtdGFibGUvc3JjL2xpYi9idWlsZGVyL2NvbXBvbmVudHMvYnVpbGRlci10b29sYmFyL2J1aWxkZXItdG9vbGJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7QUFVdkUsTUFBTSxPQUFPLHVCQUF1QjtJQU9sQyxZQUNVLGNBQXdDLEVBQ3hDLGFBQXNDLEVBQ3RDLGFBQXNDO1FBRnRDLG1CQUFjLEdBQWQsY0FBYyxDQUEwQjtRQUN4QyxrQkFBYSxHQUFiLGFBQWEsQ0FBeUI7UUFDdEMsa0JBQWEsR0FBYixhQUFhLENBQXlCO1FBVHZDLHNCQUFpQixHQUFZLEtBQUssQ0FBQztRQUVsQyxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDekMsVUFBSyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDakMsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0lBTWpELENBQUM7SUFFSjs7T0FFRztJQUNILGVBQWU7UUFDYixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRDs7T0FFRztJQUNILFVBQVU7UUFDUixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlDLEtBQUssQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDO1FBQ3BCLEtBQUssQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQyxLQUFVLEVBQUUsRUFBRTtZQUM5QixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuQyxJQUFJLElBQUksRUFBRTtnQkFDUixJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUU7b0JBQ3BELElBQUksTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFO3dCQUN4QyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7d0JBQ25ELElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7cUJBQ25CO3lCQUFNO3dCQUNMLEtBQUssQ0FBQyxxQkFBcUIsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7cUJBQzVDO2dCQUNILENBQUMsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLENBQUM7UUFDRixLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTTtRQUNKLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNO1FBQ0osTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQ3pELElBQUksTUFBTSxFQUFFO1lBQ1YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdkMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNuQjthQUFNO1lBQ0wsS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7U0FDdkM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUFZO1FBQ1YsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUM3QyxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsa0JBQWtCO1FBQ2hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLGNBQWMsRUFBRTtZQUN6RSxlQUFlLEVBQUUsSUFBSTtZQUNyQixZQUFZLEVBQUUsYUFBYTtTQUM1QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUFZO1FBQ1YsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFRDs7T0FFRztJQUNILGVBQWU7UUFDYixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzdCLENBQUM7O29IQWhHVSx1QkFBdUI7d0dBQXZCLHVCQUF1Qiw2TUNmcEMsODBDQW9DQTsyRkRyQmEsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLG9CQUFvQjsyTEFLckIsaUJBQWlCO3NCQUF6QixLQUFLO2dCQUVJLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csS0FBSztzQkFBZCxNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEJ1aWxkZXIgVG9vbGJhciBDb21wb25lbnRcbiAqIEhhbmRsZXMgZmlsZSBvcGVyYXRpb25zIGFuZCBhY3Rpb25zXG4gKi9cblxuaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERlZmluaXRpb25CdWlsZGVyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2RlZmluaXRpb24tYnVpbGRlci5zZXJ2aWNlJztcbmltcG9ydCB7IERlZmluaXRpb25FeHBvcnRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGVmaW5pdGlvbi1leHBvcnQuc2VydmljZSc7XG5pbXBvcnQgeyBEZWZpbml0aW9uSW1wb3J0U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2RlZmluaXRpb24taW1wb3J0LnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzdC1idWlsZGVyLXRvb2xiYXInLFxuICB0ZW1wbGF0ZVVybDogJy4vYnVpbGRlci10b29sYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYnVpbGRlci10b29sYmFyLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQnVpbGRlclRvb2xiYXJDb21wb25lbnQge1xuICBASW5wdXQoKSBoYXNVbnNhdmVkQ2hhbmdlczogYm9vbGVhbiA9IGZhbHNlO1xuICBcbiAgQE91dHB1dCgpIG5ld0RlZmluaXRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBzYXZlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIHByZXZpZXdUb2dnbGVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYnVpbGRlclNlcnZpY2U6IERlZmluaXRpb25CdWlsZGVyU2VydmljZSxcbiAgICBwcml2YXRlIGV4cG9ydFNlcnZpY2U6IERlZmluaXRpb25FeHBvcnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgaW1wb3J0U2VydmljZTogRGVmaW5pdGlvbkltcG9ydFNlcnZpY2VcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgbmV3IGRlZmluaXRpb24gYnV0dG9uIGNsaWNrXG4gICAqL1xuICBvbk5ld0RlZmluaXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5uZXdEZWZpbml0aW9uLmVtaXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgb3BlbiBmaWxlIGJ1dHRvbiBjbGlja1xuICAgKi9cbiAgb25PcGVuRmlsZSgpOiB2b2lkIHtcbiAgICBjb25zdCBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgaW5wdXQudHlwZSA9ICdmaWxlJztcbiAgICBpbnB1dC5hY2NlcHQgPSAnLmpzb24nO1xuICAgIGlucHV0Lm9uY2hhbmdlID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IGZpbGUgPSBldmVudC50YXJnZXQuZmlsZXNbMF07XG4gICAgICBpZiAoZmlsZSkge1xuICAgICAgICB0aGlzLmltcG9ydFNlcnZpY2UuaW1wb3J0RnJvbUZpbGUoZmlsZSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGlmIChyZXN1bHQuc3VjY2VzcyAmJiByZXN1bHQudGFibGVDb25maWcpIHtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRlclNlcnZpY2UuaW5pdGlhbGl6ZShyZXN1bHQudGFibGVDb25maWcpO1xuICAgICAgICAgICAgdGhpcy5zYXZlZC5lbWl0KCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFsZXJ0KGBGYWlsZWQgdG8gaW1wb3J0OiAke3Jlc3VsdC5lcnJvcn1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG4gICAgaW5wdXQuY2xpY2soKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgc2F2ZSBidXR0b24gY2xpY2tcbiAgICovXG4gIG9uU2F2ZSgpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuYnVpbGRlclNlcnZpY2UuZ2V0U3RhdGUoKTtcbiAgICB0aGlzLmV4cG9ydFNlcnZpY2Uuc2F2ZVRvTG9jYWxTdG9yYWdlKHN0YXRlLnRhYmxlQ29uZmlnKTtcbiAgICB0aGlzLnNhdmVkLmVtaXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgbG9hZCBmcm9tIGxvY2FsU3RvcmFnZSBidXR0b24gY2xpY2tcbiAgICovXG4gIG9uTG9hZCgpOiB2b2lkIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmV4cG9ydFNlcnZpY2UubG9hZEZyb21Mb2NhbFN0b3JhZ2UoKTtcbiAgICBpZiAoY29uZmlnKSB7XG4gICAgICB0aGlzLmJ1aWxkZXJTZXJ2aWNlLmluaXRpYWxpemUoY29uZmlnKTtcbiAgICAgIHRoaXMuc2F2ZWQuZW1pdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhbGVydCgnTm8gc2F2ZWQgY29uZmlndXJhdGlvbiBmb3VuZCcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgZXhwb3J0IEpTT04gYnV0dG9uIGNsaWNrXG4gICAqL1xuICBvbkV4cG9ydEpTT04oKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLmJ1aWxkZXJTZXJ2aWNlLmdldFN0YXRlKCk7XG4gICAgdGhpcy5leHBvcnRTZXJ2aWNlLmRvd25sb2FkQXNKU09OKHN0YXRlLnRhYmxlQ29uZmlnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgZXhwb3J0IFR5cGVTY3JpcHQgYnV0dG9uIGNsaWNrXG4gICAqL1xuICBvbkV4cG9ydFR5cGVTY3JpcHQoKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLmJ1aWxkZXJTZXJ2aWNlLmdldFN0YXRlKCk7XG4gICAgdGhpcy5leHBvcnRTZXJ2aWNlLmRvd25sb2FkQXNUeXBlU2NyaXB0KHN0YXRlLnRhYmxlQ29uZmlnLCAndGFibGUtY29uZmlnJywge1xuICAgICAgaW5jbHVkZUNvbW1lbnRzOiB0cnVlLFxuICAgICAgdmFyaWFibGVOYW1lOiAndGFibGVDb25maWcnXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGltcG9ydCBKU09OIGJ1dHRvbiBjbGlja1xuICAgKi9cbiAgb25JbXBvcnRKU09OKCk6IHZvaWQge1xuICAgIHRoaXMub25PcGVuRmlsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBwcmV2aWV3IHRvZ2dsZSBidXR0b24gY2xpY2tcbiAgICovXG4gIG9uVG9nZ2xlUHJldmlldygpOiB2b2lkIHtcbiAgICB0aGlzLnByZXZpZXdUb2dnbGVkLmVtaXQoKTtcbiAgfVxufVxuXG4iLCI8ZGl2IGNsYXNzPVwiYnVpbGRlci10b29sYmFyXCI+XG4gIDxkaXYgY2xhc3M9XCJ0b29sYmFyLXNlY3Rpb25cIj5cbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbGJhci1idG5cIiAoY2xpY2spPVwib25OZXdEZWZpbml0aW9uKClcIiB0aXRsZT1cIk5ldyBEZWZpbml0aW9uXCI+XG4gICAgICA8c3Bhbj5OZXc8L3NwYW4+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cInRvb2xiYXItYnRuXCIgKGNsaWNrKT1cIm9uT3BlbkZpbGUoKVwiIHRpdGxlPVwiT3BlbiBGaWxlXCI+XG4gICAgICA8c3Bhbj5PcGVuPC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gY2xhc3M9XCJ0b29sYmFyLWJ0blwiIChjbGljayk9XCJvblNhdmUoKVwiIHRpdGxlPVwiU2F2ZSB0byBMb2NhbFN0b3JhZ2VcIiBbY2xhc3MuaGFzLWNoYW5nZXNdPVwiaGFzVW5zYXZlZENoYW5nZXNcIj5cbiAgICAgIDxzcGFuPlNhdmU8L3NwYW4+XG4gICAgICA8c3BhbiAqbmdJZj1cImhhc1Vuc2F2ZWRDaGFuZ2VzXCIgY2xhc3M9XCJ1bnNhdmVkLWluZGljYXRvclwiPuKXjzwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbGJhci1idG5cIiAoY2xpY2spPVwib25Mb2FkKClcIiB0aXRsZT1cIkxvYWQgZnJvbSBMb2NhbFN0b3JhZ2VcIj5cbiAgICAgIDxzcGFuPkxvYWQ8L3NwYW4+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJ0b29sYmFyLXNlY3Rpb25cIj5cbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbGJhci1idG5cIiAoY2xpY2spPVwib25JbXBvcnRKU09OKClcIiB0aXRsZT1cIkltcG9ydCBKU09OXCI+XG4gICAgICA8c3Bhbj5JbXBvcnQgSlNPTjwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbGJhci1idG5cIiAoY2xpY2spPVwib25FeHBvcnRKU09OKClcIiB0aXRsZT1cIkV4cG9ydCBKU09OXCI+XG4gICAgICA8c3Bhbj5FeHBvcnQgSlNPTjwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbGJhci1idG5cIiAoY2xpY2spPVwib25FeHBvcnRUeXBlU2NyaXB0KClcIiB0aXRsZT1cIkV4cG9ydCBUeXBlU2NyaXB0XCI+XG4gICAgICA8c3Bhbj5FeHBvcnQgVFM8L3NwYW4+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJ0b29sYmFyLXNlY3Rpb25cIj5cbiAgICA8YnV0dG9uIGNsYXNzPVwidG9vbGJhci1idG5cIiAoY2xpY2spPVwib25Ub2dnbGVQcmV2aWV3KClcIiB0aXRsZT1cIlRvZ2dsZSBQcmV2aWV3XCI+XG4gICAgICA8c3Bhbj5QcmV2aWV3PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PlxuXG4iXX0=
|