@firestitch/report 18.18.1 → 18.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/app/reports/chart-axis-settings.d.ts +4 -0
  2. package/app/reports/components/report-component/report-component.component.d.ts +1 -0
  3. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +24 -0
  4. package/app/reports/dialogs/global-settings/global-settings.component.d.ts +2 -6
  5. package/app/reports/enums/report-chart-date-label.enum.d.ts +2 -1
  6. package/app/reports/enums/report-chart-span-mode.enum.d.ts +5 -0
  7. package/app/reports/enums/report-chart-span-through.enum.d.ts +3 -0
  8. package/app/reports/format.d.ts +1 -0
  9. package/app/reports/interfaces/report-chart-axis-settings.interface.d.ts +6 -0
  10. package/app/reports/interfaces/report-chart-span.interface.d.ts +6 -0
  11. package/app/reports/interfaces/report.interface.d.ts +5 -0
  12. package/esm2022/app/reports/chart-axis-settings.mjs +24 -0
  13. package/esm2022/app/reports/components/report-component/report-component.component.mjs +27 -4
  14. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +121 -16
  15. package/esm2022/app/reports/dialogs/global-settings/components/ai-knowledge/ai-knowledge.component.mjs +8 -6
  16. package/esm2022/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.mjs +3 -3
  17. package/esm2022/app/reports/dialogs/global-settings/global-settings.component.mjs +32 -51
  18. package/esm2022/app/reports/dialogs/instruction-history/instruction-history.component.mjs +5 -5
  19. package/esm2022/app/reports/enums/report-chart-date-label.enum.mjs +5 -2
  20. package/esm2022/app/reports/enums/report-chart-span-mode.enum.mjs +10 -0
  21. package/esm2022/app/reports/enums/report-chart-span-through.enum.mjs +11 -0
  22. package/esm2022/app/reports/format.mjs +3 -1
  23. package/esm2022/app/reports/interfaces/report-chart-axis-settings.interface.mjs +2 -0
  24. package/esm2022/app/reports/interfaces/report-chart-span.interface.mjs +2 -0
  25. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  26. package/esm2022/app/reports/option-builder.mjs +34 -10
  27. package/esm2022/public_api.mjs +4 -1
  28. package/fesm2022/{firestitch-report-echarts-DrTDdBIP.mjs → firestitch-report-echarts-WOx5HoDM.mjs} +2 -2
  29. package/fesm2022/{firestitch-report-echarts-DrTDdBIP.mjs.map → firestitch-report-echarts-WOx5HoDM.mjs.map} +1 -1
  30. package/fesm2022/{firestitch-report-firestitch-report-Bgr_IprU.mjs → firestitch-report-firestitch-report-DztXL6p8.mjs} +286 -136
  31. package/fesm2022/firestitch-report-firestitch-report-DztXL6p8.mjs.map +1 -0
  32. package/fesm2022/firestitch-report.mjs +1 -1
  33. package/package.json +1 -1
  34. package/public_api.d.ts +3 -0
  35. package/app/reports/dialogs/global-settings/components/general/general.component.d.ts +0 -8
  36. package/esm2022/app/reports/dialogs/global-settings/components/general/general.component.mjs +0 -34
  37. package/fesm2022/firestitch-report-firestitch-report-Bgr_IprU.mjs.map +0 -1
@@ -1,2 +1,2 @@
1
- export { c as FsAiReportComponent, F as FsAiReportsComponent, G as GRANULARITY_OPTIONS, r as ReportChangePolarity, n as ReportChartColor, m as ReportChartDataLabels, q as ReportChartDateLabel, o as ReportChartLineStyle, p as ReportChartMarkStat, d as ReportData, f as ReportFilterStateService, k as ReportListColumnFormat, g as ReportNodeType, l as ReportNumberUnits, e as ReportService, h as ReportState, i as ReportValueFormat, j as ReportValueFormula } from './firestitch-report-firestitch-report-Bgr_IprU.mjs';
1
+ export { c as FsAiReportComponent, F as FsAiReportsComponent, G as GRANULARITY_OPTIONS, s as ReportChangePolarity, n as ReportChartColor, m as ReportChartDataLabels, q as ReportChartDateLabel, o as ReportChartLineStyle, p as ReportChartMarkStat, r as ReportChartSpanThrough, d as ReportData, f as ReportFilterStateService, k as ReportListColumnFormat, g as ReportNodeType, l as ReportNumberUnits, e as ReportService, h as ReportState, i as ReportValueFormat, j as ReportValueFormula } from './firestitch-report-firestitch-report-DztXL6p8.mjs';
2
2
  //# sourceMappingURL=firestitch-report.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firestitch/report",
