@libs-ui/components-scroll-overlay 0.2.355-0 → 0.2.355-10

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/esm2022/index.mjs CHANGED
@@ -1,4 +1,3 @@
1
1
  export * from './scroll-overlay.directive';
2
2
  export * from './scroll.interface';
3
- export * from './demo/scroll-overlay.demo';
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvc2Nyb2xsLW92ZXJsYXkvc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLDRCQUE0QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9zY3JvbGwtb3ZlcmxheS5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9zY3JvbGwuaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vZGVtby9zY3JvbGwtb3ZlcmxheS5kZW1vJztcbiJdfQ==
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvc2Nyb2xsLW92ZXJsYXkvc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYyxvQkFBb0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vc2Nyb2xsLW92ZXJsYXkuZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vc2Nyb2xsLmludGVyZmFjZSc7XG4iXX0=
@@ -1,10 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { computed, signal, input, output, inject, ElementRef, Renderer2, DestroyRef, effect, untracked, Directive, Component } from '@angular/core';
2
+ import { computed, signal, input, output, inject, ElementRef, Renderer2, DestroyRef, effect, untracked, Directive } from '@angular/core';
3
3
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
4
  import { getDragEventByElement, checkMouseOverInContainer } from '@libs-ui/utils';
5
5
  import { Subscription, fromEvent, tap, switchMap, interval, takeUntil } from 'rxjs';
6
- import * as i1 from '@angular/common';
7
- import { CommonModule } from '@angular/common';
8
6
 
9
7
  /* eslint-disable @typescript-eslint/no-explicit-any */
10
8
  class LibsUiComponentsScrollOverlayDirective {
@@ -387,88 +385,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
387
385
  }]
388
386
  }], ctorParameters: () => [] });
389
387
 
390
- class LibsUiComponentsScrollOverlayDemoComponent {
391
- // Demo text content: generate 5000 words for vertical scrolling
392
- longContent = signal(Array.from({ length: 5000 }, (_, i) => `Lorem${i + 1}`).join(' '));
393
- // Demo horizontal content: generate 5000 words for horizontal scrolling
394
- longHorizontalContent = signal(Array.from({ length: 5000 }, (_, i) => `Word${i + 1}`).join(' '));
395
- // Scenario selection
396
- scenarioOptions = ['default', 'customStyle', 'autoHide', 'horizontal'];
397
- selectedScenario = 'default';
398
- // Options signals
399
- customStyleOptions = signal({ scrollbarWidth: 12, scrollbarColor: '#f3f4f6', scrollbarHoverColor: '#e5e7eb', scrollThumbColor: '#3b82f6', scrollThumbHoverColor: '#2563eb', scrollbarPadding: 4 });
400
- autoHideOptions = signal({ scrollYOpacity0: true, scrollbarWidth: 8, scrollbarColor: 'transparent', scrollThumbColor: '#9ca3af', scrollThumbHoverColor: '#6b7280' });
401
- horizontalOptions = signal({ scrollX: 'scroll', scrollY: 'hidden', scrollbarWidth: 8, scrollbarColor: '#f3f4f6', scrollThumbColor: '#3b82f6' });
402
- // Scroll event log
403
- lastEvent = signal('No events yet');
404
- // Helpers
405
- get options() {
406
- switch (this.selectedScenario) {
407
- case 'customStyle':
408
- return this.customStyleOptions();
409
- case 'autoHide':
410
- return this.autoHideOptions();
411
- case 'horizontal':
412
- return this.horizontalOptions();
413
- default:
414
- return undefined;
415
- }
416
- }
417
- get content() {
418
- return this.selectedScenario === 'horizontal' ? this.longHorizontalContent() : this.longContent();
419
- }
420
- // Event handlers
421
- onScroll() {
422
- this.lastEvent.set('Scroll event fired');
423
- }
424
- onScrollTop() {
425
- this.lastEvent.set('Reached top');
426
- }
427
- onScrollBottom() {
428
- this.lastEvent.set('Reached bottom');
429
- }
430
- // API docs
431
- inputsDoc = [
432
- { name: 'options', type: 'IScrollOverlayOptions', default: 'undefined', description: 'Cấu hình tuỳ chỉnh scrollbar' },
433
- { name: 'debugMode', type: 'boolean', default: 'false', description: 'Bật chế độ debug' },
434
- { name: 'notShowScrollBarX', type: 'boolean', default: 'false', description: 'Ẩn scrollbar ngang' },
435
- { name: 'notShowScrollBarY', type: 'boolean', default: 'false', description: 'Ẩn scrollbar dọc' },
436
- ];
437
- outputsDoc = [
438
- { name: 'outScroll', type: 'Event', description: 'Bắn ra khi scroll bất kỳ' },
439
- { name: 'outScrollTop', type: 'Event', description: 'Bắn ra khi scroll đến top' },
440
- { name: 'outScrollBottom', type: 'Event', description: 'Bắn ra khi scroll đến bottom' },
441
- ];
442
- optionsDoc = [
443
- { name: 'scrollbarWidth', type: 'number', default: 'undefined', description: 'Chiều rộng scrollbar (px)' },
444
- { name: 'scrollbarColor', type: 'string', default: 'undefined', description: 'Màu track scrollbar' },
445
- { name: 'scrollbarHoverColor', type: 'string', default: 'undefined', description: 'Màu track khi hover' },
446
- { name: 'scrollThumbColor', type: 'string', default: 'undefined', description: 'Màu thumb' },
447
- { name: 'scrollThumbHoverColor', type: 'string', default: 'undefined', description: 'Màu thumb khi hover' },
448
- { name: 'scrollbarPadding', type: 'number', default: 'undefined', description: 'Padding scrollbar' },
449
- { name: 'scrollX', type: `'hidden' | 'scroll'`, default: 'undefined', description: 'Kiểu scroll X' },
450
- { name: 'scrollXOpacity0', type: 'boolean', default: 'undefined', description: 'Ẩn track X khi không hover' },
451
- { name: 'scrollY', type: `'hidden' | 'scroll'`, default: 'undefined', description: 'Kiểu scroll Y' },
452
- { name: 'scrollYOpacity0', type: 'boolean', default: 'undefined', description: 'Ẩn track Y khi không hover' },
453
- ];
454
- interfacesDoc = [{ name: 'IScrollOverlayOptions', type: 'interface', description: 'Các tuỳ chọn cấu hình scroll-overlay' }];
455
- // Installation commands
456
- installCommandNpm = 'npm install @libs-ui/components-scroll-overlay';
457
- installCommandYarn = 'yarn add @libs-ui/components-scroll-overlay';
458
- copyToClipboard(text) {
459
- navigator.clipboard.writeText(text).then(() => console.log('Copied:', text));
460
- }
461
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsScrollOverlayDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
462
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: LibsUiComponentsScrollOverlayDemoComponent, isStandalone: true, selector: "lib-scroll-overlay-demo", ngImport: i0, template: "<div class=\"max-w-6xl mx-auto p-5 font-sans text-gray-800\">\n <header class=\"text-center py-10 bg-white rounded-lg mb-8 shadow-sm\">\n <h1 class=\"text-4xl font-bold mb-2\">Demo Scroll Overlay</h1>\n <p class=\"text-xl text-gray-500\">&#64;libs-ui/components-scroll-overlay</p>\n </header>\n\n <main>\n <!-- Gi\u1EDBi thi\u1EC7u -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Gi\u1EDBi thi\u1EC7u</h2>\n <p>\n <code>scroll-overlay</code>\n l\u00E0 m\u1ED9t directive gi\u00FAp tu\u1EF3 bi\u1EBFn scrollbar tr\u00EAn b\u1EA5t k\u1EF3 ph\u1EA7n t\u1EED n\u00E0o trong Angular, h\u1ED7 tr\u1EE3 tu\u1EF3 ch\u1EC9nh m\u00E0u, k\u00EDch th\u01B0\u1EDBc, \u1EA9n/hi\u1EC7n v\u00E0 s\u1EF1 ki\u1EC7n scroll.\n </p>\n </section>\n\n <!-- C\u00E0i \u0111\u1EB7t -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">C\u00E0i \u0111\u1EB7t</h2>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg mb-4\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandNpm }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandNpm)\">\n Sao ch\u00E9p\n </button>\n </div>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandYarn }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandYarn)\">\n Sao ch\u00E9p\n </button>\n </div>\n </section>\n\n <!-- Demo Tr\u1EF1c ti\u1EBFp -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Demo Tr\u1EF1c ti\u1EBFp</h2>\n <div class=\"grid grid-cols-4 gap-4 mb-6\">\n <button\n *ngFor=\"let sc of scenarioOptions\"\n (click)=\"selectedScenario = sc\"\n class=\"px-3 py-1 border rounded\"\n [class.bg-blue-500]=\"selectedScenario === sc\"\n [class.text-white]=\"selectedScenario === sc\">\n {{ sc }}\n </button>\n </div>\n <div class=\"p-4 bg-gray-50 rounded-lg h-[300px]\">\n <div\n LibsUiComponentsScrollOverlayDirective\n [options]=\"options\"\n (outScroll)=\"onScroll()\"\n (outScrollTop)=\"onScrollTop()\"\n (outScrollBottom)=\"onScrollBottom()\"\n class=\"w-full h-full\">\n <div\n class=\"p-2\"\n [innerText]=\"content\"\n [class.whitespace-pre-wrap]=\"selectedScenario !== 'horizontal'\"\n [class.whitespace-nowrap]=\"selectedScenario === 'horizontal'\"></div>\n </div>\n </div>\n <p class=\"mt-4 text-gray-700\">S\u1EF1 ki\u1EC7n: {{ lastEvent() }}</p>\n </section>\n\n <!-- C\u00E1ch s\u1EED d\u1EE5ng -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">C\u00E1ch s\u1EED d\u1EE5ng</h2>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm\">\n <code ngNonBindable>&lt;div LibsUiComponentsScrollOverlayDirective [options]=\"&#123; scrollbarWidth:12, scrollThumbColor:'#3b82f6' &#125;\" style=\"width:300px;height:200px;overflow:auto;\"&gt;\n N\u1ED9i dung d\u00E0i...\n&lt;/div&gt;</code>\n </pre>\n </section>\n\n <!-- API Reference -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">API Reference</h2>\n <h3 class=\"text-xl font-semibold mb-3\">Inputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">T\u00EAn</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u1EB7c \u0111\u1ECBnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let input of inputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ input.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ input.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Outputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">T\u00EAn</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let output of outputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ output.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Options</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Thu\u1ED9c t\u00EDnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u1EB7c \u0111\u1ECBnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let opt of optionsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ opt.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ opt.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Interfaces</h3>\n <div class=\"space-y-6\">\n <div\n *ngFor=\"let intf of interfacesDoc\"\n class=\"bg-gray-50 p-6 rounded-lg\">\n <h4 class=\"font-semibold mb-2\">{{ intf.name }}</h4>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm mb-3\"><code>{{ intf.type }}</code></pre>\n <p>{{ intf.description }}</p>\n </div>\n </div>\n </section>\n </main>\n</div>\n", styles: ["@charset \"UTF-8\";.demo-container{padding:24px;font-family:system-ui,-apple-system,sans-serif;max-width:1200px;margin:0 auto}.demo-intro{margin-bottom:32px}.demo-intro h3{color:#333;margin-bottom:16px}.demo-intro ul{list-style:none;padding:0}.demo-intro ul li{margin-bottom:8px;padding-left:20px;position:relative}.demo-intro ul li:before{content:\"\\2022\";position:absolute;left:0;color:#3b82f6}.demo-features{margin-bottom:32px}.demo-features h3{color:#333;margin-bottom:16px}.features-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px}.feature-item{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0}.feature-item h4{color:#1e40af;margin:0 0 8px}.feature-item p{margin:0;color:#64748b}.demo-api{margin-bottom:48px}.demo-api h3{color:#333;margin-bottom:24px}.api-section{margin-bottom:32px}.api-section h4{color:#1e40af;margin-bottom:16px}.api-table{overflow-x:auto}.api-table table{width:100%;border-collapse:collapse;background:#fff;border-radius:8px;border:1px solid #e2e8f0}.api-table table th,.api-table table td{padding:12px 16px;text-align:left;border-bottom:1px solid #e2e8f0}.api-table table th{background:#f8fafc;font-weight:600;color:#1e40af}.api-table table td{color:#64748b}.api-table table td:first-child{font-family:Fira Code,monospace;color:#334155}.api-table table td:nth-child(2){font-family:Fira Code,monospace;color:#3b82f6}.api-table table tr:last-child td{border-bottom:none}.demo-section{margin-bottom:48px}.demo-section h3{color:#333;margin-bottom:16px}.demo-description{margin-bottom:16px}.demo-description p{color:#64748b;margin-bottom:12px}.demo-description pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.demo-description pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155}.demo-box{display:flex;gap:16px;align-items:flex-start}.event-log{padding:16px;background:#f5f5f5;border-radius:4px;min-width:200px}.event-log p{margin:0;font-size:14px;color:#666}.demo-notes{margin-top:48px;padding:24px;background:#f8fafc;border-radius:8px;border:1px solid #e2e8f0}.demo-notes h3{color:#333;margin-bottom:16px}.demo-notes ul{list-style:none;padding:0;margin:0}.demo-notes ul li{color:#64748b;margin-bottom:12px;padding-left:24px;position:relative}.demo-notes ul li:before{content:\"\\2192\";position:absolute;left:0;color:#3b82f6}.demo-notes ul li:last-child{margin-bottom:0}.interface-description{margin-bottom:24px}.interface-description p{color:#64748b;margin-bottom:16px}.interface-description pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.interface-description pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155;line-height:1.6}.interface-usage{margin-bottom:24px}.interface-usage h5{color:#1e40af;margin-bottom:12px;font-size:16px}.interface-usage pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.interface-usage pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155;line-height:1.6}.interface-usage pre code .comment{color:#64748b}.interface-notes{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0}.interface-notes h5{color:#1e40af;margin-bottom:12px;font-size:16px}.interface-notes ul{list-style:none;padding:0;margin:0}.interface-notes ul li{color:#64748b;margin-bottom:8px;padding-left:20px;position:relative}.interface-notes ul li:before{content:\"\\2022\";position:absolute;left:0;color:#3b82f6}.interface-notes ul li:last-child{margin-bottom:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: LibsUiComponentsScrollOverlayDirective, selector: "[LibsUiComponentsScrollOverlayDirective]", inputs: ["debugMode", "ignoreInit", "classContainer", "options", "elementCheckScrollX", "elementCheckScrollY", "elementScroll"], outputs: ["outScroll", "outScrollX", "outScrollY", "outScrollTop", "outScrollBottom"] }] });
463
- }
464
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsScrollOverlayDemoComponent, decorators: [{
465
- type: Component,
466
- args: [{ selector: 'lib-scroll-overlay-demo', standalone: true, imports: [CommonModule, LibsUiComponentsScrollOverlayDirective], template: "<div class=\"max-w-6xl mx-auto p-5 font-sans text-gray-800\">\n <header class=\"text-center py-10 bg-white rounded-lg mb-8 shadow-sm\">\n <h1 class=\"text-4xl font-bold mb-2\">Demo Scroll Overlay</h1>\n <p class=\"text-xl text-gray-500\">&#64;libs-ui/components-scroll-overlay</p>\n </header>\n\n <main>\n <!-- Gi\u1EDBi thi\u1EC7u -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Gi\u1EDBi thi\u1EC7u</h2>\n <p>\n <code>scroll-overlay</code>\n l\u00E0 m\u1ED9t directive gi\u00FAp tu\u1EF3 bi\u1EBFn scrollbar tr\u00EAn b\u1EA5t k\u1EF3 ph\u1EA7n t\u1EED n\u00E0o trong Angular, h\u1ED7 tr\u1EE3 tu\u1EF3 ch\u1EC9nh m\u00E0u, k\u00EDch th\u01B0\u1EDBc, \u1EA9n/hi\u1EC7n v\u00E0 s\u1EF1 ki\u1EC7n scroll.\n </p>\n </section>\n\n <!-- C\u00E0i \u0111\u1EB7t -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">C\u00E0i \u0111\u1EB7t</h2>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg mb-4\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandNpm }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandNpm)\">\n Sao ch\u00E9p\n </button>\n </div>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandYarn }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandYarn)\">\n Sao ch\u00E9p\n </button>\n </div>\n </section>\n\n <!-- Demo Tr\u1EF1c ti\u1EBFp -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Demo Tr\u1EF1c ti\u1EBFp</h2>\n <div class=\"grid grid-cols-4 gap-4 mb-6\">\n <button\n *ngFor=\"let sc of scenarioOptions\"\n (click)=\"selectedScenario = sc\"\n class=\"px-3 py-1 border rounded\"\n [class.bg-blue-500]=\"selectedScenario === sc\"\n [class.text-white]=\"selectedScenario === sc\">\n {{ sc }}\n </button>\n </div>\n <div class=\"p-4 bg-gray-50 rounded-lg h-[300px]\">\n <div\n LibsUiComponentsScrollOverlayDirective\n [options]=\"options\"\n (outScroll)=\"onScroll()\"\n (outScrollTop)=\"onScrollTop()\"\n (outScrollBottom)=\"onScrollBottom()\"\n class=\"w-full h-full\">\n <div\n class=\"p-2\"\n [innerText]=\"content\"\n [class.whitespace-pre-wrap]=\"selectedScenario !== 'horizontal'\"\n [class.whitespace-nowrap]=\"selectedScenario === 'horizontal'\"></div>\n </div>\n </div>\n <p class=\"mt-4 text-gray-700\">S\u1EF1 ki\u1EC7n: {{ lastEvent() }}</p>\n </section>\n\n <!-- C\u00E1ch s\u1EED d\u1EE5ng -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">C\u00E1ch s\u1EED d\u1EE5ng</h2>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm\">\n <code ngNonBindable>&lt;div LibsUiComponentsScrollOverlayDirective [options]=\"&#123; scrollbarWidth:12, scrollThumbColor:'#3b82f6' &#125;\" style=\"width:300px;height:200px;overflow:auto;\"&gt;\n N\u1ED9i dung d\u00E0i...\n&lt;/div&gt;</code>\n </pre>\n </section>\n\n <!-- API Reference -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">API Reference</h2>\n <h3 class=\"text-xl font-semibold mb-3\">Inputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">T\u00EAn</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u1EB7c \u0111\u1ECBnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let input of inputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ input.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ input.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Outputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">T\u00EAn</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let output of outputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ output.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Options</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Thu\u1ED9c t\u00EDnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u1EB7c \u0111\u1ECBnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let opt of optionsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ opt.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ opt.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Interfaces</h3>\n <div class=\"space-y-6\">\n <div\n *ngFor=\"let intf of interfacesDoc\"\n class=\"bg-gray-50 p-6 rounded-lg\">\n <h4 class=\"font-semibold mb-2\">{{ intf.name }}</h4>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm mb-3\"><code>{{ intf.type }}</code></pre>\n <p>{{ intf.description }}</p>\n </div>\n </div>\n </section>\n </main>\n</div>\n", styles: ["@charset \"UTF-8\";.demo-container{padding:24px;font-family:system-ui,-apple-system,sans-serif;max-width:1200px;margin:0 auto}.demo-intro{margin-bottom:32px}.demo-intro h3{color:#333;margin-bottom:16px}.demo-intro ul{list-style:none;padding:0}.demo-intro ul li{margin-bottom:8px;padding-left:20px;position:relative}.demo-intro ul li:before{content:\"\\2022\";position:absolute;left:0;color:#3b82f6}.demo-features{margin-bottom:32px}.demo-features h3{color:#333;margin-bottom:16px}.features-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px}.feature-item{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0}.feature-item h4{color:#1e40af;margin:0 0 8px}.feature-item p{margin:0;color:#64748b}.demo-api{margin-bottom:48px}.demo-api h3{color:#333;margin-bottom:24px}.api-section{margin-bottom:32px}.api-section h4{color:#1e40af;margin-bottom:16px}.api-table{overflow-x:auto}.api-table table{width:100%;border-collapse:collapse;background:#fff;border-radius:8px;border:1px solid #e2e8f0}.api-table table th,.api-table table td{padding:12px 16px;text-align:left;border-bottom:1px solid #e2e8f0}.api-table table th{background:#f8fafc;font-weight:600;color:#1e40af}.api-table table td{color:#64748b}.api-table table td:first-child{font-family:Fira Code,monospace;color:#334155}.api-table table td:nth-child(2){font-family:Fira Code,monospace;color:#3b82f6}.api-table table tr:last-child td{border-bottom:none}.demo-section{margin-bottom:48px}.demo-section h3{color:#333;margin-bottom:16px}.demo-description{margin-bottom:16px}.demo-description p{color:#64748b;margin-bottom:12px}.demo-description pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.demo-description pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155}.demo-box{display:flex;gap:16px;align-items:flex-start}.event-log{padding:16px;background:#f5f5f5;border-radius:4px;min-width:200px}.event-log p{margin:0;font-size:14px;color:#666}.demo-notes{margin-top:48px;padding:24px;background:#f8fafc;border-radius:8px;border:1px solid #e2e8f0}.demo-notes h3{color:#333;margin-bottom:16px}.demo-notes ul{list-style:none;padding:0;margin:0}.demo-notes ul li{color:#64748b;margin-bottom:12px;padding-left:24px;position:relative}.demo-notes ul li:before{content:\"\\2192\";position:absolute;left:0;color:#3b82f6}.demo-notes ul li:last-child{margin-bottom:0}.interface-description{margin-bottom:24px}.interface-description p{color:#64748b;margin-bottom:16px}.interface-description pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.interface-description pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155;line-height:1.6}.interface-usage{margin-bottom:24px}.interface-usage h5{color:#1e40af;margin-bottom:12px;font-size:16px}.interface-usage pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.interface-usage pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155;line-height:1.6}.interface-usage pre code .comment{color:#64748b}.interface-notes{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0}.interface-notes h5{color:#1e40af;margin-bottom:12px;font-size:16px}.interface-notes ul{list-style:none;padding:0;margin:0}.interface-notes ul li{color:#64748b;margin-bottom:8px;padding-left:20px;position:relative}.interface-notes ul li:before{content:\"\\2022\";position:absolute;left:0;color:#3b82f6}.interface-notes ul li:last-child{margin-bottom:0}\n"] }]
467
- }] });
468
-
469
388
  /**
470
389
  * Generated bundle index. Do not edit.
471
390
  */
