ngx-edge-slider 2.1.3 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/esm2022/lib/component/simple-slider.component.mjs +215 -0
  2. package/esm2022/lib/engine/slider-engine.service.mjs +288 -0
  3. package/esm2022/lib/models/slider-config.model.mjs +18 -0
  4. package/esm2022/lib/models/slider-state.model.mjs +17 -0
  5. package/esm2022/lib/ngx-edge-slider.module.mjs +16 -0
  6. package/esm2022/lib/plugins/autoplay/autoplay.plugin.mjs +47 -0
  7. package/esm2022/lib/plugins/draggable/draggable.plugin.mjs +67 -0
  8. package/esm2022/lib/plugins/navigation/navigation.plugin.mjs +80 -0
  9. package/esm2022/lib/plugins/pagination/pagination.plugin.mjs +50 -0
  10. package/esm2022/lib/plugins/slider-plugin.mjs +2 -0
  11. package/esm2022/lib/safe-url.pipe.mjs +19 -0
  12. package/esm2022/lib/store/slider-store.service.mjs +34 -0
  13. package/esm2022/ngx-edge-slider.mjs +5 -0
  14. package/esm2022/public-api.mjs +20 -0
  15. package/fesm2022/ngx-edge-slider.mjs +824 -0
  16. package/fesm2022/ngx-edge-slider.mjs.map +1 -0
  17. package/index.d.ts +5 -0
  18. package/lib/component/simple-slider.component.d.ts +60 -0
  19. package/lib/engine/slider-engine.service.d.ts +53 -0
  20. package/lib/models/slider-config.model.d.ts +34 -0
  21. package/lib/models/slider-state.model.d.ts +22 -0
  22. package/lib/ngx-edge-slider.module.d.ts +7 -0
  23. package/lib/plugins/autoplay/autoplay.plugin.d.ts +18 -0
  24. package/lib/plugins/draggable/draggable.plugin.d.ts +20 -0
  25. package/lib/plugins/navigation/navigation.plugin.d.ts +19 -0
  26. package/lib/plugins/pagination/pagination.plugin.d.ts +17 -0
  27. package/lib/plugins/slider-plugin.d.ts +16 -0
  28. package/lib/safe-url.pipe.d.ts +10 -0
  29. package/lib/store/slider-store.service.d.ts +11 -0
  30. package/package.json +28 -16
  31. package/{src/public-api.ts → public-api.d.ts} +12 -25
  32. package/ng-package.json +0 -7
  33. package/src/lib/assets/icons/arrow-black.svg +0 -3
  34. package/src/lib/assets/icons/arrow-gray.svg +0 -3
  35. package/src/lib/component/simple-slider.component.html +0 -46
  36. package/src/lib/component/simple-slider.component.scss +0 -589
  37. package/src/lib/component/simple-slider.component.ts +0 -237
  38. package/src/lib/engine/slider-engine.service.ts +0 -349
  39. package/src/lib/models/slider-config.model.ts +0 -54
  40. package/src/lib/models/slider-state.model.ts +0 -48
  41. package/src/lib/ngx-edge-slider.module.ts +0 -8
  42. package/src/lib/plugins/autoplay/autoplay.plugin.ts +0 -52
  43. package/src/lib/plugins/draggable/draggable.plugin.ts +0 -73
  44. package/src/lib/plugins/navigation/navigation.component.scss +0 -0
  45. package/src/lib/plugins/navigation/navigation.plugin.ts +0 -90
  46. package/src/lib/plugins/pagination/pagination.plugin.ts +0 -61
  47. package/src/lib/plugins/slider-plugin.ts +0 -20
  48. package/src/lib/plugins/thumbs/thumbs-scroll.plugin.ts +0 -40
  49. package/src/lib/safe-url.pipe.ts +0 -11
  50. package/src/lib/simple-slider.directive.ts +0 -15
  51. package/src/lib/store/slider-store.service.ts +0 -35
  52. package/tsconfig.lib.json +0 -13
  53. package/tsconfig.lib.prod.json +0 -11
  54. package/tsconfig.spec.json +0 -15
