@memberjunction/ng-file-storage 3.1.0 → 3.2.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.
- package/dist/lib/file-browser/file-browser-demo.component.d.ts +10 -0
- package/dist/lib/file-browser/file-browser-demo.component.d.ts.map +1 -0
- package/dist/lib/file-browser/file-browser-demo.component.js +39 -0
- package/dist/lib/file-browser/file-browser-demo.component.js.map +1 -0
- package/dist/lib/file-browser/file-browser-resource.component.d.ts +30 -0
- package/dist/lib/file-browser/file-browser-resource.component.d.ts.map +1 -0
- package/dist/lib/file-browser/file-browser-resource.component.js +82 -0
- package/dist/lib/file-browser/file-browser-resource.component.js.map +1 -0
- package/dist/lib/file-browser/file-browser.component.d.ts +69 -0
- package/dist/lib/file-browser/file-browser.component.d.ts.map +1 -0
- package/dist/lib/file-browser/file-browser.component.js +132 -0
- package/dist/lib/file-browser/file-browser.component.js.map +1 -0
- package/dist/lib/file-browser/file-grid.component.d.ts +429 -0
- package/dist/lib/file-browser/file-grid.component.d.ts.map +1 -0
- package/dist/lib/file-browser/file-grid.component.js +2394 -0
- package/dist/lib/file-browser/file-grid.component.js.map +1 -0
- package/dist/lib/file-browser/folder-tree.component.d.ts +115 -0
- package/dist/lib/file-browser/folder-tree.component.d.ts.map +1 -0
- package/dist/lib/file-browser/folder-tree.component.js +364 -0
- package/dist/lib/file-browser/folder-tree.component.js.map +1 -0
- package/dist/lib/file-browser/storage-providers-list.component.d.ts +59 -0
- package/dist/lib/file-browser/storage-providers-list.component.d.ts.map +1 -0
- package/dist/lib/file-browser/storage-providers-list.component.js +235 -0
- package/dist/lib/file-browser/storage-providers-list.component.js.map +1 -0
- package/dist/lib/file-upload/file-upload.d.ts +19 -19
- package/dist/lib/module.d.ts +25 -18
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/module.js +44 -4
- package/dist/lib/module.js.map +1 -1
- package/dist/public-api.d.ts +3 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +6 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +9 -8
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
/**
|
|
3
|
+
* Demo wrapper component for testing the file browser UI.
|
|
4
|
+
* Navigate to this component to see the file browser in action.
|
|
5
|
+
*/
|
|
6
|
+
export declare class FileBrowserDemoComponent {
|
|
7
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FileBrowserDemoComponent, never>;
|
|
8
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FileBrowserDemoComponent, "mj-file-browser-demo", never, {}, {}, never, never, false, never>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=file-browser-demo.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-browser-demo.component.d.ts","sourceRoot":"","sources":["../../../src/lib/file-browser/file-browser-demo.component.ts"],"names":[],"mappings":";AAEA;;;GAGG;AACH,qBAuBa,wBAAwB;yCAAxB,wBAAwB;2CAAxB,wBAAwB;CAAG"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "./file-browser.component";
|
|
4
|
+
/**
|
|
5
|
+
* Demo wrapper component for testing the file browser UI.
|
|
6
|
+
* Navigate to this component to see the file browser in action.
|
|
7
|
+
*/
|
|
8
|
+
export class FileBrowserDemoComponent {
|
|
9
|
+
static ɵfac = function FileBrowserDemoComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FileBrowserDemoComponent)(); };
|
|
10
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FileBrowserDemoComponent, selectors: [["mj-file-browser-demo"]], decls: 8, vars: 0, consts: [[2, "height", "100vh", "width", "100vw", "display", "flex", "flex-direction", "column"], [2, "padding", "16px", "background-color", "#f0f0f0", "border-bottom", "1px solid #ccc"], [2, "margin", "0", "font-size", "20px"], [2, "margin", "4px 0 0 0", "font-size", "14px", "color", "#666"], [2, "flex", "1", "overflow", "hidden"]], template: function FileBrowserDemoComponent_Template(rf, ctx) { if (rf & 1) {
|
|
11
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "h1", 2);
|
|
12
|
+
i0.ɵɵtext(3, "File Browser Demo");
|
|
13
|
+
i0.ɵɵelementEnd();
|
|
14
|
+
i0.ɵɵelementStart(4, "p", 3);
|
|
15
|
+
i0.ɵɵtext(5, " Testing the Mac Finder-style file browser component ");
|
|
16
|
+
i0.ɵɵelementEnd()();
|
|
17
|
+
i0.ɵɵelementStart(6, "div", 4);
|
|
18
|
+
i0.ɵɵelement(7, "mj-file-browser");
|
|
19
|
+
i0.ɵɵelementEnd()();
|
|
20
|
+
} }, dependencies: [i1.FileBrowserComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n }"] });
|
|
21
|
+
}
|
|
22
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FileBrowserDemoComponent, [{
|
|
23
|
+
type: Component,
|
|
24
|
+
args: [{ selector: 'mj-file-browser-demo', template: `
|
|
25
|
+
<div style="height: 100vh; width: 100vw; display: flex; flex-direction: column;">
|
|
26
|
+
<div style="padding: 16px; background-color: #f0f0f0; border-bottom: 1px solid #ccc;">
|
|
27
|
+
<h1 style="margin: 0; font-size: 20px;">File Browser Demo</h1>
|
|
28
|
+
<p style="margin: 4px 0 0 0; font-size: 14px; color: #666;">
|
|
29
|
+
Testing the Mac Finder-style file browser component
|
|
30
|
+
</p>
|
|
31
|
+
</div>
|
|
32
|
+
<div style="flex: 1; overflow: hidden;">
|
|
33
|
+
<mj-file-browser></mj-file-browser>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
`, styles: ["\n :host {\n display: block;\n height: 100%;\n width: 100%;\n }\n "] }]
|
|
37
|
+
}], null, null); })();
|
|
38
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FileBrowserDemoComponent, { className: "FileBrowserDemoComponent", filePath: "src/lib/file-browser/file-browser-demo.component.ts", lineNumber: 30 }); })();
|
|
39
|
+
//# sourceMappingURL=file-browser-demo.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-browser-demo.component.js","sourceRoot":"","sources":["../../../src/lib/file-browser/file-browser-demo.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;;;AAE1C;;;GAGG;AAwBH,MAAM,OAAO,wBAAwB;kHAAxB,wBAAwB;6DAAxB,wBAAwB;YAlB7B,AADF,AADF,8BAAiF,aACO,YAC5C;YAAA,iCAAiB;YAAA,iBAAK;YAC9D,4BAA4D;YAC1D,qEACF;YACF,AADE,iBAAI,EACA;YACN,8BAAwC;YACtC,kCAAmC;YAEvC,AADE,iBAAM,EACF;;;iFAUG,wBAAwB;cAvBpC,SAAS;2BACE,sBAAsB,YACtB;;;;;;;;;;;;GAYT;;kFASU,wBAAwB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
2
|
+
import { ResourceData } from '@memberjunction/core-entities';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare function LoadFileBrowserResource(): void;
|
|
5
|
+
/**
|
|
6
|
+
* File Browser Resource Wrapper - displays the file browser in a tab
|
|
7
|
+
* Extends BaseResourceComponent to work with the MJ resource type system
|
|
8
|
+
*/
|
|
9
|
+
export declare class FileBrowserResource extends BaseResourceComponent {
|
|
10
|
+
private dataLoaded;
|
|
11
|
+
constructor();
|
|
12
|
+
set Data(value: ResourceData);
|
|
13
|
+
get Data(): ResourceData;
|
|
14
|
+
/**
|
|
15
|
+
* Load the file browser (currently just notifies load complete)
|
|
16
|
+
* In future phases, this could pass configuration from ResourceData
|
|
17
|
+
*/
|
|
18
|
+
private loadFileBrowser;
|
|
19
|
+
/**
|
|
20
|
+
* Get the display name for the file browser resource
|
|
21
|
+
*/
|
|
22
|
+
GetResourceDisplayName(data: ResourceData): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Get the icon class for file browser resources
|
|
25
|
+
*/
|
|
26
|
+
GetResourceIconClass(data: ResourceData): Promise<string>;
|
|
27
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FileBrowserResource, never>;
|
|
28
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FileBrowserResource, "mj-file-browser-resource", never, {}, {}, never, never, false, never>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=file-browser-resource.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-browser-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/file-browser/file-browser-resource.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;;AAG7D,wBAAgB,uBAAuB,SAEtC;AAED;;;GAGG;AACH,qBA0Ba,mBAAoB,SAAQ,qBAAqB;IAC5D,OAAO,CAAC,UAAU,CAAS;;IAM3B,IAAa,IAAI,CAAC,KAAK,EAAE,YAAY,EAMpC;IAED,IAAa,IAAI,IAAI,YAAY,CAEhC;IAED;;;OAGG;YACW,eAAe;IAa7B;;OAEG;IACY,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1E;;OAEG;IACY,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCA9C7D,mBAAmB;2CAAnB,mBAAmB;CAiD/B"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Component } from '@angular/core';
|
|
8
|
+
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "./file-browser.component";
|
|
12
|
+
export function LoadFileBrowserResource() {
|
|
13
|
+
// Tree-shaking prevention function
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* File Browser Resource Wrapper - displays the file browser in a tab
|
|
17
|
+
* Extends BaseResourceComponent to work with the MJ resource type system
|
|
18
|
+
*/
|
|
19
|
+
let FileBrowserResource = class FileBrowserResource extends BaseResourceComponent {
|
|
20
|
+
dataLoaded = false;
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
}
|
|
24
|
+
set Data(value) {
|
|
25
|
+
super.Data = value;
|
|
26
|
+
if (!this.dataLoaded) {
|
|
27
|
+
this.dataLoaded = true;
|
|
28
|
+
this.loadFileBrowser();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
get Data() {
|
|
32
|
+
return super.Data;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Load the file browser (currently just notifies load complete)
|
|
36
|
+
* In future phases, this could pass configuration from ResourceData
|
|
37
|
+
*/
|
|
38
|
+
async loadFileBrowser() {
|
|
39
|
+
this.NotifyLoadStarted();
|
|
40
|
+
try {
|
|
41
|
+
// File browser loads immediately
|
|
42
|
+
// In future, could pass provider selection or folder path from Data.Configuration
|
|
43
|
+
this.NotifyLoadComplete();
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error('Error loading file browser:', error);
|
|
47
|
+
this.NotifyLoadComplete();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get the display name for the file browser resource
|
|
52
|
+
*/
|
|
53
|
+
async GetResourceDisplayName(data) {
|
|
54
|
+
return data.Name || 'File Browser';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the icon class for file browser resources
|
|
58
|
+
*/
|
|
59
|
+
async GetResourceIconClass(data) {
|
|
60
|
+
return 'fa-solid fa-folder-tree';
|
|
61
|
+
}
|
|
62
|
+
static ɵfac = function FileBrowserResource_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FileBrowserResource)(); };
|
|
63
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FileBrowserResource, selectors: [["mj-file-browser-resource"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 0, consts: [[1, "file-browser-resource-container"]], template: function FileBrowserResource_Template(rf, ctx) { if (rf & 1) {
|
|
64
|
+
i0.ɵɵelementStart(0, "div", 0);
|
|
65
|
+
i0.ɵɵelement(1, "mj-file-browser");
|
|
66
|
+
i0.ɵɵelementEnd();
|
|
67
|
+
} }, dependencies: [i1.FileBrowserComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .file-browser-resource-container[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: hidden;\n }"] });
|
|
68
|
+
};
|
|
69
|
+
FileBrowserResource = __decorate([
|
|
70
|
+
RegisterClass(BaseResourceComponent, 'FileBrowserResource')
|
|
71
|
+
], FileBrowserResource);
|
|
72
|
+
export { FileBrowserResource };
|
|
73
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FileBrowserResource, [{
|
|
74
|
+
type: Component,
|
|
75
|
+
args: [{ selector: 'mj-file-browser-resource', template: `
|
|
76
|
+
<div class="file-browser-resource-container">
|
|
77
|
+
<mj-file-browser></mj-file-browser>
|
|
78
|
+
</div>
|
|
79
|
+
`, styles: ["\n :host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .file-browser-resource-container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: hidden;\n }\n "] }]
|
|
80
|
+
}], () => [], null); })();
|
|
81
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FileBrowserResource, { className: "FileBrowserResource", filePath: "src/lib/file-browser/file-browser-resource.component.ts", lineNumber: 40 }); })();
|
|
82
|
+
//# sourceMappingURL=file-browser-resource.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-browser-resource.component.js","sourceRoot":"","sources":["../../../src/lib/file-browser/file-browser-resource.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;;;AAEvD,MAAM,UAAU,uBAAuB;IACrC,mCAAmC;AACrC,CAAC;AAED;;;GAGG;AA2BI,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,qBAAqB;IACpD,UAAU,GAAG,KAAK,CAAC;IAE3B;QACE,KAAK,EAAE,CAAC;IACV,CAAC;IAED,IAAa,IAAI,CAAC,KAAmB;QACnC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAED,IAAa,IAAI;QACf,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,IAAI,CAAC;YACH,iCAAiC;YACjC,kFAAkF;YAClF,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACpD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;OAEG;IACM,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QACtD,OAAO,IAAI,CAAC,IAAI,IAAI,cAAc,CAAC;IACrC,CAAC;IAED;;OAEG;IACM,KAAK,CAAC,oBAAoB,CAAC,IAAkB;QACpD,OAAO,yBAAyB,CAAC;IACnC,CAAC;6GAhDU,mBAAmB;6DAAnB,mBAAmB;YAtB5B,8BAA6C;YAC3C,kCAAmC;YACrC,iBAAM;;;AAoBG,mBAAmB;IA1B/B,aAAa,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;GA0B/C,mBAAmB,CAiD/B;;iFAjDY,mBAAmB;cAzB/B,SAAS;2BACE,0BAA0B,YAC1B;;;;GAIT;;kFAmBU,mBAAmB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { FolderTreeComponent } from './folder-tree.component';
|
|
2
|
+
import { StorageAccountWithProvider } from '@memberjunction/core-entities';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Mac Finder-style file browser component with three-panel layout.
|
|
6
|
+
*
|
|
7
|
+
* Layout:
|
|
8
|
+
* - Left sidebar: Storage account selection
|
|
9
|
+
* - Middle panel: Folder tree navigation
|
|
10
|
+
* - Right panel: File grid with current folder contents
|
|
11
|
+
*
|
|
12
|
+
* In the enterprise model, users select from organizational storage accounts
|
|
13
|
+
* rather than connecting their own OAuth credentials.
|
|
14
|
+
*
|
|
15
|
+
* Features responsive design with collapsible sidebar for mobile devices.
|
|
16
|
+
* Responsive layout is handled via CSS media queries.
|
|
17
|
+
*/
|
|
18
|
+
export declare class FileBrowserComponent {
|
|
19
|
+
/**
|
|
20
|
+
* Reference to the folder tree component for programmatic navigation
|
|
21
|
+
*/
|
|
22
|
+
folderTree: FolderTreeComponent;
|
|
23
|
+
/**
|
|
24
|
+
* Controls manual collapse of the sidebar (toggle button on mobile).
|
|
25
|
+
* CSS media queries handle the responsive layout automatically.
|
|
26
|
+
*/
|
|
27
|
+
isSidebarCollapsed: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Currently selected storage account with its provider details.
|
|
30
|
+
*/
|
|
31
|
+
selectedAccount: StorageAccountWithProvider | null;
|
|
32
|
+
/**
|
|
33
|
+
* Currently selected folder path in the tree.
|
|
34
|
+
*/
|
|
35
|
+
selectedFolderPath: string;
|
|
36
|
+
constructor();
|
|
37
|
+
/**
|
|
38
|
+
* Toggles the visibility of the accounts sidebar.
|
|
39
|
+
* Used for manual toggle on mobile devices.
|
|
40
|
+
*/
|
|
41
|
+
toggleSidebar(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Handles storage account selection from the sidebar.
|
|
44
|
+
*
|
|
45
|
+
* @param accountWithProvider - The selected storage account with provider details, or null if no accounts available
|
|
46
|
+
*/
|
|
47
|
+
onAccountSelected(accountWithProvider: StorageAccountWithProvider | null): void;
|
|
48
|
+
/**
|
|
49
|
+
* Handles folder selection from the tree navigation.
|
|
50
|
+
*
|
|
51
|
+
* @param folderPath - The full path of the selected folder
|
|
52
|
+
*/
|
|
53
|
+
onFolderSelected(folderPath: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Handles folder navigation from the file grid (double-click on folder).
|
|
56
|
+
* Updates the folder tree to navigate to the selected folder.
|
|
57
|
+
*
|
|
58
|
+
* @param folderPath - The full path of the folder to navigate to
|
|
59
|
+
*/
|
|
60
|
+
onFolderNavigate(folderPath: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Handles folder structure changes (e.g., new folder created, folder deleted).
|
|
63
|
+
* Refreshes the folder tree to show the new structure.
|
|
64
|
+
*/
|
|
65
|
+
onFolderStructureChanged(): void;
|
|
66
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FileBrowserComponent, never>;
|
|
67
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FileBrowserComponent, "mj-file-browser", never, {}, {}, never, never, false, never>;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=file-browser.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-browser.component.d.ts","sourceRoot":"","sources":["../../../src/lib/file-browser/file-browser.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;;AAE3E;;;;;;;;;;;;;GAaG;AACH,qBAKa,oBAAoB;IAC/B;;OAEG;IAC6B,UAAU,EAAG,mBAAmB,CAAC;IAEjE;;;OAGG;IACI,kBAAkB,EAAE,OAAO,CAAS;IAE3C;;OAEG;IACI,eAAe,EAAE,0BAA0B,GAAG,IAAI,CAAQ;IAEjE;;OAEG;IACI,kBAAkB,EAAE,MAAM,CAAO;;IAIxC;;;OAGG;IACI,aAAa,IAAI,IAAI;IAI5B;;;;OAIG;IACI,iBAAiB,CAAC,mBAAmB,EAAE,0BAA0B,GAAG,IAAI,GAAG,IAAI;IAKtF;;;;OAIG;IACI,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIjD;;;;;OAKG;IACI,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMjD;;;OAGG;IACI,wBAAwB,IAAI,IAAI;yCAnE5B,oBAAoB;2CAApB,oBAAoB;CA0EhC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Component, ViewChild } from '@angular/core';
|
|
2
|
+
import { FolderTreeComponent } from './folder-tree.component';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "./storage-providers-list.component";
|
|
5
|
+
import * as i2 from "./folder-tree.component";
|
|
6
|
+
import * as i3 from "./file-grid.component";
|
|
7
|
+
/**
|
|
8
|
+
* Mac Finder-style file browser component with three-panel layout.
|
|
9
|
+
*
|
|
10
|
+
* Layout:
|
|
11
|
+
* - Left sidebar: Storage account selection
|
|
12
|
+
* - Middle panel: Folder tree navigation
|
|
13
|
+
* - Right panel: File grid with current folder contents
|
|
14
|
+
*
|
|
15
|
+
* In the enterprise model, users select from organizational storage accounts
|
|
16
|
+
* rather than connecting their own OAuth credentials.
|
|
17
|
+
*
|
|
18
|
+
* Features responsive design with collapsible sidebar for mobile devices.
|
|
19
|
+
* Responsive layout is handled via CSS media queries.
|
|
20
|
+
*/
|
|
21
|
+
export class FileBrowserComponent {
|
|
22
|
+
/**
|
|
23
|
+
* Reference to the folder tree component for programmatic navigation
|
|
24
|
+
*/
|
|
25
|
+
folderTree;
|
|
26
|
+
/**
|
|
27
|
+
* Controls manual collapse of the sidebar (toggle button on mobile).
|
|
28
|
+
* CSS media queries handle the responsive layout automatically.
|
|
29
|
+
*/
|
|
30
|
+
isSidebarCollapsed = false;
|
|
31
|
+
/**
|
|
32
|
+
* Currently selected storage account with its provider details.
|
|
33
|
+
*/
|
|
34
|
+
selectedAccount = null;
|
|
35
|
+
/**
|
|
36
|
+
* Currently selected folder path in the tree.
|
|
37
|
+
*/
|
|
38
|
+
selectedFolderPath = '/';
|
|
39
|
+
constructor() { }
|
|
40
|
+
/**
|
|
41
|
+
* Toggles the visibility of the accounts sidebar.
|
|
42
|
+
* Used for manual toggle on mobile devices.
|
|
43
|
+
*/
|
|
44
|
+
toggleSidebar() {
|
|
45
|
+
this.isSidebarCollapsed = !this.isSidebarCollapsed;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Handles storage account selection from the sidebar.
|
|
49
|
+
*
|
|
50
|
+
* @param accountWithProvider - The selected storage account with provider details, or null if no accounts available
|
|
51
|
+
*/
|
|
52
|
+
onAccountSelected(accountWithProvider) {
|
|
53
|
+
this.selectedAccount = accountWithProvider;
|
|
54
|
+
this.selectedFolderPath = '/'; // Reset to root when switching accounts
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Handles folder selection from the tree navigation.
|
|
58
|
+
*
|
|
59
|
+
* @param folderPath - The full path of the selected folder
|
|
60
|
+
*/
|
|
61
|
+
onFolderSelected(folderPath) {
|
|
62
|
+
this.selectedFolderPath = folderPath;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Handles folder navigation from the file grid (double-click on folder).
|
|
66
|
+
* Updates the folder tree to navigate to the selected folder.
|
|
67
|
+
*
|
|
68
|
+
* @param folderPath - The full path of the folder to navigate to
|
|
69
|
+
*/
|
|
70
|
+
onFolderNavigate(folderPath) {
|
|
71
|
+
if (this.folderTree) {
|
|
72
|
+
this.folderTree.navigateToPath(folderPath);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Handles folder structure changes (e.g., new folder created, folder deleted).
|
|
77
|
+
* Refreshes the folder tree to show the new structure.
|
|
78
|
+
*/
|
|
79
|
+
onFolderStructureChanged() {
|
|
80
|
+
if (this.folderTree) {
|
|
81
|
+
// Trigger a refresh of the folder tree without changing navigation
|
|
82
|
+
// This will reload the folders at the current location
|
|
83
|
+
this.folderTree.refresh();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
static ɵfac = function FileBrowserComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FileBrowserComponent)(); };
|
|
87
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FileBrowserComponent, selectors: [["mj-file-browser"]], viewQuery: function FileBrowserComponent_Query(rf, ctx) { if (rf & 1) {
|
|
88
|
+
i0.ɵɵviewQuery(FolderTreeComponent, 5);
|
|
89
|
+
} if (rf & 2) {
|
|
90
|
+
let _t;
|
|
91
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.folderTree = _t.first);
|
|
92
|
+
} }, decls: 22, vars: 5, consts: [[1, "file-browser"], [1, "mobile-header"], [1, "sidebar-toggle", 3, "click"], [1, "fa-solid", "fa-bars"], [1, "browser-title"], [1, "browser-container"], [1, "sidebar"], [1, "sidebar-section"], [1, "section-header"], [1, "section-content"], [3, "accountSelected"], [3, "folderSelected", "account"], [1, "main-panel"], [3, "folderNavigate", "folderStructureChanged", "account", "folderPath"]], template: function FileBrowserComponent_Template(rf, ctx) { if (rf & 1) {
|
|
93
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
|
|
94
|
+
i0.ɵɵlistener("click", function FileBrowserComponent_Template_button_click_2_listener() { return ctx.toggleSidebar(); });
|
|
95
|
+
i0.ɵɵelement(3, "i", 3);
|
|
96
|
+
i0.ɵɵelementEnd();
|
|
97
|
+
i0.ɵɵelementStart(4, "h2", 4);
|
|
98
|
+
i0.ɵɵtext(5, "File Browser");
|
|
99
|
+
i0.ɵɵelementEnd()();
|
|
100
|
+
i0.ɵɵelementStart(6, "div", 5)(7, "div", 6)(8, "div", 7)(9, "div", 8)(10, "h3");
|
|
101
|
+
i0.ɵɵtext(11, "ACCOUNTS");
|
|
102
|
+
i0.ɵɵelementEnd()();
|
|
103
|
+
i0.ɵɵelementStart(12, "div", 9)(13, "mj-storage-providers-list", 10);
|
|
104
|
+
i0.ɵɵlistener("accountSelected", function FileBrowserComponent_Template_mj_storage_providers_list_accountSelected_13_listener($event) { return ctx.onAccountSelected($event); });
|
|
105
|
+
i0.ɵɵelementEnd()()();
|
|
106
|
+
i0.ɵɵelementStart(14, "div", 7)(15, "div", 8)(16, "h3");
|
|
107
|
+
i0.ɵɵtext(17, "FOLDERS");
|
|
108
|
+
i0.ɵɵelementEnd()();
|
|
109
|
+
i0.ɵɵelementStart(18, "div", 9)(19, "mj-folder-tree", 11);
|
|
110
|
+
i0.ɵɵlistener("folderSelected", function FileBrowserComponent_Template_mj_folder_tree_folderSelected_19_listener($event) { return ctx.onFolderSelected($event); });
|
|
111
|
+
i0.ɵɵelementEnd()()()();
|
|
112
|
+
i0.ɵɵelementStart(20, "div", 12)(21, "mj-file-grid", 13);
|
|
113
|
+
i0.ɵɵlistener("folderNavigate", function FileBrowserComponent_Template_mj_file_grid_folderNavigate_21_listener($event) { return ctx.onFolderNavigate($event); })("folderStructureChanged", function FileBrowserComponent_Template_mj_file_grid_folderStructureChanged_21_listener() { return ctx.onFolderStructureChanged(); });
|
|
114
|
+
i0.ɵɵelementEnd()()()();
|
|
115
|
+
} if (rf & 2) {
|
|
116
|
+
i0.ɵɵadvance(7);
|
|
117
|
+
i0.ɵɵclassProp("collapsed", ctx.isSidebarCollapsed);
|
|
118
|
+
i0.ɵɵadvance(12);
|
|
119
|
+
i0.ɵɵproperty("account", ctx.selectedAccount);
|
|
120
|
+
i0.ɵɵadvance(2);
|
|
121
|
+
i0.ɵɵproperty("account", ctx.selectedAccount)("folderPath", ctx.selectedFolderPath);
|
|
122
|
+
} }, dependencies: [i1.StorageProvidersListComponent, i2.FolderTreeComponent, i3.FileGridComponent], styles: ["\n\n\n\n\n\n.file-browser[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: #f0f0f0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n border: 1px solid #ccc;\n}\n\n\n\n.mobile-header[_ngcontent-%COMP%] {\n display: none;\n align-items: center;\n padding: 8px 12px;\n background-color: #ffffff;\n border-bottom: 1px solid #ccc;\n}\n\n.mobile-header[_ngcontent-%COMP%] .browser-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #000;\n}\n\n.sidebar-toggle[_ngcontent-%COMP%] {\n margin-right: 12px;\n background: none;\n border: 1px solid #ccc;\n padding: 6px 12px;\n cursor: pointer;\n border-radius: 3px;\n}\n\n.sidebar-toggle[_ngcontent-%COMP%]:hover {\n background-color: #f0f0f0;\n}\n\n\n\n.browser-container[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n gap: 0;\n}\n\n\n\n.sidebar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background-color: #f8f8f8;\n border-right: 1px solid #ccc;\n width: 220px;\n min-width: 220px;\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n.sidebar.collapsed[_ngcontent-%COMP%] {\n width: 0;\n min-width: 0;\n border-right: none;\n opacity: 0;\n}\n\n\n\n.sidebar-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n border-bottom: 1px solid #ddd;\n}\n\n.sidebar-section[_ngcontent-%COMP%]:last-child {\n flex: 1;\n border-bottom: none;\n}\n\n.section-header[_ngcontent-%COMP%] {\n padding: 8px 12px;\n background-color: #e8e8e8;\n border-bottom: 1px solid #ccc;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 11px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n\n\n.main-panel[_ngcontent-%COMP%] {\n flex: 1;\n background-color: #fff;\n border-left: 1px solid #ccc;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n\n\n.section-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.section-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: #f0f0f0;\n}\n\n.section-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #c0c0c0;\n border-radius: 4px;\n}\n\n.section-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: #a0a0a0;\n}\n\n\n\n\n\n\n\n\n@media screen and (max-width: 1024px) {\n .sidebar[_ngcontent-%COMP%] {\n width: 200px;\n min-width: 200px;\n }\n}\n\n\n\n@media screen and (max-width: 768px) {\n .mobile-header[_ngcontent-%COMP%] {\n display: flex;\n }\n\n .browser-container[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n \n\n .sidebar[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 45px; \n\n bottom: 0;\n width: 280px;\n min-width: 280px;\n z-index: 1000;\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n }\n\n .sidebar.collapsed[_ngcontent-%COMP%] {\n transform: translateX(-100%);\n }\n\n \n\n .main-panel[_ngcontent-%COMP%] {\n flex: 1;\n }\n}\n\n\n\n@media screen and (max-width: 480px) {\n .mobile-header[_ngcontent-%COMP%] {\n padding: 6px 10px;\n }\n\n .mobile-header[_ngcontent-%COMP%] .browser-title[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .section-header[_ngcontent-%COMP%] {\n padding: 6px 10px;\n }\n\n .section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n\n .sidebar[_ngcontent-%COMP%] {\n width: 260px;\n min-width: 260px;\n }\n}"] });
|
|
123
|
+
}
|
|
124
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FileBrowserComponent, [{
|
|
125
|
+
type: Component,
|
|
126
|
+
args: [{ selector: 'mj-file-browser', template: "<div class=\"file-browser\">\n <!-- Mobile header with sidebar toggle -->\n <div class=\"mobile-header\">\n <button (click)=\"toggleSidebar()\" class=\"sidebar-toggle\">\n <i class=\"fa-solid fa-bars\"></i>\n </button>\n <h2 class=\"browser-title\">File Browser</h2>\n </div>\n\n <!-- Main two-panel layout -->\n <div class=\"browser-container\">\n <!-- Left Sidebar: Accounts + Categories -->\n <div class=\"sidebar\" [class.collapsed]=\"isSidebarCollapsed\">\n <!-- Accounts Section -->\n <div class=\"sidebar-section\">\n <div class=\"section-header\">\n <h3>ACCOUNTS</h3>\n </div>\n <div class=\"section-content\">\n <mj-storage-providers-list\n (accountSelected)=\"onAccountSelected($event)\"\n ></mj-storage-providers-list>\n </div>\n </div>\n\n <!-- Categories Section -->\n <div class=\"sidebar-section\">\n <div class=\"section-header\">\n <h3>FOLDERS</h3>\n </div>\n <div class=\"section-content\">\n <mj-folder-tree\n [account]=\"selectedAccount\"\n (folderSelected)=\"onFolderSelected($event)\"\n ></mj-folder-tree>\n </div>\n </div>\n </div>\n\n <!-- Right Panel: File Grid -->\n <div class=\"main-panel\">\n <mj-file-grid\n [account]=\"selectedAccount\"\n [folderPath]=\"selectedFolderPath\"\n (folderNavigate)=\"onFolderNavigate($event)\"\n (folderStructureChanged)=\"onFolderStructureChanged()\"\n ></mj-file-grid>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n File Browser Shell Styles\n Traditional dual-pane file manager layout\n =========================== */\n\n.file-browser {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: #f0f0f0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n border: 1px solid #ccc;\n}\n\n/* Mobile Header */\n.mobile-header {\n display: none;\n align-items: center;\n padding: 8px 12px;\n background-color: #ffffff;\n border-bottom: 1px solid #ccc;\n}\n\n.mobile-header .browser-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #000;\n}\n\n.sidebar-toggle {\n margin-right: 12px;\n background: none;\n border: 1px solid #ccc;\n padding: 6px 12px;\n cursor: pointer;\n border-radius: 3px;\n}\n\n.sidebar-toggle:hover {\n background-color: #f0f0f0;\n}\n\n/* Main Container - Two Panel Layout */\n.browser-container {\n display: flex;\n flex: 1;\n overflow: hidden;\n gap: 0;\n}\n\n/* Left Sidebar */\n.sidebar {\n display: flex;\n flex-direction: column;\n background-color: #f8f8f8;\n border-right: 1px solid #ccc;\n width: 220px;\n min-width: 220px;\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n.sidebar.collapsed {\n width: 0;\n min-width: 0;\n border-right: none;\n opacity: 0;\n}\n\n/* Sidebar Sections */\n.sidebar-section {\n display: flex;\n flex-direction: column;\n border-bottom: 1px solid #ddd;\n}\n\n.sidebar-section:last-child {\n flex: 1;\n border-bottom: none;\n}\n\n.section-header {\n padding: 8px 12px;\n background-color: #e8e8e8;\n border-bottom: 1px solid #ccc;\n}\n\n.section-header h3 {\n margin: 0;\n font-size: 11px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* Right Main Panel */\n.main-panel {\n flex: 1;\n background-color: #fff;\n border-left: 1px solid #ccc;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Custom Scrollbar Styling */\n.section-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.section-content::-webkit-scrollbar-track {\n background: #f0f0f0;\n}\n\n.section-content::-webkit-scrollbar-thumb {\n background: #c0c0c0;\n border-radius: 4px;\n}\n\n.section-content::-webkit-scrollbar-thumb:hover {\n background: #a0a0a0;\n}\n\n/* ===========================\n Responsive Design\n =========================== */\n\n/* Tablet (768px - 1024px) */\n@media screen and (max-width: 1024px) {\n .sidebar {\n width: 200px;\n min-width: 200px;\n }\n}\n\n/* Mobile (below 768px) */\n@media screen and (max-width: 768px) {\n .mobile-header {\n display: flex;\n }\n\n .browser-container {\n flex-direction: column;\n }\n\n /* Sidebar becomes overlay on mobile */\n .sidebar {\n position: absolute;\n left: 0;\n top: 45px; /* Height of mobile header */\n bottom: 0;\n width: 280px;\n min-width: 280px;\n z-index: 1000;\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n }\n\n .sidebar.collapsed {\n transform: translateX(-100%);\n }\n\n /* File grid takes full space on mobile */\n .main-panel {\n flex: 1;\n }\n}\n\n/* Small Mobile (below 480px) */\n@media screen and (max-width: 480px) {\n .mobile-header {\n padding: 6px 10px;\n }\n\n .mobile-header .browser-title {\n font-size: 14px;\n }\n\n .section-header {\n padding: 6px 10px;\n }\n\n .section-header h3 {\n font-size: 10px;\n }\n\n .sidebar {\n width: 260px;\n min-width: 260px;\n }\n}\n"] }]
|
|
127
|
+
}], () => [], { folderTree: [{
|
|
128
|
+
type: ViewChild,
|
|
129
|
+
args: [FolderTreeComponent]
|
|
130
|
+
}] }); })();
|
|
131
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FileBrowserComponent, { className: "FileBrowserComponent", filePath: "src/lib/file-browser/file-browser.component.ts", lineNumber: 24 }); })();
|
|
132
|
+
//# sourceMappingURL=file-browser.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-browser.component.js","sourceRoot":"","sources":["../../../src/lib/file-browser/file-browser.component.ts","../../../src/lib/file-browser/file-browser.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;;;;;AAG9D;;;;;;;;;;;;;GAaG;AAMH,MAAM,OAAO,oBAAoB;IAC/B;;OAEG;IAC6B,UAAU,CAAuB;IAEjE;;;OAGG;IACI,kBAAkB,GAAY,KAAK,CAAC;IAE3C;;OAEG;IACI,eAAe,GAAsC,IAAI,CAAC;IAEjE;;OAEG;IACI,kBAAkB,GAAW,GAAG,CAAC;IAExC,gBAAe,CAAC;IAEhB;;;OAGG;IACI,aAAa;QAClB,IAAI,CAAC,kBAAkB,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACI,iBAAiB,CAAC,mBAAsD;QAC7E,IAAI,CAAC,eAAe,GAAG,mBAAmB,CAAC;QAC3C,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC,wCAAwC;IACzE,CAAC;IAED;;;;OAIG;IACI,gBAAgB,CAAC,UAAkB;QACxC,IAAI,CAAC,kBAAkB,GAAG,UAAU,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACI,gBAAgB,CAAC,UAAkB;QACxC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,wBAAwB;QAC7B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,mEAAmE;YACnE,uDAAuD;YACvD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;8GAzEU,oBAAoB;6DAApB,oBAAoB;2BAIpB,mBAAmB;;;;;YCxB5B,AADF,AAFF,8BAA0B,aAEG,gBACgC;YAAjD,iGAAS,mBAAe,IAAC;YAC/B,uBAAgC;YAClC,iBAAS;YACT,6BAA0B;YAAA,4BAAY;YACxC,AADwC,iBAAK,EACvC;YASE,AADF,AADF,AAFF,AAFF,8BAA+B,aAE+B,aAE7B,aACC,UACtB;YAAA,yBAAQ;YACd,AADc,iBAAK,EACb;YAEJ,AADF,+BAA6B,qCAG1B;YADC,+IAAmB,6BAAyB,IAAC;YAGnD,AADE,AADG,iBAA4B,EACzB,EACF;YAKF,AADF,AADF,+BAA6B,cACC,UACtB;YAAA,wBAAO;YACb,AADa,iBAAK,EACZ;YAEJ,AADF,+BAA6B,0BAI1B;YADC,kIAAkB,4BAAwB,IAAC;YAInD,AADE,AADE,AADG,iBAAiB,EACd,EACF,EACF;YAIJ,AADF,gCAAwB,wBAMrB;YADC,AADA,gIAAkB,4BAAwB,IAAC,6HACjB,8BAA0B,IAAC;YAI7D,AADE,AADE,AADG,iBAAe,EACZ,EACF,EACF;;YArCmB,eAAsC;YAAtC,mDAAsC;YAoBnD,gBAA2B;YAA3B,6CAA2B;YAU/B,eAA2B;YAC3B,AADA,6CAA2B,sCACM;;;iFDpB5B,oBAAoB;cALhC,SAAS;2BACE,iBAAiB;oBAQK,UAAU;kBAAzC,SAAS;mBAAC,mBAAmB;;kFAJnB,oBAAoB"}
|