@ivcreative/accessible-vanilla-slick 1.0.2

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.
@@ -0,0 +1,2109 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // slick/src/index.js
20
+ var src_exports = {};
21
+ __export(src_exports, {
22
+ SlickSlider: () => SlickSlider_default,
23
+ default: () => Slick
24
+ });
25
+ module.exports = __toCommonJS(src_exports);
26
+
27
+ // slick/src/utils/events.js
28
+ var EventDispatcher = class {
29
+ constructor() {
30
+ this.listeners = {};
31
+ }
32
+ /**
33
+ * Subscribe to an event
34
+ */
35
+ on(event, callback, context = null) {
36
+ if (!this.listeners[event]) {
37
+ this.listeners[event] = [];
38
+ }
39
+ this.listeners[event].push({ callback, context });
40
+ return this;
41
+ }
42
+ /**
43
+ * Subscribe to an event once
44
+ */
45
+ once(event, callback, context = null) {
46
+ const wrapper = (...args) => {
47
+ callback.apply(context, args);
48
+ this.off(event, wrapper);
49
+ };
50
+ return this.on(event, wrapper, context);
51
+ }
52
+ /**
53
+ * Unsubscribe from an event
54
+ */
55
+ off(event, callback = null) {
56
+ if (!event) {
57
+ this.listeners = {};
58
+ return this;
59
+ }
60
+ if (!callback) {
61
+ delete this.listeners[event];
62
+ return this;
63
+ }
64
+ if (this.listeners[event]) {
65
+ this.listeners[event] = this.listeners[event].filter(
66
+ (listener) => listener.callback !== callback
67
+ );
68
+ }
69
+ return this;
70
+ }
71
+ /**
72
+ * Emit/trigger an event
73
+ */
74
+ emit(event, data = null) {
75
+ if (!this.listeners[event])
76
+ return this;
77
+ this.listeners[event].forEach((listener) => {
78
+ listener.callback.call(listener.context, data);
79
+ });
80
+ return this;
81
+ }
82
+ /**
83
+ * Clear all listeners
84
+ */
85
+ clear() {
86
+ this.listeners = {};
87
+ return this;
88
+ }
89
+ };
90
+
91
+ // slick/src/utils/helpers.js
92
+ function extend(target, ...sources) {
93
+ if (!sources.length)
94
+ return target;
95
+ const source = sources.shift();
96
+ if (isObject(target) && isObject(source)) {
97
+ for (const key in source) {
98
+ if (isObject(source[key])) {
99
+ if (!target[key])
100
+ Object.assign(target, { [key]: {} });
101
+ extend(target[key], source[key]);
102
+ } else {
103
+ Object.assign(target, { [key]: source[key] });
104
+ }
105
+ }
106
+ }
107
+ return extend(target, ...sources);
108
+ }
109
+ function isObject(obj) {
110
+ return obj && typeof obj === "object" && !Array.isArray(obj) && obj.constructor === Object;
111
+ }
112
+ function debounce(func, wait = 0) {
113
+ let timeout;
114
+ return function executedFunction(...args) {
115
+ const later = () => {
116
+ clearTimeout(timeout);
117
+ func(...args);
118
+ };
119
+ clearTimeout(timeout);
120
+ timeout = setTimeout(later, wait);
121
+ };
122
+ }
123
+ var idCounter = 0;
124
+ function uniqueId(prefix = "slick") {
125
+ return `${prefix}-${++idCounter}`;
126
+ }
127
+ function parseHTML(htmlString) {
128
+ const temp = document.createElement("div");
129
+ temp.innerHTML = htmlString.trim();
130
+ return temp.firstElementChild;
131
+ }
132
+ var requestAnimFrame = window.requestAnimationFrame || function(callback) {
133
+ return setTimeout(callback, 1e3 / 60);
134
+ };
135
+ var cancelAnimFrame = window.cancelAnimationFrame || function(id) {
136
+ clearTimeout(id);
137
+ };
138
+ function getWindowDimensions() {
139
+ return {
140
+ width: window.innerWidth || document.documentElement.clientWidth,
141
+ height: window.innerHeight || document.documentElement.clientHeight
142
+ };
143
+ }
144
+
145
+ // slick/src/utils/dom.js
146
+ function select(selector, context = document) {
147
+ return context.querySelector(selector);
148
+ }
149
+ function selectAll(selector, context = document) {
150
+ return Array.from(context.querySelectorAll(selector));
151
+ }
152
+ function addClass(element, className) {
153
+ if (!element)
154
+ return;
155
+ if (Array.isArray(element)) {
156
+ element.forEach((el) => addClass(el, className));
157
+ } else {
158
+ element.classList.add(...className.split(" "));
159
+ }
160
+ }
161
+ function removeClass(element, className) {
162
+ if (!element)
163
+ return;
164
+ if (Array.isArray(element)) {
165
+ element.forEach((el) => removeClass(el, className));
166
+ } else {
167
+ element.classList.remove(...className.split(" "));
168
+ }
169
+ }
170
+ function hasClass(element, className) {
171
+ return element ? element.classList.contains(className) : false;
172
+ }
173
+ function setAttribute(element, name, value) {
174
+ if (!element)
175
+ return;
176
+ if (Array.isArray(element)) {
177
+ element.forEach((el) => setAttribute(el, name, value));
178
+ } else if (typeof name === "object") {
179
+ Object.entries(name).forEach(([key, val]) => {
180
+ setAttribute(element, key, val);
181
+ });
182
+ } else {
183
+ if (value === null) {
184
+ element.removeAttribute(name);
185
+ } else {
186
+ element.setAttribute(name, value);
187
+ }
188
+ }
189
+ }
190
+ function getAttribute(element, name) {
191
+ return element ? element.getAttribute(name) : null;
192
+ }
193
+ function removeAttribute(element, name) {
194
+ if (!element)
195
+ return;
196
+ if (Array.isArray(element)) {
197
+ element.forEach((el) => removeAttribute(el, name));
198
+ } else {
199
+ element.removeAttribute(name);
200
+ }
201
+ }
202
+ function setStyle(element, name, value) {
203
+ if (!element)
204
+ return;
205
+ if (Array.isArray(element)) {
206
+ element.forEach((el) => setStyle(el, name, value));
207
+ } else if (typeof name === "object") {
208
+ Object.entries(name).forEach(([key, val]) => {
209
+ element.style[key] = val;
210
+ });
211
+ } else {
212
+ element.style[name] = value;
213
+ }
214
+ }
215
+ function getDimensions(element) {
216
+ const rect = element.getBoundingClientRect();
217
+ return {
218
+ width: element.offsetWidth || rect.width,
219
+ height: element.offsetHeight || rect.height,
220
+ top: element.offsetTop || rect.top,
221
+ left: element.offsetLeft || rect.left
222
+ };
223
+ }
224
+ function getInnerWidth(element) {
225
+ const styles = window.getComputedStyle(element);
226
+ const paddingLeft = parseFloat(styles.paddingLeft) || 0;
227
+ const paddingRight = parseFloat(styles.paddingRight) || 0;
228
+ return element.clientWidth - paddingLeft - paddingRight;
229
+ }
230
+ function getOuterWidth(element, includeMargin = false) {
231
+ let width = element.offsetWidth;
232
+ if (includeMargin) {
233
+ const style = window.getComputedStyle(element);
234
+ width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
235
+ }
236
+ return width;
237
+ }
238
+ function getOuterHeight(element, includeMargin = false) {
239
+ let height = element.offsetHeight;
240
+ if (includeMargin) {
241
+ const style = window.getComputedStyle(element);
242
+ height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
243
+ }
244
+ return height;
245
+ }
246
+ function appendChild(parent, child) {
247
+ if (!parent)
248
+ return;
249
+ if (typeof child === "string") {
250
+ parent.insertAdjacentHTML("beforeend", child);
251
+ } else {
252
+ parent.appendChild(child);
253
+ }
254
+ }
255
+ function insertBefore(target, element) {
256
+ if (!target)
257
+ return;
258
+ if (typeof element === "string") {
259
+ target.insertAdjacentHTML("beforebegin", element);
260
+ } else {
261
+ target.parentNode.insertBefore(element, target);
262
+ }
263
+ }
264
+ function remove(element) {
265
+ if (!element)
266
+ return;
267
+ if (Array.isArray(element)) {
268
+ element.forEach((el) => remove(el));
269
+ } else if (element.parentNode) {
270
+ element.parentNode.removeChild(element);
271
+ }
272
+ }
273
+ function empty(element) {
274
+ if (!element)
275
+ return;
276
+ while (element.firstChild) {
277
+ element.removeChild(element.firstChild);
278
+ }
279
+ }
280
+ function getChildren(element, selector = null) {
281
+ if (!element)
282
+ return [];
283
+ if (selector) {
284
+ return Array.from(element.children).filter((child) => child.matches(selector));
285
+ }
286
+ return Array.from(element.children);
287
+ }
288
+
289
+ // slick/src/utils/css.js
290
+ function supportsTransforms() {
291
+ const element = document.createElement("div");
292
+ return "transform" in element.style || "WebkitTransform" in element.style || "MozTransform" in element.style || "OTransform" in element.style || "msTransform" in element.style;
293
+ }
294
+ function getTransformProperty() {
295
+ const element = document.createElement("div");
296
+ const properties = ["transform", "WebkitTransform", "MozTransform", "OTransform", "msTransform"];
297
+ for (const prop of properties) {
298
+ if (prop in element.style) {
299
+ return prop;
300
+ }
301
+ }
302
+ return "transform";
303
+ }
304
+ function getTransitionProperty() {
305
+ const element = document.createElement("div");
306
+ const properties = ["transition", "WebkitTransition", "MozTransition", "OTransition", "msTransition"];
307
+ for (const prop of properties) {
308
+ if (prop in element.style) {
309
+ return prop;
310
+ }
311
+ }
312
+ return "transition";
313
+ }
314
+ function applyTransition(element, duration, easing = "ease") {
315
+ const transitionProp = getTransitionProperty();
316
+ element.style[transitionProp] = `all ${duration}ms ${easing}`;
317
+ }
318
+ function removeTransition(element) {
319
+ const transitionProp = getTransitionProperty();
320
+ element.style[transitionProp] = "none";
321
+ }
322
+ function translate3d(element, x, y = 0, z = 0) {
323
+ const transformProp = getTransformProperty();
324
+ element.style[transformProp] = `translate3d(${x}px, ${y}px, ${z}px)`;
325
+ }
326
+
327
+ // slick/src/SlickSlider.js
328
+ var SlickSlider = class _SlickSlider {
329
+ static INSTANCES = /* @__PURE__ */ new Map();
330
+ constructor(element, options = {}) {
331
+ this.element = element;
332
+ this.instanceId = uniqueId("slick");
333
+ this.constructor.INSTANCES.set(this.instanceId, this);
334
+ this.options = extend({}, this.constructor.DEFAULTS, options);
335
+ this.originalOptions = extend({}, this.options);
336
+ this.state = extend({}, this.constructor.INITIAL_STATE);
337
+ this.dispatcher = new EventDispatcher();
338
+ this.boundMethods = {};
339
+ this.init();
340
+ }
341
+ /**
342
+ * Default configuration options
343
+ */
344
+ static DEFAULTS = {
345
+ // Slider behavior
346
+ accessibility: true,
347
+ adaptiveHeight: false,
348
+ appendArrows: null,
349
+ appendDots: null,
350
+ arrows: true,
351
+ arrowsPlacement: null,
352
+ // 'before', 'after', 'split'
353
+ asNavFor: null,
354
+ autoplay: false,
355
+ autoplaySpeed: 3e3,
356
+ centerMode: false,
357
+ centerPadding: "50px",
358
+ cssEase: "ease",
359
+ customPaging: null,
360
+ dots: false,
361
+ dotsClass: "slick-dots",
362
+ draggable: true,
363
+ edge: false,
364
+ easing: "linear",
365
+ edgeFriction: 0.35,
366
+ fade: false,
367
+ focusOnSelect: false,
368
+ focusOnChange: false,
369
+ infinite: true,
370
+ initialSlide: 0,
371
+ instructionsText: null,
372
+ lazyLoad: "ondemand",
373
+ // 'ondemand', 'progressive', or false
374
+ mobileFirst: false,
375
+ nextArrow: '<button class="slick-next" aria-label="Next slide"><span class="slick-next-icon" aria-hidden="true"></span></button>',
376
+ pauseIcon: '<span class="slick-pause-icon" aria-hidden="true"></span>',
377
+ pauseOnFocus: true,
378
+ pauseOnHover: true,
379
+ playIcon: '<span class="slick-play-icon" aria-hidden="true"></span>',
380
+ prevArrow: '<button class="slick-prev" aria-label="Previous slide"><span class="slick-prev-icon" aria-hidden="true"></span></button>',
381
+ respondTo: "window",
382
+ // 'window', 'slider', or 'min'
383
+ responsive: null,
384
+ rows: 1,
385
+ rtl: false,
386
+ slide: "",
387
+ slidesPerRow: 1,
388
+ slidesToShow: 1,
389
+ slidesToScroll: 1,
390
+ speed: 500,
391
+ swipe: true,
392
+ swipeToSlide: false,
393
+ touchMove: true,
394
+ touchThreshold: 5,
395
+ useAutoplayToggleButton: true,
396
+ useCSS: true,
397
+ useGroupRole: true,
398
+ useTransform: true,
399
+ variableWidth: false,
400
+ vertical: false,
401
+ verticalSwiping: false,
402
+ waitForAnimate: true,
403
+ zIndex: 1e3,
404
+ // Accessibility
405
+ regionLabel: "slider"
406
+ };
407
+ /**
408
+ * Initial state
409
+ */
410
+ static INITIAL_STATE = {
411
+ activeBreakpoint: null,
412
+ animating: false,
413
+ autoPlayTimer: null,
414
+ currentDirection: 0,
415
+ currentLeft: 0,
416
+ currentSlide: 0,
417
+ direction: 1,
418
+ dotListElement: null,
419
+ dotSlidesToScroll: 1,
420
+ dots: null,
421
+ dragging: false,
422
+ edgeHit: false,
423
+ slidesCache: null,
424
+ gestureEndTime: 0,
425
+ gestureStartTime: 0,
426
+ instructionsText: null,
427
+ interrupted: false,
428
+ listHeight: 0,
429
+ listWidth: 0,
430
+ loadIndex: 0,
431
+ nextArrowElement: null,
432
+ pauseButton: null,
433
+ postSlideDelay: 0,
434
+ prevArrowElement: null,
435
+ scrolling: false,
436
+ slideCount: 0,
437
+ slideHeight: 0,
438
+ slideOffset: 0,
439
+ slideWidth: 0,
440
+ slideTrack: null,
441
+ slides: [],
442
+ sliding: false,
443
+ slideList: null,
444
+ swipeLeft: 0,
445
+ swiping: false,
446
+ suppressNavSync: false,
447
+ swipeDirection: null,
448
+ targetSlide: 0,
449
+ touchObject: {},
450
+ touchStartTime: 0,
451
+ transformsEnabled: false,
452
+ unslicked: false,
453
+ windowHeight: 0,
454
+ windowWidth: 0,
455
+ yeti: null
456
+ };
457
+ /**
458
+ * Key codes for keyboard navigation
459
+ */
460
+ static KEYS = {
461
+ ENTER: 13,
462
+ SPACE: 32,
463
+ LEFT: 37,
464
+ UP: 38,
465
+ RIGHT: 39,
466
+ DOWN: 40,
467
+ TAB: 9,
468
+ HOME: 36,
469
+ END: 35,
470
+ ESCAPE: 27
471
+ };
472
+ /**
473
+ * Initialize slider
474
+ */
475
+ init() {
476
+ this.element.setAttribute("data-slick-slider", this.instanceId);
477
+ addClass(this.element, "slick-slider");
478
+ this.state.transformsEnabled = supportsTransforms();
479
+ this.setProps();
480
+ this.state.currentSlide = this.options.initialSlide;
481
+ this.state.currentDirection = 1;
482
+ this.state.rtl = this.options.rtl;
483
+ this.state.rows = this.options.rows;
484
+ this.state.slideCount = 0;
485
+ this.loadSlider();
486
+ this.buildOut();
487
+ this.setupInfinite();
488
+ if (this.options.accessibility) {
489
+ setAttribute(this.element, "role", "region");
490
+ setAttribute(this.element, "aria-label", this.options.regionLabel);
491
+ }
492
+ if (this.options.arrows && this.state.slideCount > this.options.slidesToShow) {
493
+ this.buildArrows();
494
+ }
495
+ if (this.options.dots && this.state.slideCount > this.options.slidesToShow) {
496
+ this.buildDots();
497
+ }
498
+ if (this.options.autoplay && this.options.useAutoplayToggleButton && this.state.slideCount > 1) {
499
+ this.buildAutoplayButton();
500
+ }
501
+ this.updateNavigationVisibility();
502
+ addClass(this.element, "slick-initialized");
503
+ if (this.options.variableWidth) {
504
+ window.requestAnimationFrame(() => {
505
+ this.setPosition();
506
+ });
507
+ } else {
508
+ this.setPosition();
509
+ }
510
+ this.initializeEvents();
511
+ if (this.options.autoplay) {
512
+ this.autoPlay();
513
+ }
514
+ if (this.options.responsive && this.options.responsive.length) {
515
+ this.checkResponsive(true);
516
+ }
517
+ this.emit("init", { instance: this });
518
+ }
519
+ /**
520
+ * Set properties matching jQuery setProps()
521
+ */
522
+ setProps() {
523
+ this.state.positionProp = this.options.vertical ? "top" : "left";
524
+ if (this.options.fade) {
525
+ this.options.centerMode = false;
526
+ this.options.slidesToShow = 1;
527
+ this.options.slidesToScroll = 1;
528
+ }
529
+ const style = document.body.style;
530
+ if (style.transform !== void 0) {
531
+ this.state.animType = "transform";
532
+ } else if (style.webkitTransform !== void 0) {
533
+ this.state.animType = "webkitTransform";
534
+ } else if (style.MozTransform !== void 0) {
535
+ this.state.animType = "MozTransform";
536
+ } else if (style.msTransform !== void 0) {
537
+ this.state.animType = "msTransform";
538
+ } else if (style.OTransform !== void 0) {
539
+ this.state.animType = "OTransform";
540
+ } else {
541
+ this.state.animType = false;
542
+ }
543
+ }
544
+ /**
545
+ * Setup infinite mode - CRITICAL for infinite scrolling
546
+ * Clones the first and last slides to enable seamless wrapping
547
+ */
548
+ setupInfinite() {
549
+ if (!this.options.infinite || this.options.fade || this.state.slideCount <= this.options.slidesToShow) {
550
+ return;
551
+ }
552
+ const infiniteCount = this.options.centerMode ? this.options.slidesToShow + 1 : this.options.slidesToShow;
553
+ for (let i = this.state.slideCount; i > this.state.slideCount - infiniteCount; i -= 1) {
554
+ const slideIndex = i - 1;
555
+ const clone2 = this.state.slides[slideIndex].cloneNode(true);
556
+ addClass(clone2, "slick-cloned");
557
+ setAttribute(clone2, "aria-hidden", "true");
558
+ setAttribute(clone2, "tabindex", "-1");
559
+ setAttribute(clone2, "data-slick-index", String(slideIndex - this.state.slideCount));
560
+ this.state.slideTrack.insertBefore(clone2, this.state.slideTrack.firstChild);
561
+ }
562
+ const appendCount = Math.max(
563
+ this.state.slideCount,
564
+ this.options.slidesToShow + this.options.slidesToScroll
565
+ );
566
+ for (let i = 0; i < appendCount; i += 1) {
567
+ const slideIndex = i % this.state.slideCount;
568
+ const clone2 = this.state.slides[slideIndex].cloneNode(true);
569
+ addClass(clone2, "slick-cloned");
570
+ setAttribute(clone2, "aria-hidden", "true");
571
+ setAttribute(clone2, "tabindex", "-1");
572
+ setAttribute(clone2, "data-slick-index", String(i + this.state.slideCount));
573
+ appendChild(this.state.slideTrack, clone2);
574
+ }
575
+ void this.state.slideTrack.offsetWidth;
576
+ }
577
+ /**
578
+ * Load slides from DOM
579
+ */
580
+ loadSlider() {
581
+ const slides = this.options.slide ? selectAll(this.options.slide, this.element) : getChildren(this.element);
582
+ this.state.slides = Array.from(slides);
583
+ this.state.slideCount = this.state.slides.length;
584
+ this.state.slides.forEach((slide, index) => {
585
+ addClass(slide, "slick-slide");
586
+ setAttribute(slide, "data-slick-index", index);
587
+ if (this.options.useGroupRole) {
588
+ setAttribute(slide, "role", "group");
589
+ setAttribute(slide, "aria-label", `slide ${index + 1}`);
590
+ }
591
+ });
592
+ this.wrapSlideContent();
593
+ this.emit("loaded", { slideCount: this.state.slideCount });
594
+ }
595
+ /**
596
+ * Wrap slide content with inline-block div for proper layout
597
+ * Matches jQuery Slick behavior: wraps immediate children in div with display: inline-block
598
+ */
599
+ wrapSlideContent() {
600
+ this.state.slides.forEach((slide) => {
601
+ const children = Array.from(getChildren(slide));
602
+ if (children.length === 1 && children[0].tagName === "DIV") {
603
+ const innerDiv = children[0];
604
+ if (innerDiv.style.display !== "inline-block") {
605
+ setStyle(innerDiv, "width", "100%");
606
+ setStyle(innerDiv, "display", "inline-block");
607
+ }
608
+ return;
609
+ }
610
+ const hasInlineBlockWrapper = children.length === 1 && getComputedStyle(children[0]).display === "inline-block";
611
+ if (hasInlineBlockWrapper) {
612
+ return;
613
+ }
614
+ const wrapper = document.createElement("div");
615
+ setStyle(wrapper, "width", "100%");
616
+ setStyle(wrapper, "display", "inline-block");
617
+ children.forEach((child) => {
618
+ appendChild(wrapper, child);
619
+ });
620
+ appendChild(slide, wrapper);
621
+ });
622
+ }
623
+ /**
624
+ * Build slider DOM structure
625
+ */
626
+ buildOut() {
627
+ const track = select(".slick-track", this.element);
628
+ const list = select(".slick-list", this.element);
629
+ if (!track || !list) {
630
+ const listDiv = document.createElement("div");
631
+ addClass(listDiv, "slick-list");
632
+ const trackDiv = document.createElement("div");
633
+ addClass(trackDiv, "slick-track");
634
+ this.state.slides.forEach((slide) => {
635
+ appendChild(trackDiv, slide);
636
+ });
637
+ appendChild(listDiv, trackDiv);
638
+ appendChild(this.element, listDiv);
639
+ this.state.slideTrack = trackDiv;
640
+ this.state.slideList = listDiv;
641
+ } else {
642
+ this.state.slideTrack = track;
643
+ this.state.slideList = list;
644
+ }
645
+ if (this.options.accessibility) {
646
+ setAttribute(this.element, "role", "region");
647
+ setAttribute(this.element, "aria-label", this.options.regionLabel);
648
+ }
649
+ }
650
+ /**
651
+ * Build navigation arrows
652
+ */
653
+ buildArrows() {
654
+ const prevArrowHTML = this.options.prevArrow;
655
+ const prevArrow = parseHTML(prevArrowHTML);
656
+ addClass(prevArrow, "slick-arrow");
657
+ this.state.prevArrowElement = prevArrow;
658
+ prevArrow.addEventListener("click", (e) => this.prevClick(e));
659
+ const nextArrowHTML = this.options.nextArrow;
660
+ const nextArrow = parseHTML(nextArrowHTML);
661
+ addClass(nextArrow, "slick-arrow");
662
+ this.state.nextArrowElement = nextArrow;
663
+ nextArrow.addEventListener("click", (e) => this.nextClick(e));
664
+ const appendTarget = this.options.appendArrows || this.element;
665
+ const slideList = this.state.slideList;
666
+ if (slideList && slideList.parentNode === appendTarget) {
667
+ insertBefore(slideList, prevArrow);
668
+ appendChild(appendTarget, nextArrow);
669
+ } else {
670
+ appendChild(appendTarget, prevArrow);
671
+ appendChild(appendTarget, nextArrow);
672
+ }
673
+ this.emit("arrowsBuilt");
674
+ }
675
+ /**
676
+ * Build navigation dots
677
+ */
678
+ buildDots() {
679
+ const dotContainer = document.createElement("ul");
680
+ addClass(dotContainer, this.options.dotsClass);
681
+ addClass(this.element, "slick-dotted");
682
+ const dotCount = Math.ceil(this.state.slideCount / this.options.slidesToScroll);
683
+ for (let i = 0; i < dotCount; i++) {
684
+ const dot = document.createElement("li");
685
+ const button = document.createElement("button");
686
+ const icon = document.createElement("span");
687
+ addClass(icon, "slick-dot-icon");
688
+ setAttribute(button, "aria-label", `Go to slide ${i + 1}`);
689
+ setAttribute(button, "data-slide-index", i);
690
+ if (i === 0)
691
+ addClass(dot, "slick-active");
692
+ button.addEventListener("click", (e) => this.dotClick(e));
693
+ appendChild(button, icon);
694
+ appendChild(dot, button);
695
+ appendChild(dotContainer, dot);
696
+ }
697
+ this.state.dots = dotContainer;
698
+ this.state.dotListElement = dotContainer;
699
+ const appendTarget = this.options.appendDots || this.element;
700
+ appendChild(appendTarget, dotContainer);
701
+ this.updateDots();
702
+ this.emit("dotsBuilt");
703
+ }
704
+ /**
705
+ * Update dot active state
706
+ */
707
+ updateDots() {
708
+ if (!this.state.dots)
709
+ return;
710
+ const dotIndex = Math.floor(this.state.currentSlide / this.options.slidesToScroll);
711
+ const dots = Array.from(this.state.dots.children);
712
+ dots.forEach((dot, index) => {
713
+ if (index === dotIndex) {
714
+ addClass(dot, "slick-active");
715
+ } else {
716
+ removeClass(dot, "slick-active");
717
+ }
718
+ });
719
+ }
720
+ /**
721
+ * Build autoplay toggle button
722
+ */
723
+ buildAutoplayButton() {
724
+ const button = document.createElement("button");
725
+ addClass(button, "slick-autoplay-toggle-button");
726
+ setAttribute(button, "aria-label", "Play/Pause slider autoplay");
727
+ this.state.pauseButton = button;
728
+ button.addEventListener("click", () => this.autoPlayToggleHandler());
729
+ this.setAutoplayButtonState(Boolean(this.state.paused));
730
+ if (this.state.slideList) {
731
+ this.element.insertBefore(button, this.state.slideList);
732
+ } else {
733
+ appendChild(this.element, button);
734
+ }
735
+ }
736
+ /**
737
+ * Update autoplay button icon and state
738
+ */
739
+ setAutoplayButtonState(isPaused) {
740
+ if (!this.state.pauseButton)
741
+ return;
742
+ setAttribute(this.state.pauseButton, "aria-pressed", isPaused ? "true" : "false");
743
+ empty(this.state.pauseButton);
744
+ const iconMarkup = isPaused ? this.options.playIcon : this.options.pauseIcon;
745
+ if (typeof iconMarkup === "string") {
746
+ appendChild(this.state.pauseButton, parseHTML(iconMarkup));
747
+ } else if (iconMarkup) {
748
+ appendChild(this.state.pauseButton, iconMarkup);
749
+ }
750
+ }
751
+ /**
752
+ * Setup event listeners
753
+ */
754
+ initializeEvents() {
755
+ this.boundMethods.handleResize = debounce(() => this.checkResponsive(), 250);
756
+ window.addEventListener("resize", this.boundMethods.handleResize);
757
+ this.boundMethods.handleVisibilityChange = () => this.handleVisibilityChange();
758
+ document.addEventListener("visibilitychange", this.boundMethods.handleVisibilityChange);
759
+ this.boundMethods.handleKeydown = (e) => this.handleKeydown(e);
760
+ this.element.addEventListener("keydown", this.boundMethods.handleKeydown);
761
+ if (this.options.draggable && this.state.slideList) {
762
+ this.boundMethods.handleMouseDown = (e) => this.startDrag(e);
763
+ this.state.slideList.addEventListener("mousedown", this.boundMethods.handleMouseDown);
764
+ }
765
+ if (this.options.swipe && this.state.slideList && "ontouchstart" in window) {
766
+ this.boundMethods.handleTouchStart = (e) => this.startDrag(e);
767
+ this.boundMethods.handleTouchEnd = (e) => this.endDrag(e);
768
+ this.boundMethods.handleTouchMove = (e) => this.trackDrag(e);
769
+ this.state.slideList.addEventListener("touchstart", this.boundMethods.handleTouchStart, { passive: true });
770
+ this.state.slideList.addEventListener("touchend", this.boundMethods.handleTouchEnd, { passive: true });
771
+ this.state.slideList.addEventListener("touchmove", this.boundMethods.handleTouchMove, { passive: false });
772
+ }
773
+ this.boundMethods.handleFocus = () => this.handleFocus();
774
+ this.boundMethods.handleBlur = () => this.handleBlur();
775
+ this.element.addEventListener("focusin", this.boundMethods.handleFocus, true);
776
+ this.element.addEventListener("focusout", this.boundMethods.handleBlur, true);
777
+ if (this.options.focusOnSelect && this.state.slideTrack) {
778
+ this.boundMethods.handleSlideClick = (e) => this.handleSlideClick(e);
779
+ this.state.slideTrack.addEventListener("click", this.boundMethods.handleSlideClick);
780
+ }
781
+ }
782
+ /**
783
+ * Resolve slide index into range [0, slideCount - 1]
784
+ */
785
+ normalizeSlideIndex(index) {
786
+ if (this.state.slideCount <= 0 || !Number.isFinite(index)) {
787
+ return 0;
788
+ }
789
+ const count = this.state.slideCount;
790
+ let normalized = index % count;
791
+ if (normalized < 0) {
792
+ normalized += count;
793
+ }
794
+ return normalized;
795
+ }
796
+ /**
797
+ * Resolve asNavFor option to slider instances
798
+ */
799
+ getNavTargetInstances() {
800
+ const asNavFor = this.options.asNavFor;
801
+ if (!asNavFor) {
802
+ return [];
803
+ }
804
+ const targets = [];
805
+ if (typeof asNavFor === "string") {
806
+ const elements = Array.from(document.querySelectorAll(asNavFor));
807
+ elements.forEach((element) => {
808
+ const instanceId = element.getAttribute("data-slick-slider");
809
+ if (!instanceId)
810
+ return;
811
+ const instance = this.constructor.INSTANCES.get(instanceId);
812
+ if (instance && instance !== this) {
813
+ targets.push(instance);
814
+ }
815
+ });
816
+ return targets;
817
+ }
818
+ if (asNavFor instanceof _SlickSlider) {
819
+ return asNavFor === this ? [] : [asNavFor];
820
+ }
821
+ if (asNavFor instanceof Element) {
822
+ const instanceId = asNavFor.getAttribute("data-slick-slider");
823
+ const instance = instanceId ? this.constructor.INSTANCES.get(instanceId) : null;
824
+ return instance && instance !== this ? [instance] : [];
825
+ }
826
+ return [];
827
+ }
828
+ /**
829
+ * Sync current slide to linked sliders (asNavFor)
830
+ */
831
+ syncAsNavFor(index, dontAnimate = false) {
832
+ const targets = this.getNavTargetInstances();
833
+ if (!targets.length) {
834
+ return;
835
+ }
836
+ targets.forEach((target) => {
837
+ if (!target || target.state.unslicked) {
838
+ return;
839
+ }
840
+ const targetIndex = target.normalizeSlideIndex(index);
841
+ if (target.state.currentSlide === targetIndex) {
842
+ return;
843
+ }
844
+ target.state.suppressNavSync = true;
845
+ target.goTo(targetIndex, dontAnimate);
846
+ target.state.suppressNavSync = false;
847
+ });
848
+ }
849
+ /**
850
+ * Handle click-to-select on slide track
851
+ */
852
+ handleSlideClick(e) {
853
+ const targetSlide = e.target.closest(".slick-slide");
854
+ if (!targetSlide || !this.state.slideTrack || !this.state.slideTrack.contains(targetSlide)) {
855
+ return;
856
+ }
857
+ const rawIndex = parseInt(getAttribute(targetSlide, "data-slick-index"), 10);
858
+ if (Number.isNaN(rawIndex)) {
859
+ return;
860
+ }
861
+ const index = this.normalizeSlideIndex(rawIndex);
862
+ this.goTo(index);
863
+ }
864
+ /**
865
+ * Public API: Go to next slide
866
+ */
867
+ next() {
868
+ this.changeSlide({ data: { message: "next" } });
869
+ }
870
+ /**
871
+ * Public API: Go to previous slide
872
+ */
873
+ prev() {
874
+ this.changeSlide({ data: { message: "prev" } });
875
+ }
876
+ /**
877
+ * Public API: Go to specific slide
878
+ */
879
+ goTo(index, dontAnimate = false) {
880
+ if (index < 0 || index >= this.state.slideCount)
881
+ return;
882
+ this.changeSlide({ data: { message: "index", index } }, dontAnimate);
883
+ }
884
+ /**
885
+ * Public API: Play autoplay
886
+ */
887
+ play() {
888
+ if (!this.options.autoplay)
889
+ return;
890
+ this.state.paused = false;
891
+ this.autoPlay();
892
+ this.setAutoplayButtonState(false);
893
+ this.emit("play");
894
+ }
895
+ /**
896
+ * Public API: Pause autoplay
897
+ */
898
+ pause() {
899
+ if (!this.options.autoplay)
900
+ return;
901
+ this.autoPlayClear();
902
+ this.state.paused = true;
903
+ this.setAutoplayButtonState(true);
904
+ this.emit("pause");
905
+ }
906
+ /**
907
+ * Public API: Get current slide index
908
+ */
909
+ getCurrentSlide() {
910
+ return this.state.currentSlide;
911
+ }
912
+ /**
913
+ * Public API: Get configuration option
914
+ */
915
+ getOption(option) {
916
+ return this.options[option];
917
+ }
918
+ /**
919
+ * Public API: Set configuration option
920
+ */
921
+ setOption(option, value) {
922
+ this.options[option] = value;
923
+ this.emit("setOption", { option, value });
924
+ }
925
+ /**
926
+ * Public API: Add slide(s)
927
+ * Adds new slide(s) to the carousel
928
+ */
929
+ addSlide(markup, index = null, addBefore = false) {
930
+ if (!markup)
931
+ return false;
932
+ if (typeof index === "boolean") {
933
+ addBefore = index;
934
+ index = null;
935
+ }
936
+ if (index !== null && (index < 0 || index >= this.state.slideCount)) {
937
+ return false;
938
+ }
939
+ this.unloadClones();
940
+ let newSlide;
941
+ if (typeof markup === "string") {
942
+ newSlide = parseHTML(markup);
943
+ } else {
944
+ newSlide = markup;
945
+ }
946
+ if (typeof index === "number") {
947
+ if (index === 0 && this.state.slides.length === 0) {
948
+ appendChild(this.state.slideTrack, newSlide);
949
+ } else if (addBefore) {
950
+ const targetSlide = this.state.slides[index];
951
+ if (targetSlide && targetSlide.parentNode) {
952
+ insertBefore(targetSlide, newSlide);
953
+ } else {
954
+ appendChild(this.state.slideTrack, newSlide);
955
+ }
956
+ } else {
957
+ const targetSlide = this.state.slides[index];
958
+ if (targetSlide && targetSlide.nextSibling) {
959
+ insertBefore(targetSlide.nextSibling, newSlide);
960
+ } else if (targetSlide && targetSlide.parentNode) {
961
+ appendChild(this.state.slideTrack, newSlide);
962
+ }
963
+ }
964
+ } else {
965
+ if (addBefore === true) {
966
+ if (this.state.slideTrack.firstChild) {
967
+ insertBefore(this.state.slideTrack.firstChild, newSlide);
968
+ } else {
969
+ appendChild(this.state.slideTrack, newSlide);
970
+ }
971
+ } else {
972
+ appendChild(this.state.slideTrack, newSlide);
973
+ }
974
+ }
975
+ addClass(newSlide, "slick-slide");
976
+ this.state.slides = getChildren(this.state.slideTrack).filter((el) => !hasClass(el, "slick-cloned"));
977
+ this.state.slideCount = this.state.slides.length;
978
+ this.reinit();
979
+ this.emit("addSlide");
980
+ return true;
981
+ }
982
+ /**
983
+ * Public API: Remove slide
984
+ * Removes a slide from the carousel
985
+ */
986
+ removeSlide(index, removeBefore = false, removeAll = false) {
987
+ if (this.state.slideCount < 1 || index < 0 || index > this.state.slideCount - 1) {
988
+ return false;
989
+ }
990
+ this.unloadClones();
991
+ if (removeAll === true) {
992
+ while (this.state.slideTrack.firstChild) {
993
+ const child = this.state.slideTrack.firstChild;
994
+ if (!hasClass(child, "slick-cloned")) {
995
+ remove(child);
996
+ }
997
+ }
998
+ } else {
999
+ const slideToRemove = this.state.slides[index];
1000
+ if (slideToRemove) {
1001
+ remove(slideToRemove);
1002
+ }
1003
+ }
1004
+ this.state.slides = getChildren(this.state.slideTrack).filter((el) => !hasClass(el, "slick-cloned"));
1005
+ this.state.slideCount = this.state.slides.length;
1006
+ if (this.state.currentSlide >= this.state.slideCount && this.state.currentSlide !== 0) {
1007
+ this.state.currentSlide = this.state.currentSlide - this.options.slidesToScroll;
1008
+ }
1009
+ this.reinit();
1010
+ this.emit("removeSlide");
1011
+ return true;
1012
+ }
1013
+ /**
1014
+ * Alias for addSlide (jQuery Slick compatibility)
1015
+ */
1016
+ slickAdd(markup, index = null, addBefore = false) {
1017
+ return this.addSlide(markup, index, addBefore);
1018
+ }
1019
+ /**
1020
+ * Alias for removeSlide (jQuery Slick compatibility)
1021
+ */
1022
+ slickRemove(index, removeBefore = false, removeAll = false) {
1023
+ return this.removeSlide(index, removeBefore, removeAll);
1024
+ }
1025
+ /**
1026
+ * Alias for slickFilter (jQuery Slick compatibility)
1027
+ */
1028
+ filterSlides(filter) {
1029
+ return this.slickFilter(filter);
1030
+ }
1031
+ /**
1032
+ * Public API: Filter slides (jQuery Slick compatibility)
1033
+ */
1034
+ slickFilter(filter) {
1035
+ if (filter == null || !this.state.slideTrack) {
1036
+ return false;
1037
+ }
1038
+ if (!this.state.slidesCache) {
1039
+ this.state.slidesCache = this.state.slides.slice();
1040
+ }
1041
+ this.unloadClones();
1042
+ const filteredSlides = this.state.slidesCache.filter(
1043
+ (slide, index) => this.matchesSlideFilter(slide, filter, index)
1044
+ );
1045
+ empty(this.state.slideTrack);
1046
+ filteredSlides.forEach((slide) => appendChild(this.state.slideTrack, slide));
1047
+ this.state.currentSlide = 0;
1048
+ this.reinit();
1049
+ this.emit("filter");
1050
+ return true;
1051
+ }
1052
+ /**
1053
+ * Alias for slickUnfilter (jQuery Slick compatibility)
1054
+ */
1055
+ unfilterSlides() {
1056
+ return this.slickUnfilter();
1057
+ }
1058
+ /**
1059
+ * Public API: Remove active filter and restore all slides (jQuery Slick compatibility)
1060
+ */
1061
+ slickUnfilter() {
1062
+ if (!this.state.slideTrack || !this.state.slidesCache) {
1063
+ return false;
1064
+ }
1065
+ this.unloadClones();
1066
+ empty(this.state.slideTrack);
1067
+ this.state.slidesCache.forEach((slide) => appendChild(this.state.slideTrack, slide));
1068
+ this.state.slidesCache = null;
1069
+ this.state.currentSlide = 0;
1070
+ this.reinit();
1071
+ this.emit("unfilter");
1072
+ return true;
1073
+ }
1074
+ /**
1075
+ * Match slide against a jQuery-like filter selector or callback
1076
+ */
1077
+ matchesSlideFilter(slide, filter, index) {
1078
+ if (typeof filter === "function") {
1079
+ return Boolean(filter.call(slide, index, slide));
1080
+ }
1081
+ if (typeof filter !== "string") {
1082
+ return false;
1083
+ }
1084
+ const hasEvenPseudo = /:even\b/.test(filter);
1085
+ const hasOddPseudo = /:odd\b/.test(filter);
1086
+ const selector = filter.replace(/:even\b|:odd\b/g, "").trim();
1087
+ const parityMatch = hasEvenPseudo ? index % 2 === 0 : hasOddPseudo ? index % 2 === 1 : true;
1088
+ if (!parityMatch) {
1089
+ return false;
1090
+ }
1091
+ if (!selector) {
1092
+ return true;
1093
+ }
1094
+ try {
1095
+ return slide.matches(selector);
1096
+ } catch (e) {
1097
+ return false;
1098
+ }
1099
+ }
1100
+ /**
1101
+ * Public API: Destroy slider
1102
+ */
1103
+ destroy() {
1104
+ removeEventListener(window, "resize", this.boundMethods.handleResize);
1105
+ removeEventListener(document, "visibilitychange", this.boundMethods.handleVisibilityChange);
1106
+ removeEventListener(this.element, "keydown", this.boundMethods.handleKeydown);
1107
+ this.dispatcher.clear();
1108
+ if (this.state.pauseButton)
1109
+ remove(this.state.pauseButton);
1110
+ if (this.state.prevArrowElement)
1111
+ remove(this.state.prevArrowElement);
1112
+ if (this.state.nextArrowElement)
1113
+ remove(this.state.nextArrowElement);
1114
+ if (this.state.dots)
1115
+ remove(this.state.dots);
1116
+ this.state.unslicked = true;
1117
+ this.constructor.INSTANCES.delete(this.instanceId);
1118
+ this.emit("destroy");
1119
+ }
1120
+ /**
1121
+ * Handle slide change
1122
+ */
1123
+ changeSlide(e, dontAnimate = false) {
1124
+ const message = e?.data?.message;
1125
+ const previousSlide = this.normalizeSlideIndex(this.state.currentSlide);
1126
+ let targetSlide = previousSlide;
1127
+ if (message === "next") {
1128
+ targetSlide = previousSlide + this.options.slidesToScroll;
1129
+ } else if (message === "prev") {
1130
+ targetSlide = previousSlide - this.options.slidesToScroll;
1131
+ } else if (message === "index" && Number.isInteger(e?.data?.index)) {
1132
+ targetSlide = e.data.index;
1133
+ }
1134
+ if (this.options.fade) {
1135
+ if (!this.options.infinite) {
1136
+ targetSlide = Math.max(0, Math.min(targetSlide, this.state.slideCount - 1));
1137
+ } else {
1138
+ targetSlide = this.normalizeSlideIndex(targetSlide);
1139
+ }
1140
+ if (targetSlide === previousSlide)
1141
+ return;
1142
+ if (this.state.animating && this.options.waitForAnimate)
1143
+ return;
1144
+ this.emit("beforeChange", { previousSlide, nextSlide: targetSlide });
1145
+ const shouldAnimate2 = this.options.useCSS && !dontAnimate && this.options.speed > 0;
1146
+ this.state.currentSlide = targetSlide;
1147
+ if (!this.state.suppressNavSync && this.options.asNavFor) {
1148
+ this.syncAsNavFor(targetSlide, dontAnimate);
1149
+ }
1150
+ if (shouldAnimate2) {
1151
+ this.state.animating = true;
1152
+ this.fadeSlideTransition(previousSlide, targetSlide, () => {
1153
+ this.state.animating = false;
1154
+ this.setPosition();
1155
+ this.emit("afterChange", { currentSlide: this.state.currentSlide });
1156
+ });
1157
+ } else {
1158
+ this.state.animating = false;
1159
+ this.setPosition();
1160
+ this.emit("afterChange", { currentSlide: this.state.currentSlide });
1161
+ }
1162
+ return;
1163
+ }
1164
+ if (!this.options.infinite) {
1165
+ targetSlide = Math.max(0, Math.min(targetSlide, this.state.slideCount - 1));
1166
+ }
1167
+ if (targetSlide === previousSlide)
1168
+ return;
1169
+ if (this.state.animating && this.options.waitForAnimate)
1170
+ return;
1171
+ this.emit("beforeChange", { previousSlide, nextSlide: targetSlide });
1172
+ const shouldAnimate = this.options.useCSS && !dontAnimate && this.options.speed > 0;
1173
+ this.state.animating = shouldAnimate;
1174
+ if (shouldAnimate) {
1175
+ applyTransition(this.state.slideTrack, this.options.speed, this.options.cssEase);
1176
+ this.animateHeight();
1177
+ } else {
1178
+ removeTransition(this.state.slideTrack);
1179
+ }
1180
+ this.state.currentSlide = targetSlide;
1181
+ const normalizedTarget = this.normalizeSlideIndex(targetSlide);
1182
+ if (!this.state.suppressNavSync && this.options.asNavFor) {
1183
+ this.syncAsNavFor(normalizedTarget, dontAnimate);
1184
+ }
1185
+ this.setPosition();
1186
+ if (shouldAnimate) {
1187
+ window.setTimeout(() => {
1188
+ if (this.options.infinite) {
1189
+ let repositionSlide = targetSlide;
1190
+ if (targetSlide >= this.state.slideCount) {
1191
+ repositionSlide = targetSlide % this.state.slideCount;
1192
+ } else if (targetSlide < 0) {
1193
+ repositionSlide = this.state.slideCount + targetSlide % this.state.slideCount;
1194
+ }
1195
+ if (repositionSlide !== targetSlide) {
1196
+ removeTransition(this.state.slideTrack);
1197
+ this.state.currentSlide = repositionSlide;
1198
+ this.setPosition();
1199
+ } else {
1200
+ removeTransition(this.state.slideTrack);
1201
+ }
1202
+ } else {
1203
+ removeTransition(this.state.slideTrack);
1204
+ }
1205
+ this.state.animating = false;
1206
+ }, this.options.speed);
1207
+ } else {
1208
+ this.state.animating = false;
1209
+ }
1210
+ this.emit("afterChange", { currentSlide: this.state.currentSlide });
1211
+ }
1212
+ /**
1213
+ * Quick reposition for infinite wrap - minimal calculations, no forced reflows
1214
+ * Used when wrapping from last slide to first (or vice versa) to maintain 60fps
1215
+ */
1216
+ quickReposition() {
1217
+ if (!this.state.slideList || !this.state.slideTrack)
1218
+ return;
1219
+ if (!this.state.slideWidth) {
1220
+ const listWidth = this.state.listWidth || getInnerWidth(this.state.slideList) || 400;
1221
+ this.state.slideWidth = Math.ceil(listWidth / this.options.slidesToShow);
1222
+ }
1223
+ let targetLeft = 0;
1224
+ if (this.options.variableWidth) {
1225
+ const allSlidesInDOM = selectAll(".slick-slide", this.state.slideTrack);
1226
+ let slideIndex = this.state.currentSlide;
1227
+ const cloneOffset = this.options.infinite && this.state.slideCount > this.options.slidesToShow ? this.options.centerMode ? this.options.slidesToShow + 1 : this.options.slidesToShow : 0;
1228
+ slideIndex = this.state.currentSlide + cloneOffset;
1229
+ if (slideIndex < 0 || slideIndex >= allSlidesInDOM.length) {
1230
+ slideIndex = Math.max(0, Math.min(slideIndex, allSlidesInDOM.length - 1));
1231
+ }
1232
+ const targetSlide = allSlidesInDOM[slideIndex];
1233
+ if (targetSlide) {
1234
+ const slideOffsetLeft = targetSlide.offsetLeft || 0;
1235
+ targetLeft = -slideOffsetLeft;
1236
+ if (this.options.centerMode && this.state.listWidth) {
1237
+ const slideWidth = getOuterWidth(targetSlide);
1238
+ targetLeft += (this.state.listWidth - slideWidth) / 2;
1239
+ }
1240
+ }
1241
+ } else {
1242
+ const allSlidesInDOM = selectAll(".slick-slide", this.state.slideTrack);
1243
+ const totalSlideCount = allSlidesInDOM.length;
1244
+ const trackWidth = Math.ceil(this.state.slideWidth * totalSlideCount);
1245
+ setStyle(this.state.slideTrack, "width", `${trackWidth}px`);
1246
+ let slideOffset = 0;
1247
+ if (this.options.infinite && this.state.slideCount > this.options.slidesToShow) {
1248
+ slideOffset = this.state.slideWidth * this.options.slidesToShow * -1;
1249
+ }
1250
+ if (this.state.slideCount <= this.options.slidesToShow) {
1251
+ slideOffset = 0;
1252
+ }
1253
+ if (this.options.centerMode && this.state.slideCount <= this.options.slidesToShow) {
1254
+ slideOffset = this.state.slideWidth * Math.floor(this.options.slidesToShow) / 2 - this.state.slideWidth * this.state.slideCount / 2;
1255
+ } else if (this.options.centerMode && this.options.infinite) {
1256
+ slideOffset += this.state.slideWidth * Math.floor(this.options.slidesToShow / 2) - this.state.slideWidth;
1257
+ } else if (this.options.centerMode) {
1258
+ slideOffset = 0;
1259
+ slideOffset += this.state.slideWidth * Math.floor(this.options.slidesToShow / 2);
1260
+ }
1261
+ targetLeft = this.state.currentSlide * this.state.slideWidth * -1 + slideOffset;
1262
+ }
1263
+ if (this.options.useTransform && this.state.transformsEnabled) {
1264
+ translate3d(this.state.slideTrack, targetLeft, 0, 0);
1265
+ } else {
1266
+ setStyle(this.state.slideTrack, "left", `${targetLeft}px`);
1267
+ }
1268
+ this.updateSlideVisibility();
1269
+ this.updateArrows();
1270
+ this.updateDots();
1271
+ }
1272
+ /**
1273
+ * Fade transition between slides (jQuery Slick parity)
1274
+ */
1275
+ fadeSlideTransition(fromIndex, toIndex, callback) {
1276
+ const fromSlide = this.state.slides[this.normalizeSlideIndex(fromIndex)];
1277
+ const toSlide = this.state.slides[this.normalizeSlideIndex(toIndex)];
1278
+ if (!toSlide) {
1279
+ if (callback)
1280
+ callback();
1281
+ return;
1282
+ }
1283
+ const transitionValue = `opacity ${this.options.speed}ms ${this.options.cssEase}`;
1284
+ if (fromSlide) {
1285
+ setStyle(fromSlide, "transition", transitionValue);
1286
+ setStyle(fromSlide, "opacity", "0");
1287
+ setStyle(fromSlide, "z-index", String(this.options.zIndex - 2));
1288
+ }
1289
+ setStyle(toSlide, "transition", transitionValue);
1290
+ setStyle(toSlide, "opacity", "1");
1291
+ setStyle(toSlide, "z-index", String(this.options.zIndex - 1));
1292
+ const newHeight = getOuterHeight(toSlide);
1293
+ if (newHeight > 0 && this.state.slideTrack) {
1294
+ setStyle(this.state.slideTrack, "height", `${newHeight}px`);
1295
+ }
1296
+ window.setTimeout(() => {
1297
+ if (fromSlide) {
1298
+ setStyle(fromSlide, "transition", "");
1299
+ }
1300
+ setStyle(toSlide, "transition", "");
1301
+ if (callback)
1302
+ callback();
1303
+ }, this.options.speed);
1304
+ }
1305
+ /**
1306
+ * Position slides for fade mode (jQuery Slick parity)
1307
+ * Uses absolute positioning so all slides overlap at the same location
1308
+ */
1309
+ setFade() {
1310
+ if (!this.state.slideTrack)
1311
+ return;
1312
+ const slides = selectAll(".slick-slide", this.state.slideTrack);
1313
+ if (!slides.length)
1314
+ return;
1315
+ let maxHeight = 0;
1316
+ slides.forEach((slide) => {
1317
+ const slideHeight = getOuterHeight(slide);
1318
+ if (slideHeight > maxHeight) {
1319
+ maxHeight = slideHeight;
1320
+ }
1321
+ });
1322
+ if (maxHeight > 0) {
1323
+ setStyle(this.state.slideTrack, "height", `${maxHeight}px`);
1324
+ }
1325
+ slides.forEach((slide, index) => {
1326
+ setStyle(slide, "position", "absolute");
1327
+ setStyle(slide, "left", "0");
1328
+ setStyle(slide, "top", "0");
1329
+ setStyle(slide, "width", "100%");
1330
+ setStyle(slide, "opacity", "0");
1331
+ setStyle(slide, "z-index", String(this.options.zIndex - 2));
1332
+ setStyle(slide, "transition", "");
1333
+ });
1334
+ const currentIndex = Math.max(0, Math.min(this.state.currentSlide, slides.length - 1));
1335
+ if (slides[currentIndex]) {
1336
+ setStyle(slides[currentIndex], "opacity", "1");
1337
+ setStyle(slides[currentIndex], "z-index", String(this.options.zIndex - 1));
1338
+ }
1339
+ }
1340
+ /**
1341
+ * Set slide position
1342
+ */
1343
+ setPosition() {
1344
+ if (!this.state.slideList || !this.state.slideTrack)
1345
+ return;
1346
+ if (this.options.centerMode) {
1347
+ if (this.options.vertical) {
1348
+ setStyle(this.state.slideList, "padding", `${this.options.centerPadding} 0px`);
1349
+ } else {
1350
+ setStyle(this.state.slideList, "padding", `0px ${this.options.centerPadding}`);
1351
+ }
1352
+ } else {
1353
+ setStyle(this.state.slideList, "padding", "0px");
1354
+ }
1355
+ void this.state.slideList.offsetWidth;
1356
+ let listWidth = getInnerWidth(this.state.slideList) || getDimensions(this.state.slideList).width;
1357
+ if (!listWidth || listWidth <= 0) {
1358
+ const containerWidth = getDimensions(this.state.slideList).width;
1359
+ if (containerWidth && containerWidth > 0) {
1360
+ listWidth = containerWidth;
1361
+ } else {
1362
+ const parentWidth = this.element.offsetWidth || window.innerWidth;
1363
+ listWidth = parentWidth > 0 ? parentWidth : 300;
1364
+ }
1365
+ }
1366
+ this.state.listWidth = listWidth;
1367
+ if (this.options.fade) {
1368
+ this.state.slideWidth = listWidth;
1369
+ setStyle(this.state.slideTrack, "width", `${listWidth}px`);
1370
+ setStyle(this.state.slideTrack, "position", "relative");
1371
+ setStyle(this.state.slideTrack, "left", "0");
1372
+ setStyle(this.state.slideTrack, "top", "0");
1373
+ setStyle(this.state.slideTrack, "transform", "none");
1374
+ this.setFade();
1375
+ this.updateSlideVisibility();
1376
+ this.updateDots();
1377
+ this.updateArrows();
1378
+ this.updateNavigationVisibility();
1379
+ this.setHeight();
1380
+ return;
1381
+ }
1382
+ let trackWidth = 0;
1383
+ let targetLeft = 0;
1384
+ let slideOffset = 0;
1385
+ if (this.options.variableWidth) {
1386
+ const allSlidesInDOM = selectAll(".slick-slide", this.state.slideTrack);
1387
+ const totalSlideCount = allSlidesInDOM.length;
1388
+ trackWidth = 5e3 * totalSlideCount;
1389
+ setStyle(this.state.slideTrack, "width", `${trackWidth}px`);
1390
+ allSlidesInDOM.forEach((slide) => {
1391
+ if (slide.style.display === "none") {
1392
+ setStyle(slide, "display", "block");
1393
+ }
1394
+ });
1395
+ void this.state.slideTrack.offsetHeight;
1396
+ void this.state.slideTrack.getBoundingClientRect();
1397
+ allSlidesInDOM.forEach((slide) => void slide.offsetLeft);
1398
+ let slideIndex = this.state.currentSlide;
1399
+ const cloneOffset = this.options.infinite && this.state.slideCount > this.options.slidesToShow ? this.options.centerMode ? this.options.slidesToShow + 1 : this.options.slidesToShow : 0;
1400
+ slideIndex = this.state.currentSlide + cloneOffset;
1401
+ if (slideIndex < 0 || slideIndex >= allSlidesInDOM.length) {
1402
+ slideIndex = Math.max(0, Math.min(slideIndex, allSlidesInDOM.length - 1));
1403
+ }
1404
+ const targetSlide = allSlidesInDOM[slideIndex];
1405
+ if (targetSlide) {
1406
+ const slideOffsetLeft = targetSlide.offsetLeft || 0;
1407
+ if (this.options.rtl && !this.options.vertical) {
1408
+ const slideWidth = getOuterWidth(targetSlide);
1409
+ targetLeft = -(trackWidth - slideOffsetLeft - slideWidth);
1410
+ } else {
1411
+ targetLeft = -slideOffsetLeft;
1412
+ }
1413
+ if (this.options.centerMode) {
1414
+ const slideWidth = getOuterWidth(targetSlide);
1415
+ targetLeft += (listWidth - slideWidth) / 2;
1416
+ }
1417
+ }
1418
+ this.state.slideWidth = listWidth;
1419
+ } else {
1420
+ this.state.slideWidth = Math.ceil(listWidth / this.options.slidesToShow);
1421
+ const allSlidesInDOM = selectAll(".slick-slide", this.state.slideTrack);
1422
+ const slidesToStyle = allSlidesInDOM && allSlidesInDOM.length > 0 ? allSlidesInDOM : this.state.slides;
1423
+ const totalSlideCount = slidesToStyle.length;
1424
+ trackWidth = Math.ceil(this.state.slideWidth * totalSlideCount);
1425
+ setStyle(this.state.slideTrack, "width", `${trackWidth}px`);
1426
+ let offset = 0;
1427
+ const firstSlide = this.state.slides[0];
1428
+ if (firstSlide) {
1429
+ const styles = window.getComputedStyle(firstSlide);
1430
+ const marginLeft = parseFloat(styles.marginLeft) || 0;
1431
+ const marginRight = parseFloat(styles.marginRight) || 0;
1432
+ const paddingLeft = parseFloat(styles.paddingLeft) || 0;
1433
+ const paddingRight = parseFloat(styles.paddingRight) || 0;
1434
+ const borderLeft = parseFloat(styles.borderLeft) || 0;
1435
+ const borderRight = parseFloat(styles.borderRight) || 0;
1436
+ offset = marginLeft + marginRight + paddingLeft + paddingRight + borderLeft + borderRight;
1437
+ }
1438
+ const slideWidthToSet = Math.max(0, this.state.slideWidth - offset);
1439
+ slidesToStyle.forEach((slide) => {
1440
+ setStyle(slide, "width", `${slideWidthToSet}px`);
1441
+ });
1442
+ slideOffset = 0;
1443
+ if (this.options.infinite) {
1444
+ if (this.state.slideCount > this.options.slidesToShow) {
1445
+ slideOffset = this.state.slideWidth * this.options.slidesToShow * -1;
1446
+ }
1447
+ } else {
1448
+ if (this.state.currentSlide + this.options.slidesToShow > this.state.slideCount) {
1449
+ slideOffset = (this.state.currentSlide + this.options.slidesToShow - this.state.slideCount) * this.state.slideWidth;
1450
+ }
1451
+ }
1452
+ if (this.state.slideCount <= this.options.slidesToShow) {
1453
+ slideOffset = 0;
1454
+ }
1455
+ if (this.options.centerMode && this.state.slideCount <= this.options.slidesToShow) {
1456
+ slideOffset = this.state.slideWidth * Math.floor(this.options.slidesToShow) / 2 - this.state.slideWidth * this.state.slideCount / 2;
1457
+ } else if (this.options.centerMode && this.options.infinite) {
1458
+ slideOffset += this.state.slideWidth * Math.floor(this.options.slidesToShow / 2) - this.state.slideWidth;
1459
+ } else if (this.options.centerMode) {
1460
+ slideOffset = 0;
1461
+ slideOffset += this.state.slideWidth * Math.floor(this.options.slidesToShow / 2);
1462
+ }
1463
+ targetLeft = this.state.currentSlide * this.state.slideWidth * -1 + slideOffset;
1464
+ }
1465
+ setStyle(this.state.slideTrack, "width", `${trackWidth}px`);
1466
+ if (this.options.rtl && !this.options.vertical && !this.options.fade) {
1467
+ targetLeft = -targetLeft;
1468
+ }
1469
+ if (this.options.fade) {
1470
+ this.setFade();
1471
+ } else if (this.options.useTransform && this.state.transformsEnabled) {
1472
+ translate3d(this.state.slideTrack, targetLeft, 0, 0);
1473
+ } else {
1474
+ setStyle(this.state.slideTrack, "left", `${targetLeft}px`);
1475
+ }
1476
+ this.updateSlideVisibility();
1477
+ this.updateDots();
1478
+ this.updateArrows();
1479
+ this.updateNavigationVisibility();
1480
+ this.setHeight();
1481
+ }
1482
+ /**
1483
+ * Get total margin width (left + right) of a slide
1484
+ */
1485
+ getSlideMargins(slide) {
1486
+ const styles = window.getComputedStyle(slide);
1487
+ const marginLeft = parseFloat(styles.marginLeft) || 0;
1488
+ const marginRight = parseFloat(styles.marginRight) || 0;
1489
+ return marginLeft + marginRight;
1490
+ }
1491
+ /**
1492
+ * Update slide ARIA hidden states and active classes
1493
+ */
1494
+ updateSlideVisibility() {
1495
+ if (!this.state.slideTrack)
1496
+ return;
1497
+ const allSlides = selectAll(".slick-slide", this.state.slideTrack);
1498
+ if (this.options.fade) {
1499
+ allSlides.forEach((slide) => {
1500
+ removeClass(slide, "slick-active");
1501
+ removeClass(slide, "slick-current");
1502
+ removeClass(slide, "slick-center");
1503
+ });
1504
+ if (allSlides[this.state.currentSlide]) {
1505
+ addClass(allSlides[this.state.currentSlide], "slick-active");
1506
+ addClass(allSlides[this.state.currentSlide], "slick-current");
1507
+ }
1508
+ return;
1509
+ }
1510
+ allSlides.forEach((slide) => {
1511
+ removeClass(slide, "slick-active");
1512
+ removeClass(slide, "slick-current");
1513
+ removeClass(slide, "slick-center");
1514
+ setAttribute(slide, "aria-hidden", "true");
1515
+ });
1516
+ const hasClones = selectAll(".slick-cloned", this.state.slideTrack).length > 0;
1517
+ const offsetForClones = hasClones && this.options.infinite && this.state.slideCount > this.options.slidesToShow ? this.options.centerMode ? this.options.slidesToShow + 1 : this.options.slidesToShow : 0;
1518
+ const centerOffset = this.options.centerMode ? Math.floor(this.options.slidesToShow / 2) : 0;
1519
+ const visibleStart = offsetForClones + this.state.currentSlide - centerOffset;
1520
+ const visibleEnd = visibleStart + this.options.slidesToShow;
1521
+ const centerIndex = offsetForClones + this.state.currentSlide;
1522
+ allSlides.forEach((slide, index) => {
1523
+ if (index >= visibleStart && index < visibleEnd) {
1524
+ addClass(slide, "slick-active");
1525
+ removeAttribute(slide, "aria-hidden");
1526
+ }
1527
+ if (index === centerIndex) {
1528
+ addClass(slide, "slick-current");
1529
+ if (this.options.centerMode) {
1530
+ addClass(slide, "slick-center");
1531
+ }
1532
+ }
1533
+ });
1534
+ }
1535
+ /**
1536
+ * Update arrow disabled states
1537
+ */
1538
+ updateArrows() {
1539
+ if (!this.options.arrows)
1540
+ return;
1541
+ if (!this.state.prevArrowElement || !this.state.nextArrowElement)
1542
+ return;
1543
+ const maxIndex = Math.max(0, this.state.slideCount - this.options.slidesToShow);
1544
+ const disablePrev = !this.options.infinite && this.state.currentSlide === 0;
1545
+ const disableNext = !this.options.infinite && this.state.currentSlide >= maxIndex;
1546
+ if (disablePrev) {
1547
+ addClass(this.state.prevArrowElement, "slick-disabled");
1548
+ setAttribute(this.state.prevArrowElement, "disabled", "disabled");
1549
+ } else {
1550
+ removeClass(this.state.prevArrowElement, "slick-disabled");
1551
+ removeAttribute(this.state.prevArrowElement, "disabled");
1552
+ }
1553
+ if (disableNext) {
1554
+ addClass(this.state.nextArrowElement, "slick-disabled");
1555
+ setAttribute(this.state.nextArrowElement, "disabled", "disabled");
1556
+ } else {
1557
+ removeClass(this.state.nextArrowElement, "slick-disabled");
1558
+ removeAttribute(this.state.nextArrowElement, "disabled");
1559
+ }
1560
+ }
1561
+ /**
1562
+ * Update navigation visibility based on slide count
1563
+ * Hide arrows and dots if there aren't enough slides
1564
+ */
1565
+ updateNavigationVisibility() {
1566
+ const shouldShowNav = this.state.slideCount > this.options.slidesToShow;
1567
+ if (this.state.prevArrowElement) {
1568
+ if (shouldShowNav) {
1569
+ removeClass(this.state.prevArrowElement, "slick-hidden");
1570
+ removeAttribute(this.state.prevArrowElement, "aria-hidden");
1571
+ } else {
1572
+ addClass(this.state.prevArrowElement, "slick-hidden");
1573
+ setAttribute(this.state.prevArrowElement, "aria-hidden", "true");
1574
+ }
1575
+ }
1576
+ if (this.state.nextArrowElement) {
1577
+ if (shouldShowNav) {
1578
+ removeClass(this.state.nextArrowElement, "slick-hidden");
1579
+ removeAttribute(this.state.nextArrowElement, "aria-hidden");
1580
+ } else {
1581
+ addClass(this.state.nextArrowElement, "slick-hidden");
1582
+ setAttribute(this.state.nextArrowElement, "aria-hidden", "true");
1583
+ }
1584
+ }
1585
+ if (this.state.dots) {
1586
+ if (shouldShowNav) {
1587
+ removeClass(this.state.dots, "slick-hidden");
1588
+ removeAttribute(this.state.dots, "aria-hidden");
1589
+ } else {
1590
+ addClass(this.state.dots, "slick-hidden");
1591
+ setAttribute(this.state.dots, "aria-hidden", "true");
1592
+ }
1593
+ }
1594
+ }
1595
+ /**
1596
+ * Set list height to match current slide height (for adaptive height)
1597
+ */
1598
+ setHeight() {
1599
+ if (this.options.slidesToShow === 1 && this.options.adaptiveHeight === true && !this.options.vertical && this.state.slideList) {
1600
+ let slideIndex = this.state.currentSlide;
1601
+ if (this.options.infinite && slideIndex >= this.state.slideCount) {
1602
+ slideIndex = slideIndex % this.state.slideCount;
1603
+ } else if (this.options.infinite && slideIndex < 0) {
1604
+ slideIndex = this.state.slideCount + slideIndex % this.state.slideCount;
1605
+ }
1606
+ const currentSlide = this.state.slides[slideIndex];
1607
+ if (currentSlide) {
1608
+ const targetHeight = getOuterHeight(currentSlide);
1609
+ setStyle(this.state.slideList, "height", `${targetHeight}px`);
1610
+ }
1611
+ }
1612
+ }
1613
+ /**
1614
+ * Animate list height to match slide height when changing slides
1615
+ */
1616
+ animateHeight() {
1617
+ if (this.options.slidesToShow === 1 && this.options.adaptiveHeight === true && !this.options.vertical && this.state.slideList) {
1618
+ let slideIndex = this.state.currentSlide;
1619
+ if (this.options.infinite && slideIndex >= this.state.slideCount) {
1620
+ slideIndex = slideIndex % this.state.slideCount;
1621
+ } else if (this.options.infinite && slideIndex < 0) {
1622
+ slideIndex = this.state.slideCount + slideIndex % this.state.slideCount;
1623
+ }
1624
+ const currentSlide = this.state.slides[slideIndex];
1625
+ if (currentSlide) {
1626
+ const targetHeight = getOuterHeight(currentSlide);
1627
+ if (this.state.animating) {
1628
+ applyTransition(this.state.slideList, this.options.speed, this.options.cssEase);
1629
+ setStyle(this.state.slideList, "height", `${targetHeight}px`);
1630
+ window.setTimeout(() => {
1631
+ removeTransition(this.state.slideList);
1632
+ }, this.options.speed);
1633
+ } else {
1634
+ setStyle(this.state.slideList, "height", `${targetHeight}px`);
1635
+ }
1636
+ }
1637
+ }
1638
+ }
1639
+ /**
1640
+ * Handle previous arrow click
1641
+ */
1642
+ prevClick() {
1643
+ this.prev();
1644
+ }
1645
+ /**
1646
+ * Handle next arrow click
1647
+ */
1648
+ nextClick() {
1649
+ this.next();
1650
+ }
1651
+ /**
1652
+ * Handle dot click
1653
+ */
1654
+ dotClick(e) {
1655
+ const index = parseInt(getAttribute(e.currentTarget, "data-slide-index"));
1656
+ this.goTo(index);
1657
+ }
1658
+ /**
1659
+ * Start drag/swipe
1660
+ */
1661
+ startDrag(e) {
1662
+ const touch = e.type === "touchstart" ? e.touches[0] : e;
1663
+ this.state.touchObject = {
1664
+ startX: touch.pageX,
1665
+ startY: touch.pageY,
1666
+ curX: touch.pageX,
1667
+ curY: touch.pageY
1668
+ };
1669
+ this.state.dragging = true;
1670
+ this.state.touchStartTime = (/* @__PURE__ */ new Date()).getTime();
1671
+ if (e.type === "mousedown") {
1672
+ this.boundMethods.handleMouseMove = (e2) => this.trackDrag(e2);
1673
+ this.boundMethods.handleMouseUp = (e2) => this.endDrag(e2);
1674
+ document.addEventListener("mousemove", this.boundMethods.handleMouseMove);
1675
+ document.addEventListener("mouseup", this.boundMethods.handleMouseUp);
1676
+ }
1677
+ }
1678
+ /**
1679
+ * Track drag/swipe movement
1680
+ */
1681
+ trackDrag(e) {
1682
+ if (!this.state.dragging)
1683
+ return;
1684
+ const touch = e.type.indexOf("touch") !== -1 ? e.touches[0] : e;
1685
+ this.state.touchObject.curX = touch.pageX;
1686
+ this.state.touchObject.curY = touch.pageY;
1687
+ const swipeLength = Math.round(Math.sqrt(
1688
+ Math.pow(this.state.touchObject.curX - this.state.touchObject.startX, 2) + Math.pow(this.state.touchObject.curY - this.state.touchObject.startY, 2)
1689
+ ));
1690
+ if (swipeLength > this.options.touchThreshold) {
1691
+ this.state.swiping = true;
1692
+ const swipeAngle = Math.atan2(
1693
+ this.state.touchObject.curY - this.state.touchObject.startY,
1694
+ this.state.touchObject.curX - this.state.touchObject.startX
1695
+ ) * 180 / Math.PI;
1696
+ const horizontalSwipe = Math.abs(swipeAngle) < 45 || Math.abs(swipeAngle) > 135;
1697
+ const verticalSwipe = Math.abs(swipeAngle) >= 45 && Math.abs(swipeAngle) <= 135;
1698
+ if (this.options.vertical && verticalSwipe) {
1699
+ if (e.type === "touchmove" && this.options.touchMove) {
1700
+ e.preventDefault();
1701
+ }
1702
+ const swipeDistance = this.state.touchObject.curY - this.state.touchObject.startY;
1703
+ this.swipeHandler(swipeDistance);
1704
+ } else if (!this.options.vertical && horizontalSwipe) {
1705
+ if (e.type === "touchmove" && this.options.touchMove) {
1706
+ e.preventDefault();
1707
+ }
1708
+ const swipeDistance = this.state.touchObject.curX - this.state.touchObject.startX;
1709
+ this.swipeHandler(swipeDistance);
1710
+ }
1711
+ }
1712
+ }
1713
+ /**
1714
+ * End drag/swipe
1715
+ */
1716
+ endDrag(e) {
1717
+ if (!this.state.dragging)
1718
+ return;
1719
+ this.state.dragging = false;
1720
+ if (e.type === "mouseup") {
1721
+ document.removeEventListener("mousemove", this.boundMethods.handleMouseMove);
1722
+ document.removeEventListener("mouseup", this.boundMethods.handleMouseUp);
1723
+ }
1724
+ if (this.state.swiping) {
1725
+ this.state.swiping = false;
1726
+ const swipeTime = (/* @__PURE__ */ new Date()).getTime() - this.state.touchStartTime;
1727
+ const swipeDistance = this.options.vertical ? this.state.touchObject.curY - this.state.touchObject.startY : this.state.touchObject.curX - this.state.touchObject.startX;
1728
+ const referenceWidth = this.options.variableWidth ? this.state.listWidth : this.state.slideWidth;
1729
+ const minSwipe = referenceWidth / (this.options.touchThreshold || 5);
1730
+ if (Math.abs(swipeDistance) > minSwipe) {
1731
+ if (swipeDistance > 0) {
1732
+ this.prev();
1733
+ } else {
1734
+ this.next();
1735
+ }
1736
+ } else {
1737
+ this.setPosition();
1738
+ }
1739
+ }
1740
+ this.state.touchObject = {};
1741
+ }
1742
+ /**
1743
+ * Handle swipe movement
1744
+ */
1745
+ swipeHandler(swipeDistance) {
1746
+ if (this.options.variableWidth)
1747
+ return;
1748
+ const currentLeft = this.state.currentSlide * -this.state.slideWidth;
1749
+ const targetLeft = currentLeft + swipeDistance;
1750
+ let adjustedDistance = swipeDistance;
1751
+ if (!this.options.infinite) {
1752
+ const maxLeft = 0;
1753
+ const minLeft = -(this.state.slideCount - this.options.slidesToShow) * this.state.slideWidth;
1754
+ if (targetLeft > maxLeft) {
1755
+ adjustedDistance = swipeDistance * this.options.edgeFriction;
1756
+ } else if (targetLeft < minLeft) {
1757
+ adjustedDistance = swipeDistance * this.options.edgeFriction;
1758
+ }
1759
+ }
1760
+ const newLeft = currentLeft + adjustedDistance;
1761
+ translate3d(this.state.slideTrack, newLeft, 0, 0);
1762
+ }
1763
+ /**
1764
+ * Handle keyboard navigation
1765
+ */
1766
+ handleKeydown(e) {
1767
+ }
1768
+ /**
1769
+ * Handle focus
1770
+ */
1771
+ handleFocus() {
1772
+ this.state.focussed = true;
1773
+ if (this.options.pauseOnFocus && this.options.autoplay) {
1774
+ this.pause();
1775
+ }
1776
+ }
1777
+ /**
1778
+ * Handle blur
1779
+ */
1780
+ handleBlur() {
1781
+ this.state.focussed = false;
1782
+ if (this.options.autoplay && !this.state.paused) {
1783
+ this.play();
1784
+ }
1785
+ }
1786
+ /**
1787
+ * Handle visibility change (tab switch)
1788
+ */
1789
+ handleVisibilityChange() {
1790
+ if (document.hidden) {
1791
+ this.state.interrupted = true;
1792
+ if (this.options.autoplay) {
1793
+ this.autoPlayClear();
1794
+ }
1795
+ } else {
1796
+ this.state.interrupted = false;
1797
+ if (this.options.autoplay && !this.state.paused) {
1798
+ this.autoPlay();
1799
+ }
1800
+ }
1801
+ }
1802
+ /**
1803
+ * Start autoplay
1804
+ */
1805
+ autoPlay() {
1806
+ this.state.paused = false;
1807
+ this.state.autoPlayTimer = setInterval(() => {
1808
+ if (!this.state.paused && !this.state.interrupted && !this.state.focussed) {
1809
+ this.next();
1810
+ }
1811
+ }, this.options.autoplaySpeed);
1812
+ }
1813
+ /**
1814
+ * Clear autoplay timer
1815
+ */
1816
+ autoPlayClear() {
1817
+ if (this.state.autoPlayTimer) {
1818
+ clearInterval(this.state.autoPlayTimer);
1819
+ this.state.autoPlayTimer = null;
1820
+ }
1821
+ }
1822
+ /**
1823
+ * Handle autoplay button toggle
1824
+ */
1825
+ autoPlayToggleHandler() {
1826
+ if (this.state.paused) {
1827
+ this.play();
1828
+ } else {
1829
+ this.pause();
1830
+ }
1831
+ }
1832
+ /**
1833
+ * Check responsive breakpoints
1834
+ */
1835
+ checkResponsive(initial = false) {
1836
+ if (!this.options.responsive || !Array.isArray(this.options.responsive)) {
1837
+ return;
1838
+ }
1839
+ const windowWidth = getWindowDimensions().width;
1840
+ let targetBreakpoint = null;
1841
+ let targetSettings = null;
1842
+ let respondToWidth = windowWidth;
1843
+ if (this.options.respondTo === "window") {
1844
+ respondToWidth = windowWidth;
1845
+ } else if (this.options.respondTo === "slider") {
1846
+ respondToWidth = getDimensions(this.element).width;
1847
+ } else if (this.options.respondTo === "min") {
1848
+ respondToWidth = Math.min(windowWidth, getDimensions(this.element).width);
1849
+ }
1850
+ this.originalOptions.responsive.forEach((breakpoint) => {
1851
+ if (breakpoint.breakpoint) {
1852
+ if (this.originalOptions.mobileFirst) {
1853
+ if (respondToWidth >= breakpoint.breakpoint) {
1854
+ targetBreakpoint = breakpoint.breakpoint;
1855
+ targetSettings = breakpoint.settings;
1856
+ }
1857
+ } else {
1858
+ if (respondToWidth < breakpoint.breakpoint) {
1859
+ if (targetBreakpoint === null || breakpoint.breakpoint < targetBreakpoint) {
1860
+ targetBreakpoint = breakpoint.breakpoint;
1861
+ targetSettings = breakpoint.settings;
1862
+ }
1863
+ }
1864
+ }
1865
+ }
1866
+ });
1867
+ if (targetSettings) {
1868
+ if (targetSettings === "unslick") {
1869
+ this.unslick();
1870
+ } else {
1871
+ const optionsChanged = this.state.activeBreakpoint !== targetBreakpoint;
1872
+ if (optionsChanged) {
1873
+ this.state.activeBreakpoint = targetBreakpoint;
1874
+ const currentSlide = this.state.currentSlide;
1875
+ const newOptions = extend({}, this.originalOptions, targetSettings);
1876
+ this.options = newOptions;
1877
+ this.refresh();
1878
+ if (currentSlide < this.state.slideCount) {
1879
+ this.state.currentSlide = currentSlide;
1880
+ this.setPosition();
1881
+ }
1882
+ this.emit("breakpoint", { breakpoint: targetBreakpoint });
1883
+ }
1884
+ }
1885
+ } else if (this.state.activeBreakpoint !== null) {
1886
+ this.state.activeBreakpoint = null;
1887
+ const currentSlide = this.state.currentSlide;
1888
+ this.options = extend({}, this.originalOptions);
1889
+ this.refresh();
1890
+ if (currentSlide < this.state.slideCount) {
1891
+ this.state.currentSlide = currentSlide;
1892
+ this.setPosition();
1893
+ }
1894
+ this.emit("breakpoint", { breakpoint: null });
1895
+ }
1896
+ }
1897
+ /**
1898
+ * Refresh slider without destroying/recreating
1899
+ */
1900
+ refresh() {
1901
+ if (this.state.dots) {
1902
+ remove(this.state.dots);
1903
+ this.state.dots = null;
1904
+ removeClass(this.element, "slick-dotted");
1905
+ }
1906
+ if (this.options.dots) {
1907
+ this.buildDots();
1908
+ }
1909
+ if (this.options.arrows && (!this.state.prevArrowElement || !this.state.nextArrowElement)) {
1910
+ this.buildArrows();
1911
+ } else if (!this.options.arrows) {
1912
+ if (this.state.prevArrowElement) {
1913
+ remove(this.state.prevArrowElement);
1914
+ this.state.prevArrowElement = null;
1915
+ }
1916
+ if (this.state.nextArrowElement) {
1917
+ remove(this.state.nextArrowElement);
1918
+ this.state.nextArrowElement = null;
1919
+ }
1920
+ }
1921
+ this.setPosition();
1922
+ }
1923
+ /**
1924
+ * Reinitialize slider after slides have been added/removed
1925
+ */
1926
+ reinit() {
1927
+ const allSlides = getChildren(this.state.slideTrack);
1928
+ this.state.slides = allSlides.filter((slide) => !hasClass(slide, "slick-cloned"));
1929
+ this.state.slideCount = this.state.slides.length;
1930
+ if (this.state.currentSlide >= this.state.slideCount && this.state.currentSlide !== 0) {
1931
+ this.state.currentSlide = this.state.currentSlide - this.options.slidesToScroll;
1932
+ }
1933
+ if (this.state.slideCount <= this.options.slidesToShow) {
1934
+ this.state.currentSlide = 0;
1935
+ }
1936
+ this.state.slides.forEach((slide, index) => {
1937
+ addClass(slide, "slick-slide");
1938
+ setAttribute(slide, "data-slick-index", index);
1939
+ });
1940
+ if (this.options.infinite) {
1941
+ this.setupInfinite();
1942
+ }
1943
+ if (this.options.arrows && this.state.slideCount > this.options.slidesToShow) {
1944
+ if (!this.state.prevArrowElement) {
1945
+ this.buildArrows();
1946
+ }
1947
+ }
1948
+ if (this.options.dots && this.state.slideCount > this.options.slidesToShow) {
1949
+ if (!this.state.dots) {
1950
+ this.buildDots();
1951
+ } else {
1952
+ const dotCount = Math.ceil(this.state.slideCount / this.options.slidesToScroll);
1953
+ const dotContainer = this.state.dots;
1954
+ empty(dotContainer);
1955
+ for (let i = 0; i < dotCount; i++) {
1956
+ const dot = document.createElement("li");
1957
+ const button = document.createElement("button");
1958
+ const icon = document.createElement("span");
1959
+ addClass(icon, "slick-dot-icon");
1960
+ setAttribute(button, "aria-label", `Go to slide ${i + 1}`);
1961
+ setAttribute(button, "data-slide-index", i);
1962
+ if (i === 0)
1963
+ addClass(dot, "slick-active");
1964
+ button.addEventListener("click", (e) => this.dotClick(e));
1965
+ appendChild(button, icon);
1966
+ appendChild(dot, button);
1967
+ appendChild(dotContainer, dot);
1968
+ }
1969
+ }
1970
+ }
1971
+ this.setPosition();
1972
+ this.updateSlideVisibility();
1973
+ this.updateNavigationVisibility();
1974
+ this.emit("reInit");
1975
+ }
1976
+ /**
1977
+ * Unload cloned slides (used by addSlide/removeSlide)
1978
+ */
1979
+ unloadClones() {
1980
+ const clones = selectAll(".slick-cloned", this.state.slideTrack);
1981
+ clones.forEach((clone2) => remove(clone2));
1982
+ }
1983
+ /**
1984
+ * Unload slider elements
1985
+ */
1986
+ unload() {
1987
+ if (this.boundMethods.handleResize) {
1988
+ window.removeEventListener("resize", this.boundMethods.handleResize);
1989
+ }
1990
+ if (this.boundMethods.handleVisibilityChange) {
1991
+ document.removeEventListener("visibilitychange", this.boundMethods.handleVisibilityChange);
1992
+ }
1993
+ if (this.boundMethods.handleKeydown) {
1994
+ this.element.removeEventListener("keydown", this.boundMethods.handleKeydown);
1995
+ }
1996
+ if (this.boundMethods.handleMouseDown && this.state.slideList) {
1997
+ this.state.slideList.removeEventListener("mousedown", this.boundMethods.handleMouseDown);
1998
+ }
1999
+ if (this.boundMethods.handleTouchStart && this.state.slideList) {
2000
+ this.state.slideList.removeEventListener("touchstart", this.boundMethods.handleTouchStart);
2001
+ this.state.slideList.removeEventListener("touchend", this.boundMethods.handleTouchEnd);
2002
+ this.state.slideList.removeEventListener("touchmove", this.boundMethods.handleTouchMove);
2003
+ }
2004
+ if (this.boundMethods.handleFocus) {
2005
+ this.element.removeEventListener("focusin", this.boundMethods.handleFocus, true);
2006
+ }
2007
+ if (this.boundMethods.handleBlur) {
2008
+ this.element.removeEventListener("focusout", this.boundMethods.handleBlur, true);
2009
+ }
2010
+ if (this.boundMethods.handleSlideClick && this.state.slideTrack) {
2011
+ this.state.slideTrack.removeEventListener("click", this.boundMethods.handleSlideClick);
2012
+ }
2013
+ if (this.state.autoPlayTimer) {
2014
+ clearInterval(this.state.autoPlayTimer);
2015
+ this.state.autoPlayTimer = null;
2016
+ }
2017
+ if (this.state.prevArrowElement && this.state.prevArrowElement.parentNode) {
2018
+ remove(this.state.prevArrowElement);
2019
+ this.state.prevArrowElement = null;
2020
+ }
2021
+ if (this.state.nextArrowElement && this.state.nextArrowElement.parentNode) {
2022
+ remove(this.state.nextArrowElement);
2023
+ this.state.nextArrowElement = null;
2024
+ }
2025
+ if (this.state.dots && this.state.dots.parentNode) {
2026
+ remove(this.state.dots);
2027
+ this.state.dots = null;
2028
+ }
2029
+ if (this.state.pauseButton && this.state.pauseButton.parentNode) {
2030
+ remove(this.state.pauseButton);
2031
+ this.state.pauseButton = null;
2032
+ }
2033
+ if (this.state.slideTrack && this.state.slideTrack.parentNode) {
2034
+ const slides = getChildren(this.state.slideTrack);
2035
+ slides.forEach((slide) => {
2036
+ appendChild(this.state.slideList, slide);
2037
+ });
2038
+ remove(this.state.slideTrack);
2039
+ this.state.slideTrack = null;
2040
+ }
2041
+ }
2042
+ /**
2043
+ * On event - register listener
2044
+ */
2045
+ on(event, callback, context = null) {
2046
+ this.dispatcher.on(event, callback, context);
2047
+ return this;
2048
+ }
2049
+ /**
2050
+ * Once event - register one-time listener
2051
+ */
2052
+ once(event, callback, context = null) {
2053
+ this.dispatcher.once(event, callback, context);
2054
+ return this;
2055
+ }
2056
+ /**
2057
+ * Off event - remove listener
2058
+ */
2059
+ off(event, callback = null) {
2060
+ this.dispatcher.off(event, callback);
2061
+ return this;
2062
+ }
2063
+ /**
2064
+ * Emit custom event
2065
+ */
2066
+ emit(event, data = null) {
2067
+ this.dispatcher.emit(event, data);
2068
+ try {
2069
+ const customEvent = new CustomEvent(`slick:${event}`, {
2070
+ detail: data,
2071
+ bubbles: true,
2072
+ cancelable: true
2073
+ });
2074
+ this.element.dispatchEvent(customEvent);
2075
+ } catch (e) {
2076
+ try {
2077
+ const evt = document.createEvent("CustomEvent");
2078
+ evt.initCustomEvent(`slick:${event}`, true, true, data);
2079
+ this.element.dispatchEvent(evt);
2080
+ } catch (err) {
2081
+ console.warn("CustomEvent not supported");
2082
+ }
2083
+ }
2084
+ return this;
2085
+ }
2086
+ };
2087
+ var SlickSlider_default = SlickSlider;
2088
+
2089
+ // slick/src/index.js
2090
+ function Slick(element, options = {}) {
2091
+ if (Array.isArray(element)) {
2092
+ return element.map((el) => new SlickSlider_default(el, options));
2093
+ }
2094
+ return new SlickSlider_default(element, options);
2095
+ }
2096
+ Slick.auto = function(selector, options = {}) {
2097
+ const elements = document.querySelectorAll(selector);
2098
+ return Array.from(elements).map((el) => new SlickSlider_default(el, options));
2099
+ };
2100
+ Slick.version = "2.0.0";
2101
+ if (typeof window !== "undefined") {
2102
+ window.Slick = Slick;
2103
+ window.SlickSlider = SlickSlider_default;
2104
+ window.slickModule = {
2105
+ Slick,
2106
+ SlickSlider: SlickSlider_default,
2107
+ default: Slick
2108
+ };
2109
+ }