@@ -0,0 +1,215 @@
1
+ import { Component, ChangeDetectionStrategy, Input, EventEmitter, Output, ViewChild, ViewEncapsulation, } from "@angular/core";
2
+ import { Subject, takeUntil } from "rxjs";
3
+ import { SliderEngine } from "../engine/slider-engine.service";
4
+ import { SliderStore } from "../store/slider-store.service";
5
+ import { SliderAutoplayPlugin } from "../plugins/autoplay/autoplay.plugin";
6
+ import { SliderDraggablePlugin } from "../plugins/draggable/draggable.plugin";
7
+ import { SliderNavigationPlugin } from "../plugins/navigation/navigation.plugin";
8
+ import { SliderPaginationPlugin } from "../plugins/pagination/pagination.plugin";
9
+ import { CommonModule } from "@angular/common";
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "../engine/slider-engine.service";
12
+ import * as i2 from "../store/slider-store.service";
13
+ import * as i3 from "../plugins/draggable/draggable.plugin";
14
+ import * as i4 from "../plugins/pagination/pagination.plugin";
15
+ import * as i5 from "../plugins/navigation/navigation.plugin";
16
+ import * as i6 from "../plugins/autoplay/autoplay.plugin";
17
+ import * as i7 from "@angular/common";
18
+ export class SimpleSliderComponent {
19
+ engine;
20
+ store;
21
+ draggable;
22
+ pagination;
23
+ navigation;
24
+ autoplay;
25
+ config;
26
+ slideTemplate;
27
+ navigationTemplate;
28
+ paginationTemplate;
29
+ slideChange = new EventEmitter();
30
+ isDraggingPointer = false;
31
+ dragStartX = 0;
32
+ dragStartY = 0;
33
+ lastIndex = -1;
34
+ lastSlidesRef = null;
35
+ destroy$ = new Subject();
36
+ state$;
37
+ sliderHost;
38
+ constructor(engine, store, draggable, pagination, navigation, autoplay) {
39
+ this.engine = engine;
40
+ this.store = store;
41
+ this.draggable = draggable;
42
+ this.pagination = pagination;
43
+ this.navigation = navigation;
44
+ this.autoplay = autoplay;
45
+ }
46
+ ngOnInit() {
47
+ this.state$ = this.store.view$;
48
+ this.state$.pipe(takeUntil(this.destroy$)).subscribe((state) => {
49
+ if (state.currentSlide !== this.lastIndex) {
50
+ this.lastIndex = state.currentSlide;
51
+ this.slideChange.emit(state.currentSlide);
52
+ }
53
+ });
54
+ this.lastSlidesRef = this.config?.slides ?? null;
55
+ this.resolvePlugins(this.config);
56
+ }
57
+ ngAfterViewInit() {
58
+ if (this.sliderHost?.nativeElement) {
59
+ this.engine.attachContainer(this.sliderHost.nativeElement);
60
+ }
61
+ }
62
+ ngOnChanges(changes) {
63
+ if (!changes["config"] || !this.config)
64
+ return;
65
+ const newSlidesRef = this.config.slides ?? null;
66
+ if (newSlidesRef !== this.lastSlidesRef) {
67
+ this.lastSlidesRef = newSlidesRef;
68
+ this.engine.destroy();
69
+ this.resolvePlugins(this.config);
70
+ }
71
+ }
72
+ ngOnDestroy() {
73
+ this.destroySlider();
74
+ }
75
+ goTo(index) {
76
+ this.engine.selectSlide(index); // add this line
77
+ //this.slideChange.emit(index);
78
+ }
79
+ destroySlider() {
80
+ this.destroy$.next();
81
+ this.destroy$.complete();
82
+ this.engine.destroy();
83
+ } // destroys plugins and clears store
84
+ onNext() {
85
+ this.engine.next();
86
+ }
87
+ onPrevious() {
88
+ this.engine.previous();
89
+ }
90
+ selectSlide(index) {
91
+ this.engine.selectSlide(index);
92
+ }
93
+ onRecalculate() {
94
+ this.engine.recalculate();
95
+ }
96
+ // Navigation
97
+ /** Expose navigation observables safely */
98
+ get canPrev$() {
99
+ if (!this.navigation) {
100
+ console.warn("Navigation plugin is not enabled.");
101
+ return null;
102
+ }
103
+ return this.navigation.canPrev$;
104
+ }
105
+ get canNext$() {
106
+ if (!this.navigation) {
107
+ console.warn("Navigation plugin is not enabled.");
108
+ return null;
109
+ }
110
+ return this.navigation.canNext$;
111
+ }
112
+ /** Expose next/prev methods */
113
+ next() {
114
+ this.navigation?.next();
115
+ }
116
+ prev() {
117
+ this.navigation?.prev();
118
+ }
119
+ /** Expose pagination observable */
120
+ get pager$() {
121
+ if (!this.pagination) {
122
+ console.warn("Pagination plugin is not enabled for this slider.");
123
+ return null;
124
+ }
125
+ return this.pagination.pager$;
126
+ }
127
+ /** Expose a goToSlide method */
128
+ goToSlide(index) {
129
+ this.pagination.goToSlide(index);
130
+ }
131
+ // Handle Pointers
132
+ onPointerDown(event) {
133
+ // Only start drag if not clicking a nav button
134
+ if (event.target.closest(".nav-btn")) {
135
+ return; // ignore
136
+ }
137
+ this.dragStartX = event.clientX;
138
+ this.dragStartY = event.clientY;
139
+ this.isDraggingPointer = false;
140
+ // Do not capture yet; wait until movement exceeds threshold
141
+ this.engine.handleDragStart(event);
142
+ }
143
+ onPointerMove(event) {
144
+ const dx = Math.abs(event.clientX - this.dragStartX);
145
+ const dy = Math.abs(event.clientY - this.dragStartY);
146
+ if (!this.isDraggingPointer && (dx > 5 || dy > 5)) {
147
+ this.isDraggingPointer = true;
148
+ // Now start capturing pointer so dragging works outside the slider bounds
149
+ event.currentTarget.setPointerCapture(event.pointerId);
150
+ }
151
+ if (this.isDraggingPointer) {
152
+ this.engine.handleDragMove(event);
153
+ }
154
+ }
155
+ onPointerUp(event) {
156
+ if (!event)
157
+ return;
158
+ if (!this.isDraggingPointer) {
159
+ const target = event.target;
160
+ // Only select the slide if click is not on an interactive child
161
+ const slideEl = target.closest(".slide");
162
+ if (slideEl && !target.closest("button, video, a")) {
163
+ const indexAttr = slideEl.getAttribute("data-index");
164
+ const index = indexAttr ? parseInt(indexAttr, 10) : null;
165
+ if (index !== null)
166
+ this.engine.selectSlide(index);
167
+ }
168
+ }
169
+ this.engine.handleDragEnd();
170
+ this.isDraggingPointer = false;
171
+ // Release pointer capture if it was captured
172
+ try {
173
+ event.currentTarget.releasePointerCapture(event.pointerId);
174
+ }
175
+ catch { }
176
+ }
177
+ resolvePlugins(config) {
178
+ const runtimePlugins = [];
179
+ const cfg = config.plugins ?? {}; // <-- safe fallback
180
+ if (cfg.draggable)
181
+ runtimePlugins.push(this.draggable);
182
+ if (cfg.pagination)
183
+ runtimePlugins.push(this.pagination);
184
+ if (cfg.navigation)
185
+ runtimePlugins.push(this.navigation);
186
+ if (cfg.autoplay) {
187
+ this.autoplay.setConfig(cfg.autoplay);
188
+ runtimePlugins.push(this.autoplay);
189
+ }
190
+ this.engine.init({ ...config, plugins: undefined }, runtimePlugins);
191
+ if (cfg.navigation) {
192
+ setTimeout(() => this.navigation?.updateArrows?.());
193
+ }
194
+ }
195
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SimpleSliderComponent, deps: [{ token: i1.SliderEngine }, { token: i2.SliderStore }, { token: i3.SliderDraggablePlugin }, { token: i4.SliderPaginationPlugin }, { token: i5.SliderNavigationPlugin }, { token: i6.SliderAutoplayPlugin }], target: i0.ɵɵFactoryTarget.Component });
196
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SimpleSliderComponent, isStandalone: true, selector: "app-simple-slider", inputs: { config: "config", slideTemplate: "slideTemplate", navigationTemplate: "navigationTemplate", paginationTemplate: "paginationTemplate" }, outputs: { slideChange: "slideChange" }, providers: [SliderEngine, SliderStore, SliderDraggablePlugin, SliderPaginationPlugin, SliderNavigationPlugin, SliderAutoplayPlugin], viewQueries: [{ propertyName: "sliderHost", first: true, predicate: ["sliderHost"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"state$ | async as state\">\r\n <div\r\n class=\"slider\"\r\n #sliderHost\r\n [class.slider-vertical]=\"state.vertical\"\r\n [class.slider-draggable]=\"state.isDragging\"\r\n [class.slider--main]=\"!config.isThumbs\"\r\n [class.slider--thumbs]=\"config.isThumbs\"\r\n *ngIf=\"state.visibleSlides?.length > 0 && state.isVisible\"\r\n (pointerdown)=\"onPointerDown($event)\"\r\n (pointermove)=\"onPointerMove($event)\"\r\n (pointerup)=\"onPointerUp($event)\"\r\n (pointercancel)=\"onPointerUp($event)\">\r\n <div\r\n class=\"slider__wrapper\"\r\n [ngStyle]=\"{\r\n transform: state.translate,\r\n transition: draggable.isDraggingPointer ? 'none' : 'transform 0.3s ease',\r\n display: 'flex',\r\n 'flex-direction': state.vertical ? 'column' : 'row',\r\n 'justify-content': state.visibleSlides?.length < state.slidesPerView ? 'center' : 'flex-start',\r\n gap: (state.slidesPerView > 1 ? state.gap || 0 : 0) + 'px',\r\n }\">\r\n <div\r\n *ngFor=\"let slide of state.visibleSlides; let i = index\"\r\n class=\"slide\"\r\n [attr.data-index]=\"i\"\r\n [class.slide--current]=\"state.selectedSlide === i\"\r\n [style.flex]=\"\r\n !config.isThumbs\r\n ? '0 0 calc(' +\r\n 100 / state.slidesPerView +\r\n '% - ' +\r\n ((state.gap || 0) * (state.slidesPerView - 1)) / state.slidesPerView +\r\n 'px)'\r\n : '0 0 ' + thumbSize + 'px'\r\n \"\r\n [style.width]=\"config.isThumbs ? thumbSize + 'px' : null\"\r\n [style.height]=\"config.isThumbs ? thumbSize + 'px' : null\"\r\n (click)=\"engine.selectSlide(i)\">\r\n <ng-container\r\n *ngTemplateOutlet=\"slideTemplate ? slideTemplate : defaultSlideTemplate; context: { slide: slide, index: i }\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;position:relative}.slider-main-product{display:inline-flex;height:520px}.slider-main{width:100%;height:600px;justify-content:center;display:flex}@media (max-width: 577px){.slider-main{height:100%;display:block}}.slider--main{height:100%;overflow:hidden}.slider--main .slider__wrapper{display:flex;will-change:transform}.slider--main .slider__wrapper .slide{flex:0 0 100%}.slider--main .slider__wrapper .slide .slide-content,.slider--main .slider__wrapper .slide picture{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.slider--main .slider__wrapper .slide .slide-content .drag-handle,.slider--main .slider__wrapper .slide picture .drag-handle{width:100%;height:100%;cursor:grab;z-index:10;pointer-events:all}.slider--main .slider__wrapper .slide .slide-content img,.slider--main .slider__wrapper .slide picture img{max-width:100%;max-height:100%;object-fit:contain;display:block;transform-origin:center;transform:translateZ(0);pointer-events:none}.slider--thumbs{margin-top:24px;margin-bottom:36px;height:70px!important}.slider--thumbs .slider__wrapper{display:flex;gap:8px;will-change:transform;transform:translateZ(0)}.slider--thumbs .slide{flex:0 0 auto;pointer-events:auto}.slider--thumbs .slide .slide-content{width:54px;height:68px;display:flex;align-items:center;justify-content:center;border:1px solid #ebebeb;cursor:pointer}.slider--thumbs .slide .slide-content img{max-width:100%;max-height:100%;object-fit:contain;display:block;transform:scale(.9)}.slider--thumbs .slide .slide-content.slide--current{border-color:#212121}.slider{width:100%;height:100%;overflow:hidden;position:relative;touch-action:none;cursor:grab;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;-webkit-tap-highlight-color:transparent}.slider.slider-can-drag{cursor:grab}.slider.slider-is-dragging{cursor:grabbing}.slider.slider-dragged{box-shadow:0 0 10px #0000001a}.slider.slider-drag-prevent-click{pointer-events:none}.slider .slider__wrapper{display:flex;transition:transform .3s cubic-bezier(.25,.46,.45,.84);will-change:transform;transform:none;width:auto;height:100%}.slider .slide{display:flex;align-items:center;justify-content:center;height:100%;overflow:hidden;flex-shrink:0;position:relative;transition:transform .3s cubic-bezier(.25,.46,.45,.84)}@media (min-width: 1441px){.slider--thumbs .slide{flex:0 0 20%}}@media (max-width: 1024px){.slider--thumbs .slide{flex:0 0 33.333%}}@media (max-width: 1023px){.slider--thumbs .slide{flex:0 0 50%}}.slider-arrow-next,.slider-arrow-prev{position:absolute;top:50%;transform:translateY(-50%);width:32px;height:32px;background:#fffc no-repeat center center;cursor:pointer;z-index:10}.slider-arrow-next.next,.slider-arrow-prev.next{right:10px}.slider-arrow-next.prev,.slider-arrow-prev.prev{left:10px}.thumbs-wrapper{position:relative}.thumb-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:20;width:48px;height:48px;background:#ffffffe6 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='4.51 0.01 10.99 19.97'%3E%3Cpath fill='%23000' d='m4.508 18.968 1.006 1.006 9.983-9.984L5.514.005 4.508 1.011l8.984 8.984-8.984 8.973Z'/%3E%3C/svg%3E\") no-repeat center center/11px 18px;font-size:36px;line-height:56px;opacity:0;pointer-events:none;transition:opacity .2s ease}.thumb-nav.activeArrow{opacity:1;pointer-events:all}.thumb-nav--left{left:-73px;transform:translateY(-50%) rotate(180deg)!important}.thumb-nav--right{right:-65px}.slider-pagination .thumb-dots-wrapper{display:flex;align-items:center;justify-content:center;gap:7px}.slider-pagination .thumb-dots-wrapper .thumb-dot{display:inline-block;width:4px;height:4px;margin:0 0 0 8px;border-radius:50%;background:#b3b3b3}.slider-pagination .thumb-dots-wrapper .thumb-dot.active,.slider-pagination .thumb-dots-wrapper .thumb-dot:hover{background:#212121;border:1px solid #212121}.slider-pagination .thumb-dots-wrapper .thumb-dot.hidden{opacity:0;pointer-events:none}.slider-container{position:relative;z-index:10}.slider-container .slider{position:relative;z-index:1}.slider-container .slider.slider-is-dragging{pointer-events:none}.slider-container .slider-nav{position:absolute;inset:0;pointer-events:none;z-index:20}.slider-container .slider-nav .nav-btn{pointer-events:auto;z-index:30;position:absolute;width:42px;height:42px;border-radius:2px;display:inline-flex;align-items:center;justify-content:center;border:0;cursor:pointer;background:transparent;font-size:32px;line-height:1;transition:transform .15s ease,opacity .15s ease}.slider-container .slider-nav .nav-btn:hover{transform:translateY(-1px);background:#0009}.slider-container .slider-nav .nav-btn.is-hidden{color:#a0a0a58d;opacity:.3;cursor:not-allowed;pointer-events:auto}.slider-container .slider-nav.nav--top-left .nav-btn--prev{top:-50px;left:-20px}.slider-container .slider-nav.nav--top-left .nav-btn--next{top:-50px;left:42px}.slider-container .slider-nav.nav--top-center .nav-btn--prev{top:-50px;left:50%;transform:translate(-50px)}.slider-container .slider-nav.nav--top-center .nav-btn--next{top:-50px;left:50%;transform:translate(10px)}.slider-container .slider-nav.nav--top-right .nav-btn--prev{top:-50px;right:42px}.slider-container .slider-nav.nav--top-right .nav-btn--next{top:-50px;right:-20px}.slider-container .slider-nav.nav--bottom-left .nav-btn--prev{bottom:30px;left:-20px}.slider-container .slider-nav.nav--bottom-left .nav-btn--next{bottom:30px;left:42px}.slider-container .slider-nav.nav--bottom-center .nav-btn--prev{bottom:30px;left:50%;transform:translate(-50px)}.slider-container .slider-nav.nav--bottom-center .nav-btn--next{bottom:30px;left:50%;transform:translate(10px)}.slider-container .slider-nav.nav--bottom-right .nav-btn--prev{bottom:30px;right:42px}.slider-container .slider-nav.nav--bottom-right .nav-btn--next{bottom:30px;right:-20px}.slider-container .slider-nav.nav--center-sides .nav-btn{background:#000000b3;color:#fff}.slider-container .slider-nav.nav--center-sides .nav-btn--prev{top:50%;left:-50px;transform:translateY(-50%)}.slider-container .slider-nav.nav--center-sides .nav-btn--next{top:50%;right:-50px;transform:translateY(-50%)}@media (max-width: 1024px){.slider-container .slider-nav .nav--top-left .nav-btn--prev,.slider-container .slider-nav .nav--top-center .nav-btn--prev,.slider-container .slider-nav .nav--top-right .nav-btn--prev,.slider-container .slider-nav .nav--bottom-left .nav-btn--prev,.slider-container .slider-nav .nav--bottom-center .nav-btn--prev,.slider-container .slider-nav .nav--bottom-right .nav-btn--prev,.slider-container .slider-nav .nav--center-sides .nav-btn--prev{left:clamp(8px,5%,40px);right:auto}.slider-container .slider-nav .nav--top-left .nav-btn--next,.slider-container .slider-nav .nav--top-center .nav-btn--next,.slider-container .slider-nav .nav--top-right .nav-btn--next,.slider-container .slider-nav .nav--bottom-left .nav-btn--next,.slider-container .slider-nav .nav--bottom-center .nav-btn--next,.slider-container .slider-nav .nav--bottom-right .nav-btn--next,.slider-container .slider-nav .nav--center-sides .nav-btn--next{right:clamp(8px,5%,20px);left:auto}}@media (max-width: 768px){.slider-container .slider-nav .nav-btn{width:36px;height:36px;font-size:24px}}@media (max-width: 480px){.slider-container .slider-nav .slider-container .slider-nav.nav--center-sides{pointer-events:auto}.slider-container .slider-nav .slider-container .slider-nav.nav--center-sides .nav-btn{width:32px;height:32px;font-size:20px;pointer-events:auto;z-index:20;background:#000000b3;color:#fff}.slider-container .slider-nav .slider-container .slider__wrapper{position:relative}.slider-container .slider-nav .slider-container .slider__wrapper .slide-content{pointer-events:auto}.slider-container .slider-nav .nav-btn{width:32px;height:32px;font-size:20px}.slider-container .slider-nav .nav-btn--prev{left:8px!important;right:auto!important}.slider-container .slider-nav .nav-btn--next{right:8px!important;left:auto!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
197
+ }
198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SimpleSliderComponent, decorators: [{
199
+ type: Component,
200
+ args: [{ selector: "app-simple-slider", changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: true, imports: [CommonModule], providers: [SliderEngine, SliderStore, SliderDraggablePlugin, SliderPaginationPlugin, SliderNavigationPlugin, SliderAutoplayPlugin], template: "<ng-container *ngIf=\"state$ | async as state\">\r\n <div\r\n class=\"slider\"\r\n #sliderHost\r\n [class.slider-vertical]=\"state.vertical\"\r\n [class.slider-draggable]=\"state.isDragging\"\r\n [class.slider--main]=\"!config.isThumbs\"\r\n [class.slider--thumbs]=\"config.isThumbs\"\r\n *ngIf=\"state.visibleSlides?.length > 0 && state.isVisible\"\r\n (pointerdown)=\"onPointerDown($event)\"\r\n (pointermove)=\"onPointerMove($event)\"\r\n (pointerup)=\"onPointerUp($event)\"\r\n (pointercancel)=\"onPointerUp($event)\">\r\n <div\r\n class=\"slider__wrapper\"\r\n [ngStyle]=\"{\r\n transform: state.translate,\r\n transition: draggable.isDraggingPointer ? 'none' : 'transform 0.3s ease',\r\n display: 'flex',\r\n 'flex-direction': state.vertical ? 'column' : 'row',\r\n 'justify-content': state.visibleSlides?.length < state.slidesPerView ? 'center' : 'flex-start',\r\n gap: (state.slidesPerView > 1 ? state.gap || 0 : 0) + 'px',\r\n }\">\r\n <div\r\n *ngFor=\"let slide of state.visibleSlides; let i = index\"\r\n class=\"slide\"\r\n [attr.data-index]=\"i\"\r\n [class.slide--current]=\"state.selectedSlide === i\"\r\n [style.flex]=\"\r\n !config.isThumbs\r\n ? '0 0 calc(' +\r\n 100 / state.slidesPerView +\r\n '% - ' +\r\n ((state.gap || 0) * (state.slidesPerView - 1)) / state.slidesPerView +\r\n 'px)'\r\n : '0 0 ' + thumbSize + 'px'\r\n \"\r\n [style.width]=\"config.isThumbs ? thumbSize + 'px' : null\"\r\n [style.height]=\"config.isThumbs ? thumbSize + 'px' : null\"\r\n (click)=\"engine.selectSlide(i)\">\r\n <ng-container\r\n *ngTemplateOutlet=\"slideTemplate ? slideTemplate : defaultSlideTemplate; context: { slide: slide, index: i }\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;position:relative}.slider-main-product{display:inline-flex;height:520px}.slider-main{width:100%;height:600px;justify-content:center;display:flex}@media (max-width: 577px){.slider-main{height:100%;display:block}}.slider--main{height:100%;overflow:hidden}.slider--main .slider__wrapper{display:flex;will-change:transform}.slider--main .slider__wrapper .slide{flex:0 0 100%}.slider--main .slider__wrapper .slide .slide-content,.slider--main .slider__wrapper .slide picture{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.slider--main .slider__wrapper .slide .slide-content .drag-handle,.slider--main .slider__wrapper .slide picture .drag-handle{width:100%;height:100%;cursor:grab;z-index:10;pointer-events:all}.slider--main .slider__wrapper .slide .slide-content img,.slider--main .slider__wrapper .slide picture img{max-width:100%;max-height:100%;object-fit:contain;display:block;transform-origin:center;transform:translateZ(0);pointer-events:none}.slider--thumbs{margin-top:24px;margin-bottom:36px;height:70px!important}.slider--thumbs .slider__wrapper{display:flex;gap:8px;will-change:transform;transform:translateZ(0)}.slider--thumbs .slide{flex:0 0 auto;pointer-events:auto}.slider--thumbs .slide .slide-content{width:54px;height:68px;display:flex;align-items:center;justify-content:center;border:1px solid #ebebeb;cursor:pointer}.slider--thumbs .slide .slide-content img{max-width:100%;max-height:100%;object-fit:contain;display:block;transform:scale(.9)}.slider--thumbs .slide .slide-content.slide--current{border-color:#212121}.slider{width:100%;height:100%;overflow:hidden;position:relative;touch-action:none;cursor:grab;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;-webkit-tap-highlight-color:transparent}.slider.slider-can-drag{cursor:grab}.slider.slider-is-dragging{cursor:grabbing}.slider.slider-dragged{box-shadow:0 0 10px #0000001a}.slider.slider-drag-prevent-click{pointer-events:none}.slider .slider__wrapper{display:flex;transition:transform .3s cubic-bezier(.25,.46,.45,.84);will-change:transform;transform:none;width:auto;height:100%}.slider .slide{display:flex;align-items:center;justify-content:center;height:100%;overflow:hidden;flex-shrink:0;position:relative;transition:transform .3s cubic-bezier(.25,.46,.45,.84)}@media (min-width: 1441px){.slider--thumbs .slide{flex:0 0 20%}}@media (max-width: 1024px){.slider--thumbs .slide{flex:0 0 33.333%}}@media (max-width: 1023px){.slider--thumbs .slide{flex:0 0 50%}}.slider-arrow-next,.slider-arrow-prev{position:absolute;top:50%;transform:translateY(-50%);width:32px;height:32px;background:#fffc no-repeat center center;cursor:pointer;z-index:10}.slider-arrow-next.next,.slider-arrow-prev.next{right:10px}.slider-arrow-next.prev,.slider-arrow-prev.prev{left:10px}.thumbs-wrapper{position:relative}.thumb-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:20;width:48px;height:48px;background:#ffffffe6 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='4.51 0.01 10.99 19.97'%3E%3Cpath fill='%23000' d='m4.508 18.968 1.006 1.006 9.983-9.984L5.514.005 4.508 1.011l8.984 8.984-8.984 8.973Z'/%3E%3C/svg%3E\") no-repeat center center/11px 18px;font-size:36px;line-height:56px;opacity:0;pointer-events:none;transition:opacity .2s ease}.thumb-nav.activeArrow{opacity:1;pointer-events:all}.thumb-nav--left{left:-73px;transform:translateY(-50%) rotate(180deg)!important}.thumb-nav--right{right:-65px}.slider-pagination .thumb-dots-wrapper{display:flex;align-items:center;justify-content:center;gap:7px}.slider-pagination .thumb-dots-wrapper .thumb-dot{display:inline-block;width:4px;height:4px;margin:0 0 0 8px;border-radius:50%;background:#b3b3b3}.slider-pagination .thumb-dots-wrapper .thumb-dot.active,.slider-pagination .thumb-dots-wrapper .thumb-dot:hover{background:#212121;border:1px solid #212121}.slider-pagination .thumb-dots-wrapper .thumb-dot.hidden{opacity:0;pointer-events:none}.slider-container{position:relative;z-index:10}.slider-container .slider{position:relative;z-index:1}.slider-container .slider.slider-is-dragging{pointer-events:none}.slider-container .slider-nav{position:absolute;inset:0;pointer-events:none;z-index:20}.slider-container .slider-nav .nav-btn{pointer-events:auto;z-index:30;position:absolute;width:42px;height:42px;border-radius:2px;display:inline-flex;align-items:center;justify-content:center;border:0;cursor:pointer;background:transparent;font-size:32px;line-height:1;transition:transform .15s ease,opacity .15s ease}.slider-container .slider-nav .nav-btn:hover{transform:translateY(-1px);background:#0009}.slider-container .slider-nav .nav-btn.is-hidden{color:#a0a0a58d;opacity:.3;cursor:not-allowed;pointer-events:auto}.slider-container .slider-nav.nav--top-left .nav-btn--prev{top:-50px;left:-20px}.slider-container .slider-nav.nav--top-left .nav-btn--next{top:-50px;left:42px}.slider-container .slider-nav.nav--top-center .nav-btn--prev{top:-50px;left:50%;transform:translate(-50px)}.slider-container .slider-nav.nav--top-center .nav-btn--next{top:-50px;left:50%;transform:translate(10px)}.slider-container .slider-nav.nav--top-right .nav-btn--prev{top:-50px;right:42px}.slider-container .slider-nav.nav--top-right .nav-btn--next{top:-50px;right:-20px}.slider-container .slider-nav.nav--bottom-left .nav-btn--prev{bottom:30px;left:-20px}.slider-container .slider-nav.nav--bottom-left .nav-btn--next{bottom:30px;left:42px}.slider-container .slider-nav.nav--bottom-center .nav-btn--prev{bottom:30px;left:50%;transform:translate(-50px)}.slider-container .slider-nav.nav--bottom-center .nav-btn--next{bottom:30px;left:50%;transform:translate(10px)}.slider-container .slider-nav.nav--bottom-right .nav-btn--prev{bottom:30px;right:42px}.slider-container .slider-nav.nav--bottom-right .nav-btn--next{bottom:30px;right:-20px}.slider-container .slider-nav.nav--center-sides .nav-btn{background:#000000b3;color:#fff}.slider-container .slider-nav.nav--center-sides .nav-btn--prev{top:50%;left:-50px;transform:translateY(-50%)}.slider-container .slider-nav.nav--center-sides .nav-btn--next{top:50%;right:-50px;transform:translateY(-50%)}@media (max-width: 1024px){.slider-container .slider-nav .nav--top-left .nav-btn--prev,.slider-container .slider-nav .nav--top-center .nav-btn--prev,.slider-container .slider-nav .nav--top-right .nav-btn--prev,.slider-container .slider-nav .nav--bottom-left .nav-btn--prev,.slider-container .slider-nav .nav--bottom-center .nav-btn--prev,.slider-container .slider-nav .nav--bottom-right .nav-btn--prev,.slider-container .slider-nav .nav--center-sides .nav-btn--prev{left:clamp(8px,5%,40px);right:auto}.slider-container .slider-nav .nav--top-left .nav-btn--next,.slider-container .slider-nav .nav--top-center .nav-btn--next,.slider-container .slider-nav .nav--top-right .nav-btn--next,.slider-container .slider-nav .nav--bottom-left .nav-btn--next,.slider-container .slider-nav .nav--bottom-center .nav-btn--next,.slider-container .slider-nav .nav--bottom-right .nav-btn--next,.slider-container .slider-nav .nav--center-sides .nav-btn--next{right:clamp(8px,5%,20px);left:auto}}@media (max-width: 768px){.slider-container .slider-nav .nav-btn{width:36px;height:36px;font-size:24px}}@media (max-width: 480px){.slider-container .slider-nav .slider-container .slider-nav.nav--center-sides{pointer-events:auto}.slider-container .slider-nav .slider-container .slider-nav.nav--center-sides .nav-btn{width:32px;height:32px;font-size:20px;pointer-events:auto;z-index:20;background:#000000b3;color:#fff}.slider-container .slider-nav .slider-container .slider__wrapper{position:relative}.slider-container .slider-nav .slider-container .slider__wrapper .slide-content{pointer-events:auto}.slider-container .slider-nav .nav-btn{width:32px;height:32px;font-size:20px}.slider-container .slider-nav .nav-btn--prev{left:8px!important;right:auto!important}.slider-container .slider-nav .nav-btn--next{right:8px!important;left:auto!important}}\n"] }]
201
+ }], ctorParameters: () => [{ type: i1.SliderEngine }, { type: i2.SliderStore }, { type: i3.SliderDraggablePlugin }, { type: i4.SliderPaginationPlugin }, { type: i5.SliderNavigationPlugin }, { type: i6.SliderAutoplayPlugin }], propDecorators: { config: [{
202
+ type: Input
203
+ }], slideTemplate: [{
204
+ type: Input
205
+ }], navigationTemplate: [{
206
+ type: Input
207
+ }], paginationTemplate: [{
208
+ type: Input
209
+ }], slideChange: [{
210
+ type: Output
211
+ }], sliderHost: [{
212
+ type: ViewChild,
213
+ args: ["sliderHost", { static: false }]
214
+ }] } });
215
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2ltcGxlLXNsaWRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRnZS1zbGlkZXIvc3JjL2xpYi9jb21wb25lbnQvc2ltcGxlLXNsaWRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRnZS1zbGlkZXIvc3JjL2xpYi9jb21wb25lbnQvc2ltcGxlLXNsaWRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULHVCQUF1QixFQUd2QixLQUFLLEVBQ0wsWUFBWSxFQUNaLE1BQU0sRUFJTixTQUFTLEVBR1QsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBYyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXRELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDM0UsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDOUUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDakYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFFakYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7Ozs7QUFZL0MsTUFBTSxPQUFPLHFCQUFxQjtJQWtCdEI7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBdEJELE1BQU0sQ0FBZ0I7SUFDdEIsYUFBYSxDQUFvQjtJQUNqQyxrQkFBa0IsQ0FBb0I7SUFDdEMsa0JBQWtCLENBQW9CO0lBQ3JDLFdBQVcsR0FBRyxJQUFJLFlB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LGNBQ3pCLElBQUksV0FDUCxDQUFDLFlBQVksQ0FBQyxhQUNaLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFBRSxxQkFBcUIsRUFBRSxzQkFBc0IsRUFBRSxzQkFBc0IsRUFBRSxvQkFBb0IsQ0FBQzs0UEFHMUgsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDSSxXQUFXO3NCQUFwQixNQUFNO2dCQVVxQyxVQUFVO3NCQUFyRCxTQUFTO3VCQUFDLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcclxuICBPbkluaXQsXHJcbiAgVGVtcGxhdGVSZWYsXHJcbiAgSW5wdXQsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIE91dHB1dCxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkRlc3Ryb3ksXHJcbiAgVmlld0NoaWxkLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBWaWV3RW5jYXBzdWxhdGlvbixcclxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBTbGlkZXJWaWV3U3RhdGUgfSBmcm9tIFwiLi4vbW9kZWxzL3NsaWRlci1zdGF0ZS5tb2RlbFwiO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCB0YWtlVW50aWwgfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBTbGlkZXJDb25maWcgfSBmcm9tIFwiLi4vbW9kZWxzL3NsaWRlci1jb25maWcubW9kZWxcIjtcclxuaW1wb3J0IHsgU2xpZGVyRW5naW5lIH0gZnJvbSBcIi4uL2VuZ2luZS9zbGlkZXItZW5naW5lLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgU2xpZGVyU3RvcmUgfSBmcm9tIFwiLi4vc3RvcmUvc2xpZGVyLXN0b3JlLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgU2xpZGVyQXV0b3BsYXlQbHVnaW4gfSBmcm9tIFwiLi4vcGx1Z2lucy9hdXRvcGxheS9hdXRvcGxheS5wbHVnaW5cIjtcclxuaW1wb3J0IHsgU2xpZGVyRHJhZ2dhYmxlUGx1Z2luIH0gZnJvbSBcIi4uL3BsdWdpbnMvZHJhZ2dhYmxlL2RyYWdnYWJsZS5wbHVnaW5cIjtcclxuaW1wb3J0IHsgU2xpZGVyTmF2aWdhdGlvblBsdWdpbiB9IGZyb20gXCIuLi9wbHVnaW5zL25hdmlnYXRpb24vbmF2aWdhdGlvbi5wbHVnaW5cIjtcclxuaW1wb3J0IHsgU2xpZGVyUGFnaW5hdGlvblBsdWdpbiB9IGZyb20gXCIuLi9wbHVnaW5zL3BhZ2luYXRpb24vcGFnaW5hdGlvbi5wbHVnaW5cIjtcclxuaW1wb3J0IHsgUGFnZXIsIFNsaWRlclBsdWdpbiB9IGZyb20gXCIuLi9wbHVnaW5zL3NsaWRlci1wbHVnaW5cIjtcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6IFwiYXBwLXNpbXBsZS1zbGlkZXJcIixcclxuICB0ZW1wbGF0ZVVybDogXCIuL3NpbXBsZS1zbGlkZXIuY29tcG9uZW50Lmh0bWxcIixcclxuICBzdHlsZVVybDogXCIuL3NpbXBsZS1zbGlkZXIuY29tcG9uZW50LnNjc3NcIixcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXHJcbiAgcHJvdmlkZXJzOiBbU2xpZGVyRW5naW5lLCBTbGlkZXJTdG9yZSwgU2xpZGVyRHJhZ2dhYmxlUGx1Z2luLCBTbGlkZXJQYWdpbmF0aW9uUGx1Z2luLCBTbGlkZXJOYXZpZ2F0aW9uUGx1Z2luLCBTbGlkZXJBdXRvcGxheVBsdWdpbl0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTaW1wbGVTbGlkZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcclxuICBASW5wdXQoKSBjb25maWchOiBTbGlkZXJDb25maWc7XHJcbiAgQElucHV0KCkgc2xpZGVUZW1wbGF0ZT86IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgQElucHV0KCkgbmF2aWdhdGlvblRlbXBsYXRlPzogVGVtcGxhdGVSZWY8YW55PjtcclxuICBASW5wdXQoKSBwYWdpbmF0aW9uVGVtcGxhdGU/OiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIEBPdXRwdXQoKSBzbGlkZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xyXG5cclxuICBwcml2YXRlIGlzRHJhZ2dpbmdQb2ludGVyID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBkcmFnU3RhcnRYID0gMDtcclxuICBwcml2YXRlIGRyYWdTdGFydFkgPSAwO1xyXG4gIHByaXZhdGUgbGFzdEluZGV4ID0gLTE7XHJcbiAgcHJpdmF0ZSBsYXN0U2xpZGVzUmVmOiBhbnlbXSB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICBzdGF0ZSQhOiBPYnNlcnZhYmxlPFNsaWRlclZpZXdTdGF0ZT47XHJcbiAgQFZpZXdDaGlsZChcInNsaWRlckhvc3RcIiwgeyBzdGF0aWM6IGZhbHNlIH0pIHNsaWRlckhvc3Q/OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGVuZ2luZTogU2xpZGVyRW5naW5lLFxyXG4gICAgcHJpdmF0ZSBzdG9yZTogU2xpZGVyU3RvcmUsXHJcbiAgICBwcml2YXRlIGRyYWdnYWJsZTogU2xpZGVyRHJhZ2dhYmxlUGx1Z2luLFxyXG4gICAgcHJpdmF0ZSBwYWdpbmF0aW9uOiBTbGlkZXJQYWdpbmF0aW9uUGx1Z2luLFxyXG4gICAgcHJpdmF0ZSBuYXZpZ2F0aW9uOiBTbGlkZXJOYXZpZ2F0aW9uUGx1Z2luLFxyXG4gICAgcHJpdmF0ZSBhdXRvcGxheTogU2xpZGVyQXV0b3BsYXlQbHVnaW4sXHJcbiAgKSB7fVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuc3RhdGUkID0gdGhpcy5zdG9yZS52aWV3JDtcclxuXHJcbiAgICB0aGlzLnN0YXRlJC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChzdGF0ZSkgPT4ge1xyXG4gICAgICBpZiAoc3RhdGUuY3VycmVudFNsaWRlICE9PSB0aGlzLmxhc3RJbmRleCkge1xyXG4gICAgICAgIHRoaXMubGFzdEluZGV4ID0gc3RhdGUuY3VycmVudFNsaWRlO1xyXG4gICAgICAgIHRoaXMuc2xpZGVDaGFuZ2UuZW1pdChzdGF0ZS5jdXJyZW50U2xpZGUpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHRoaXMubGFzdFNsaWRlc1JlZiA9IHRoaXMuY29uZmlnPy5zbGlkZXMgPz8gbnVsbDtcclxuICAgIHRoaXMucmVzb2x2ZVBsdWdpbnModGhpcy5jb25maWcpO1xyXG4gIH1cclxuICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICBpZiAodGhpcy5zbGlkZXJIb3N0Py5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgIHRoaXMuZW5naW5lLmF0dGFjaENvbnRhaW5lcih0aGlzLnNsaWRlckhvc3QubmF0aXZlRWxlbWVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICBpZiAoIWNoYW5nZXNbXCJjb25maWdcIl0gfHwgIXRoaXMuY29uZmlnKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgbmV3U2xpZGVzUmVmID0gdGhpcy5jb25maWcuc2xpZGVzID8/IG51bGw7XHJcblxyXG4gICAgaWYgKG5ld1NsaWRlc1JlZiAhPT0gdGhpcy5sYXN0U2xpZGVzUmVmKSB7XHJcbiAgICAgIHRoaXMubGFzdFNsaWRlc1JlZiA9IG5ld1NsaWRlc1JlZjtcclxuICAgICAgdGhpcy5lbmdpbmUuZGVzdHJveSgpO1xyXG4gICAgICB0aGlzLnJlc29sdmVQbHVnaW5zKHRoaXMuY29uZmlnKTtcclxuICAgIH1cclxuICB9XHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLmRlc3Ryb3lTbGlkZXIoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnb1RvKGluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMuZW5naW5lLnNlbGVjdFNsaWRlKGluZGV4KTsgLy8gYWRkIHRoaXMgbGluZVxyXG4gICAgLy90aGlzLnNsaWRlQ2hhbmdlLmVtaXQoaW5kZXgpO1xyXG4gIH1cclxuXHJcbiAgZGVzdHJveVNsaWRlcigpIHtcclxuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xyXG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xyXG4gICAgdGhpcy5lbmdpbmUuZGVzdHJveSgpO1xyXG4gIH0gLy8gZGVzdHJveXMgcGx1Z2lucyBhbmQgY2xlYXJzIHN0b3JlXHJcblxyXG4gIG9uTmV4dCgpIHtcclxuICAgIHRoaXMuZW5naW5lLm5leHQoKTtcclxuICB9XHJcbiAgb25QcmV2aW91cygpIHtcclxuICAgIHRoaXMuZW5naW5lLnByZXZpb3VzKCk7XHJcbiAgfVxyXG4gIHNlbGVjdFNsaWRlKGluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMuZW5naW5lLnNlbGVjdFNsaWRlKGluZGV4KTtcclxuICB9XHJcbiAgb25SZWNhbGN1bGF0ZSgpIHtcclxuICAgIHRoaXMuZW5naW5lLnJlY2FsY3VsYXRlKCk7XHJcbiAgfVxyXG4gIC8vIE5hdmlnYXRpb25cclxuICAvKiogRXhwb3NlIG5hdmlnYXRpb24gb2JzZXJ2YWJsZXMgc2FmZWx5ICovXHJcbiAgZ2V0IGNhblByZXYkKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4gfCBudWxsIHtcclxuICAgIGlmICghdGhpcy5uYXZpZ2F0aW9uKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcIk5hdmlnYXRpb24gcGx1Z2luIGlzIG5vdCBlbmFibGVkLlwiKTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5uYXZpZ2F0aW9uLmNhblByZXYkO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGNhbk5leHQkKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4gfCBudWxsIHtcclxuICAgIGlmICghdGhpcy5uYXZpZ2F0aW9uKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcIk5hdmlnYXRpb24gcGx1Z2luIGlzIG5vdCBlbmFibGVkLlwiKTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5uYXZpZ2F0aW9uLmNhbk5leHQkO1xyXG4gIH1cclxuXHJcbiAgLyoqIEV4cG9zZSBuZXh0L3ByZXYgbWV0aG9kcyAqL1xyXG4gIHB1YmxpYyBuZXh0KCkge1xyXG4gICAgdGhpcy5uYXZpZ2F0aW9uPy5uZXh0KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcHJldigpIHtcclxuICAgIHRoaXMubmF2aWdhdGlvbj8ucHJldigpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEV4cG9zZSBwYWdpbmF0aW9uIG9ic2VydmFibGUgKi9cclxuICBnZXQgcGFnZXIkKCk6IE9ic2VydmFibGU8UGFnZXIgfCBudWxsPiB8IG51bGwge1xyXG4gICAgaWYgKCF0aGlzLnBhZ2luYXRpb24pIHtcclxuICAgICAgY29uc29sZS53YXJuKFwiUGFnaW5hdGlvbiBwbHVnaW4gaXMgbm90IGVuYWJsZWQgZm9yIHRoaXMgc2xpZGVyLlwiKTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5wYWdpbmF0aW9uLnBhZ2VyJDtcclxuICB9XHJcblxyXG4gIC8qKiBFeHBvc2UgYSBnb1RvU2xpZGUgbWV0aG9kICovXHJcbiAgcHVibGljIGdvVG9TbGlkZShpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnBhZ2luYXRpb24uZ29Ub1NsaWRlKGluZGV4KTtcclxuICB9XHJcblxyXG4gIC8vIEhhbmRsZSBQb2ludGVyc1xyXG5cclxuICBvblBvaW50ZXJEb3duKGV2ZW50OiBQb2ludGVyRXZlbnQpIHtcclxuICAgIC8vIE9ubHkgc3RhcnQgZHJhZyBpZiBub3QgY2xpY2tpbmcgYSBuYXYgYnV0dG9uXHJcbiAgICBpZiAoKGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdChcIi5uYXYtYnRuXCIpKSB7XHJcbiAgICAgIHJldHVybjsgLy8gaWdub3JlXHJcbiAgICB9XHJcbiAgICB0aGlzLmRyYWdTdGFydFggPSBldmVudC5jbGllbnRYO1xyXG4gICAgdGhpcy5kcmFnU3RhcnRZID0gZXZlbnQuY2xpZW50WTtcclxuICAgIHRoaXMuaXNEcmFnZ2luZ1BvaW50ZXIgPSBmYWxzZTtcclxuXHJcbiAgICAvLyBEbyBub3QgY2FwdHVyZSB5ZXQ7IHdhaXQgdW50aWwgbW92ZW1lbnQgZXhjZWVkcyB0aHJlc2hvbGRcclxuICAgIHRoaXMuZW5naW5lLmhhbmRsZURyYWdTdGFydChldmVudCk7XHJcbiAgfVxyXG5cclxuICBvblBvaW50ZXJNb3ZlKGV2ZW50OiBQb2ludGVyRXZlbnQpIHtcclxuICAgIGNvbnN0IGR4ID0gTWF0aC5hYnMoZXZlbnQuY2xpZW50WCAtIHRoaXMuZHJhZ1N0YXJ0WCk7XHJcbiAgICBjb25zdCBkeSA9IE1hdGguYWJzKGV2ZW50LmNsaWVudFkgLSB0aGlzLmRyYWdTdGFydFkpO1xyXG5cclxuICAgIGlmICghdGhpcy5pc0RyYWdnaW5nUG9pbnRlciAmJiAoZHggPiA1IHx8IGR5ID4gNSkpIHtcclxuICAgICAgdGhpcy5pc0RyYWdnaW5nUG9pbnRlciA9IHRydWU7XHJcblxyXG4gICAgICAvLyBOb3cgc3RhcnQgY2FwdHVyaW5nIHBvaW50ZXIgc28gZHJhZ2dpbmcgd29ya3Mgb3V0c2lkZSB0aGUgc2xpZGVyIGJvdW5kc1xyXG4gICAgICAoZXZlbnQuY3VycmVudFRhcmdldCBhcyBIVE1MRWxlbWVudCkuc2V0UG9pbnRlckNhcHR1cmUoZXZlbnQucG9pbnRlcklkKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5pc0RyYWdnaW5nUG9pbnRlcikge1xyXG4gICAgICB0aGlzLmVuZ2luZS5oYW5kbGVEcmFnTW92ZShldmVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvblBvaW50ZXJVcChldmVudDogUG9pbnRlckV2ZW50KSB7XHJcbiAgICBpZiAoIWV2ZW50KSByZXR1cm47XHJcblxyXG4gICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmdQb2ludGVyKSB7XHJcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcclxuXHJcbiAgICAgIC8vIE9ubHkgc2VsZWN0IHRoZSBzbGlkZSBpZiBjbGljayBpcyBub3Qgb24gYW4gaW50ZXJhY3RpdmUgY2hpbGRcclxuICAgICAgY29uc3Qgc2xpZGVFbCA9IHRhcmdldC5jbG9zZXN0KFwiLnNsaWRlXCIpO1xyXG4gICAgICBpZiAoc2xpZGVFbCAmJiAhdGFyZ2V0LmNsb3Nlc3QoXCJidXR0b24sIHZpZGVvLCBhXCIpKSB7XHJcbiAgICAgICAgY29uc3QgaW5kZXhBdHRyID0gc2xpZGVFbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWluZGV4XCIpO1xyXG4gICAgICAgIGNvbnN0IGluZGV4ID0gaW5kZXhBdHRyID8gcGFyc2VJbnQoaW5kZXhBdHRyLCAxMCkgOiBudWxsO1xyXG4gICAgICAgIGlmIChpbmRleCAhPT0gbnVsbCkgdGhpcy5lbmdpbmUuc2VsZWN0U2xpZGUoaW5kZXgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5lbmdpbmUuaGFuZGxlRHJhZ0VuZCgpO1xyXG4gICAgdGhpcy5pc0RyYWdnaW5nUG9pbnRlciA9IGZhbHNlO1xyXG5cclxuICAgIC8vIFJlbGVhc2UgcG9pbnRlciBjYXB0dXJlIGlmIGl0IHdhcyBjYXB0dXJlZFxyXG4gICAgdHJ5IHtcclxuICAgICAgKGV2ZW50LmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQpLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShldmVudC5wb2ludGVySWQpO1xyXG4gICAgfSBjYXRjaCB7fVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZXNvbHZlUGx1Z2lucyhjb25maWc6IFNsaWRlckNvbmZpZykge1xyXG4gICAgY29uc3QgcnVudGltZVBsdWdpbnM6IFNsaWRlclBsdWdpbltdID0gW107XHJcblxyXG4gICAgY29uc3QgY2ZnID0gY29uZmlnLnBsdWdpbnMgPz8ge307IC8vIDwtLSBzYWZlIGZhbGxiYWNrXHJcblxyXG4gICAgaWYgKGNmZy5kcmFnZ2FibGUpIHJ1bnRpbWVQbHVnaW5zLnB1c2godGhpcy5kcmFnZ2FibGUpO1xyXG4gICAgaWYgKGNmZy5wYWdpbmF0aW9uKSBydW50aW1lUGx1Z2lucy5wdXNoKHRoaXMucGFnaW5hdGlvbik7XHJcbiAgICBpZiAoY2ZnLm5hdmlnYXRpb24pIHJ1bnRpbWVQbHVnaW5zLnB1c2godGhpcy5uYXZpZ2F0aW9uKTtcclxuXHJcbiAgICBpZiAoY2ZnLmF1dG9wbGF5KSB7XHJcbiAgICAgIHRoaXMuYXV0b3BsYXkuc2V0Q29uZmlnKGNmZy5hdXRvcGxheSk7XHJcbiAgICAgIHJ1bnRpbWVQbHVnaW5zLnB1c2godGhpcy5hdXRvcGxheSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5lbmdpbmUuaW5pdCh7IC4uLmNvbmZpZywgcGx1Z2luczogdW5kZWZpbmVkIH0sIHJ1bnRpbWVQbHVnaW5zKTtcclxuXHJcbiAgICBpZiAoY2ZnLm5hdmlnYXRpb24pIHtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLm5hdmlnYXRpb24/LnVwZGF0ZUFycm93cz8uKCkpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwic3RhdGUkIHwgYXN5bmMgYXMgc3RhdGVcIj5cclxuICA8ZGl2XHJcbiAgICBjbGFzcz1cInNsaWRlclwiXHJcbiAgICAjc2xpZGVySG9zdFxyXG4gICAgW2NsYXNzLnNsaWRlci12ZXJ0aWNhbF09XCJzdGF0ZS52ZXJ0aWNhbFwiXHJcbiAgICBbY2xhc3Muc2xpZGVyLWRyYWdnYWJsZV09XCJzdGF0ZS5pc0RyYWdnaW5nXCJcclxuICAgIFtjbGFzcy5zbGlkZXItLW1haW5dPVwiIWNvbmZpZy5pc1RodW1ic1wiXHJcbiAgICBbY2xhc3Muc2xpZGVyLS10aHVtYnNdPVwiY29uZmlnLmlzVGh1bWJzXCJcclxuICAgICpuZ0lmPVwic3RhdGUudmlzaWJsZVNsaWRlcz8ubGVuZ3RoID4gMCAmJiBzdGF0ZS5pc1Zpc2libGVcIlxyXG4gICAgKHBvaW50ZXJkb3duKT1cIm9uUG9pbnRlckRvd24oJGV2ZW50KVwiXHJcbiAgICAocG9pbnRlcm1vdmUpPVwib25Qb2ludGVyTW92ZSgkZXZlbnQpXCJcclxuICAgIChwb2ludGVydXApPVwib25Qb2ludGVyVXAoJGV2ZW50KVwiXHJcbiAgICAocG9pbnRlcmNhbmNlbCk9XCJvblBvaW50ZXJVcCgkZXZlbnQpXCI+XHJcbiAgICA8ZGl2XHJcbiAgICAgIGNsYXNzPVwic2xpZGVyX193cmFwcGVyXCJcclxuICAgICAgW25nU3R5bGVdPVwie1xyXG4gICAgICAgIHRyYW5zZm9ybTogc3RhdGUudHJhbnNsYXRlLFxyXG4gICAgICAgIHRyYW5zaXRpb246IGRyYWdnYWJsZS5pc0RyYWdnaW5nUG9pbnRlciA/ICdub25lJyA6ICd0cmFuc2Zvcm0gMC4zcyBlYXNlJyxcclxuICAgICAgICBkaXNwbGF5OiAnZmxleCcsXHJcbiAgICAgICAgJ2ZsZXgtZGlyZWN0aW9uJzogc3RhdGUudmVydGljYWwgPyAnY29sdW1uJyA6ICdyb3cnLFxyXG4gICAgICAgICdqdXN0aWZ5LWNvbnRlbnQnOiBzdGF0ZS52aXNpYmxlU2xpZGVzPy5sZW5ndGggPCBzdGF0ZS5zbGlkZXNQZXJWaWV3ID8gJ2NlbnRlcicgOiAnZmxleC1zdGFydCcsXHJcbiAgICAgICAgZ2FwOiAoc3RhdGUuc2xpZGVzUGVyVmlldyA+IDEgPyBzdGF0ZS5nYXAgfHwgMCA6IDApICsgJ3B4JyxcclxuICAgICAgfVwiPlxyXG4gICAgICA8ZGl2XHJcbiAgICAgICAgKm5nRm9yPVwibGV0IHNsaWRlIG9mIHN0YXRlLnZpc2libGVTbGlkZXM7IGxldCBpID0gaW5kZXhcIlxyXG4gICAgICAgIGNsYXNzPVwic2xpZGVcIlxyXG4gICAgICAgIFthdHRyLmRhdGEtaW5kZXhdPVwiaVwiXHJcbiAgICAgICAgW2NsYXNzLnNsaWRlLS1jdXJyZW50XT1cInN0YXRlLnNlbGVjdGVkU2xpZGUgPT09IGlcIlxyXG4gICAgICAgIFtzdHlsZS5mbGV4XT1cIlxyXG4gICAgICAgICAgIWNvbmZpZy5pc1RodW1ic1xyXG4gICAgICAgICAgICA/ICcwIDAgY2FsYygnICtcclxuICAgICAgICAgICAgICAxMDAgLyBzdGF0ZS5zbGlkZXNQZXJWaWV3ICtcclxuICAgICAgICAgICAgICAnJSAtICcgK1xyXG4gICAgICAgICAgICAgICgoc3RhdGUuZ2FwIHx8IDApICogKHN0YXRlLnNsaWRlc1BlclZpZXcgLSAxKSkgLyBzdGF0ZS5zbGlkZXNQZXJWaWV3ICtcclxuICAgICAgICAgICAgICAncHgpJ1xyXG4gICAgICAgICAgICA6ICcwIDAgJyArIHRodW1iU2l6ZSArICdweCdcclxuICAgICAgICBcIlxyXG4gICAgICAgIFtzdHlsZS53aWR0aF09XCJjb25maWcuaXNUaHVtYnMgPyB0aHVtYlNpemUgKyAncHgnIDogbnVsbFwiXHJcbiAgICAgICAgW3N0eWxlLmhlaWdodF09XCJjb25maWcuaXNUaHVtYnMgPyB0aHVtYlNpemUgKyAncHgnIDogbnVsbFwiXHJcbiAgICAgICAgKGNsaWNrKT1cImVuZ2luZS5zZWxlY3RTbGlkZShpKVwiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwic2xpZGVUZW1wbGF0ZSA/IHNsaWRlVGVtcGxhdGUgOiBkZWZhdWx0U2xpZGVUZW1wbGF0ZTsgY29udGV4dDogeyBzbGlkZTogc2xpZGUsIGluZGV4OiBpIH1cIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9uZy1jb250YWluZXI+XHJcbiJdfQ==
@@ -0,0 +1,288 @@
1
+ import { Injectable } from "@angular/core";
2
+ import { fromEvent, merge, Subject, auditTime, takeUntil } from "rxjs";
3
+ import { DEFAULT_CONFIG } from "../models/slider-config.model";
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "../store/slider-store.service";
6
+ export class SliderEngine {
7
+ store;
8
+ config;
9
+ plugins = [];
10
+ syncThumbsEngine;
11
+ // RX lifecycle
12
+ destroy$ = new Subject();
13
+ // Container-based breakpoints
14
+ containerEl;
15
+ ro;
16
+ measuredSlideSizePx;
17
+ constructor(store) {
18
+ this.store = store;
19
+ }
20
+ /* ---------------- Public API ---------------- */
21
+ init(config, plugins = []) {
22
+ this.config = { ...DEFAULT_CONFIG, ...config, plugins: { ...(config.plugins ?? {}) } };
23
+ this.plugins = plugins;
24
+ this.plugins.forEach((p) => p.init?.(this));
25
+ this.setupViewportSignals();
26
+ this.applyBreakpoint();
27
+ this.clampIndicesAfterLayoutChange();
28
+ this.recalculate();
29
+ }
30
+ /** Call this from the component once you have the slider host element */
31
+ attachContainer(el) {
32
+ this.containerEl = el;
33
+ // Observe container size changes (robust in grids/sidebars/tabs)
34
+ this.ro?.disconnect();
35
+ this.ro = new ResizeObserver(() => {
36
+ // We reuse the same debounced layout handler
37
+ this.onLayoutSignal();
38
+ });
39
+ this.ro.observe(el);
40
+ this.measureSlideSize();
41
+ // Apply immediately based on real container width
42
+ this.onLayoutSignal();
43
+ }
44
+ measureSlideSize() {
45
+ if (!this.containerEl)
46
+ return;
47
+ const firstSlide = this.containerEl.querySelector(".slide");
48
+ if (!firstSlide)
49
+ return;
50
+ const rect = firstSlide.getBoundingClientRect();
51
+ if (rect.width > 0)
52
+ this.measuredSlideSizePx = rect.width;
53
+ }
54
+ destroy() {
55
+ // Stop Rx streams
56
+ this.destroy$.next();
57
+ this.destroy$.complete();
58
+ // Disconnect ResizeObserver
59
+ this.ro?.disconnect();
60
+ this.ro = undefined;
61
+ this.containerEl = undefined;
62
+ // Plugin cleanup
63
+ this.plugins.forEach((p) => p.destroy?.());
64
+ this.plugins = [];
65
+ // Reset store
66
+ this.store.reset();
67
+ }
68
+ next() {
69
+ this.goTo(this.store.snapshot.currentSlide + this.slideStep());
70
+ this.plugins.forEach((p) => p.onNext?.());
71
+ }
72
+ previous() {
73
+ this.goTo(this.store.snapshot.currentSlide - this.slideStep());
74
+ this.plugins.forEach((p) => p.onPrevious?.());
75
+ }
76
+ getContainerEl() {
77
+ return this.containerEl;
78
+ }
79
+ selectSlide(index) {
80
+ const slidesPerView = this.store.snapshot.slidesPerView;
81
+ // 1️⃣ Mark selected
82
+ this.store.update({ selectedSlide: index });
83
+ // 2️⃣ Calculate page start
84
+ let pageStart = Math.floor(index / slidesPerView) * slidesPerView;
85
+ // 3️⃣ Clamp to maxStartIndex
86
+ pageStart = Math.min(pageStart, this.maxStartIndex);
87
+ // 4️⃣ If synced with thumbs, also clamp to their max index
88
+ if (this.syncThumbsEngine) {
89
+ const thumbMaxIndex = this.syncThumbsEngine.getMaxStartIndex();
90
+ pageStart = Math.min(pageStart, thumbMaxIndex);
91
+ }
92
+ // 5️⃣ Move main slider
93
+ if (pageStart !== this.store.snapshot.currentSlide) {
94
+ this.goToSlide(pageStart);
95
+ }
96
+ // 6️⃣ Notify plugins
97
+ this.plugins.forEach((p) => p.onSlideClick?.(index));
98
+ }
99
+ /* ---------------- Drag ---------------- */
100
+ handleDragStart(event) {
101
+ this.store.update({ isDragging: true });
102
+ this.plugins.forEach((p) => p.onDragStart?.(event));
103
+ }
104
+ handleDragMove(event) {
105
+ this.plugins.forEach((p) => p.onDragMove?.(event));
106
+ }
107
+ handleDragEnd() {
108
+ this.store.update({ isDragging: false });
109
+ this.plugins.forEach((p) => p.onDragEnd?.());
110
+ }
111
+ goTo(index) {
112
+ this.goToSlide(index); // reuse your existing private method
113
+ }
114
+ /* ---------------- Internals ---------------- */
115
+ goToSlide(index) {
116
+ const clamped = Math.max(0, Math.min(index, this.maxStartIndex));
117
+ // console.log("[Engine] goToSlide index:", index, "clamped:", clamped);
118
+ this.store.update({ currentSlide: clamped });
119
+ this.recalculate();
120
+ // NOTE: calling onSlideClick here is a bit semantically odd (since it’s not always a click),
121
+ // but I preserved your behavior.
122
+ this.plugins.forEach((p) => p.onSlideClick?.(index));
123
+ }
124
+ recalculate() {
125
+ if (this.store.snapshot.isDragging)
126
+ return; // skip during drag
127
+ const slides = this.config.slides ?? [];
128
+ const maxStartIndex = this.getMaxStartIndex();
129
+ const current = this.store.snapshot.currentSlide;
130
+ this.store.update({
131
+ visibleSlides: slides,
132
+ translate: this.translate(current),
133
+ pager: this.buildPager(),
134
+ maxStartIndex,
135
+ canPrev: current > 0,
136
+ canNext: current < maxStartIndex,
137
+ });
138
+ }
139
+ translate(index) {
140
+ const axis = this.config.vertical ? "Y" : "X";
141
+ const containerSize = this.containerEl
142
+ ? this.config.vertical
143
+ ? this.containerEl.clientHeight
144
+ : this.containerEl.clientWidth
145
+ : this.config.vertical
146
+ ? window.innerHeight
147
+ : window.innerWidth;
148
+ const gap = this.store.snapshot.gap ?? 0;
149
+ const spv = this.store.snapshot.slidesPerView;
150
+ const slideSize = this.config.isThumbs && this.measuredSlideSizePx
151
+ ? this.measuredSlideSizePx
152
+ : spv > 0
153
+ ? (containerSize - gap * (spv - 1)) / spv
154
+ : containerSize;
155
+ // move by "pageStart * (slideSize + gap)"
156
+ const offset = index * (slideSize + gap);
157
+ return `translate${axis}(-${offset}px)`;
158
+ }
159
+ /** Debounced layout signals for resize/orientation/container changes */
160
+ setupViewportSignals() {
161
+ // If you want "only after resizing stops", replace auditTime with debounceTime(120)
162
+ const resize$ = fromEvent(window, "resize", { passive: true });
163
+ const orientation$ = fromEvent(window, "orientationchange", { passive: true });
164
+ merge(resize$, orientation$)
165
+ .pipe(auditTime(80), // good compromise: responsive without over-recalc
166
+ takeUntil(this.destroy$))
167
+ .subscribe(() => this.onLayoutSignal());
168
+ }
169
+ onLayoutSignal() {
170
+ const beforeSlidesPerView = this.store.snapshot.slidesPerView;
171
+ const beforeVisible = this.store.snapshot.isVisible;
172
+ this.applyBreakpoint();
173
+ const afterSlidesPerView = this.store.snapshot.slidesPerView;
174
+ const afterVisible = this.store.snapshot.isVisible;
175
+ if (beforeSlidesPerView !== afterSlidesPerView || beforeVisible !== afterVisible) {
176
+ this.clampIndicesAfterLayoutChange();
177
+ }
178
+ this.measureSlideSize();
179
+ this.recalculate();
180
+ }
181
+ getBreakpointWidth() {
182
+ if (this.containerEl) {
183
+ // Prefer clientWidth (layout), fallback to rect width
184
+ return this.containerEl.clientWidth || this.containerEl.getBoundingClientRect().width || window.innerWidth;
185
+ }
186
+ return window.innerWidth;
187
+ }
188
+ applyBreakpoint() {
189
+ const width = this.getBreakpointWidth();
190
+ const bp = this.config.breakpoints;
191
+ let override;
192
+ let device = "desktop";
193
+ if (width < 768) {
194
+ override = bp?.mobile;
195
+ device = "mobile";
196
+ }
197
+ else if (width < 1024) {
198
+ override = bp?.tablet;
199
+ device = "tablet";
200
+ }
201
+ else {
202
+ override = bp?.desktop;
203
+ device = "desktop";
204
+ }
205
+ // Merge overrides
206
+ this.config = { ...this.config, ...override };
207
+ this.store.update({
208
+ slidesPerView: this.config.slidesPerView,
209
+ gap: this.config.gap ?? 0, // ✅ NEW
210
+ isVisible: this.config.showOn?.[device] ?? true,
211
+ });
212
+ }
213
+ clampIndicesAfterLayoutChange() {
214
+ const max = this.getMaxStartIndex();
215
+ const current = this.store.snapshot.currentSlide;
216
+ const selected = this.store.snapshot.selectedSlide;
217
+ const clampedCurrent = Math.max(0, Math.min(current, max));
218
+ const clampedSelected = selected === -1 ? -1 : Math.max(0, Math.min(selected, (this.config.slides?.length ?? 0) - 1));
219
+ this.store.update({
220
+ currentSlide: clampedCurrent,
221
+ selectedSlide: clampedSelected,
222
+ });
223
+ }
224
+ buildPager() {
225
+ const totalSlides = this.config.slides.length;
226
+ const currentSlide = this.store.snapshot.selectedSlide !== -1 ? this.store.snapshot.selectedSlide : this.store.snapshot.currentSlide;
227
+ const maxVisibleDots = 5;
228
+ let start = Math.max(0, currentSlide - Math.floor(maxVisibleDots / 2));
229
+ let end = start + maxVisibleDots;
230
+ if (end > totalSlides) {
231
+ end = totalSlides;
232
+ start = Math.max(0, end - maxVisibleDots);
233
+ }
234
+ const visibleDots = Array.from({ length: end - start }, (_, i) => start + i);
235
+ const activeDotIndex = visibleDots.indexOf(currentSlide);
236
+ return {
237
+ currentPage: currentSlide,
238
+ totalPages: totalSlides,
239
+ visibleDots,
240
+ activeDotIndex,
241
+ };
242
+ }
243
+ slideStep() {
244
+ return this.store.snapshot.slidesPerView;
245
+ }
246
+ get maxStartIndex() {
247
+ const total = this.config.slides?.length ?? 0;
248
+ return Math.max(0, total - this.store.snapshot.slidesPerView);
249
+ }
250
+ getMaxStartIndex() {
251
+ const total = this.config.slides?.length ?? 0;
252
+ const spv = this.store.snapshot.slidesPerView || 1;
253
+ return Math.max(0, total - spv);
254
+ }
255
+ /* -------- Plugin-safe API -------- */
256
+ getState() {
257
+ return this.store.snapshot;
258
+ }
259
+ getStateObservable() {
260
+ return this.store.view$;
261
+ }
262
+ setState(patch) {
263
+ this.store.update(patch);
264
+ }
265
+ getConfig() {
266
+ return this.config;
267
+ }
268
+ /** Link this slider to thumbs */
269
+ syncWithThumbs(thumbsEngine) {
270
+ this.syncThumbsEngine = thumbsEngine;
271
+ }
272
+ /* -------- Read-only helpers -------- */
273
+ getSlidesPerView() {
274
+ return this.store.snapshot.slidesPerView;
275
+ }
276
+ getCurrentSlide() {
277
+ return this.store.snapshot.currentSlide;
278
+ }
279
+ getSelectedSlide() {
280
+ return this.store.snapshot.selectedSlide;
281
+ }
282
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SliderEngine, deps: [{ token: i1.SliderStore }], target: i0.ɵɵFactoryTarget.Injectable });
283
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SliderEngine });
284
+ }
285
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SliderEngine, decorators: [{
286
+ type: Injectable
287
+ }], ctorParameters: () => [{ type: i1.SliderStore }] });
288
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGVyLWVuZ2luZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWVkZ2Utc2xpZGVyL3NyYy9saWIvZW5naW5lL3NsaWRlci1lbmdpbmUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZFLE9BQU8sRUFBZ0IsY0FBYyxFQUFFLE1BQU0sK0JBQStCLENBQUM7OztBQU03RSxNQUFNLE9BQU8sWUFBWTtJQWNIO0lBYlosTUFBTSxDQUFnQjtJQUN0QixPQUFPLEdBQW1CLEVBQUUsQ0FBQztJQUM3QixnQkFBZ0IsQ0FBZ0I7SUFFeEMsZUFBZTtJQUNQLFFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO0lBRXZDLDhCQUE4QjtJQUN0QixXQUFXLENBQWU7SUFDMUIsRUFBRSxDQUFrQjtJQUVwQixtQkFBbUIsQ0FBVTtJQUVyQyxZQUFvQixLQUFrQjtRQUFsQixVQUFLLEdBQUwsS0FBSyxDQUFhO0lBQUcsQ0FBQztJQUUxQyxrREFBa0Q7SUFFbEQsSUFBSSxDQUFDLE1BQW9CLEVBQUUsVUFBMEIsRUFBRTtRQUNyRCxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsR0FBRyxjQUFjLEVBQUUsR0FBRyxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3ZGLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBRXZCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENB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UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztJQUVELGlDQUFpQztJQUNqQyxjQUFjLENBQUMsWUFBMEI7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFlBQVksQ0FBQztJQUN2QyxDQUFDO0lBRUQseUNBQXlDO0lBRXpDLGdCQUFnQjtRQUNkLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDO0lBQzNDLENBQUM7SUFFRCxlQUFlO1FBQ2IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUM7SUFDMUMsQ0FBQztJQUVELGdCQUFnQjtRQUNkLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDO0lBQzNDLENBQUM7d0dBblZVLFlBQVk7NEdBQVosWUFBWTs7NEZBQVosWUFBWTtrQkFEeEIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBmcm9tRXZlbnQsIG1lcmdlLCBTdWJqZWN0LCBhdWRpdFRpbWUsIHRha2VVbnRpbCB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7IFNsaWRlckNvbmZpZywgREVGQVVMVF9DT05GSUcgfSBmcm9tIFwiLi4vbW9kZWxzL3NsaWRlci1jb25maWcubW9kZWxcIjtcclxuaW1wb3J0IHsgU2xpZGVyVmlld1N0YXRlIH0gZnJvbSBcIi4uL21vZGVscy9zbGlkZXItc3RhdGUubW9kZWxcIjtcclxuaW1wb3J0IHsgU2xpZGVyUGx1Z2luIH0gZnJvbSBcIi4uL3BsdWdpbnMvc2xpZGVyLXBsdWdpblwiO1xyXG5pbXBvcnQgeyBTbGlkZXJTdG9yZSB9IGZyb20gXCIuLi9zdG9yZS9zbGlkZXItc3RvcmUuc2VydmljZVwiO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgU2xpZGVyRW5naW5lIHtcclxuICBwcml2YXRlIGNvbmZpZyE6IFNsaWRlckNvbmZpZztcclxuICBwcml2YXRlIHBsdWdpbnM6IFNsaWRlclBsdWdpbltdID0gW107XHJcbiAgcHJpdmF0ZSBzeW5jVGh1bWJzRW5naW5lPzogU2xpZGVyRW5naW5lO1xyXG5cclxuICAvLyBSWCBsaWZlY3ljbGVcclxuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgLy8gQ29udGFpbmVyLWJhc2VkIGJyZWFrcG9pbnRzXHJcbiAgcHJpdmF0ZSBjb250YWluZXJFbD86IEhUTUxFbGVtZW50O1xyXG4gIHByaXZhdGUgcm8/OiBSZXNpemVPYnNlcnZlcjtcclxuXHJcbiAgcHJpdmF0ZSBtZWFzdXJlZFNsaWRlU2l6ZVB4PzogbnVtYmVyO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0b3JlOiBTbGlkZXJTdG9yZSkge31cclxuXHJcbiAgLyogLS0tLS0tLS0tLS0tLS0tLSBQdWJsaWMgQVBJIC0tLS0tLS0tLS0tLS0tLS0gKi9cclxuXHJcbiAgaW5pdChjb25maWc6IFNsaWRlckNvbmZpZywgcGx1Z2luczogU2xpZGVyUGx1Z2luW10gPSBbXSkge1xyXG4gICAgdGhpcy5jb25maWcgPSB7IC4uLkRFRkFVTFRfQ09ORklHLCAuLi5jb25maWcsIHBsdWdpbnM6IHsgLi4uKGNvbmZpZy5wbHVnaW5zID8/IHt9KSB9IH07XHJcbiAgICB0aGlzLnBsdWdpbnMgPSBwbHVnaW5zO1xyXG5cclxuICAgIHRoaXMucGx1Z2lucy5mb3JFYWNoKChwKSA9PiBwLmluaXQ/Lih0aGlzKSk7XHJcblxyXG4gICAgdGhpcy5zZXR1cFZpZXdwb3J0U2lnbmFscygpO1xyXG4gICAgdGhpcy5hcHBseUJyZWFrcG9pbnQoKTtcclxuICAgIHRoaXMuY2xhbXBJbmRpY2VzQWZ0ZXJMYXlvdXRDaGFuZ2UoKTtcclxuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcclxuICB9XHJcblxyXG4gIC8qKiBDYWxsIHRoaXMgZnJvbSB0aGUgY29tcG9uZW50IG9uY2UgeW91IGhhdmUgdGhlIHNsaWRlciBob3N0IGVsZW1lbnQgKi9cclxuICBhdHRhY2hDb250YWluZXIoZWw6IEhUTUxFbGVtZW50KSB7XHJcbiAgICB0aGlzLmNvbnRhaW5lckVsID0gZWw7XHJcblxyXG4gICAgLy8gT2JzZXJ2ZSBjb250YWluZXIgc2l6ZSBjaGFuZ2VzIChyb2J1c3QgaW4gZ3JpZHMvc2lkZWJhcnMvdGFicylcclxuICAgIHRoaXMucm8/LmRpc2Nvbm5lY3QoKTtcclxuICAgIHRoaXMucm8gPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xyXG4gICAgICAvLyBXZSByZXVzZSB0aGUgc2FtZSBkZWJvdW5jZWQgbGF5b3V0IGhhbmRsZXJcclxuICAgICAgdGhpcy5vbkxheW91dFNpZ25hbCgpO1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLnJvLm9ic2VydmUoZWwpO1xyXG5cclxuICAgIHRoaXMubWVhc3VyZVNsaWRlU2l6ZSgpO1xyXG4gICAgLy8gQXBwbHkgaW1tZWRpYXRlbHkgYmFzZWQgb24gcmVhbCBjb250YWluZXIgd2lkdGhcclxuICAgIHRoaXMub25MYXlvdXRTaWduYWwoKTtcclxuICB9XHJcbiAgcHJpdmF0ZSBtZWFzdXJlU2xpZGVTaXplKCkge1xyXG4gICAgaWYgKCF0aGlzLmNvbnRhaW5lckVsKSByZXR1cm47XHJcbiAgICBjb25zdCBmaXJzdFNsaWRlID0gdGhpcy5jb250YWluZXJFbC5xdWVyeVNlbGVjdG9yPEhUTUxFbGVtZW50PihcIi5zbGlkZVwiKTtcclxuICAgIGlmICghZmlyc3RTbGlkZSkgcmV0dXJuO1xyXG4gICAgY29uc3QgcmVjdCA9IGZpcnN0U2xpZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBpZiAocmVjdC53aWR0aCA+IDApIHRoaXMubWVhc3VyZWRTbGlkZVNpemVQeCA9IHJlY3Qud2lkdGg7XHJcbiAgfVxyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICAvLyBTdG9wIFJ4IHN0cmVhbXNcclxuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xyXG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xyXG5cclxuICAgIC8vIERpc2Nvbm5lY3QgUmVzaXplT2JzZXJ2ZXJcclxuICAgIHRoaXMucm8/LmRpc2Nvbm5lY3QoKTtcclxuICAgIHRoaXMucm8gPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmNvbnRhaW5lckVsID0gdW5kZWZpbmVkO1xyXG5cclxuICAgIC8vIFBsdWdpbiBjbGVhbnVwXHJcbiAgICB0aGlzLnBsdWdpbnMuZm9yRWFjaCgocCkgPT4gcC5kZXN0cm95Py4oKSk7XHJcbiAgICB0aGlzLnBsdWdpbnMgPSBbXTtcclxuXHJcbiAgICAvLyBSZXNldCBzdG9yZVxyXG4gICAgdGhpcy5zdG9yZS5yZXNldCgpO1xyXG4gIH1cclxuXHJcbiAgbmV4dCgpIHtcclxuICAgIHRoaXMuZ29Ubyh0aGlzLnN0b3JlLnNuYXBzaG90LmN1cnJlbnRTbGlkZSArIHRoaXMuc2xpZGVTdGVwKCkpO1xyXG4gICAgdGhpcy5wbHVnaW5zLmZvckVhY2goKHApID0+IHAub25OZXh0Py4oKSk7XHJcbiAgfVxyXG5cclxuICBwcmV2aW91cygpIHtcclxuICAgIHRoaXMuZ29Ubyh0aGlzLnN0b3JlLnNuYXBzaG90LmN1cnJlbnRTbGlkZSAtIHRoaXMuc2xpZGVTdGVwKCkpO1xyXG4gICAgdGhpcy5wbHVnaW5zLmZvckVhY2goKHApID0+IHAub25QcmV2aW91cz8uKCkpO1xyXG4gIH1cclxuICBwdWJsaWMgZ2V0Q29udGFpbmVyRWwoKTogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyRWw7XHJcbiAgfVxyXG4gIHNlbGVjdFNsaWRlKGluZGV4OiBudW1iZXIpIHtcclxuICAgIGNvbnN0IHNsaWRlc1BlclZpZXcgPSB0aGlzLnN0b3JlLnNuYXBzaG90LnNsaWRlc1BlclZpZXc7XHJcblxyXG4gICAgLy8gMe+4j+KDoyBNYXJrIHNlbGVjdGVkXHJcbiAgICB0aGlzLnN0b3JlLnVwZGF0ZSh7IHNlbGVjdGVkU2xpZGU6IGluZGV4IH0pO1xyXG5cclxuICAgIC8vIDLvuI/ig6MgQ2FsY3VsYXRlIHBhZ2Ugc3RhcnRcclxuICAgIGxldCBwYWdlU3RhcnQgPSBNYXRoLmZsb29yKGluZGV4IC8gc2xpZGVzUGVyVmlldykgKiBzbGlkZXNQZXJWaWV3O1xyXG5cclxuICAgIC8vIDPvuI/ig6MgQ2xhbXAgdG8gbWF4U3RhcnRJbmRleFxyXG4gICAgcGFnZVN0YXJ0ID0gTWF0aC5taW4ocGFnZVN0YXJ0LCB0aGlzLm1heFN0YXJ0SW5kZXgpO1xyXG5cclxuICAgIC8vIDTvuI/ig6MgSWYgc3luY2VkIHdpdGggdGh1bWJzLCBhbHNvIGNsYW1wIHRvIHRoZWlyIG1heCBpbmRleFxyXG4gICAgaWYgKHRoaXMuc3luY1RodW1ic0VuZ2luZSkge1xyXG4gICAgICBjb25zdCB0aHVtYk1heEluZGV4ID0gdGhpcy5zeW5jVGh1bWJzRW5naW5lLmdldE1heFN0YXJ0SW5kZXgoKTtcclxuICAgICAgcGFnZVN0YXJ0ID0gTWF0aC5taW4ocGFnZVN0YXJ0LCB0aHVtYk1heEluZGV4KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyA177iP4oOjIE1vdmUgbWFpbiBzbGlkZXJcclxuICAgIGlmIChwYWdlU3RhcnQgIT09IHRoaXMuc3RvcmUuc25hcHNob3QuY3VycmVudFNsaWRlKSB7XHJcbiAgICAgIHRoaXMuZ29Ub1NsaWRlKHBhZ2VTdGFydCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gNu+4j+KDoyBOb3RpZnkgcGx1Z2luc1xyXG4gICAgdGhpcy5wbHVnaW5zLmZvckVhY2goKHApID0+IHAub25TbGlkZUNsaWNrPy4oaW5kZXgpKTtcclxuICB9XHJcblxyXG4gIC8qIC0tLS0tLS0tLS0tLS0tLS0gRHJhZyAtLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG4gIGhhbmRsZURyYWdTdGFydChldmVudDogUG9pbnRlckV2ZW50KSB7XHJcbiAgICB0aGlzLnN0b3JlLnVwZGF0ZSh7IGlzRHJhZ2dpbmc6IHRydWUgfSk7XHJcbiAgICB0aGlzLnBsdWdpbnMuZm9yRWFjaCgocCkgPT4gcC5vbkRyYWdTdGFydD8uKGV2ZW50KSk7XHJcbiAgfVxyXG4gIGhhbmRsZURyYWdNb3ZlKGV2ZW50OiBQb2ludGVyRXZlbnQpIHtcclxuICAgIHRoaXMucGx1Z2lucy5mb3JFYWNoKChwKSA9PiBwLm9uRHJhZ01vdmU/LihldmVudCkpO1xyXG4gIH1cclxuICBoYW5kbGVEcmFnRW5kKCkge1xyXG4gICAgdGhpcy5zdG9yZS51cGRhdGUoeyBpc0RyYWdnaW5nOiBmYWxzZSB9KTtcclxuICAgIHRoaXMucGx1Z2lucy5mb3JFYWNoKChwKSA9PiBwLm9uRHJhZ0VuZD8uKCkpO1xyXG4gIH1cclxuICBwdWJsaWMgZ29UbyhpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmdvVG9TbGlkZShpbmRleCk7IC8vIHJldXNlIHlvdXIgZXhpc3RpbmcgcHJpdmF0ZSBtZXRob2RcclxuICB9XHJcbiAgLyogLS0tLS0tLS0tLS0tLS0tLSBJbnRlcm5hbHMgLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuICBwcml2YXRlIGdvVG9TbGlkZShpbmRleDogbnVtYmVyKSB7XHJcbiAgICBjb25zdCBjbGFtcGVkID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oaW5kZXgsIHRoaXMubWF4U3RhcnRJbmRleCkpO1xyXG4gICAgLy8gY29uc29sZS5sb2coXCJbRW5naW5lXSBnb1RvU2xpZGUgaW5kZXg6XCIsIGluZGV4LCBcImNsYW1wZWQ6XCIsIGNsYW1wZWQpO1xyXG5cclxuICAgIHRoaXMuc3RvcmUudXBkYXRlKHsgY3VycmVudFNsaWRlOiBjbGFtcGVkIH0pO1xyXG4gICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xyXG5cclxuICAgIC8vIE5PVEU6IGNhbGxpbmcgb25TbGlkZUNsaWNrIGhlcmUgaXMgYSBiaXQgc2VtYW50aWNhbGx5IG9kZCAoc2luY2UgaXTigJlzIG5vdCBhbHdheXMgYSBjbGljayksXHJcbiAgICAvLyBidXQgSSBwcmVzZXJ2ZWQgeW91ciBiZWhhdmlvci5cclxuICAgIHRoaXMucGx1Z2lucy5mb3JFYWNoKChwKSA9PiBwLm9uU2xpZGVDbGljaz8uKGluZGV4KSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcmVjYWxjdWxhdGUoKSB7XHJcbiAgICBpZiAodGhpcy5zdG9yZS5zbmFwc2hvdC5pc0RyYWdnaW5nKSByZXR1cm47IC8vIHNraXAgZHVyaW5nIGRyYWdcclxuICAgIGNvbnN0IHNsaWRlcyA9IHRoaXMuY29uZmlnLnNsaWRlcyA/PyBbXTtcclxuICAgIGNvbnN0IG1heFN0YXJ0SW5kZXggPSB0aGlzLmdldE1heFN0YXJ0SW5kZXgoKTtcclxuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnN0b3JlLnNuYXBzaG90LmN1cnJlbnRTbGlkZTtcclxuXHJcbiAgICB0aGlzLnN0b3JlLnVwZGF0ZSh7XHJcbiAgICAgIHZpc2libGVTbGlkZXM6IHNsaWRlcyxcclxuICAgICAgdHJhbnNsYXRlOiB0aGlzLnRyYW5zbGF0ZShjdXJyZW50KSxcclxuICAgICAgcGFnZXI6IHRoaXMuYnVpbGRQYWdlcigpLFxyXG4gICAgICBtYXhTdGFydEluZGV4LFxyXG4gICAgICBjYW5QcmV2OiBjdXJyZW50ID4gMCxcclxuICAgICAgY2FuTmV4dDogY3VycmVudCA8IG1heFN0YXJ0SW5kZXgsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdHJhbnNsYXRlKGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgYXhpcyA9IHRoaXMuY29uZmlnLnZlcnRpY2FsID8gXCJZXCIgOiBcIlhcIjtcclxuXHJcbiAgICBjb25zdCBjb250YWluZXJTaXplID0gdGhpcy5jb250YWluZXJFbFxyXG4gICAgICA/IHRoaXMuY29uZmlnLnZlcnRpY2FsXHJcbiAgICAgICAgPyB0aGlzLmNvbnRhaW5lckVsLmNsaWVudEhlaWdodFxyXG4gICAgICAgIDogdGhpcy5jb250YWluZXJFbC5jbGllbnRXaWR0aFxyXG4gICAgICA6IHRoaXMuY29uZmlnLnZlcnRpY2FsXHJcbiAgICAgICAgPyB3aW5kb3cuaW5uZXJIZWlnaHRcclxuICAgICAgICA6IHdpbmRvdy5pbm5lcldpZHRoO1xyXG5cclxuICAgIGNvbnN0IGdhcCA9IHRoaXMuc3RvcmUuc25hcHNob3QuZ2FwID8/IDA7XHJcblxyXG4gICAgY29uc3Qgc3B2ID0gdGhpcy5zdG9yZS5zbmFwc2hvdC5zbGlkZXNQZXJWaWV3O1xyXG4gICAgY29uc3Qgc2xpZGVTaXplID1cclxuICAgICAgdGhpcy5jb25maWcuaXNUaHVtYnMgJiYgdGhpcy5tZWFzdXJlZFNsaWRlU2l6ZVB4XHJcbiAgICAgICAgPyB0aGlzLm1lYXN1cmVkU2xpZGVTaXplUHhcclxuICAgICAgICA6IHNwdiA+IDBcclxuICAgICAgICAgID8gKGNvbnRhaW5lclNpemUgLSBnYXAgKiAoc3B2IC0gMSkpIC8gc3B2XHJcbiAgICAgICAgICA6IGNvbnRhaW5lclNpemU7XHJcblxyXG4gICAgLy8gbW92ZSBieSBcInBhZ2VTdGFydCAqIChzbGlkZVNpemUgKyBnYXApXCJcclxuICAgIGNvbnN0IG9mZnNldCA9IGluZGV4ICogKHNsaWRlU2l6ZSArIGdhcCk7XHJcblxyXG4gICAgcmV0dXJuIGB0cmFuc2xhdGUke2F4aXN9KC0ke29mZnNldH1weClgO1xyXG4gIH1cclxuXHJcbiAgLyoqIERlYm91bmNlZCBsYXlvdXQgc2lnbmFscyBmb3IgcmVzaXplL29yaWVudGF0aW9uL2NvbnRhaW5lciBjaGFuZ2VzICovXHJcbiAgcHJpdmF0ZSBzZXR1cFZpZXdwb3J0U2lnbmFscygpIHtcclxuICAgIC8vIElmIHlvdSB3YW50IFwib25seSBhZnRlciByZXNpemluZyBzdG9wc1wiLCByZXBsYWNlIGF1ZGl0VGltZSB3aXRoIGRlYm91bmNlVGltZSgxMjApXHJcbiAgICBjb25zdCByZXNpemUkID0gZnJvbUV2ZW50KHdpbmRvdywgXCJyZXNpemVcIiwgeyBwYXNzaXZlOiB0cnVlIH0gYXMgYW55KTtcclxuICAgIGNvbnN0IG9yaWVudGF0aW9uJCA9IGZyb21FdmVudCh3aW5kb3csIFwib3JpZW50YXRpb25jaGFuZ2VcIiwgeyBwYXNzaXZlOiB0cnVlIH0gYXMgYW55KTtcclxuXHJcbiAgICBtZXJnZShyZXNpemUkLCBvcmllbnRhdGlvbiQpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIGF1ZGl0VGltZSg4MCksIC8vIGdvb2QgY29tcHJvbWlzZTogcmVzcG9uc2l2ZSB3aXRob3V0IG92ZXItcmVjYWxjXHJcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpLFxyXG4gICAgICApXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5vbkxheW91dFNpZ25hbCgpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgb25MYXlvdXRTaWduYWwoKSB7XHJcbiAgICBjb25zdCBiZWZvcmVTbGlkZXNQZXJWaWV3ID0gdGhpcy5zdG9yZS5zbmFwc2hvdC5zbGlkZXNQZXJWaWV3O1xyXG4gICAgY29uc3QgYmVmb3JlVmlzaWJsZSA9IHRoaXMuc3RvcmUuc25hcHNob3QuaXNWaXNpYmxlO1xyXG5cclxuICAgIHRoaXMuYXBwbHlCcmVha3BvaW50KCk7XHJcblxyXG4gICAgY29uc3QgYWZ0ZXJTbGlkZXNQZXJWaWV3ID0gdGhpcy5zdG9yZS5zbmFwc2hvdC5zbGlkZXNQZXJWaWV3O1xyXG4gICAgY29uc3QgYWZ0ZXJWaXNpYmxlID0gdGhpcy5zdG9yZS5zbmFwc2hvdC5pc1Zpc2libGU7XHJcblxyXG4gICAgaWYgKGJlZm9yZVNsaWRlc1BlclZpZXcgIT09IGFmdGVyU2xpZGVzUGVyVmlldyB8fCBiZWZvcmVWaXNpYmxlICE9PSBhZnRlclZpc2libGUpIHtcclxuICAgICAgdGhpcy5jbGFtcEluZGljZXNBZnRlckxheW91dENoYW5nZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMubWVhc3VyZVNsaWRlU2l6ZSgpO1xyXG5cclxuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0QnJlYWtwb2ludFdpZHRoKCk6IG51bWJlciB7XHJcbiAgICBpZiAodGhpcy5jb250YWluZXJFbCkge1xyXG4gICAgICAvLyBQcmVmZXIgY2xpZW50V2lkdGggKGxheW91dCksIGZhbGxiYWNrIHRvIHJlY3Qgd2lkdGhcclxuICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyRWwuY2xpZW50V2lkdGggfHwgdGhpcy5jb250YWluZXJFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCB8fCB3aW5kb3cuaW5uZXJXaWR0aDtcclxuICAgIH1cclxuICAgIHJldHVybiB3aW5kb3cuaW5uZXJXaWR0aDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXBwbHlCcmVha3BvaW50KCkge1xyXG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmdldEJyZWFrcG9pbnRXaWR0aCgpO1xyXG4gICAgY29uc3QgYnAgPSB0aGlzLmNvbmZpZy5icmVha3BvaW50cztcclxuXHJcbiAgICBsZXQgb3ZlcnJpZGU6IFBhcnRpYWw8U2xpZGVyQ29uZmlnPiB8IHVuZGVmaW5lZDtcclxuICAgIGxldCBkZXZpY2U6IFwibW9iaWxlXCIgfCBcInRhYmxldFwiIHwgXCJkZXNrdG9wXCIgPSBcImRlc2t0b3BcIjtcclxuXHJcbiAgICBpZiAod2lkdGggPCA3NjgpIHtcclxuICAgICAgb3ZlcnJpZGUgPSBicD8ubW9iaWxlO1xyXG4gICAgICBkZXZpY2UgPSBcIm1vYmlsZVwiO1xyXG4gICAgfSBlbHNlIGlmICh3aWR0aCA8IDEwMjQpIHtcclxuICAgICAgb3ZlcnJpZGUgPSBicD8udGFibGV0O1xyXG4gICAgICBkZXZpY2UgPSBcInRhYmxldFwiO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgb3ZlcnJpZGUgPSBicD8uZGVza3RvcDtcclxuICAgICAgZGV2aWNlID0gXCJkZXNrdG9wXCI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gTWVyZ2Ugb3ZlcnJpZGVzXHJcbiAgICB0aGlzLmNvbmZpZyA9IHsgLi4udGhpcy5jb25maWcsIC4uLm92ZXJyaWRlIH07XHJcblxyXG4gICAgdGhpcy5zdG9yZS51cGRhdGUoe1xyXG4gICAgICBzbGlkZXNQZXJWaWV3OiB0aGlzLmNvbmZpZy5zbGlkZXNQZXJWaWV3LFxyXG4gICAgICBnYXA6IHRoaXMuY29uZmlnLmdhcCA/PyAwLCAvLyDinIUgTkVXXHJcbiAgICAgIGlzVmlzaWJsZTogdGhpcy5jb25maWcuc2hvd09uPy5bZGV2aWNlXSA/PyB0cnVlLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNsYW1wSW5kaWNlc0FmdGVyTGF5b3V0Q2hhbmdlKCkge1xyXG4gICAgY29uc3QgbWF4ID0gdGhpcy5nZXRNYXhTdGFydEluZGV4KCk7XHJcblxyXG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuc3RvcmUuc25hcHNob3QuY3VycmVudFNsaWRlO1xyXG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnN0b3JlLnNuYXBzaG90LnNlbGVjdGVkU2xpZGU7XHJcblxyXG4gICAgY29uc3QgY2xhbXBlZEN1cnJlbnQgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihjdXJyZW50LCBtYXgpKTtcclxuICAgIGNvbnN0IGNsYW1wZWRTZWxlY3RlZCA9IHNlbGVjdGVkID09PSAtMSA/IC0xIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oc2VsZWN0ZWQsICh0aGlzLmNvbmZpZy5zbGlkZXM/Lmxlbmd0aCA/PyAwKSAtIDEpKTtcclxuXHJcbiAgICB0aGlzLnN0b3JlLnVwZGF0ZSh7XHJcbiAgICAgIGN1cnJlbnRTbGlkZTogY2xhbXBlZEN1cnJlbnQsXHJcbiAgICAgIHNlbGVjdGVkU2xpZGU6IGNsYW1wZWRTZWxlY3RlZCxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBidWlsZFBhZ2VyKCkge1xyXG4gICAgY29uc3QgdG90YWxTbGlkZXMgPSB0aGlzLmNvbmZpZy5zbGlkZXMubGVuZ3RoO1xyXG4gICAgY29uc3QgY3VycmVudFNsaWRlID0gdGhpcy5zdG9yZS5zbmFwc2hvdC5zZWxlY3RlZFNsaWRlICE9PSAtMSA/IHRoaXMuc3RvcmUuc25hcHNob3Quc2VsZWN0ZWRTbGlkZSA6IHRoaXMuc3RvcmUuc25hcHNob3QuY3VycmVudFNsaWRlO1xyXG5cclxuICAgIGNvbnN0IG1heFZpc2libGVEb3RzID0gNTtcclxuXHJcbiAgICBsZXQgc3RhcnQgPSBNYXRoLm1heCgwLCBjdXJyZW50U2xpZGUgLSBNYXRoLmZsb29yKG1heFZpc2libGVEb3RzIC8gMikpO1xyXG4gICAgbGV0IGVuZCA9IHN0YXJ0ICsgbWF4VmlzaWJsZURvdHM7XHJcblxyXG4gICAgaWYgKGVuZCA+IHRvdGFsU2xpZGVzKSB7XHJcbiAgICAgIGVuZCA9IHRvdGFsU2xpZGVzO1xyXG4gICAgICBzdGFydCA9IE1hdGgubWF4KDAsIGVuZCAtIG1heFZpc2libGVEb3RzKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB2aXNpYmxlRG90cyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IGVuZCAtIHN0YXJ0IH0sIChfLCBpKSA9PiBzdGFydCArIGkpO1xyXG4gICAgY29uc3QgYWN0aXZlRG90SW5kZXggPSB2aXNpYmxlRG90cy5pbmRleE9mKGN1cnJlbnRTbGlkZSk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgY3VycmVudFBhZ2U6IGN1cnJlbnRTbGlkZSxcclxuICAgICAgdG90YWxQYWdlczogdG90YWxTbGlkZXMsXHJcbiAgICAgIHZpc2libGVEb3RzLFxyXG4gICAgICBhY3RpdmVEb3RJbmRleCxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNsaWRlU3RlcCgpIHtcclxuICAgIHJldHVybiB0aGlzLnN0b3JlLnNuYXBzaG90LnNsaWRlc1BlclZpZXc7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldCBtYXhTdGFydEluZGV4KCkge1xyXG4gICAgY29uc3QgdG90YWwgPSB0aGlzLmNvbmZpZy5zbGlkZXM/Lmxlbmd0aCA/PyAwO1xyXG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIHRvdGFsIC0gdGhpcy5zdG9yZS5zbmFwc2hvdC5zbGlkZXNQZXJWaWV3KTtcclxuICB9XHJcbiAgZ2V0TWF4U3RhcnRJbmRleCgpIHtcclxuICAgIGNvbnN0IHRvdGFsID0gdGhpcy5jb25maWcuc2xpZGVzPy5sZW5ndGggPz8gMDtcclxuICAgIGNvbnN0IHNwdiA9IHRoaXMuc3RvcmUuc25hcHNob3Quc2xpZGVzUGVyVmlldyB8fCAxO1xyXG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIHRvdGFsIC0gc3B2KTtcclxuICB9XHJcbiAgLyogLS0tLS0tLS0gUGx1Z2luLXNhZmUgQVBJIC0tLS0tLS0tICovXHJcblxyXG4gIGdldFN0YXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3RvcmUuc25hcHNob3Q7XHJcbiAgfVxyXG5cclxuICBnZXRTdGF0ZU9ic2VydmFibGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zdG9yZS52aWV3JDtcclxuICB9XHJcblxyXG4gIHNldFN0YXRlKHBhdGNoOiBQYXJ0aWFsPFNsaWRlclZpZXdTdGF0ZT4pIHtcclxuICAgIHRoaXMuc3RvcmUudXBkYXRlKHBhdGNoKTtcclxuICB9XHJcblxyXG4gIGdldENvbmZpZygpIHtcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZztcclxuICB9XHJcblxyXG4gIC8qKiBMaW5rIHRoaXMgc2xpZGVyIHRvIHRodW1icyAqL1xyXG4gIHN5bmNXaXRoVGh1bWJzKHRodW1ic0VuZ2luZTogU2xpZGVyRW5naW5lKSB7XHJcbiAgICB0aGlzLnN5bmNUaHVtYnNFbmdpbmUgPSB0aHVtYnNFbmdpbmU7XHJcbiAgfVxyXG5cclxuICAvKiAtLS0tLS0tLSBSZWFkLW9ubHkgaGVscGVycyAtLS0tLS0tLSAqL1xyXG5cclxuICBnZXRTbGlkZXNQZXJWaWV3KCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5zdG9yZS5zbmFwc2hvdC5zbGlkZXNQZXJWaWV3O1xyXG4gIH1cclxuXHJcbiAgZ2V0Q3VycmVudFNsaWRlKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5zdG9yZS5zbmFwc2hvdC5jdXJyZW50U2xpZGU7XHJcbiAgfVxyXG5cclxuICBnZXRTZWxlY3RlZFNsaWRlKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5zdG9yZS5zbmFwc2hvdC5zZWxlY3RlZFNsaWRlO1xyXG4gIH1cclxufVxyXG4iXX0=