472
391
 
473
- export { LibsUiComponentsScrollOverlayDemoComponent, LibsUiComponentsScrollOverlayDirective };
392
+ export { LibsUiComponentsScrollOverlayDirective };
474
393
  //# sourceMappingURL=libs-ui-components-scroll-overlay.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"libs-ui-components-scroll-overlay.mjs","sources":["../../../../../libs-ui/components/scroll-overlay/src/scroll-overlay.directive.ts","../../../../../libs-ui/components/scroll-overlay/src/demo/scroll-overlay.demo.ts","../../../../../libs-ui/components/scroll-overlay/src/demo/scroll-overlay.demo.html","../../../../../libs-ui/components/scroll-overlay/src/libs-ui-components-scroll-overlay.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DestroyRef, Directive, ElementRef, OnDestroy, Renderer2, computed, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { checkMouseOverInContainer, getDragEventByElement } from '@libs-ui/utils';\nimport { Subscription, fromEvent, interval, switchMap, takeUntil, tap } from 'rxjs';\nimport { IScrollOverlayOptions, TYPE_SCROLL_DIRECTION } from './scroll.interface';\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiComponentsScrollOverlayDirective]',\n standalone: true,\n})\nexport class LibsUiComponentsScrollOverlayDirective implements OnDestroy {\n // #region PROPERTY\n private readonly styles = computed(\n () => `\n .scrollbar-track{\n background-color:${this.scrollbarColor()};\n }\n .scrollbar-track:hover{\n background-color:${this.scrollbarHoverColor()};\n }\n .scrollbar-track-X {\n width:100%;\n position: absolute;\n bottom: 0;\n left: 0;\n visibility: hidden;\n cursor: pointer;\n opacity: 0;\n z-index: 1;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n }\n\n .scrollbar-track-Y {\n height:100%;\n position: absolute;\n top: 0;\n right: 0;\n visibility: hidden;\n cursor: pointer;\n opacity: 0;\n z-index: 1;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n }\n\n .scrollbar-thumb{\n background-color:${this.scrollThumbColor()};\n }\n .scrollbar-thumb:hover{\n background-color:${this.scrollThumbHoverColor()};\n }\n\n .scrollbar-thumb-X {\n height: calc(100% - ${this.scrollbarPadding() * 2}px);\n bottom: ${this.scrollbarPadding()}px;\n border-radius: 4px;\n cursor: grabbing;\n transition: background-color 0.3s;\n position: absolute;\n }\n\n .scrollbar-thumb-Y {\n width: calc(100% - ${this.scrollbarPadding() * 2}px);\n right: ${this.scrollbarPadding()}px;\n border-radius: 4px;\n cursor: grabbing;\n transition: background-color 0.3s;\n position: absolute;\n }\n\n .lib-ui-scroll-overlay-container .lib-ui-scroll-overlay-element::-webkit-scrollbar {\n width: 0 !important;\n height: 0 !important;\n }\n `,\n {}\n );\n private isScrollThumb = signal<boolean>(false);\n private keepDisplayThumb = signal<boolean>(false);\n private subsX = new Subscription();\n private subsY = new Subscription();\n private scrollbarWidth = computed(() => this.options()?.scrollbarWidth ?? 10); // Chiều rộng thanh cuộn\n private scrollbarPadding = computed(() => this.options()?.scrollbarPadding ?? 2); // Chiều rộng thanh cuộn\n private scrollbarColor = computed(() => this.options()?.scrollbarColor ?? '');\n private scrollbarHoverColor = computed(() => this.options()?.scrollbarColor ?? '#CDD0D640');\n private scrollThumbColor = computed(() => this.options()?.scrollThumbColor ?? '#CDD0D6');\n private scrollThumbHoverColor = computed(() => this.options()?.scrollThumbHoverColor ?? '#9CA2AD');\n private readonly divContainer = document.createElement('div');\n private readonly trackX: HTMLElement = document.createElement('div');\n private readonly thumbX: HTMLElement = document.createElement('div');\n private readonly trackY: HTMLElement = document.createElement('div');\n private readonly thumbY: HTMLElement = document.createElement('div');\n\n // #region INPUT\n readonly debugMode = input<boolean>(false);\n readonly ignoreInit = input<boolean>(false);\n readonly classContainer = input<string, string | undefined>('', { transform: (value) => value ?? '' });\n readonly options = input<IScrollOverlayOptions | undefined>(Object.assign({}));\n readonly elementCheckScrollX = input<HTMLElement>();\n readonly elementCheckScrollY = input<HTMLElement>();\n readonly elementScroll = input<HTMLElement>();\n\n // #region OUTPUT\n readonly outScroll = output<Event>();\n readonly outScrollX = output<Event>();\n readonly outScrollY = output<Event>();\n readonly outScrollTop = output<Event>();\n readonly outScrollBottom = output<Event>();\n\n // #region INJECT\n private element = inject(ElementRef);\n private render2 = inject(Renderer2);\n private destroyRef = inject(DestroyRef);\n\n constructor() {\n effect(() => {\n if (this.ignoreInit()) {\n return;\n }\n const options = this.options();\n this.divContainer.className = '';\n this.classContainer()\n ?.split(' ')\n .forEach((className) => {\n if (!className) {\n return;\n }\n this.divContainer.classList.add(className);\n });\n\n untracked(() => {\n this.Element.classList.toggle('overflow-hidden', options?.scrollX === 'hidden' && options?.scrollY === 'hidden');\n if (options?.scrollX !== 'hidden') {\n this.subsX.unsubscribe();\n this.trackX.className = '';\n this.thumbX.className = '';\n this.trackX.style.height = `${this.scrollbarWidth()}px`;\n this.createScrollbar('X', this.trackX, this.thumbX);\n this.bindEventsScrollBar('X', this.trackX);\n\n this.handlerDragAndDropThumb('X');\n this.handlerClickTrack('X');\n }\n\n if (options?.scrollY !== 'hidden') {\n this.trackY.className = '';\n this.thumbY.className = '';\n this.trackY.style.width = `${this.scrollbarWidth()}px`;\n this.subsY.unsubscribe();\n this.createScrollbar('Y', this.trackY, this.thumbY);\n this.bindEventsScrollBar('Y', this.trackY);\n\n this.handlerDragAndDropThumb('Y');\n this.handlerClickTrack('Y');\n }\n });\n });\n }\n\n // #region FUNCTIONS\n private get Element(): HTMLElement {\n return this.elementScroll() || this.element.nativeElement;\n }\n\n private createScrollbar(scrollDirection: TYPE_SCROLL_DIRECTION, trackEl: HTMLElement, thumbEl: HTMLElement) {\n const idStyleTag = '#id-style-tag-custom-scroll-overlay';\n const styleElCustomScrollOverlay = document.getElementById(idStyleTag);\n\n if (!styleElCustomScrollOverlay) {\n const styleEl = document.createElement('style');\n styleEl.setAttribute('id', idStyleTag);\n styleEl.innerHTML = this.styles();\n document.head.append(styleEl);\n }\n\n const stylesProperty = {\n 'box-sizing': 'border-box',\n 'scrollbar-width': 'none',\n 'scrollbar-color': this.options()?.ignoreTransparentScrollBarColorDefault ? 'auto' : 'transparent transparent',\n overflow: 'hidden',\n 'overflow-x': `${this.options()?.scrollX || 'scroll'}`,\n 'overflow-y': `${this.options()?.scrollY || 'scroll'}`,\n } as any;\n\n Object.keys(stylesProperty).forEach((key) => {\n this.render2.setStyle(this.Element, key, stylesProperty[key], 1);\n });\n\n trackEl.classList.add(`scrollbar-track`);\n trackEl.classList.add(`scrollbar-track-${scrollDirection}`);\n\n thumbEl.classList.add(`scrollbar-thumb`);\n thumbEl.classList.add(`scrollbar-thumb-${scrollDirection}`);\n trackEl.appendChild(thumbEl);\n if (this.Element.className) {\n this.Element.className.split(' ').forEach((className: string) => {\n if (\n className &&\n (['w-full', 'w-screen', 'h-full', 'h-screen', 'shrink-0'].includes(className) || className.includes('min-h-') || className.includes('min-w-') || /^(!?)(h|w)-\\[[0-9]+px\\]$/.test(className)) &&\n !this.divContainer.classList.contains(className)\n ) {\n this.divContainer.classList.add(className);\n }\n });\n if (!this.Element.className.includes('min-h-')) {\n this.divContainer.classList.add('min-h-0');\n }\n if (!this.Element.className.includes('min-w-')) {\n this.divContainer.classList.add('min-w-0');\n }\n if (!this.Element.className.includes('lib-ui-scroll-overlay-element')) {\n this.Element.classList.add('lib-ui-scroll-overlay-element');\n }\n }\n if (!this.divContainer.classList.contains('lib-ui-scroll-overlay-container')) {\n this.divContainer.classList.add('lib-ui-scroll-overlay-container');\n }\n this.divContainer.appendChild(trackEl);\n\n if (!this.divContainer.style.position) {\n this.Element.parentElement?.insertBefore(this.divContainer, this.Element);\n this.divContainer.style.position = 'relative';\n }\n this.divContainer.append(this.Element);\n this.updateScrollbarSize(scrollDirection);\n }\n\n private bindEventsScrollBar(scrollDirection: TYPE_SCROLL_DIRECTION, trackEl: HTMLElement) {\n let scrollLeft = this.Element.scrollLeft;\n let scrollTop = this.Element.scrollTop;\n const subs: Subscription = fromEvent<Event>(this.Element, 'scroll')\n .pipe(\n tap((event) => {\n const target = this.Element;\n\n this.outScroll.emit(event);\n if (scrollDirection === 'X') {\n if (target.scrollLeft && target.scrollLeft + target.offsetWidth >= target.scrollWidth) {\n target.scrollLeft = target.scrollWidth - target.offsetWidth - (target.offsetWidth - target.clientWidth);\n }\n\n if (target.scrollLeft !== scrollLeft) {\n this.outScrollX.emit(event);\n }\n scrollLeft = target.scrollLeft;\n this.updateScrollbarPosition(scrollDirection);\n\n return;\n }\n\n if (target.scrollTop === scrollTop) {\n return;\n }\n this.updateScrollbarPosition(scrollDirection);\n scrollTop = target.scrollTop;\n this.outScrollY.emit(event);\n\n if (target.scrollTop === 0) {\n return this.outScrollTop.emit(event);\n }\n\n if (target.scrollHeight <= target.scrollTop + target.offsetHeight + 3) {\n return this.outScrollBottom.emit(event);\n }\n }),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe();\n\n subs.add(\n fromEvent(document, 'resize')\n .pipe(tap(this.updateScrollbarSize.bind(this, scrollDirection)), takeUntilDestroyed(this.destroyRef))\n .subscribe()\n );\n\n const mouseLeave = fromEvent(this.divContainer, 'mouseleave');\n const mouseenter = fromEvent(this.divContainer, 'mouseenter');\n\n subs.add(\n mouseenter\n .pipe(\n tap(() => {\n if ((scrollDirection === 'X' && !this.options()?.scrollXOpacity0) || (scrollDirection === 'Y' && !this.options()?.scrollYOpacity0)) {\n trackEl.style.visibility = 'visible';\n trackEl.style.opacity = '1';\n }\n this.updateScrollbarSize(scrollDirection);\n }),\n switchMap(() => interval(1000).pipe(takeUntil(mouseLeave))),\n tap(this.updateScrollbarSize.bind(this, scrollDirection)),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe()\n );\n\n subs.add(\n mouseLeave\n .pipe(\n tap(() => {\n if (this.keepDisplayThumb()) {\n return;\n }\n trackEl.style.visibility = 'hidden';\n trackEl.style.opacity = '0';\n }),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe()\n );\n\n if (scrollDirection === 'X') {\n this.subsX = subs;\n\n return;\n }\n\n if (scrollDirection === 'Y') {\n this.subsY = subs;\n\n return;\n }\n }\n\n protected handlerClickTrack(scrollDirection: TYPE_SCROLL_DIRECTION) {\n const elementTrack = scrollDirection === 'X' ? this.trackX : this.trackY;\n const elementThumb = scrollDirection === 'X' ? this.thumbX : this.thumbY;\n const subs = scrollDirection === 'X' ? this.subsX : this.subsY;\n\n subs.add(\n fromEvent<MouseEvent>(elementTrack, 'click').subscribe((e) => {\n if (this.isScrollThumb()) {\n return;\n }\n if ((scrollDirection === 'X' && e.clientX < elementThumb.getBoundingClientRect().left) || (scrollDirection === 'Y' && e.clientY < elementThumb.getBoundingClientRect().top)) {\n this.updateScrollPositionByUserAction(scrollDirection, e, 'smooth', 0);\n return;\n }\n\n if (scrollDirection === 'X') {\n this.updateScrollPositionByUserAction(scrollDirection, e, 'smooth', -1 * elementThumb.getBoundingClientRect().width);\n return;\n }\n this.updateScrollPositionByUserAction(scrollDirection, e, 'smooth', -1 * elementThumb.getBoundingClientRect().height);\n })\n );\n }\n\n protected handlerDragAndDropThumb(scrollDirection: TYPE_SCROLL_DIRECTION) {\n const elementTrack = scrollDirection === 'X' ? this.trackX : this.trackY;\n const elementThumb = scrollDirection === 'X' ? this.thumbX : this.thumbY;\n const subs = scrollDirection === 'X' ? this.subsX : this.subsY;\n let lengthThumbToPointClick = 0;\n\n subs.add(\n getDragEventByElement({\n elementMouseDown: elementThumb,\n functionMouseDown: (mouseEvent: MouseEvent) => {\n this.isScrollThumb.set(true);\n this.keepDisplayThumb.set(true);\n if (scrollDirection === 'X') {\n lengthThumbToPointClick = elementThumb.getBoundingClientRect().left - mouseEvent.clientX;\n return;\n }\n lengthThumbToPointClick = elementThumb.getBoundingClientRect().top - mouseEvent.clientY;\n },\n functionMouseUp: (mouseEvent: MouseEvent) => {\n this.keepDisplayThumb.set(false);\n lengthThumbToPointClick = 0;\n if (!checkMouseOverInContainer(mouseEvent, this.Element)) {\n elementTrack.style.visibility = 'hidden';\n elementTrack.style.opacity = '0';\n }\n setTimeout(() => {\n this.isScrollThumb.set(false);\n }, 250);\n },\n destroyRef: this.destroyRef,\n }).subscribe((mouseEvent: MouseEvent) => {\n this.updateScrollPositionByUserAction(scrollDirection, mouseEvent, 'auto', lengthThumbToPointClick);\n })\n );\n }\n\n private updateScrollPositionByUserAction(scrollDirection: TYPE_SCROLL_DIRECTION, e: MouseEvent, behavior: 'auto' | 'smooth', lengthThumbToPointClick = 0) {\n e.stopPropagation();\n if (scrollDirection === 'X') {\n const containerWidth = this.Element.offsetWidth;\n const contentWidth = (this.elementCheckScrollX() || this.Element).scrollWidth;\n const thumbPosition = e.clientX - this.Element.getBoundingClientRect().left + lengthThumbToPointClick;\n const scrollLeft = (thumbPosition / (containerWidth - this.thumbX.offsetWidth)) * (contentWidth - containerWidth);\n\n this.Element.scroll({ left: scrollLeft, behavior });\n return;\n }\n const containerHeight = this.Element.offsetHeight;\n const contentHeight = (this.elementCheckScrollY() || this.Element).scrollHeight;\n const thumbPosition = e.clientY - this.Element.getBoundingClientRect().top + lengthThumbToPointClick;\n const scrollTop = (thumbPosition / (containerHeight - this.thumbY.offsetHeight)) * (contentHeight - containerHeight);\n\n this.Element.scroll({ top: scrollTop, behavior });\n }\n\n private updateScrollbarSize(scrollDirection: TYPE_SCROLL_DIRECTION) {\n if (scrollDirection === 'X') {\n const containerWidth = this.Element.offsetWidth;\n const contentWidth = (this.elementCheckScrollX() || this.Element).scrollWidth;\n const thumbWidth = (containerWidth / contentWidth) * containerWidth;\n\n this.thumbX.style.width = `${Math.max(20, thumbWidth)}px`;\n this.trackX.style.display = 'none';\n if (contentWidth > containerWidth) {\n this.trackX.style.display = 'block';\n }\n this.updateScrollbarPosition(scrollDirection);\n\n return;\n }\n\n const containerHeight = this.Element.offsetHeight;\n const contentHeight = (this.elementCheckScrollY() || this.Element).scrollHeight;\n const thumbHeight = (containerHeight / contentHeight) * containerHeight;\n\n this.thumbY.style.height = `${Math.max(20, thumbHeight)}px`;\n this.trackY.style.display = 'none';\n if (contentHeight > containerHeight) {\n this.trackY.style.display = 'block';\n }\n\n this.updateScrollbarPosition('Y');\n }\n\n private updateScrollbarPosition(scrollDirection: TYPE_SCROLL_DIRECTION) {\n if (scrollDirection === 'X') {\n const containerWidth = this.Element.offsetWidth;\n const contentWidth = (this.elementCheckScrollX() || this.Element).scrollWidth;\n const scrollLeft = this.Element.scrollLeft;\n const thumbPosition = (scrollLeft / (contentWidth - containerWidth)) * (containerWidth - this.thumbX.offsetWidth);\n\n this.thumbX.style.left = `${thumbPosition}px`;\n\n return;\n }\n const containerHeight = this.Element.offsetHeight;\n const contentHeight = (this.elementCheckScrollY() || this.Element).scrollHeight;\n const scrollTop = this.Element.scrollTop;\n const thumbPosition = (scrollTop / (contentHeight - containerHeight)) * (containerHeight - this.thumbY.offsetHeight);\n\n this.thumbY.style.top = `${thumbPosition}px`;\n }\n\n ngOnDestroy(): void {\n this.divContainer.remove();\n this.subsX.unsubscribe();\n this.subsY.unsubscribe();\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, signal } from '@angular/core';\nimport { LibsUiComponentsScrollOverlayDirective } from '../scroll-overlay.directive';\nimport { IScrollOverlayOptions } from '../scroll.interface';\n\n@Component({\n selector: 'lib-scroll-overlay-demo',\n standalone: true,\n imports: [CommonModule, LibsUiComponentsScrollOverlayDirective],\n templateUrl: './scroll-overlay.demo.html',\n styleUrls: ['./scroll-overlay.demo.scss'],\n})\nexport class LibsUiComponentsScrollOverlayDemoComponent {\n // Demo text content: generate 5000 words for vertical scrolling\n longContent = signal(Array.from({ length: 5000 }, (_, i) => `Lorem${i + 1}`).join(' '));\n // Demo horizontal content: generate 5000 words for horizontal scrolling\n longHorizontalContent = signal(Array.from({ length: 5000 }, (_, i) => `Word${i + 1}`).join(' '));\n\n // Scenario selection\n scenarioOptions = ['default', 'customStyle', 'autoHide', 'horizontal'] as const;\n selectedScenario: (typeof this.scenarioOptions)[number] = 'default';\n\n // Options signals\n customStyleOptions = signal<IScrollOverlayOptions>({ scrollbarWidth: 12, scrollbarColor: '#f3f4f6', scrollbarHoverColor: '#e5e7eb', scrollThumbColor: '#3b82f6', scrollThumbHoverColor: '#2563eb', scrollbarPadding: 4 });\n autoHideOptions = signal<IScrollOverlayOptions>({ scrollYOpacity0: true, scrollbarWidth: 8, scrollbarColor: 'transparent', scrollThumbColor: '#9ca3af', scrollThumbHoverColor: '#6b7280' });\n horizontalOptions = signal<IScrollOverlayOptions>({ scrollX: 'scroll', scrollY: 'hidden', scrollbarWidth: 8, scrollbarColor: '#f3f4f6', scrollThumbColor: '#3b82f6' });\n\n // Scroll event log\n lastEvent = signal<string>('No events yet');\n\n // Helpers\n get options(): IScrollOverlayOptions | undefined {\n switch (this.selectedScenario) {\n case 'customStyle':\n return this.customStyleOptions();\n case 'autoHide':\n return this.autoHideOptions();\n case 'horizontal':\n return this.horizontalOptions();\n default:\n return undefined;\n }\n }\n\n get content(): string {\n return this.selectedScenario === 'horizontal' ? this.longHorizontalContent() : this.longContent();\n }\n\n // Event handlers\n onScroll() {\n this.lastEvent.set('Scroll event fired');\n }\n onScrollTop() {\n this.lastEvent.set('Reached top');\n }\n onScrollBottom() {\n this.lastEvent.set('Reached bottom');\n }\n\n // API docs\n inputsDoc = [\n { name: 'options', type: 'IScrollOverlayOptions', default: 'undefined', description: 'Cấu hình tuỳ chỉnh scrollbar' },\n { name: 'debugMode', type: 'boolean', default: 'false', description: 'Bật chế độ debug' },\n { name: 'notShowScrollBarX', type: 'boolean', default: 'false', description: 'Ẩn scrollbar ngang' },\n { name: 'notShowScrollBarY', type: 'boolean', default: 'false', description: 'Ẩn scrollbar dọc' },\n ];\n outputsDoc = [\n { name: 'outScroll', type: 'Event', description: 'Bắn ra khi scroll bất kỳ' },\n { name: 'outScrollTop', type: 'Event', description: 'Bắn ra khi scroll đến top' },\n { name: 'outScrollBottom', type: 'Event', description: 'Bắn ra khi scroll đến bottom' },\n ];\n optionsDoc = [\n { name: 'scrollbarWidth', type: 'number', default: 'undefined', description: 'Chiều rộng scrollbar (px)' },\n { name: 'scrollbarColor', type: 'string', default: 'undefined', description: 'Màu track scrollbar' },\n { name: 'scrollbarHoverColor', type: 'string', default: 'undefined', description: 'Màu track khi hover' },\n { name: 'scrollThumbColor', type: 'string', default: 'undefined', description: 'Màu thumb' },\n { name: 'scrollThumbHoverColor', type: 'string', default: 'undefined', description: 'Màu thumb khi hover' },\n { name: 'scrollbarPadding', type: 'number', default: 'undefined', description: 'Padding scrollbar' },\n { name: 'scrollX', type: `'hidden' | 'scroll'`, default: 'undefined', description: 'Kiểu scroll X' },\n { name: 'scrollXOpacity0', type: 'boolean', default: 'undefined', description: 'Ẩn track X khi không hover' },\n { name: 'scrollY', type: `'hidden' | 'scroll'`, default: 'undefined', description: 'Kiểu scroll Y' },\n { name: 'scrollYOpacity0', type: 'boolean', default: 'undefined', description: 'Ẩn track Y khi không hover' },\n ];\n interfacesDoc = [{ name: 'IScrollOverlayOptions', type: 'interface', description: 'Các tuỳ chọn cấu hình scroll-overlay' }];\n\n // Installation commands\n installCommandNpm = 'npm install @libs-ui/components-scroll-overlay';\n installCommandYarn = 'yarn add @libs-ui/components-scroll-overlay';\n\n copyToClipboard(text: string) {\n navigator.clipboard.writeText(text).then(() => console.log('Copied:', text));\n }\n}\n","<div class=\"max-w-6xl mx-auto p-5 font-sans text-gray-800\">\n <header class=\"text-center py-10 bg-white rounded-lg mb-8 shadow-sm\">\n <h1 class=\"text-4xl font-bold mb-2\">Demo Scroll Overlay</h1>\n <p class=\"text-xl text-gray-500\">&#64;libs-ui/components-scroll-overlay</p>\n </header>\n\n <main>\n <!-- Giới thiệu -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Giới thiệu</h2>\n <p>\n <code>scroll-overlay</code>\n là một directive giúp tuỳ biến scrollbar trên bất kỳ phần tử nào trong Angular, hỗ trợ tuỳ chỉnh màu, kích thước, ẩn/hiện và sự kiện scroll.\n </p>\n </section>\n\n <!-- Cài đặt -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Cài đặt</h2>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg mb-4\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandNpm }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandNpm)\">\n Sao chép\n </button>\n </div>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandYarn }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandYarn)\">\n Sao chép\n </button>\n </div>\n </section>\n\n <!-- Demo Trực tiếp -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Demo Trực tiếp</h2>\n <div class=\"grid grid-cols-4 gap-4 mb-6\">\n <button\n *ngFor=\"let sc of scenarioOptions\"\n (click)=\"selectedScenario = sc\"\n class=\"px-3 py-1 border rounded\"\n [class.bg-blue-500]=\"selectedScenario === sc\"\n [class.text-white]=\"selectedScenario === sc\">\n {{ sc }}\n </button>\n </div>\n <div class=\"p-4 bg-gray-50 rounded-lg h-[300px]\">\n <div\n LibsUiComponentsScrollOverlayDirective\n [options]=\"options\"\n (outScroll)=\"onScroll()\"\n (outScrollTop)=\"onScrollTop()\"\n (outScrollBottom)=\"onScrollBottom()\"\n class=\"w-full h-full\">\n <div\n class=\"p-2\"\n [innerText]=\"content\"\n [class.whitespace-pre-wrap]=\"selectedScenario !== 'horizontal'\"\n [class.whitespace-nowrap]=\"selectedScenario === 'horizontal'\"></div>\n </div>\n </div>\n <p class=\"mt-4 text-gray-700\">Sự kiện: {{ lastEvent() }}</p>\n </section>\n\n <!-- Cách sử dụng -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Cách sử dụng</h2>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm\">\n <code ngNonBindable>&lt;div LibsUiComponentsScrollOverlayDirective [options]=\"&#123; scrollbarWidth:12, scrollThumbColor:'#3b82f6' &#125;\" style=\"width:300px;height:200px;overflow:auto;\"&gt;\n Nội dung dài...\n&lt;/div&gt;</code>\n </pre>\n </section>\n\n <!-- API Reference -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">API Reference</h2>\n <h3 class=\"text-xl font-semibold mb-3\">Inputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Tên</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Kiểu</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Mặc định</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Mô tả</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let input of inputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ input.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ input.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Outputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Tên</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Kiểu</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Mô tả</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let output of outputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ output.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Options</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Thuộc tính</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Kiểu</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Mặc định</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Mô tả</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let opt of optionsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ opt.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ opt.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Interfaces</h3>\n <div class=\"space-y-6\">\n <div\n *ngFor=\"let intf of interfacesDoc\"\n class=\"bg-gray-50 p-6 rounded-lg\">\n <h4 class=\"font-semibold mb-2\">{{ intf.name }}</h4>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm mb-3\"><code>{{ intf.type }}</code></pre>\n <p>{{ intf.description }}</p>\n </div>\n </div>\n </section>\n </main>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"libs-ui-components-scroll-overlay.mjs","sources":["../../../../../libs-ui/components/scroll-overlay/src/scroll-overlay.directive.ts","../../../../../libs-ui/components/scroll-overlay/src/libs-ui-components-scroll-overlay.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DestroyRef, Directive, ElementRef, OnDestroy, Renderer2, computed, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { checkMouseOverInContainer, getDragEventByElement } from '@libs-ui/utils';\nimport { Subscription, fromEvent, interval, switchMap, takeUntil, tap } from 'rxjs';\nimport { IScrollOverlayOptions, TYPE_SCROLL_DIRECTION } from './scroll.interface';\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiComponentsScrollOverlayDirective]',\n standalone: true,\n})\nexport class LibsUiComponentsScrollOverlayDirective implements OnDestroy {\n // #region PROPERTY\n private readonly styles = computed(\n () => `\n .scrollbar-track{\n background-color:${this.scrollbarColor()};\n }\n .scrollbar-track:hover{\n background-color:${this.scrollbarHoverColor()};\n }\n .scrollbar-track-X {\n width:100%;\n position: absolute;\n bottom: 0;\n left: 0;\n visibility: hidden;\n cursor: pointer;\n opacity: 0;\n z-index: 1;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n }\n\n .scrollbar-track-Y {\n height:100%;\n position: absolute;\n top: 0;\n right: 0;\n visibility: hidden;\n cursor: pointer;\n opacity: 0;\n z-index: 1;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n }\n\n .scrollbar-thumb{\n background-color:${this.scrollThumbColor()};\n }\n .scrollbar-thumb:hover{\n background-color:${this.scrollThumbHoverColor()};\n }\n\n .scrollbar-thumb-X {\n height: calc(100% - ${this.scrollbarPadding() * 2}px);\n bottom: ${this.scrollbarPadding()}px;\n border-radius: 4px;\n cursor: grabbing;\n transition: background-color 0.3s;\n position: absolute;\n }\n\n .scrollbar-thumb-Y {\n width: calc(100% - ${this.scrollbarPadding() * 2}px);\n right: ${this.scrollbarPadding()}px;\n border-radius: 4px;\n cursor: grabbing;\n transition: background-color 0.3s;\n position: absolute;\n }\n\n .lib-ui-scroll-overlay-container .lib-ui-scroll-overlay-element::-webkit-scrollbar {\n width: 0 !important;\n height: 0 !important;\n }\n `,\n {}\n );\n private isScrollThumb = signal<boolean>(false);\n private keepDisplayThumb = signal<boolean>(false);\n private subsX = new Subscription();\n private subsY = new Subscription();\n private scrollbarWidth = computed(() => this.options()?.scrollbarWidth ?? 10); // Chiều rộng thanh cuộn\n private scrollbarPadding = computed(() => this.options()?.scrollbarPadding ?? 2); // Chiều rộng thanh cuộn\n private scrollbarColor = computed(() => this.options()?.scrollbarColor ?? '');\n private scrollbarHoverColor = computed(() => this.options()?.scrollbarColor ?? '#CDD0D640');\n private scrollThumbColor = computed(() => this.options()?.scrollThumbColor ?? '#CDD0D6');\n private scrollThumbHoverColor = computed(() => this.options()?.scrollThumbHoverColor ?? '#9CA2AD');\n private readonly divContainer = document.createElement('div');\n private readonly trackX: HTMLElement = document.createElement('div');\n private readonly thumbX: HTMLElement = document.createElement('div');\n private readonly trackY: HTMLElement = document.createElement('div');\n private readonly thumbY: HTMLElement = document.createElement('div');\n\n // #region INPUT\n readonly debugMode = input<boolean>(false);\n readonly ignoreInit = input<boolean>(false);\n readonly classContainer = input<string, string | undefined>('', { transform: (value) => value ?? '' });\n readonly options = input<IScrollOverlayOptions | undefined>(Object.assign({}));\n readonly elementCheckScrollX = input<HTMLElement>();\n readonly elementCheckScrollY = input<HTMLElement>();\n readonly elementScroll = input<HTMLElement>();\n\n // #region OUTPUT\n readonly outScroll = output<Event>();\n readonly outScrollX = output<Event>();\n readonly outScrollY = output<Event>();\n readonly outScrollTop = output<Event>();\n readonly outScrollBottom = output<Event>();\n\n // #region INJECT\n private element = inject(ElementRef);\n private render2 = inject(Renderer2);\n private destroyRef = inject(DestroyRef);\n\n constructor() {\n effect(() => {\n if (this.ignoreInit()) {\n return;\n }\n const options = this.options();\n this.divContainer.className = '';\n this.classContainer()\n ?.split(' ')\n .forEach((className) => {\n if (!className) {\n return;\n }\n this.divContainer.classList.add(className);\n });\n\n untracked(() => {\n this.Element.classList.toggle('overflow-hidden', options?.scrollX === 'hidden' && options?.scrollY === 'hidden');\n if (options?.scrollX !== 'hidden') {\n this.subsX.unsubscribe();\n this.trackX.className = '';\n this.thumbX.className = '';\n this.trackX.style.height = `${this.scrollbarWidth()}px`;\n this.createScrollbar('X', this.trackX, this.thumbX);\n this.bindEventsScrollBar('X', this.trackX);\n\n this.handlerDragAndDropThumb('X');\n this.handlerClickTrack('X');\n }\n\n if (options?.scrollY !== 'hidden') {\n this.trackY.className = '';\n this.thumbY.className = '';\n this.trackY.style.width = `${this.scrollbarWidth()}px`;\n this.subsY.unsubscribe();\n this.createScrollbar('Y', this.trackY, this.thumbY);\n this.bindEventsScrollBar('Y', this.trackY);\n\n this.handlerDragAndDropThumb('Y');\n this.handlerClickTrack('Y');\n }\n });\n });\n }\n\n // #region FUNCTIONS\n private get Element(): HTMLElement {\n return this.elementScroll() || this.element.nativeElement;\n }\n\n private createScrollbar(scrollDirection: TYPE_SCROLL_DIRECTION, trackEl: HTMLElement, thumbEl: HTMLElement) {\n const idStyleTag = '#id-style-tag-custom-scroll-overlay';\n const styleElCustomScrollOverlay = document.getElementById(idStyleTag);\n\n if (!styleElCustomScrollOverlay) {\n const styleEl = document.createElement('style');\n styleEl.setAttribute('id', idStyleTag);\n styleEl.innerHTML = this.styles();\n document.head.append(styleEl);\n }\n\n const stylesProperty = {\n 'box-sizing': 'border-box',\n 'scrollbar-width': 'none',\n 'scrollbar-color': this.options()?.ignoreTransparentScrollBarColorDefault ? 'auto' : 'transparent transparent',\n overflow: 'hidden',\n 'overflow-x': `${this.options()?.scrollX || 'scroll'}`,\n 'overflow-y': `${this.options()?.scrollY || 'scroll'}`,\n } as any;\n\n Object.keys(stylesProperty).forEach((key) => {\n this.render2.setStyle(this.Element, key, stylesProperty[key], 1);\n });\n\n trackEl.classList.add(`scrollbar-track`);\n trackEl.classList.add(`scrollbar-track-${scrollDirection}`);\n\n thumbEl.classList.add(`scrollbar-thumb`);\n thumbEl.classList.add(`scrollbar-thumb-${scrollDirection}`);\n trackEl.appendChild(thumbEl);\n if (this.Element.className) {\n this.Element.className.split(' ').forEach((className: string) => {\n if (\n className &&\n (['w-full', 'w-screen', 'h-full', 'h-screen', 'shrink-0'].includes(className) || className.includes('min-h-') || className.includes('min-w-') || /^(!?)(h|w)-\\[[0-9]+px\\]$/.test(className)) &&\n !this.divContainer.classList.contains(className)\n ) {\n this.divContainer.classList.add(className);\n }\n });\n if (!this.Element.className.includes('min-h-')) {\n this.divContainer.classList.add('min-h-0');\n }\n if (!this.Element.className.includes('min-w-')) {\n this.divContainer.classList.add('min-w-0');\n }\n if (!this.Element.className.includes('lib-ui-scroll-overlay-element')) {\n this.Element.classList.add('lib-ui-scroll-overlay-element');\n }\n }\n if (!this.divContainer.classList.contains('lib-ui-scroll-overlay-container')) {\n this.divContainer.classList.add('lib-ui-scroll-overlay-container');\n }\n this.divContainer.appendChild(trackEl);\n\n if (!this.divContainer.style.position) {\n this.Element.parentElement?.insertBefore(this.divContainer, this.Element);\n this.divContainer.style.position = 'relative';\n }\n this.divContainer.append(this.Element);\n this.updateScrollbarSize(scrollDirection);\n }\n\n private bindEventsScrollBar(scrollDirection: TYPE_SCROLL_DIRECTION, trackEl: HTMLElement) {\n let scrollLeft = this.Element.scrollLeft;\n let scrollTop = this.Element.scrollTop;\n const subs: Subscription = fromEvent<Event>(this.Element, 'scroll')\n .pipe(\n tap((event) => {\n const target = this.Element;\n\n this.outScroll.emit(event);\n if (scrollDirection === 'X') {\n if (target.scrollLeft && target.scrollLeft + target.offsetWidth >= target.scrollWidth) {\n target.scrollLeft = target.scrollWidth - target.offsetWidth - (target.offsetWidth - target.clientWidth);\n }\n\n if (target.scrollLeft !== scrollLeft) {\n this.outScrollX.emit(event);\n }\n scrollLeft = target.scrollLeft;\n this.updateScrollbarPosition(scrollDirection);\n\n return;\n }\n\n if (target.scrollTop === scrollTop) {\n return;\n }\n this.updateScrollbarPosition(scrollDirection);\n scrollTop = target.scrollTop;\n this.outScrollY.emit(event);\n\n if (target.scrollTop === 0) {\n return this.outScrollTop.emit(event);\n }\n\n if (target.scrollHeight <= target.scrollTop + target.offsetHeight + 3) {\n return this.outScrollBottom.emit(event);\n }\n }),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe();\n\n subs.add(\n fromEvent(document, 'resize')\n .pipe(tap(this.updateScrollbarSize.bind(this, scrollDirection)), takeUntilDestroyed(this.destroyRef))\n .subscribe()\n );\n\n const mouseLeave = fromEvent(this.divContainer, 'mouseleave');\n const mouseenter = fromEvent(this.divContainer, 'mouseenter');\n\n subs.add(\n mouseenter\n .pipe(\n tap(() => {\n if ((scrollDirection === 'X' && !this.options()?.scrollXOpacity0) || (scrollDirection === 'Y' && !this.options()?.scrollYOpacity0)) {\n trackEl.style.visibility = 'visible';\n trackEl.style.opacity = '1';\n }\n this.updateScrollbarSize(scrollDirection);\n }),\n switchMap(() => interval(1000).pipe(takeUntil(mouseLeave))),\n tap(this.updateScrollbarSize.bind(this, scrollDirection)),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe()\n );\n\n subs.add(\n mouseLeave\n .pipe(\n tap(() => {\n if (this.keepDisplayThumb()) {\n return;\n }\n trackEl.style.visibility = 'hidden';\n trackEl.style.opacity = '0';\n }),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe()\n );\n\n if (scrollDirection === 'X') {\n this.subsX = subs;\n\n return;\n }\n\n if (scrollDirection === 'Y') {\n this.subsY = subs;\n\n return;\n }\n }\n\n protected handlerClickTrack(scrollDirection: TYPE_SCROLL_DIRECTION) {\n const elementTrack = scrollDirection === 'X' ? this.trackX : this.trackY;\n const elementThumb = scrollDirection === 'X' ? this.thumbX : this.thumbY;\n const subs = scrollDirection === 'X' ? this.subsX : this.subsY;\n\n subs.add(\n fromEvent<MouseEvent>(elementTrack, 'click').subscribe((e) => {\n if (this.isScrollThumb()) {\n return;\n }\n if ((scrollDirection === 'X' && e.clientX < elementThumb.getBoundingClientRect().left) || (scrollDirection === 'Y' && e.clientY < elementThumb.getBoundingClientRect().top)) {\n this.updateScrollPositionByUserAction(scrollDirection, e, 'smooth', 0);\n return;\n }\n\n if (scrollDirection === 'X') {\n this.updateScrollPositionByUserAction(scrollDirection, e, 'smooth', -1 * elementThumb.getBoundingClientRect().width);\n return;\n }\n this.updateScrollPositionByUserAction(scrollDirection, e, 'smooth', -1 * elementThumb.getBoundingClientRect().height);\n })\n );\n }\n\n protected handlerDragAndDropThumb(scrollDirection: TYPE_SCROLL_DIRECTION) {\n const elementTrack = scrollDirection === 'X' ? this.trackX : this.trackY;\n const elementThumb = scrollDirection === 'X' ? this.thumbX : this.thumbY;\n const subs = scrollDirection === 'X' ? this.subsX : this.subsY;\n let lengthThumbToPointClick = 0;\n\n subs.add(\n getDragEventByElement({\n elementMouseDown: elementThumb,\n functionMouseDown: (mouseEvent: MouseEvent) => {\n this.isScrollThumb.set(true);\n this.keepDisplayThumb.set(true);\n if (scrollDirection === 'X') {\n lengthThumbToPointClick = elementThumb.getBoundingClientRect().left - mouseEvent.clientX;\n return;\n }\n lengthThumbToPointClick = elementThumb.getBoundingClientRect().top - mouseEvent.clientY;\n },\n functionMouseUp: (mouseEvent: MouseEvent) => {\n this.keepDisplayThumb.set(false);\n lengthThumbToPointClick = 0;\n if (!checkMouseOverInContainer(mouseEvent, this.Element)) {\n elementTrack.style.visibility = 'hidden';\n elementTrack.style.opacity = '0';\n }\n setTimeout(() => {\n this.isScrollThumb.set(false);\n }, 250);\n },\n destroyRef: this.destroyRef,\n }).subscribe((mouseEvent: MouseEvent) => {\n this.updateScrollPositionByUserAction(scrollDirection, mouseEvent, 'auto', lengthThumbToPointClick);\n })\n );\n }\n\n private updateScrollPositionByUserAction(scrollDirection: TYPE_SCROLL_DIRECTION, e: MouseEvent, behavior: 'auto' | 'smooth', lengthThumbToPointClick = 0) {\n e.stopPropagation();\n if (scrollDirection === 'X') {\n const containerWidth = this.Element.offsetWidth;\n const contentWidth = (this.elementCheckScrollX() || this.Element).scrollWidth;\n const thumbPosition = e.clientX - this.Element.getBoundingClientRect().left + lengthThumbToPointClick;\n const scrollLeft = (thumbPosition / (containerWidth - this.thumbX.offsetWidth)) * (contentWidth - containerWidth);\n\n this.Element.scroll({ left: scrollLeft, behavior });\n return;\n }\n const containerHeight = this.Element.offsetHeight;\n const contentHeight = (this.elementCheckScrollY() || this.Element).scrollHeight;\n const thumbPosition = e.clientY - this.Element.getBoundingClientRect().top + lengthThumbToPointClick;\n const scrollTop = (thumbPosition / (containerHeight - this.thumbY.offsetHeight)) * (contentHeight - containerHeight);\n\n this.Element.scroll({ top: scrollTop, behavior });\n }\n\n private updateScrollbarSize(scrollDirection: TYPE_SCROLL_DIRECTION) {\n if (scrollDirection === 'X') {\n const containerWidth = this.Element.offsetWidth;\n const contentWidth = (this.elementCheckScrollX() || this.Element).scrollWidth;\n const thumbWidth = (containerWidth / contentWidth) * containerWidth;\n\n this.thumbX.style.width = `${Math.max(20, thumbWidth)}px`;\n this.trackX.style.display = 'none';\n if (contentWidth > containerWidth) {\n this.trackX.style.display = 'block';\n }\n this.updateScrollbarPosition(scrollDirection);\n\n return;\n }\n\n const containerHeight = this.Element.offsetHeight;\n const contentHeight = (this.elementCheckScrollY() || this.Element).scrollHeight;\n const thumbHeight = (containerHeight / contentHeight) * containerHeight;\n\n this.thumbY.style.height = `${Math.max(20, thumbHeight)}px`;\n this.trackY.style.display = 'none';\n if (contentHeight > containerHeight) {\n this.trackY.style.display = 'block';\n }\n\n this.updateScrollbarPosition('Y');\n }\n\n private updateScrollbarPosition(scrollDirection: TYPE_SCROLL_DIRECTION) {\n if (scrollDirection === 'X') {\n const containerWidth = this.Element.offsetWidth;\n const contentWidth = (this.elementCheckScrollX() || this.Element).scrollWidth;\n const scrollLeft = this.Element.scrollLeft;\n const thumbPosition = (scrollLeft / (contentWidth - containerWidth)) * (containerWidth - this.thumbX.offsetWidth);\n\n this.thumbX.style.left = `${thumbPosition}px`;\n\n return;\n }\n const containerHeight = this.Element.offsetHeight;\n const contentHeight = (this.elementCheckScrollY() || this.Element).scrollHeight;\n const scrollTop = this.Element.scrollTop;\n const thumbPosition = (scrollTop / (contentHeight - containerHeight)) * (containerHeight - this.thumbY.offsetHeight);\n\n this.thumbY.style.top = `${thumbPosition}px`;\n }\n\n ngOnDestroy(): void {\n this.divContainer.remove();\n this.subsX.unsubscribe();\n this.subsY.unsubscribe();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  export * from './scroll-overlay.directive';