3
- "version": "18.18.1",
3
+ "version": "18.19.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/Firestitch/ngx-report"
package/public_api.d.ts CHANGED
@@ -7,6 +7,8 @@ export * from './app/reports/interfaces/report.interface';
7
7
  export * from './app/reports/interfaces/report-state-snapshot.interface';
8
8
  export * from './app/reports/interfaces/report-tile-state.interface';
9
9
  export * from './app/reports/interfaces/report-drill-step.interface';
10
+ export * from './app/reports/interfaces/report-chart-span.interface';
11
+ export * from './app/reports/interfaces/report-chart-axis-settings.interface';
10
12
  export * from './app/reports/interfaces/report-drill-crumb.interface';
11
13
  export * from './app/reports/interfaces/report-drill-refusal.type';
12
14
  export * from './app/reports/interfaces/report-filter-match.type';
@@ -37,4 +39,5 @@ export * from './app/reports/enums/report-chart-color.enum';
37
39
  export * from './app/reports/enums/report-chart-line-style.enum';
38
40
  export * from './app/reports/enums/report-chart-mark-stat.enum';
39
41
  export * from './app/reports/enums/report-chart-date-label.enum';
42
+ export * from './app/reports/enums/report-chart-span-through.enum';
40
43
  export * from './app/reports/enums/report-change-polarity.enum';