2
2
  export * from './scroll.interface';
3
- export * from './demo/scroll-overlay.demo';
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@libs-ui/components-scroll-overlay",
3
- "version": "0.2.355-0",
3
+ "version": "0.2.355-10",
4
4
  "peerDependencies": {
5
5
  "@angular/core": ">=18.0.0",
6
- "@libs-ui/utils": "0.2.355-0",
6
+ "@libs-ui/utils": "0.2.355-10",
7
7
  "rxjs": "~7.8.0"
8
8
  },
9
9
  "sideEffects": false,
package/README.md DELETED
@@ -1,138 +0,0 @@
1
- # Scroll Overlay Component
2
-
3
- ## Giới thiệu
4
-
5
- `scroll-overlay` là một directive mạnh mẽ giúp tuỳ biến thanh cuộn (scrollbar) cho bất kỳ phần tử nào trong ứng dụng Angular. Directive này cung cấp giao diện thanh cuộn đẹp, có thể tuỳ chỉnh màu sắc, kích thước, hiệu ứng hover, và nhiều tuỳ chọn nâng cao khác.
6
-
7
- ## Tính năng
8
-
9
- - Tuỳ chỉnh màu sắc, chiều rộng, padding của thanh cuộn
10
- - Hỗ trợ cả chiều ngang (X) và dọc (Y)
11
- - Hiệu ứng hover cho track và thumb
12
- - Ẩn/hiện scrollbar khi hover hoặc theo tuỳ chọn
13
- - Hỗ trợ drag & drop thumb để cuộn
14
- - Sự kiện scroll chi tiết (top, bottom, X, Y)
15
- - Dễ dàng tích hợp vào bất kỳ container nào
16
-
17
- ## Cài đặt
18
-
19
- Cài đặt package qua npm hoặc yarn:
20
-
21
- ```bash
22
- npm install @libs-ui/components-scroll-overlay
23
- ```
24
-
25
- hoặc
26
-
27
- ```bash
28
- yarn add @libs-ui/components-scroll-overlay
29
- ```
30
-
31
- ## Sử dụng
32
-
33
- ### Import directive
34
-
35
- ```typescript
36
- import { LibsUiComponentsScrollOverlayDirective } from '@libs-ui/components-scroll-overlay';
37
-
38
- @Component({
39
- selector: 'app-example',
40
- standalone: true,
41
- imports: [LibsUiComponentsScrollOverlayDirective],
42
- template: `
43
- <div
44
- LibsUiComponentsScrollOverlayDirective
45
- style="width: 300px; height: 400px;">
46
- Nội dung dài ở đây...
47
- </div>
48
- `,
49
- })
50
- export class ExampleComponent {}
51
- ```
52
-
53
- ### Ví dụ nâng cao với options
54
-
55
- ```html
56
- <div
57
- LibsUiComponentsScrollOverlayDirective
58
- [options]="{scrollbarWidth: 12, scrollbarColor: '#eee', scrollThumbColor: '#888', scrollYOpacity0: true}"
59
- style="width: 300px; height: 400px;">
60
- Nội dung dài ở đây...
61
- </div>
62
- ```
63
-
64
- ## API Reference
65
-
66
- ### Inputs
67
-
68
- | Input | Type | Mô tả |
69
- | ------------------- | --------------------- | ------------------------------------------------------------- |
70
- | options | IScrollOverlayOptions | Tuỳ chọn cấu hình thanh cuộn |
71
- | debugMode | boolean | Bật chế độ debug |
72
- | ignoreInit | boolean | Bỏ qua khởi tạo directive |
73
- | classContainer | string | Thêm class cho container bọc ngoài |
74
- | notShowScrollBarX | boolean | Không hiển thị thanh cuộn ngang |
75
- | notShowScrollBarY | boolean | Không hiển thị thanh cuộn dọc |
76
- | elementCheckScrollX | HTMLElement | Phần tử dùng để kiểm tra scroll X (mặc định là chính element) |
77
- | elementCheckScrollY | HTMLElement | Phần tử dùng để kiểm tra scroll Y (mặc định là chính element) |
78
- | elementScroll | HTMLElement | Phần tử thực hiện scroll (mặc định là chính element) |
79
-
80
- ### Outputs
81
-
82
- | Output | Type | Mô tả |
83
- | --------------- | ----- | ----------------------------------- |
84
- | outScroll | Event | Bắn ra khi scroll bất kỳ |
85
- | outScrollX | Event | Bắn ra khi scroll theo chiều ngang |
86
- | outScrollY | Event | Bắn ra khi scroll theo chiều dọc |
87
- | outScrollTop | Event | Bắn ra khi scroll tới đầu (top) |
88
- | outScrollBottom | Event | Bắn ra khi scroll tới cuối (bottom) |
89
-
90
- ### Options (IScrollOverlayOptions)
91
-
92
- | Thuộc tính | Type | Mô tả |
93
- | --------------------- | ------------------ | ----------------------------------------------- |
94
- | scrollbarWidth | number | Chiều rộng/thanh cuộn (px) |
95
- | scrollbarColor | string | Màu nền track |
96
- | scrollbarHoverColor | string | Màu nền track khi hover |
97
- | scrollThumbColor | string | Màu thumb |
98
- | scrollThumbHoverColor | string | Màu thumb khi hover |
99
- | scrollbarPadding | number | Padding của scrollbar |
100
- | scrollX | 'hidden'\|'scroll' | Kiểu hiển thị scroll X ('hidden' hoặc 'scroll') |
101
- | scrollXOpacity0 | boolean | Ẩn track X khi không hover |
102
- | scrollY | 'hidden'\|'scroll' | Kiểu hiển thị scroll Y ('hidden' hoặc 'scroll') |
103
- | scrollYOpacity0 | boolean | Ẩn track Y khi không hover |
104
-
105
- ## Interface
106
-
107
- ```typescript
108
- export interface IScrollOverlayOptions {
109
- scrollbarWidth?: number;
110
- scrollbarColor?: string;
111
- scrollbarHoverColor?: string;
112
- scrollThumbColor?: string;
113
- scrollThumbHoverColor?: string;
114
- scrollbarPadding?: number;
115
- scrollX?: 'hidden' | 'scroll';
116
- scrollXOpacity0?: boolean;
117
- scrollY?: 'hidden' | 'scroll';
118
- scrollYOpacity0?: boolean;
119
- }
120
- ```
121
-
122
- ## Ví dụ sử dụng nâng cao
123
-
124
- ```html
125
- <!-- Scroll overlay với tuỳ chỉnh màu sắc và hiệu ứng ẩn/hiện -->
126
- <div
127
- LibsUiComponentsScrollOverlayDirective
128
- [options]="{scrollbarWidth: 8, scrollbarColor: '#f3f4f6', scrollThumbColor: '#3b82f6', scrollThumbHoverColor: '#2563eb', scrollYOpacity0: true}"
129
- style="width: 250px; height: 350px;">
130
- <div style="height: 1000px;">Nội dung rất dài để test scroll overlay...</div>
131
- </div>
132
- ```
133
-
134
- ## Ghi chú
135
-
136
- - Directive này hoạt động tốt với mọi phần tử có overflow.
137
- - Có thể kết hợp nhiều options để đạt hiệu quả UI mong muốn.
138
- - Để tuỳ chỉnh sâu hơn, hãy xem thêm code và các sự kiện output để tích hợp logic riêng.
@@ -1,44 +0,0 @@
1
- import { IScrollOverlayOptions } from '../scroll.interface';
2
- import * as i0 from "@angular/core";
3
- export declare class LibsUiComponentsScrollOverlayDemoComponent {
4
- longContent: import("@angular/core").WritableSignal<string>;
5
- longHorizontalContent: import("@angular/core").WritableSignal<string>;
6
- scenarioOptions: readonly ["default", "customStyle", "autoHide", "horizontal"];
7
- selectedScenario: (typeof this.scenarioOptions)[number];
8
- customStyleOptions: import("@angular/core").WritableSignal<IScrollOverlayOptions>;
9
- autoHideOptions: import("@angular/core").WritableSignal<IScrollOverlayOptions>;
10
- horizontalOptions: import("@angular/core").WritableSignal<IScrollOverlayOptions>;
11
- lastEvent: import("@angular/core").WritableSignal<string>;
12
- get options(): IScrollOverlayOptions | undefined;
13
- get content(): string;
14
- onScroll(): void;
15
- onScrollTop(): void;
16
- onScrollBottom(): void;
17
- inputsDoc: {
18
- name: string;
19
- type: string;
20
- default: string;
21
- description: string;
22
- }[];
23
- outputsDoc: {
24
- name: string;
25
- type: string;
26
- description: string;
27
- }[];
28
- optionsDoc: {
29
- name: string;
30
- type: string;
31
- default: string;
32
- description: string;
33
- }[];
34
- interfacesDoc: {
35
- name: string;
36
- type: string;
37
- description: string;
38
- }[];
39
- installCommandNpm: string;
40
- installCommandYarn: string;
41
- copyToClipboard(text: string): void;
42
- static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiComponentsScrollOverlayDemoComponent, never>;
43
- static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiComponentsScrollOverlayDemoComponent, "lib-scroll-overlay-demo", never, {}, {}, never, never, true, never>;
44
- }
@@ -1,84 +0,0 @@
1
- import { CommonModule } from '@angular/common';
2
- import { Component, signal } from '@angular/core';
3
- import { LibsUiComponentsScrollOverlayDirective } from '../scroll-overlay.directive';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "@angular/common";
6
- export class LibsUiComponentsScrollOverlayDemoComponent {
7
- // Demo text content: generate 5000 words for vertical scrolling
8
- longContent = signal(Array.from({ length: 5000 }, (_, i) => `Lorem${i + 1}`).join(' '));
9
- // Demo horizontal content: generate 5000 words for horizontal scrolling
10
- longHorizontalContent = signal(Array.from({ length: 5000 }, (_, i) => `Word${i + 1}`).join(' '));
11
- // Scenario selection
12
- scenarioOptions = ['default', 'customStyle', 'autoHide', 'horizontal'];
13
- selectedScenario = 'default';
14
- // Options signals
15
- customStyleOptions = signal({ scrollbarWidth: 12, scrollbarColor: '#f3f4f6', scrollbarHoverColor: '#e5e7eb', scrollThumbColor: '#3b82f6', scrollThumbHoverColor: '#2563eb', scrollbarPadding: 4 });
16
- autoHideOptions = signal({ scrollYOpacity0: true, scrollbarWidth: 8, scrollbarColor: 'transparent', scrollThumbColor: '#9ca3af', scrollThumbHoverColor: '#6b7280' });
17
- horizontalOptions = signal({ scrollX: 'scroll', scrollY: 'hidden', scrollbarWidth: 8, scrollbarColor: '#f3f4f6', scrollThumbColor: '#3b82f6' });
18
- // Scroll event log
19
- lastEvent = signal('No events yet');
20
- // Helpers
21
- get options() {
22
- switch (this.selectedScenario) {
23
- case 'customStyle':
24
- return this.customStyleOptions();
25
- case 'autoHide':
26
- return this.autoHideOptions();
27
- case 'horizontal':
28
- return this.horizontalOptions();
29
- default:
30
- return undefined;
31
- }
32
- }
33
- get content() {
34
- return this.selectedScenario === 'horizontal' ? this.longHorizontalContent() : this.longContent();
35
- }
36
- // Event handlers
37
- onScroll() {
38
- this.lastEvent.set('Scroll event fired');
39
- }
40
- onScrollTop() {
41
- this.lastEvent.set('Reached top');
42
- }
43
- onScrollBottom() {
44
- this.lastEvent.set('Reached bottom');
45
- }
46
- // API docs
47
- inputsDoc = [
48
- { name: 'options', type: 'IScrollOverlayOptions', default: 'undefined', description: 'Cấu hình tuỳ chỉnh scrollbar' },
49
- { name: 'debugMode', type: 'boolean', default: 'false', description: 'Bật chế độ debug' },
50
- { name: 'notShowScrollBarX', type: 'boolean', default: 'false', description: 'Ẩn scrollbar ngang' },
51
- { name: 'notShowScrollBarY', type: 'boolean', default: 'false', description: 'Ẩn scrollbar dọc' },
52
- ];
53
- outputsDoc = [
54
- { name: 'outScroll', type: 'Event', description: 'Bắn ra khi scroll bất kỳ' },
55
- { name: 'outScrollTop', type: 'Event', description: 'Bắn ra khi scroll đến top' },
56
- { name: 'outScrollBottom', type: 'Event', description: 'Bắn ra khi scroll đến bottom' },
57
- ];
58
- optionsDoc = [
59
- { name: 'scrollbarWidth', type: 'number', default: 'undefined', description: 'Chiều rộng scrollbar (px)' },
60
- { name: 'scrollbarColor', type: 'string', default: 'undefined', description: 'Màu track scrollbar' },
61
- { name: 'scrollbarHoverColor', type: 'string', default: 'undefined', description: 'Màu track khi hover' },
62
- { name: 'scrollThumbColor', type: 'string', default: 'undefined', description: 'Màu thumb' },
63
- { name: 'scrollThumbHoverColor', type: 'string', default: 'undefined', description: 'Màu thumb khi hover' },
64
- { name: 'scrollbarPadding', type: 'number', default: 'undefined', description: 'Padding scrollbar' },
65
- { name: 'scrollX', type: `'hidden' | 'scroll'`, default: 'undefined', description: 'Kiểu scroll X' },
66
- { name: 'scrollXOpacity0', type: 'boolean', default: 'undefined', description: 'Ẩn track X khi không hover' },
67
- { name: 'scrollY', type: `'hidden' | 'scroll'`, default: 'undefined', description: 'Kiểu scroll Y' },
68
- { name: 'scrollYOpacity0', type: 'boolean', default: 'undefined', description: 'Ẩn track Y khi không hover' },
69
- ];
70
- interfacesDoc = [{ name: 'IScrollOverlayOptions', type: 'interface', description: 'Các tuỳ chọn cấu hình scroll-overlay' }];
71
- // Installation commands
72
- installCommandNpm = 'npm install @libs-ui/components-scroll-overlay';
73
- installCommandYarn = 'yarn add @libs-ui/components-scroll-overlay';
74
- copyToClipboard(text) {
75
- navigator.clipboard.writeText(text).then(() => console.log('Copied:', text));
76
- }
77
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsScrollOverlayDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
78
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: LibsUiComponentsScrollOverlayDemoComponent, isStandalone: true, selector: "lib-scroll-overlay-demo", ngImport: i0, template: "<div class=\"max-w-6xl mx-auto p-5 font-sans text-gray-800\">\n <header class=\"text-center py-10 bg-white rounded-lg mb-8 shadow-sm\">\n <h1 class=\"text-4xl font-bold mb-2\">Demo Scroll Overlay</h1>\n <p class=\"text-xl text-gray-500\">&#64;libs-ui/components-scroll-overlay</p>\n </header>\n\n <main>\n <!-- Gi\u1EDBi thi\u1EC7u -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Gi\u1EDBi thi\u1EC7u</h2>\n <p>\n <code>scroll-overlay</code>\n l\u00E0 m\u1ED9t directive gi\u00FAp tu\u1EF3 bi\u1EBFn scrollbar tr\u00EAn b\u1EA5t k\u1EF3 ph\u1EA7n t\u1EED n\u00E0o trong Angular, h\u1ED7 tr\u1EE3 tu\u1EF3 ch\u1EC9nh m\u00E0u, k\u00EDch th\u01B0\u1EDBc, \u1EA9n/hi\u1EC7n v\u00E0 s\u1EF1 ki\u1EC7n scroll.\n </p>\n </section>\n\n <!-- C\u00E0i \u0111\u1EB7t -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">C\u00E0i \u0111\u1EB7t</h2>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg mb-4\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandNpm }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandNpm)\">\n Sao ch\u00E9p\n </button>\n </div>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandYarn }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandYarn)\">\n Sao ch\u00E9p\n </button>\n </div>\n </section>\n\n <!-- Demo Tr\u1EF1c ti\u1EBFp -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Demo Tr\u1EF1c ti\u1EBFp</h2>\n <div class=\"grid grid-cols-4 gap-4 mb-6\">\n <button\n *ngFor=\"let sc of scenarioOptions\"\n (click)=\"selectedScenario = sc\"\n class=\"px-3 py-1 border rounded\"\n [class.bg-blue-500]=\"selectedScenario === sc\"\n [class.text-white]=\"selectedScenario === sc\">\n {{ sc }}\n </button>\n </div>\n <div class=\"p-4 bg-gray-50 rounded-lg h-[300px]\">\n <div\n LibsUiComponentsScrollOverlayDirective\n [options]=\"options\"\n (outScroll)=\"onScroll()\"\n (outScrollTop)=\"onScrollTop()\"\n (outScrollBottom)=\"onScrollBottom()\"\n class=\"w-full h-full\">\n <div\n class=\"p-2\"\n [innerText]=\"content\"\n [class.whitespace-pre-wrap]=\"selectedScenario !== 'horizontal'\"\n [class.whitespace-nowrap]=\"selectedScenario === 'horizontal'\"></div>\n </div>\n </div>\n <p class=\"mt-4 text-gray-700\">S\u1EF1 ki\u1EC7n: {{ lastEvent() }}</p>\n </section>\n\n <!-- C\u00E1ch s\u1EED d\u1EE5ng -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">C\u00E1ch s\u1EED d\u1EE5ng</h2>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm\">\n <code ngNonBindable>&lt;div LibsUiComponentsScrollOverlayDirective [options]=\"&#123; scrollbarWidth:12, scrollThumbColor:'#3b82f6' &#125;\" style=\"width:300px;height:200px;overflow:auto;\"&gt;\n N\u1ED9i dung d\u00E0i...\n&lt;/div&gt;</code>\n </pre>\n </section>\n\n <!-- API Reference -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">API Reference</h2>\n <h3 class=\"text-xl font-semibold mb-3\">Inputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">T\u00EAn</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u1EB7c \u0111\u1ECBnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let input of inputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ input.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ input.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Outputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">T\u00EAn</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let output of outputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ output.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Options</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Thu\u1ED9c t\u00EDnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u1EB7c \u0111\u1ECBnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let opt of optionsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ opt.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ opt.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Interfaces</h3>\n <div class=\"space-y-6\">\n <div\n *ngFor=\"let intf of interfacesDoc\"\n class=\"bg-gray-50 p-6 rounded-lg\">\n <h4 class=\"font-semibold mb-2\">{{ intf.name }}</h4>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm mb-3\"><code>{{ intf.type }}</code></pre>\n <p>{{ intf.description }}</p>\n </div>\n </div>\n </section>\n </main>\n</div>\n", styles: ["@charset \"UTF-8\";.demo-container{padding:24px;font-family:system-ui,-apple-system,sans-serif;max-width:1200px;margin:0 auto}.demo-intro{margin-bottom:32px}.demo-intro h3{color:#333;margin-bottom:16px}.demo-intro ul{list-style:none;padding:0}.demo-intro ul li{margin-bottom:8px;padding-left:20px;position:relative}.demo-intro ul li:before{content:\"\\2022\";position:absolute;left:0;color:#3b82f6}.demo-features{margin-bottom:32px}.demo-features h3{color:#333;margin-bottom:16px}.features-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px}.feature-item{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0}.feature-item h4{color:#1e40af;margin:0 0 8px}.feature-item p{margin:0;color:#64748b}.demo-api{margin-bottom:48px}.demo-api h3{color:#333;margin-bottom:24px}.api-section{margin-bottom:32px}.api-section h4{color:#1e40af;margin-bottom:16px}.api-table{overflow-x:auto}.api-table table{width:100%;border-collapse:collapse;background:#fff;border-radius:8px;border:1px solid #e2e8f0}.api-table table th,.api-table table td{padding:12px 16px;text-align:left;border-bottom:1px solid #e2e8f0}.api-table table th{background:#f8fafc;font-weight:600;color:#1e40af}.api-table table td{color:#64748b}.api-table table td:first-child{font-family:Fira Code,monospace;color:#334155}.api-table table td:nth-child(2){font-family:Fira Code,monospace;color:#3b82f6}.api-table table tr:last-child td{border-bottom:none}.demo-section{margin-bottom:48px}.demo-section h3{color:#333;margin-bottom:16px}.demo-description{margin-bottom:16px}.demo-description p{color:#64748b;margin-bottom:12px}.demo-description pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.demo-description pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155}.demo-box{display:flex;gap:16px;align-items:flex-start}.event-log{padding:16px;background:#f5f5f5;border-radius:4px;min-width:200px}.event-log p{margin:0;font-size:14px;color:#666}.demo-notes{margin-top:48px;padding:24px;background:#f8fafc;border-radius:8px;border:1px solid #e2e8f0}.demo-notes h3{color:#333;margin-bottom:16px}.demo-notes ul{list-style:none;padding:0;margin:0}.demo-notes ul li{color:#64748b;margin-bottom:12px;padding-left:24px;position:relative}.demo-notes ul li:before{content:\"\\2192\";position:absolute;left:0;color:#3b82f6}.demo-notes ul li:last-child{margin-bottom:0}.interface-description{margin-bottom:24px}.interface-description p{color:#64748b;margin-bottom:16px}.interface-description pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.interface-description pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155;line-height:1.6}.interface-usage{margin-bottom:24px}.interface-usage h5{color:#1e40af;margin-bottom:12px;font-size:16px}.interface-usage pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.interface-usage pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155;line-height:1.6}.interface-usage pre code .comment{color:#64748b}.interface-notes{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0}.interface-notes h5{color:#1e40af;margin-bottom:12px;font-size:16px}.interface-notes ul{list-style:none;padding:0;margin:0}.interface-notes ul li{color:#64748b;margin-bottom:8px;padding-left:20px;position:relative}.interface-notes ul li:before{content:\"\\2022\";position:absolute;left:0;color:#3b82f6}.interface-notes ul li:last-child{margin-bottom:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: LibsUiComponentsScrollOverlayDirective, selector: "[LibsUiComponentsScrollOverlayDirective]", inputs: ["debugMode", "ignoreInit", "classContainer", "options", "elementCheckScrollX", "elementCheckScrollY", "elementScroll"], outputs: ["outScroll", "outScrollX", "outScrollY", "outScrollTop", "outScrollBottom"] }] });
79
- }
80
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsScrollOverlayDemoComponent, decorators: [{
81
- type: Component,
82
- args: [{ selector: 'lib-scroll-overlay-demo', standalone: true, imports: [CommonModule, LibsUiComponentsScrollOverlayDirective], template: "<div class=\"max-w-6xl mx-auto p-5 font-sans text-gray-800\">\n <header class=\"text-center py-10 bg-white rounded-lg mb-8 shadow-sm\">\n <h1 class=\"text-4xl font-bold mb-2\">Demo Scroll Overlay</h1>\n <p class=\"text-xl text-gray-500\">&#64;libs-ui/components-scroll-overlay</p>\n </header>\n\n <main>\n <!-- Gi\u1EDBi thi\u1EC7u -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Gi\u1EDBi thi\u1EC7u</h2>\n <p>\n <code>scroll-overlay</code>\n l\u00E0 m\u1ED9t directive gi\u00FAp tu\u1EF3 bi\u1EBFn scrollbar tr\u00EAn b\u1EA5t k\u1EF3 ph\u1EA7n t\u1EED n\u00E0o trong Angular, h\u1ED7 tr\u1EE3 tu\u1EF3 ch\u1EC9nh m\u00E0u, k\u00EDch th\u01B0\u1EDBc, \u1EA9n/hi\u1EC7n v\u00E0 s\u1EF1 ki\u1EC7n scroll.\n </p>\n </section>\n\n <!-- C\u00E0i \u0111\u1EB7t -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">C\u00E0i \u0111\u1EB7t</h2>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg mb-4\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandNpm }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandNpm)\">\n Sao ch\u00E9p\n </button>\n </div>\n <div class=\"flex items-center bg-gray-100 p-4 rounded-lg\">\n <pre class=\"flex-1 text-sm overflow-x-auto\"><code>{{ installCommandYarn }}</code></pre>\n <button\n class=\"ml-4 px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600\"\n (click)=\"copyToClipboard(installCommandYarn)\">\n Sao ch\u00E9p\n </button>\n </div>\n </section>\n\n <!-- Demo Tr\u1EF1c ti\u1EBFp -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">Demo Tr\u1EF1c ti\u1EBFp</h2>\n <div class=\"grid grid-cols-4 gap-4 mb-6\">\n <button\n *ngFor=\"let sc of scenarioOptions\"\n (click)=\"selectedScenario = sc\"\n class=\"px-3 py-1 border rounded\"\n [class.bg-blue-500]=\"selectedScenario === sc\"\n [class.text-white]=\"selectedScenario === sc\">\n {{ sc }}\n </button>\n </div>\n <div class=\"p-4 bg-gray-50 rounded-lg h-[300px]\">\n <div\n LibsUiComponentsScrollOverlayDirective\n [options]=\"options\"\n (outScroll)=\"onScroll()\"\n (outScrollTop)=\"onScrollTop()\"\n (outScrollBottom)=\"onScrollBottom()\"\n class=\"w-full h-full\">\n <div\n class=\"p-2\"\n [innerText]=\"content\"\n [class.whitespace-pre-wrap]=\"selectedScenario !== 'horizontal'\"\n [class.whitespace-nowrap]=\"selectedScenario === 'horizontal'\"></div>\n </div>\n </div>\n <p class=\"mt-4 text-gray-700\">S\u1EF1 ki\u1EC7n: {{ lastEvent() }}</p>\n </section>\n\n <!-- C\u00E1ch s\u1EED d\u1EE5ng -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">C\u00E1ch s\u1EED d\u1EE5ng</h2>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm\">\n <code ngNonBindable>&lt;div LibsUiComponentsScrollOverlayDirective [options]=\"&#123; scrollbarWidth:12, scrollThumbColor:'#3b82f6' &#125;\" style=\"width:300px;height:200px;overflow:auto;\"&gt;\n N\u1ED9i dung d\u00E0i...\n&lt;/div&gt;</code>\n </pre>\n </section>\n\n <!-- API Reference -->\n <section class=\"bg-white rounded-lg p-8 mb-8 shadow-sm\">\n <h2 class=\"text-2xl font-bold mb-5 pb-3 border-b border-gray-200\">API Reference</h2>\n <h3 class=\"text-xl font-semibold mb-3\">Inputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">T\u00EAn</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u1EB7c \u0111\u1ECBnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let input of inputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ input.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ input.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ input.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Outputs</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">T\u00EAn</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let output of outputsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ output.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ output.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Options</h3>\n <table class=\"min-w-full bg-white border border-gray-200 mb-6\">\n <thead>\n <tr>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Thu\u1ED9c t\u00EDnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">Ki\u1EC3u</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u1EB7c \u0111\u1ECBnh</th>\n <th class=\"py-2 px-4 border-b bg-gray-100\">M\u00F4 t\u1EA3</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let opt of optionsDoc\">\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.name }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">\n <code>{{ opt.type }}</code>\n </td>\n <td class=\"py-2 px-4 border-b\">{{ opt.default }}</td>\n <td class=\"py-2 px-4 border-b\">{{ opt.description }}</td>\n </tr>\n </tbody>\n </table>\n <h3 class=\"text-xl font-semibold mb-3\">Interfaces</h3>\n <div class=\"space-y-6\">\n <div\n *ngFor=\"let intf of interfacesDoc\"\n class=\"bg-gray-50 p-6 rounded-lg\">\n <h4 class=\"font-semibold mb-2\">{{ intf.name }}</h4>\n <pre class=\"bg-gray-100 p-4 rounded-lg overflow-auto text-sm mb-3\"><code>{{ intf.type }}</code></pre>\n <p>{{ intf.description }}</p>\n </div>\n </div>\n </section>\n </main>\n</div>\n", styles: ["@charset \"UTF-8\";.demo-container{padding:24px;font-family:system-ui,-apple-system,sans-serif;max-width:1200px;margin:0 auto}.demo-intro{margin-bottom:32px}.demo-intro h3{color:#333;margin-bottom:16px}.demo-intro ul{list-style:none;padding:0}.demo-intro ul li{margin-bottom:8px;padding-left:20px;position:relative}.demo-intro ul li:before{content:\"\\2022\";position:absolute;left:0;color:#3b82f6}.demo-features{margin-bottom:32px}.demo-features h3{color:#333;margin-bottom:16px}.features-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px}.feature-item{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0}.feature-item h4{color:#1e40af;margin:0 0 8px}.feature-item p{margin:0;color:#64748b}.demo-api{margin-bottom:48px}.demo-api h3{color:#333;margin-bottom:24px}.api-section{margin-bottom:32px}.api-section h4{color:#1e40af;margin-bottom:16px}.api-table{overflow-x:auto}.api-table table{width:100%;border-collapse:collapse;background:#fff;border-radius:8px;border:1px solid #e2e8f0}.api-table table th,.api-table table td{padding:12px 16px;text-align:left;border-bottom:1px solid #e2e8f0}.api-table table th{background:#f8fafc;font-weight:600;color:#1e40af}.api-table table td{color:#64748b}.api-table table td:first-child{font-family:Fira Code,monospace;color:#334155}.api-table table td:nth-child(2){font-family:Fira Code,monospace;color:#3b82f6}.api-table table tr:last-child td{border-bottom:none}.demo-section{margin-bottom:48px}.demo-section h3{color:#333;margin-bottom:16px}.demo-description{margin-bottom:16px}.demo-description p{color:#64748b;margin-bottom:12px}.demo-description pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.demo-description pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155}.demo-box{display:flex;gap:16px;align-items:flex-start}.event-log{padding:16px;background:#f5f5f5;border-radius:4px;min-width:200px}.event-log p{margin:0;font-size:14px;color:#666}.demo-notes{margin-top:48px;padding:24px;background:#f8fafc;border-radius:8px;border:1px solid #e2e8f0}.demo-notes h3{color:#333;margin-bottom:16px}.demo-notes ul{list-style:none;padding:0;margin:0}.demo-notes ul li{color:#64748b;margin-bottom:12px;padding-left:24px;position:relative}.demo-notes ul li:before{content:\"\\2192\";position:absolute;left:0;color:#3b82f6}.demo-notes ul li:last-child{margin-bottom:0}.interface-description{margin-bottom:24px}.interface-description p{color:#64748b;margin-bottom:16px}.interface-description pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.interface-description pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155;line-height:1.6}.interface-usage{margin-bottom:24px}.interface-usage h5{color:#1e40af;margin-bottom:12px;font-size:16px}.interface-usage pre{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0;overflow-x:auto}.interface-usage pre code{font-family:Fira Code,monospace;font-size:14px;color:#334155;line-height:1.6}.interface-usage pre code .comment{color:#64748b}.interface-notes{background:#f8fafc;padding:16px;border-radius:8px;border:1px solid #e2e8f0}.interface-notes h5{color:#1e40af;margin-bottom:12px;font-size:16px}.interface-notes ul{list-style:none;padding:0;margin:0}.interface-notes ul li{color:#64748b;margin-bottom:8px;padding-left:20px;position:relative}.interface-notes ul li:before{content:\"\\2022\";position:absolute;left:0;color:#3b82f6}.interface-notes ul li:last-child{margin-bottom:0}\n"] }]
83
- }] });
84
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsLW92ZXJsYXkuZGVtby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9zY3JvbGwtb3ZlcmxheS9zcmMvZGVtby9zY3JvbGwtb3ZlcmxheS5kZW1vLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL3Njcm9sbC1vdmVybGF5L3NyYy9kZW1vL3Njcm9sbC1vdmVybGF5LmRlbW8uaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7OztBQVVyRixNQUFNLE9BQU8sMENBQTBDO0lBQ3JELGdFQUFnRTtJQUNoRSxXQUFXLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3hGLHdFQUF3RTtJQUN4RSxxQkFBcUIsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFakcscUJBQXFCO0lBQ3JCLGVBQWUsR0FBRyxDQUFDLFNBQVMsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLFlBQVksQ0FBVSxDQUFDO0lBQ2hGLGdC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LEVBQUUsZUFBZSxFQUFFO1FBQ3BHLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsNEJBQTRCLEVBQUU7S0FDOUcsQ0FBQztJQUNGLGFBQWEsR0FBRyxDQUFDLEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLHNDQUFzQyxFQUFFLENBQUMsQ0FBQztJQUU1SCx3QkFBd0I7SUFDeEIsaUJBQWlCLEdBQUcsZ0RBQWdELENBQUM7SUFDckUsa0JBQWtCLEdBQUcsNkNBQTZDLENBQUM7SUFFbkUsZUFBZSxDQUFDLElBQVk7UUFDMUIsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDL0UsQ0FBQzt3R0EvRVUsMENBQTBDOzRGQUExQywwQ0FBMEMsbUZDWnZELHlrT0FpS0EscWlIRHpKWSxZQUFZLDRKQUFFLHNDQUFzQzs7NEZBSW5ELDBDQUEwQztrQkFQdEQsU0FBUzsrQkFDRSx5QkFBeUIsY0FDdkIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLHNDQUFzQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbXBvbmVudCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzU2Nyb2xsT3ZlcmxheURpcmVjdGl2ZSB9IGZyb20gJy4uL3Njcm9sbC1vdmVybGF5LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJU2Nyb2xsT3ZlcmxheU9wdGlvbnMgfSBmcm9tICcuLi9zY3JvbGwuaW50ZXJmYWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLXNjcm9sbC1vdmVybGF5LWRlbW8nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBMaWJzVWlDb21wb25lbnRzU2Nyb2xsT3ZlcmxheURpcmVjdGl2ZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9zY3JvbGwtb3ZlcmxheS5kZW1vLmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zY3JvbGwtb3ZlcmxheS5kZW1vLnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpQ29tcG9uZW50c1Njcm9sbE92ZXJsYXlEZW1vQ29tcG9uZW50IHtcbiAgLy8gRGVtbyB0ZXh0IGNvbnRlbnQ6IGdlbmVyYXRlIDUwMDAgd29yZHMgZm9yIHZlcnRpY2FsIHNjcm9sbGluZ1xuICBsb25nQ29udGVudCA9IHNpZ25hbChBcnJheS5mcm9tKHsgbGVuZ3RoOiA1MDAwIH0sIChfLCBpKSA9PiBgTG9yZW0ke2kgKyAxfWApLmpvaW4oJyAnKSk7XG4gIC8vIERlbW8gaG9yaXpvbnRhbCBjb250ZW50OiBnZW5lcmF0ZSA1MDAwIHdvcmRzIGZvciBob3Jpem9udGFsIHNjcm9sbGluZ1xuICBsb25nSG9yaXpvbnRhbENvbnRlbnQgPSBzaWduYWwoQXJyYXkuZnJvbSh7IGxlbmd0aDogNTAwMCB9LCAoXywgaSkgPT4gYFdvcmQke2kgKyAxfWApLmpvaW4oJyAnKSk7XG5cbiAgLy8gU2NlbmFyaW8gc2VsZWN0aW9uXG4gIHNjZW5hcmlvT3B0aW9ucyA9IFsnZGVmYXVsdCcsICdjdXN0b21TdHlsZScsICdhdXRvSGlkZScsICdob3Jpem9udGFsJ10gYXMgY29uc3Q7XG4gIHNlbGVjdGVkU2NlbmFyaW86ICh0eXBlb2YgdGhpcy5zY2VuYXJpb09wdGlvbnMpW251bWJlcl0gPSAnZGVmYXVsdCc7XG5cbiAgLy8gT3B0aW9ucyBzaWduYWxzXG4gIGN1c3RvbVN0eWxlT3B0aW9ucyA9IHNpZ25hbDxJU2Nyb2xsT3ZlcmxheU9wdGlvbnM+KHsgc2Nyb2xsYmFyV2lkdGg6IDEyLCBzY3JvbGxiYXJDb2xvcjogJyNmM2Y0ZjYnLCBzY3JvbGxiYXJIb3ZlckNvbG9yOiAnI2U1ZTdlYicsIHNjcm9sbFRodW1iQ29sb3I6ICcjM2I4MmY2Jywgc2Nyb2xsVGh1bWJIb3ZlckNvbG9yOiAnIzI1NjNlYicsIHNjcm9sbGJhclBhZGRpbmc6IDQgfSk7XG4gIGF1dG9IaWRlT3B0aW9ucyA9IHNpZ25hbDxJU2Nyb2xsT3ZlcmxheU9wdGlvbnM+KHsgc2Nyb2xsWU9wYWNpdHkwOiB0cnVlLCBzY3JvbGxiYXJXaWR0aDogOCwgc2Nyb2xsYmFyQ29sb3I6ICd0cmFuc3BhcmVudCcsIHNjcm9sbFRodW1iQ29sb3I6ICcjOWNhM2FmJywgc2Nyb2xsVGh1bWJIb3ZlckNvbG9yOiAnIzZiNzI4MCcgfSk7XG4gIGhvcml6b250YWxPcHRpb25zID0gc2lnbmFsPElTY3JvbGxPdmVybGF5T3B0aW9ucz4oeyBzY3JvbGxYOiAnc2Nyb2xsJywgc2Nyb2xsWTogJ2hpZGRlbicsIHNjcm9sbGJhcldpZHRoOiA4LCBzY3JvbGxiYXJDb2xvcjogJyNmM2Y0ZjYnLCBzY3JvbGxUaHVtYkNvbG9yOiAnIzNiODJmNicgfSk7XG5cbiAgLy8gU2Nyb2xsIGV2ZW50IGxvZ1xuICBsYXN0RXZlbnQgPSBzaWduYWw8c3RyaW5nPignTm8gZXZlbnRzIHlldCcpO1xuXG4gIC8vIEhlbHBlcnNcbiAgZ2V0IG9wdGlvbnMoKTogSVNjcm9sbE92ZXJsYXlPcHRpb25zIHwgdW5kZWZpbmVkIHtcbiAgICBzd2l0Y2ggKHRoaXMuc2VsZWN0ZWRTY2VuYXJpbykge1xuICAgICAgY2FzZSAnY3VzdG9tU3R5bGUnOlxuICAgICAgICByZXR1cm4gdGhpcy5jdXN0b21TdHlsZU9wdGlvbnMoKTtcbiAgICAgIGNhc2UgJ2F1dG9IaWRlJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0b0hpZGVPcHRpb25zKCk7XG4gICAgICBjYXNlICdob3Jpem9udGFsJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuaG9yaXpvbnRhbE9wdGlvbnMoKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGNvbnRlbnQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFNjZW5hcmlvID09PSAnaG9yaXpvbnRhbCcgPyB0aGlzLmxvbmdIb3Jpem9udGFsQ29udGVudCgpIDogdGhpcy5sb25nQ29udGVudCgpO1xuICB9XG5cbiAgLy8gRXZlbnQgaGFuZGxlcnNcbiAgb25TY3JvbGwoKSB7XG4gICAgdGhpcy5sYXN0RXZlbnQuc2V0KCdTY3JvbGwgZXZlbnQgZmlyZWQnKTtcbiAgfVxuICBvblNjcm9sbFRvcCgpIHtcbiAgICB0aGlzLmxhc3RFdmVudC5zZXQoJ1JlYWNoZWQgdG9wJyk7XG4gIH1cbiAgb25TY3JvbGxCb3R0b20oKSB7XG4gICAgdGhpcy5sYXN0RXZlbnQuc2V0KCdSZWFjaGVkIGJvdHRvbScpO1xuICB9XG5cbiAgLy8gQVBJIGRvY3NcbiAgaW5wdXRzRG9jID0gW1xuICAgIHsgbmFtZTogJ29wdGlvbnMnLCB0eXBlOiAnSVNjcm9sbE92ZXJsYXlPcHRpb25zJywgZGVmYXVsdDogJ3VuZGVmaW5lZCcsIGRlc2NyaXB0aW9uOiAnQ+G6pXUgaMOsbmggdHXhu7MgY2jhu4luaCBzY3JvbGxiYXInIH0sXG4gICAgeyBuYW1lOiAnZGVidWdNb2RlJywgdHlwZTogJ2Jvb2xlYW4nLCBkZWZhdWx0OiAnZmFsc2UnLCBkZXNjcmlwdGlvbjogJ0Lhuq10IGNo4bq/IMSR4buZIGRlYnVnJyB9LFxuICAgIHsgbmFtZTogJ25vdFNob3dTY3JvbGxCYXJYJywgdHlwZTogJ2Jvb2xlYW4nLCBkZWZhdWx0OiAnZmFsc2UnLCBkZXNjcmlwdGlvbjogJ+G6qG4gc2Nyb2xsYmFyIG5nYW5nJyB9LFxuICAgIHsgbmFtZTogJ25vdFNob3dTY3JvbGxCYXJZJywgdHlwZTogJ2Jvb2xlYW4nLCBkZWZhdWx0OiAnZmFsc2UnLCBkZXNjcmlwdGlvbjogJ+G6qG4gc2Nyb2xsYmFyIGThu41jJyB9LFxuICBdO1xuICBvdXRwdXRzRG9jID0gW1xuICAgIHsgbmFtZTogJ291dFNjcm9sbCcsIHR5cGU6ICdFdmVudCcsIGRlc2NyaXB0aW9uOiAnQuG6r24gcmEga2hpIHNjcm9sbCBi4bqldCBr4buzJyB9LFxuICAgIHsgbmFtZTogJ291dFNjcm9sbFRvcCcsIHR5cGU6ICdFdmVudCcsIGRlc2NyaXB0aW9uOiAnQuG6r24gcmEga2hpIHNjcm9sbCDEkeG6v24gdG9wJyB9LFxuICAgIHsgbmFtZTogJ291dFNjcm9sbEJvdHRvbScsIHR5cGU6ICdFdmVudCcsIGRlc2NyaXB0aW9uOiAnQuG6r24gcmEga2hpIHNjcm9sbCDEkeG6v24gYm90dG9tJyB9LFxuICBdO1xuICBvcHRpb25zRG9jID0gW1xuICAgIHsgbmFtZTogJ3Njcm9sbGJhcldpZHRoJywgdHlwZTogJ251bWJlcicsIGRlZmF1bHQ6ICd1bmRlZmluZWQnLCBkZXNjcmlwdGlvbjogJ0NoaeG7gXUgcuG7mW5nIHNjcm9sbGJhciAocHgpJyB9LFxuICAgIHsgbmFtZTogJ3Njcm9sbGJhckNvbG9yJywgdHlwZTogJ3N0cmluZycsIGRlZmF1bHQ6ICd1bmRlZmluZWQnLCBkZXNjcmlwdGlvbjogJ03DoHUgdHJhY2sgc2Nyb2xsYmFyJyB9LFxuICAgIHsgbmFtZTogJ3Njcm9sbGJhckhvdmVyQ29sb3InLCB0eXBlOiAnc3RyaW5nJywgZGVmYXVsdDogJ3VuZGVmaW5lZCcsIGRlc2NyaXB0aW9uOiAnTcOgdSB0cmFjayBraGkgaG92ZXInIH0sXG4gICAgeyBuYW1lOiAnc2Nyb2xsVGh1bWJDb2xvcicsIHR5cGU6ICdzdHJpbmcnLCBkZWZhdWx0OiAndW5kZWZpbmVkJywgZGVzY3JpcHRpb246ICdNw6B1IHRodW1iJyB9LFxuICAgIHsgbmFtZTogJ3Njcm9sbFRodW1iSG92ZXJDb2xvcicsIHR5cGU6ICdzdHJpbmcnLCBkZWZhdWx0OiAndW5kZWZpbmVkJywgZGVzY3JpcHRpb246ICdNw6B1IHRodW1iIGtoaSBob3ZlcicgfSxcbiAgICB7IG5hbWU6ICdzY3JvbGxiYXJQYWRkaW5nJywgdHlwZTogJ251bWJlcicsIGRlZmF1bHQ6ICd1bmRlZmluZWQnLCBkZXNjcmlwdGlvbjogJ1BhZGRpbmcgc2Nyb2xsYmFyJyB9LFxuICAgIHsgbmFtZTogJ3Njcm9sbFgnLCB0eXBlOiBgJ2hpZGRlbicgfCAnc2Nyb2xsJ2AsIGRlZmF1bHQ6ICd1bmRlZmluZWQnLCBkZXNjcmlwdGlvbjogJ0tp4buDdSBzY3JvbGwgWCcgfSxcbiAgICB7IG5hbWU6ICdzY3JvbGxYT3BhY2l0eTAnLCB0eXBlOiAnYm9vbGVhbicsIGRlZmF1bHQ6ICd1bmRlZmluZWQnLCBkZXNjcmlwdGlvbjogJ+G6qG4gdHJhY2sgWCBraGkga2jDtG5nIGhvdmVyJyB9LFxuICAgIHsgbmFtZTogJ3Njcm9sbFknLCB0eXBlOiBgJ2hpZGRlbicgfCAnc2Nyb2xsJ2AsIGRlZmF1bHQ6ICd1bmRlZmluZWQnLCBkZXNjcmlwdGlvbjogJ0tp4buDdSBzY3JvbGwgWScgfSxcbiAgICB7IG5hbWU6ICdzY3JvbGxZT3BhY2l0eTAnLCB0eXBlOiAnYm9vbGVhbicsIGRlZmF1bHQ6ICd1bmRlZmluZWQnLCBkZXNjcmlwdGlvbjogJ+G6qG4gdHJhY2sgWSBraGkga2jDtG5nIGhvdmVyJyB9LFxuICBdO1xuICBpbnRlcmZhY2VzRG9jID0gW3sgbmFtZTogJ0lTY3JvbGxPdmVybGF5T3B0aW9ucycsIHR5cGU6ICdpbnRlcmZhY2UnLCBkZXNjcmlwdGlvbjogJ0PDoWMgdHXhu7MgY2jhu41uIGPhuqV1IGjDrG5oIHNjcm9sbC1vdmVybGF5JyB9XTtcblxuICAvLyBJbnN0YWxsYXRpb24gY29tbWFuZHNcbiAgaW5zdGFsbENvbW1hbmROcG0gPSAnbnBtIGluc3RhbGwgQGxpYnMtdWkvY29tcG9uZW50cy1zY3JvbGwtb3ZlcmxheSc7XG4gIGluc3RhbGxDb21tYW5kWWFybiA9ICd5YXJuIGFkZCBAbGlicy11aS9jb21wb25lbnRzLXNjcm9sbC1vdmVybGF5JztcblxuICBjb3B5VG9DbGlwYm9hcmQodGV4dDogc3RyaW5nKSB7XG4gICAgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQodGV4dCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQ29waWVkOicsIHRleHQpKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm1heC13LTZ4bCBteC1hdXRvIHAtNSBmb250LXNhbnMgdGV4dC1ncmF5LTgwMFwiPlxuICA8aGVhZGVyIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktMTAgYmctd2hpdGUgcm91bmRlZC1sZyBtYi04IHNoYWRvdy1zbVwiPlxuICAgIDxoMSBjbGFzcz1cInRleHQtNHhsIGZvbnQtYm9sZCBtYi0yXCI+RGVtbyBTY3JvbGwgT3ZlcmxheTwvaDE+XG4gICAgPHAgY2xhc3M9XCJ0ZXh0LXhsIHRleHQtZ3JheS01MDBcIj4mIzY0O2xpYnMtdWkvY29tcG9uZW50cy1zY3JvbGwtb3ZlcmxheTwvcD5cbiAgPC9oZWFkZXI+XG5cbiAgPG1haW4+XG4gICAgPCEtLSBHaeG7m2kgdGhp4buHdSAtLT5cbiAgICA8c2VjdGlvbiBjbGFzcz1cImJnLXdoaXRlIHJvdW5kZWQtbGcgcC04IG1iLTggc2hhZG93LXNtXCI+XG4gICAgICA8aDIgY2xhc3M9XCJ0ZXh0LTJ4bCBmb250LWJvbGQgbWItNSBwYi0zIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPkdp4bubaSB0aGnhu4d1PC9oMj5cbiAgICAgIDxwPlxuICAgICAgICA8Y29kZT5zY3JvbGwtb3ZlcmxheTwvY29kZT5cbiAgICAgICAgbMOgIG3hu5l0IGRpcmVjdGl2ZSBnacO6cCB0deG7syBiaeG6v24gc2Nyb2xsYmFyIHRyw6puIGLhuqV0IGvhu7MgcGjhuqduIHThu60gbsOgbyB0cm9uZyBBbmd1bGFyLCBo4buXIHRy4bujIHR14buzIGNo4buJbmggbcOgdSwga8OtY2ggdGjGsOG7m2MsIOG6qW4vaGnhu4duIHbDoCBz4buxIGtp4buHbiBzY3JvbGwuXG4gICAgICA8L3A+XG4gICAgPC9zZWN0aW9uPlxuXG4gICAgPCEtLSBDw6BpIMSR4bq3dCAtLT5cbiAgICA8c2VjdGlvbiBjbGFzcz1cImJnLXdoaXRlIHJvdW5kZWQtbGcgcC04IG1iLTggc2hhZG93LXNtXCI+XG4gICAgICA8aDIgY2xhc3M9XCJ0ZXh0LTJ4bCBmb250LWJvbGQgbWItNSBwYi0zIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPkPDoGkgxJHhurd0PC9oMj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBiZy1ncmF5LTEwMCBwLTQgcm91bmRlZC1sZyBtYi00XCI+XG4gICAgICAgIDxwcmUgY2xhc3M9XCJmbGV4LTEgdGV4dC1zbSBvdmVyZmxvdy14LWF1dG9cIj48Y29kZT57eyBpbnN0YWxsQ29tbWFuZE5wbSB9fTwvY29kZT48L3ByZT5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIGNsYXNzPVwibWwtNCBweC0zIHB5LTEgYmctYmx1ZS01MDAgdGV4dC13aGl0ZSByb3VuZGVkIGhvdmVyOmJnLWJsdWUtNjAwXCJcbiAgICAgICAgICAoY2xpY2spPVwiY29weVRvQ2xpcGJvYXJkKGluc3RhbGxDb21tYW5kTnBtKVwiPlxuICAgICAgICAgIFNhbyBjaMOpcFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGJnLWdyYXktMTAwIHAtNCByb3VuZGVkLWxnXCI+XG4gICAgICAgIDxwcmUgY2xhc3M9XCJmbGV4LTEgdGV4dC1zbSBvdmVyZmxvdy14LWF1dG9cIj48Y29kZT57eyBpbnN0YWxsQ29tbWFuZFlhcm4gfX08L2NvZGU+PC9wcmU+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICBjbGFzcz1cIm1sLTQgcHgtMyBweS0xIGJnLWJsdWUtNTAwIHRleHQtd2hpdGUgcm91bmRlZCBob3ZlcjpiZy1ibHVlLTYwMFwiXG4gICAgICAgICAgKGNsaWNrKT1cImNvcHlUb0NsaXBib2FyZChpbnN0YWxsQ29tbWFuZFlhcm4pXCI+XG4gICAgICAgICAgU2FvIGNow6lwXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9zZWN0aW9uPlxuXG4gICAgPCEtLSBEZW1vIFRy4buxYyB0aeG6v3AgLS0+XG4gICAgPHNlY3Rpb24gY2xhc3M9XCJiZy13aGl0ZSByb3VuZGVkLWxnIHAtOCBtYi04IHNoYWRvdy1zbVwiPlxuICAgICAgPGgyIGNsYXNzPVwidGV4dC0yeGwgZm9udC1ib2xkIG1iLTUgcGItMyBib3JkZXItYiBib3JkZXItZ3JheS0yMDBcIj5EZW1vIFRy4buxYyB0aeG6v3A8L2gyPlxuICAgICAgPGRpdiBjbGFzcz1cImdyaWQgZ3JpZC1jb2xzLTQgZ2FwLTQgbWItNlwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nRm9yPVwibGV0IHNjIG9mIHNjZW5hcmlvT3B0aW9uc1wiXG4gICAgICAgICAgKGNsaWNrKT1cInNlbGVjdGVkU2NlbmFyaW8gPSBzY1wiXG4gICAgICAgICAgY2xhc3M9XCJweC0zIHB5LTEgYm9yZGVyIHJvdW5kZWRcIlxuICAgICAgICAgIFtjbGFzcy5iZy1ibHVlLTUwMF09XCJzZWxlY3RlZFNjZW5hcmlvID09PSBzY1wiXG4gICAgICAgICAgW2NsYXNzLnRleHQtd2hpdGVdPVwic2VsZWN0ZWRTY2VuYXJpbyA9PT0gc2NcIj5cbiAgICAgICAgICB7eyBzYyB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInAtNCBiZy1ncmF5LTUwIHJvdW5kZWQtbGcgaC1bMzAwcHhdXCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBMaWJzVWlDb21wb25lbnRzU2Nyb2xsT3ZlcmxheURpcmVjdGl2ZVxuICAgICAgICAgIFtvcHRpb25zXT1cIm9wdGlvbnNcIlxuICAgICAgICAgIChvdXRTY3JvbGwpPVwib25TY3JvbGwoKVwiXG4gICAgICAgICAgKG91dFNjcm9sbFRvcCk9XCJvblNjcm9sbFRvcCgpXCJcbiAgICAgICAgICAob3V0U2Nyb2xsQm90dG9tKT1cIm9uU2Nyb2xsQm90dG9tKClcIlxuICAgICAgICAgIGNsYXNzPVwidy1mdWxsIGgtZnVsbFwiPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwicC0yXCJcbiAgICAgICAgICAgIFtpbm5lclRleHRdPVwiY29udGVudFwiXG4gICAgICAgICAgICBbY2xhc3Mud2hpdGVzcGFjZS1wcmUtd3JhcF09XCJzZWxlY3RlZFNjZW5hcmlvICE9PSAnaG9yaXpvbnRhbCdcIlxuICAgICAgICAgICAgW2NsYXNzLndoaXRlc3BhY2Utbm93cmFwXT1cInNlbGVjdGVkU2NlbmFyaW8gPT09ICdob3Jpem9udGFsJ1wiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPHAgY2xhc3M9XCJtdC00IHRleHQtZ3JheS03MDBcIj5T4buxIGtp4buHbjoge3sgbGFzdEV2ZW50KCkgfX08L3A+XG4gICAgPC9zZWN0aW9uPlxuXG4gICAgPCEtLSBDw6FjaCBz4butIGThu6VuZyAtLT5cbiAgICA8c2VjdGlvbiBjbGFzcz1cImJnLXdoaXRlIHJvdW5kZWQtbGcgcC04IG1iLTggc2hhZG93LXNtXCI+XG4gICAgICA8aDIgY2xhc3M9XCJ0ZXh0LTJ4bCBmb250LWJvbGQgbWItNSBwYi0zIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPkPDoWNoIHPhu60gZOG7pW5nPC9oMj5cbiAgICAgIDxwcmUgY2xhc3M9XCJiZy1ncmF5LTEwMCBwLTQgcm91bmRlZC1sZyBvdmVyZmxvdy1hdXRvIHRleHQtc21cIj5cbiAgICAgICAgPGNvZGUgbmdOb25CaW5kYWJsZT4mbHQ7ZGl2IExpYnNVaUNvbXBvbmVudHNTY3JvbGxPdmVybGF5RGlyZWN0aXZlIFtvcHRpb25zXT1cIiYjMTIzOyBzY3JvbGxiYXJXaWR0aDoxMiwgc2Nyb2xsVGh1bWJDb2xvcjonIzNiODJmNicgJiMxMjU7XCIgc3R5bGU9XCJ3aWR0aDozMDBweDtoZWlnaHQ6MjAwcHg7b3ZlcmZsb3c6YXV0bztcIiZndDtcbiAgTuG7mWkgZHVuZyBkw6BpLi4uXG4mbHQ7L2RpdiZndDs8L2NvZGU+XG4gICAgICA8L3ByZT5cbiAgICA8L3NlY3Rpb24+XG5cbiAgICA8IS0tIEFQSSBSZWZlcmVuY2UgLS0+XG4gICAgPHNlY3Rpb24gY2xhc3M9XCJiZy13aGl0ZSByb3VuZGVkLWxnIHAtOCBtYi04IHNoYWRvdy1zbVwiPlxuICAgICAgPGgyIGNsYXNzPVwidGV4dC0yeGwgZm9udC1ib2xkIG1iLTUgcGItMyBib3JkZXItYiBib3JkZXItZ3JheS0yMDBcIj5BUEkgUmVmZXJlbmNlPC9oMj5cbiAgICAgIDxoMyBjbGFzcz1cInRleHQteGwgZm9udC1zZW1pYm9sZCBtYi0zXCI+SW5wdXRzPC9oMz5cbiAgICAgIDx0YWJsZSBjbGFzcz1cIm1pbi13LWZ1bGwgYmctd2hpdGUgYm9yZGVyIGJvcmRlci1ncmF5LTIwMCBtYi02XCI+XG4gICAgICAgIDx0aGVhZD5cbiAgICAgICAgICA8dHI+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJweS0yIHB4LTQgYm9yZGVyLWIgYmctZ3JheS0xMDBcIj5Uw6puPC90aD5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cInB5LTIgcHgtNCBib3JkZXItYiBiZy1ncmF5LTEwMFwiPktp4buDdTwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJweS0yIHB4LTQgYm9yZGVyLWIgYmctZ3JheS0xMDBcIj5N4bq3YyDEkeG7i25oPC90aD5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cInB5LTIgcHgtNCBib3JkZXItYiBiZy1ncmF5LTEwMFwiPk3DtCB04bqjPC90aD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L3RoZWFkPlxuICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBpbnB1dCBvZiBpbnB1dHNEb2NcIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cInB5LTIgcHgtNCBib3JkZXItYlwiPlxuICAgICAgICAgICAgICA8Y29kZT57eyBpbnB1dC5uYW1lIH19PC9jb2RlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cInB5LTIgcHgtNCBib3JkZXItYlwiPlxuICAgICAgICAgICAgICA8Y29kZT57eyBpbnB1dC50eXBlIH19PC9jb2RlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cInB5LTIgcHgtNCBib3JkZXItYlwiPnt7IGlucHV0LmRlZmF1bHQgfX08L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwicHktMiBweC00IGJvcmRlci1iXCI+e3sgaW5wdXQuZGVzY3JpcHRpb24gfX08L3RkPlxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIDwvdGJvZHk+XG4gICAgICA8L3RhYmxlPlxuICAgICAgPGgzIGNsYXNzPVwidGV4dC14bCBmb250LXNlbWlib2xkIG1iLTNcIj5PdXRwdXRzPC9oMz5cbiAgICAgIDx0YWJsZSBjbGFzcz1cIm1pbi13LWZ1bGwgYmctd2hpdGUgYm9yZGVyIGJvcmRlci1ncmF5LTIwMCBtYi02XCI+XG4gICAgICAgIDx0aGVhZD5cbiAgICAgICAgICA8dHI+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJweS0yIHB4LTQgYm9yZGVyLWIgYmctZ3JheS0xMDBcIj5Uw6puPC90aD5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cInB5LTIgcHgtNCBib3JkZXItYiBiZy1ncmF5LTEwMFwiPktp4buDdTwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJweS0yIHB4LTQgYm9yZGVyLWIgYmctZ3JheS0xMDBcIj5Nw7QgdOG6ozwvdGg+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90aGVhZD5cbiAgICAgICAgPHRib2R5PlxuICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgb3V0cHV0IG9mIG91dHB1dHNEb2NcIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cInB5LTIgcHgtNCBib3JkZXItYlwiPlxuICAgICAgICAgICAgICA8Y29kZT57eyBvdXRwdXQubmFtZSB9fTwvY29kZT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJweS0yIHB4LTQgYm9yZGVyLWJcIj5cbiAgICAgICAgICAgICAgPGNvZGU+e3sgb3V0cHV0LnR5cGUgfX08L2NvZGU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwicHktMiBweC00IGJvcmRlci1iXCI+e3sgb3V0cHV0LmRlc2NyaXB0aW9uIH19PC90ZD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L3Rib2R5PlxuICAgICAgPC90YWJsZT5cbiAgICAgIDxoMyBjbGFzcz1cInRleHQteGwgZm9udC1zZW1pYm9sZCBtYi0zXCI+T3B0aW9uczwvaDM+XG4gICAgICA8dGFibGUgY2xhc3M9XCJtaW4tdy1mdWxsIGJnLXdoaXRlIGJvcmRlciBib3JkZXItZ3JheS0yMDAgbWItNlwiPlxuICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgPHRyPlxuICAgICAgICAgICAgPHRoIGNsYXNzPVwicHktMiBweC00IGJvcmRlci1iIGJnLWdyYXktMTAwXCI+VGh14buZYyB0w61uaDwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJweS0yIHB4LTQgYm9yZGVyLWIgYmctZ3JheS0xMDBcIj5LaeG7g3U8L3RoPlxuICAgICAgICAgICAgPHRoIGNsYXNzPVwicHktMiBweC00IGJvcmRlci1iIGJnLWdyYXktMTAwXCI+TeG6t2MgxJHhu4tuaDwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJweS0yIHB4LTQgYm9yZGVyLWIgYmctZ3JheS0xMDBcIj5Nw7QgdOG6ozwvdGg+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90aGVhZD5cbiAgICAgICAgPHRib2R5PlxuICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgb3B0IG9mIG9wdGlvbnNEb2NcIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cInB5LTIgcHgtNCBib3JkZXItYlwiPlxuICAgICAgICAgICAgICA8Y29kZT57eyBvcHQubmFtZSB9fTwvY29kZT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJweS0yIHB4LTQgYm9yZGVyLWJcIj5cbiAgICAgICAgICAgICAgPGNvZGU+e3sgb3B0LnR5cGUgfX08L2NvZGU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwicHktMiBweC00IGJvcmRlci1iXCI+e3sgb3B0LmRlZmF1bHQgfX08L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwicHktMiBweC00IGJvcmRlci1iXCI+e3sgb3B0LmRlc2NyaXB0aW9uIH19PC90ZD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L3Rib2R5PlxuICAgICAgPC90YWJsZT5cbiAgICAgIDxoMyBjbGFzcz1cInRleHQteGwgZm9udC1zZW1pYm9sZCBtYi0zXCI+SW50ZXJmYWNlczwvaDM+XG4gICAgICA8ZGl2IGNsYXNzPVwic3BhY2UteS02XCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgaW50ZiBvZiBpbnRlcmZhY2VzRG9jXCJcbiAgICAgICAgICBjbGFzcz1cImJnLWdyYXktNTAgcC02IHJvdW5kZWQtbGdcIj5cbiAgICAgICAgICA8aDQgY2xhc3M9XCJmb250LXNlbWlib2xkIG1iLTJcIj57eyBpbnRmLm5hbWUgfX08L2g0PlxuICAgICAgICAgIDxwcmUgY2xhc3M9XCJiZy1ncmF5LTEwMCBwLTQgcm91bmRlZC1sZyBvdmVyZmxvdy1hdXRvIHRleHQtc20gbWItM1wiPjxjb2RlPnt7IGludGYudHlwZSB9fTwvY29kZT48L3ByZT5cbiAgICAgICAgICA8cD57eyBpbnRmLmRlc2NyaXB0aW9uIH19PC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvc2VjdGlvbj5cbiAgPC9tYWluPlxuPC9kaXY+XG4iXX0=