@@ -1,8 +0,0 @@
1
- import * as i0 from "@angular/core";
2
- export declare class GeneralComponent {
3
- readonly concurrency: import("@angular/core").ModelSignal<number>;
4
- readonly min: import("@angular/core").InputSignal<number>;
5
- readonly max: import("@angular/core").InputSignal<number>;
6
- static ɵfac: i0.ɵɵFactoryDeclaration<GeneralComponent, never>;
7
- static ɵcmp: i0.ɵɵComponentDeclaration<GeneralComponent, "fs-ai-report-global-settings-general", never, { "concurrency": { "alias": "concurrency"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": true; "isSignal": true; }; "max": { "alias": "max"; "required": true; "isSignal": true; }; }, { "concurrency": "concurrencyChange"; }, never, never, true, never>;
8
- }
@@ -1,34 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';
2
- import { ControlContainer, FormsModule, NgForm } from '@angular/forms';
3
- import { MatFormField, MatHint, MatLabel } from '@angular/material/form-field';
4
- import { MatInput } from '@angular/material/input';
5
- import { FsFormModule } from '@firestitch/form';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "@angular/forms";
8
- import * as i2 from "@firestitch/form";
9
- // The General tab: report-module settings that aren't the AI knowledge document.
10
- // Currently just the semantic-build concurrency — how many summary calls the
11
- // build runs at once. A field-level child of the settings dialog form (its input
12
- // registers with the parent <form fsForm> via the ControlContainer view
13
- // provider), so the dialog's Save button submits and validates it. The value
14
- // itself is held on the shell (bound through `concurrency`), and the safe band
15
- // (`min`/`max`) comes from the backend so the field can't be set out of range.
16
- export class GeneralComponent {
17
- concurrency = model(0);
18
- min = input.required();
19
- max = input.required();
20
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GeneralComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: GeneralComponent, isStandalone: true, selector: "fs-ai-report-global-settings-general", inputs: { concurrency: { classPropertyName: "concurrency", publicName: "concurrency", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: true, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { concurrency: "concurrencyChange" }, ngImport: i0, template: "<div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>Semantic build concurrency</mat-label>\n <input\n matInput\n type=\"number\"\n [ngModel]=\"concurrency()\"\n (ngModelChange)=\"concurrency.set($event)\"\n name=\"semanticBuildConcurrency\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"min()\"\n [fsFormMax]=\"max()\">\n <mat-hint>\n How many AI calls the semantic-database build runs at once ({{ min() }}\u2013{{ max() }}).\n Higher is faster but more likely to hit the AI provider's rate limit. Default is 8.\n </mat-hint>\n </mat-form-field>\n</div>\n", styles: [".tab-body{padding-top:16px}mat-form-field{display:block;max-width:340px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "directive", type: i2.FsFormMinDirective, selector: "[fsFormMin]", inputs: ["fsFormMin", "fsFormMinMessage"] }, { kind: "directive", type: i2.FsFormMaxDirective, selector: "[fsFormMax]", inputs: ["fsFormMax", "fsFormMaxMessage"] }, { kind: "directive", type: i2.FsFormIntegerDirective, selector: "[fsFormInteger]", inputs: ["fsFormInteger", "fsFormIntegerMessage"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
22
- }
23
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GeneralComponent, decorators: [{
24
- type: Component,
25
- args: [{ selector: 'fs-ai-report-global-settings-general', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
26
- FormsModule,
27
- FsFormModule,
28
- MatFormField,
29
- MatLabel,
30
- MatHint,
31
- MatInput,
32
- ], template: "<div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>Semantic build concurrency</mat-label>\n <input\n matInput\n type=\"number\"\n [ngModel]=\"concurrency()\"\n (ngModelChange)=\"concurrency.set($event)\"\n name=\"semanticBuildConcurrency\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"min()\"\n [fsFormMax]=\"max()\">\n <mat-hint>\n How many AI calls the semantic-database build runs at once ({{ min() }}\u2013{{ max() }}).\n Higher is faster but more likely to hit the AI provider's rate limit. Default is 8.\n </mat-hint>\n </mat-form-field>\n</div>\n", styles: [".tab-body{padding-top:16px}mat-form-field{display:block;max-width:340px}\n"] }]
33
- }] });
34
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvZGlhbG9ncy9nbG9iYWwtc2V0dGluZ3MvY29tcG9uZW50cy9nZW5lcmFsL2dlbmVyYWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvZ2xvYmFsLXNldHRpbmdzL2NvbXBvbmVudHMvZ2VuZXJhbC9nZW5lcmFsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQy9FLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVuRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7Ozs7QUFHaEQsaUZBQWlGO0FBQ2pGLDZFQUE2RTtBQUM3RSxpRkFBaUY7QUFDakYsd0VBQXdFO0FBQ3hFLDZFQUE2RTtBQUM3RSwrRUFBK0U7QUFDL0UsK0VBQStFO0FBaUIvRSxNQUFNLE9BQU8sZ0JBQWdCO0lBRVgsV0FBVyxHQUFHLEtBQUssQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUMvQixHQUFHLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBVSxDQUFDO0lBQy9CLEdBQUcsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFVLENBQUM7d0dBSnBDLGdCQUFnQjs0RkFBaEIsZ0JBQWdCLHVnQkNoQzdCLDRxQkFtQkEsbUlES0ksV0FBVyxneEJBQ1gsWUFBWSxta0JBQ1osWUFBWSw0TEFDWixRQUFRLHNEQUNSLE9BQU8sOEVBQ1AsUUFBUSxzVEFUSyxDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQzs7NEZBWXhELGdCQUFnQjtrQkFoQjVCLFNBQVM7K0JBQ0Usc0NBQXNDLGlCQUdqQyxDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxtQkFDbEQsdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxJQUFJLFdBQ1A7d0JBQ1AsV0FBVzt3QkFDWCxZQUFZO3dCQUNaLFlBQVk7d0JBQ1osUUFBUTt3QkFDUixPQUFPO3dCQUNQLFFBQVE7cUJBQ1QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBpbnB1dCwgbW9kZWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xDb250YWluZXIsIEZvcm1zTW9kdWxlLCBOZ0Zvcm0gfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IE1hdEZvcm1GaWVsZCwgTWF0SGludCwgTWF0TGFiZWwgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuXG5pbXBvcnQgeyBGc0Zvcm1Nb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9mb3JtJztcblxuXG4vLyBUaGUgR2VuZXJhbCB0YWI6IHJlcG9ydC1tb2R1bGUgc2V0dGluZ3MgdGhhdCBhcmVuJ3QgdGhlIEFJIGtub3dsZWRnZSBkb2N1bWVudC5cbi8vIEN1cnJlbnRseSBqdXN0IHRoZSBzZW1hbnRpYy1idWlsZCBjb25jdXJyZW5jeSDigJQgaG93IG1hbnkgc3VtbWFyeSBjYWxscyB0aGVcbi8vIGJ1aWxkIHJ1bnMgYXQgb25jZS4gQSBmaWVsZC1sZXZlbCBjaGlsZCBvZiB0aGUgc2V0dGluZ3MgZGlhbG9nIGZvcm0gKGl0cyBpbnB1dFxuLy8gcmVnaXN0ZXJzIHdpdGggdGhlIHBhcmVudCA8Zm9ybSBmc0Zvcm0+IHZpYSB0aGUgQ29udHJvbENvbnRhaW5lciB2aWV3XG4vLyBwcm92aWRlciksIHNvIHRoZSBkaWFsb2cncyBTYXZlIGJ1dHRvbiBzdWJtaXRzIGFuZCB2YWxpZGF0ZXMgaXQuIFRoZSB2YWx1ZVxuLy8gaXRzZWxmIGlzIGhlbGQgb24gdGhlIHNoZWxsIChib3VuZCB0aHJvdWdoIGBjb25jdXJyZW5jeWApLCBhbmQgdGhlIHNhZmUgYmFuZFxuLy8gKGBtaW5gL2BtYXhgKSBjb21lcyBmcm9tIHRoZSBiYWNrZW5kIHNvIHRoZSBmaWVsZCBjYW4ndCBiZSBzZXQgb3V0IG9mIHJhbmdlLlxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZnMtYWktcmVwb3J0LWdsb2JhbC1zZXR0aW5ncy1nZW5lcmFsJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dlbmVyYWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9nZW5lcmFsLmNvbXBvbmVudC5zY3NzJ10sXG4gIHZpZXdQcm92aWRlcnM6IFt7IHByb3ZpZGU6IENvbnRyb2xDb250YWluZXIsIHVzZUV4aXN0aW5nOiBOZ0Zvcm0gfV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgRnNGb3JtTW9kdWxlLFxuICAgIE1hdEZvcm1GaWVsZCxcbiAgICBNYXRMYWJlbCxcbiAgICBNYXRIaW50LFxuICAgIE1hdElucHV0LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBHZW5lcmFsQ29tcG9uZW50IHtcblxuICBwdWJsaWMgcmVhZG9ubHkgY29uY3VycmVuY3kgPSBtb2RlbDxudW1iZXI+KDApO1xuICBwdWJsaWMgcmVhZG9ubHkgbWluID0gaW5wdXQucmVxdWlyZWQ8bnVtYmVyPigpO1xuICBwdWJsaWMgcmVhZG9ubHkgbWF4ID0gaW5wdXQucmVxdWlyZWQ8bnVtYmVyPigpO1xufVxuIiwiPGRpdiBjbGFzcz1cImZzLWNvbHVtbiB0YWItYm9keVwiPlxuICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgPG1hdC1sYWJlbD5TZW1hbnRpYyBidWlsZCBjb25jdXJyZW5jeTwvbWF0LWxhYmVsPlxuICAgIDxpbnB1dFxuICAgICAgICBtYXRJbnB1dFxuICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgW25nTW9kZWxdPVwiY29uY3VycmVuY3koKVwiXG4gICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImNvbmN1cnJlbmN5LnNldCgkZXZlbnQpXCJcbiAgICAgICAgbmFtZT1cInNlbWFudGljQnVpbGRDb25jdXJyZW5jeVwiXG4gICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgW2ZzRm9ybUludGVnZXJdPVwidHJ1ZVwiXG4gICAgICAgIFtmc0Zvcm1NaW5dPVwibWluKClcIlxuICAgICAgICBbZnNGb3JtTWF4XT1cIm1heCgpXCI+XG4gICAgPG1hdC1oaW50PlxuICAgICAgSG93IG1hbnkgQUkgY2FsbHMgdGhlIHNlbWFudGljLWRhdGFiYXNlIGJ1aWxkIHJ1bnMgYXQgb25jZSAoe3sgbWluKCkgfX3igJN7eyBtYXgoKSB9fSkuXG4gICAgICBIaWdoZXIgaXMgZmFzdGVyIGJ1dCBtb3JlIGxpa2VseSB0byBoaXQgdGhlIEFJIHByb3ZpZGVyJ3MgcmF0ZSBsaW1pdC4gRGVmYXVsdCBpcyA4LlxuICAgIDwvbWF0LWhpbnQ+XG4gIDwvbWF0LWZvcm0tZmllbGQ+XG48L2Rpdj5cbiJdfQ==