{
+ if (this.swiper.activeIndex === i + 1) {
+ this.swiper.slidePrev();
+ } else if (this.swiper.activeIndex === i - 1) {
+ this.swiper.slideNext();
+ }
+ }}
+ class="swiper-slide swiper-slide-${i}"
+ data-history=${i}
+ >
+
+ ${c.template}
+
+
+ `,
+ )}
+
+
+
+
+
+
+
+
+
this.onBackSpace()([cards, options])}
+ >
+ BACK
+
+ `;
+ }}
+ >
+
+ `;
+ },
+})
+export class GenericModal extends LitElement {
+ @Injector(MODAL_DIALOG_DATA)
+ private data: {
+ cards: BehaviorSubject;
+ options: BehaviorSubject;
+ };
+
+ @Inject(ModalService)
+ private modalService: ModalService;
+
+ @Inject(HotKeysService)
+ private hotkeys: HotKeysService;
+
+ @Inject(ResponsiveService)
+ private responsive: ResponsiveService;
+
+ @Router()
+ private router: Router;
+
+ @Inject(GenericAppsService)
+ private genericAppsService: GenericAppsService;
+
+ private swiper: Swiper;
+
+ private rendered: boolean;
+
+ private leftKey = this.hotkeys.bind('left');
+ private rightKey = this.hotkeys.bind('right');
+ private enterKey = this.hotkeys.bind('enter');
+ private backKey = this.hotkeys.bind('backspace');
+
+ private goToPage(index: number): Reader<[Card[], MenuOptions], void> {
+ return ([cards, options]) => {
+ const card = cards[index];
+ if (card.path) {
+ const slideOutUpOptions = options.animations?.speed?.slideOutUp;
+ if (options.disableAnimations) {
+ this.router.go(card.path);
+ } else {
+ animateElement(
+ this.swiper.slides[index],
+ 'slideOutUp',
+ `duration-${slideOutUpOptions ? slideOutUpOptions : 200}`,
+ ).subscribe(() => this.router.go(card.path));
+ }
+ }
+ };
+ }
+
+ private onBackSpace(): Reader<[Card[], MenuOptions], Promise> {
+ return async ([cards, options]) => {
+ const card = cards[this.swiper.activeIndex];
+ if (card.backPath) {
+ const zoomOutOptions = options.animations?.speed?.zoomOut;
+ await Promise.all(
+ [...(Array.from(this.swiper.slides) as HTMLElement[])].map(
+ (e) =>
+ !options.disableAnimations &&
+ animateElement(
+ e,
+ 'zoomOut',
+ `duration-${zoomOutOptions ? zoomOutOptions : 200}`,
+ ).toPromise(),
+ ),
+ );
+ this.router.go(card.backPath);
+ this.genericAppsService.popTrace();
+ }
+ };
+ }
+
+ private initSwiper(dom: {
+ pagination: HTMLElement;
+ prev: HTMLElement;
+ next: HTMLElement;
+ container: HTMLElement;
+ }): Reader {
+ return (options) => {
+ return new Swiper(
+ dom.container,
+ Object.assign(
+ {
+ slidesPerView: 3,
+ coverflowEffect: {
+ rotate: 50,
+ stretch: 50,
+ depth: 100,
+ modifier: 1,
+ slideShadows: false,
+ },
+ effect: 'coverflow' as never,
+ breakpoints: {
+ 640: {
+ slidesPerView: 1,
+ },
+ 768: {
+ slidesPerView: 2,
+ },
+ 1024: {
+ slidesPerView: 3,
+ },
+ },
+ centeredSlides: true,
+ spaceBetween: 30,
+ pagination: {
+ el: dom.pagination,
+ type: 'fraction',
+ },
+ navigation: {
+ nextEl: dom.next,
+ prevEl: dom.prev,
+ },
+ },
+ options ? options.swiper : {},
+ ),
+ );
+ };
+ }
+
+ private setShadowToActivePage() {
+ const activeSlideElement = this.swiper.slides[this.swiper.activeIndex];
+ [...Array.from(this.swiper.slides)].map((slide) =>
+ slide.classList.remove('filter'),
+ );
+
+ activeSlideElement.classList.add('filter');
+ }
+}
diff --git a/src/action-control/generic-apps.service.ts b/src/action-control/generic-apps.service.ts
new file mode 100644
index 0000000..2d9c638
--- /dev/null
+++ b/src/action-control/generic-apps.service.ts
@@ -0,0 +1,61 @@
+import { Injectable } from '@rxdi/core';
+import { BehaviorSubject, fromEvent } from 'rxjs';
+import { filter } from 'rxjs/operators';
+
+export interface Trace {
+ activeIndex: number;
+ path: string;
+}
+@Injectable()
+export class GenericAppsService {
+ trace: BehaviorSubject = new BehaviorSubject([]);
+
+ OnInit() {
+ const cache = localStorage.getItem('trace');
+ if (cache) {
+ this.trace.next(JSON.parse(cache));
+ }
+ }
+
+ listenForEscapeKey() {
+ return fromEvent(document, 'keyup').pipe(
+ filter((e) => e['key'] === 'Escape'),
+ );
+ }
+
+ addTrace(trace: Trace) {
+ let traces = this.trace.getValue();
+ const traceExists = traces.find((t) => t.path === trace.path);
+ if (traceExists) {
+ if (traceExists.activeIndex !== trace.activeIndex) {
+ traces = traces.filter((t) => t.path !== trace.path);
+ } else {
+ return;
+ }
+ }
+ traces.push(trace);
+ this.trace.next(traces);
+ localStorage.setItem('trace', JSON.stringify(this.trace.getValue()));
+ }
+
+ popTrace() {
+ const traces = this.trace.getValue();
+ traces.pop();
+ this.trace.next(traces);
+ localStorage.setItem('trace', JSON.stringify(this.trace.getValue()));
+ }
+
+ clearTraces() {
+ this.trace.next([]);
+ localStorage.removeItem('trace');
+ }
+
+ getLastTrace() {
+ const traces = this.trace.getValue();
+ return traces[traces.length - 1];
+ }
+
+ traceAsObservable() {
+ return this.trace.asObservable();
+ }
+}
diff --git a/src/action-control/generic-menu.ts b/src/action-control/generic-menu.ts
new file mode 100644
index 0000000..c024906
--- /dev/null
+++ b/src/action-control/generic-menu.ts
@@ -0,0 +1,94 @@
+import { Inject } from '@rxdi/core';
+import { css, LitElement, TemplateResult } from '@rxdi/lit-html';
+import { ModalService } from '../modal';
+import { BehaviorSubject } from 'rxjs';
+
+import { Card, GenericModal } from './generic-apps.modal';
+import { MenuOptions } from './menu.interface';
+
+export class GenericMenuComponent extends LitElement {
+ @Inject(ModalService)
+ private modalProvider: ModalService;
+
+ constructor(
+ private template: TemplateResult,
+ public cards: BehaviorSubject = new BehaviorSubject([]),
+ private options: BehaviorSubject> = new BehaviorSubject(
+ {},
+ ),
+ ) {
+ super();
+ }
+
+ render() {
+ if (this.template) {
+ return this.template;
+ }
+ throw new Error('Please specifiy generic template');
+ }
+
+ OnInit() {
+ this.openDialog().subscribe();
+ }
+
+ private openDialog() {
+ return this.modalProvider.openComponent(
+ GenericModal,
+ {
+ cards: this.cards,
+ options: this.options,
+ },
+ {
+ backdropClose: true,
+ style: css`
+ .wrapper {
+ position: fixed;
+ top: 0;
+ left: 0;
+ align-items: center;
+ justify-content: center;
+ pointer-events: none;
+ width: 100%;
+ height: 100%;
+ z-index: 1000;
+ }
+
+ @keyframes scale {
+ from {
+ transform: scale(0.4);
+ }
+ to {
+ transform: scale(1);
+ }
+ }
+
+ @keyframes blur {
+ to {
+ backdrop-filter: blur(20px);
+ }
+ }
+
+ .backdrop {
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ position: absolute;
+ pointer-events: all;
+ z-index: 10;
+ backdrop-filter: blur(25px);
+ /* animation: blur 1s linear forwards; */
+ }
+
+ .content {
+ z-index: 20;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ pointer-events: all;
+ }
+ `,
+ },
+ );
+ }
+}
diff --git a/src/action-control/index.ts b/src/action-control/index.ts
new file mode 100644
index 0000000..ffeb14d
--- /dev/null
+++ b/src/action-control/index.ts
@@ -0,0 +1,4 @@
+export * from './modal';
+export * from './decorators/view';
+export * from './apps.service';
+export * from './generic-apps.service';
diff --git a/src/action-control/menu.interface.ts b/src/action-control/menu.interface.ts
new file mode 100644
index 0000000..9416675
--- /dev/null
+++ b/src/action-control/menu.interface.ts
@@ -0,0 +1,9 @@
+import { SwiperOptions } from './swiper/swiper.min';
+
+export interface MenuOptions {
+ disableAnimations: boolean;
+ animations: {
+ speed: { zoomOut: number; slideOutUp: number; zoomIn: number };
+ };
+ swiper: Partial;
+}
diff --git a/src/action-control/modal.ts b/src/action-control/modal.ts
new file mode 100644
index 0000000..ffa9b32
--- /dev/null
+++ b/src/action-control/modal.ts
@@ -0,0 +1,32 @@
+import { Inject } from '@rxdi/core';
+import { html } from '@rxdi/lit-html';
+import { Card } from './generic-apps.modal';
+import { GenericMenuComponent } from './generic-menu';
+import { BehaviorSubject } from 'rxjs';
+
+import { AppsService } from './apps.service';
+import { SwiperOptions } from './swiper/swiper.min';
+
+export interface MenuOptions {
+ disableAnimations: boolean;
+ animations: {
+ speed: { zoomOut: number; slideOutUp: number; zoomIn: number };
+ };
+ swiper: Partial;
+}
+
+export class AppsModalComponent extends GenericMenuComponent {
+ @Inject(AppsService)
+ private static appsService: AppsService;
+
+ constructor(
+ cards?: BehaviorSubject,
+ options?: BehaviorSubject
+ ) {
+ super(
+ html``,
+ cards,
+ options || AppsModalComponent.appsService.options
+ );
+ }
+}
diff --git a/src/action-control/swiper/swiper.css.ts b/src/action-control/swiper/swiper.css.ts
new file mode 100644
index 0000000..423d496
--- /dev/null
+++ b/src/action-control/swiper/swiper.css.ts
@@ -0,0 +1,715 @@
+import { css } from '@rxdi/lit-html';
+
+export const SwiperCss = css`
+ /**
+ * Swiper 4.5.3
+ * Most modern mobile touch slider and framework with hardware accelerated transitions
+ * http://www.idangero.us/swiper/
+ *
+ * Copyright 2014-2019 Vladimir Kharlampidi
+ *
+ * Released under the MIT License
+ *
+ * Released on: October 16, 2019
+ */
+ .swiper-container {
+ margin-left: auto;
+ margin-right: auto;
+ position: relative;
+ overflow: hidden;
+ list-style: none;
+ padding: 0;
+ /* Fix of Webkit flickering */
+ z-index: 1;
+ }
+ .swiper-container-no-flexbox .swiper-slide {
+ float: left;
+ }
+ .swiper-container-vertical > .swiper-wrapper {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ }
+ .swiper-wrapper {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ z-index: 1;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-transition-property: -webkit-transform;
+ transition-property: -webkit-transform;
+ -o-transition-property: transform;
+ transition-property: transform;
+ transition-property: transform, -webkit-transform;
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+ }
+ .swiper-container-android .swiper-slide,
+ .swiper-wrapper {
+ -webkit-transform: translate3d(0px, 0, 0);
+ transform: translate3d(0px, 0, 0);
+ }
+ .swiper-container-multirow > .swiper-wrapper {
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ }
+ .swiper-container-free-mode > .swiper-wrapper {
+ -webkit-transition-timing-function: ease-out;
+ -o-transition-timing-function: ease-out;
+ transition-timing-function: ease-out;
+ margin: 0 auto;
+ }
+ .swiper-slide {
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ width: 100%;
+ height: 100%;
+ position: relative;
+ -webkit-transition-property: -webkit-transform;
+ transition-property: -webkit-transform;
+ -o-transition-property: transform;
+ transition-property: transform;
+ transition-property: transform, -webkit-transform;
+ }
+ .swiper-slide-invisible-blank {
+ visibility: hidden;
+ }
+ /* Auto Height */
+ .swiper-container-autoheight,
+ .swiper-container-autoheight .swiper-slide {
+ height: auto;
+ }
+ .swiper-container-autoheight .swiper-wrapper {
+ -webkit-box-align: start;
+ -webkit-align-items: flex-start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ -webkit-transition-property: height, -webkit-transform;
+ transition-property: height, -webkit-transform;
+ -o-transition-property: transform, height;
+ transition-property: transform, height;
+ transition-property: transform, height, -webkit-transform;
+ }
+ /* 3D Effects */
+ .swiper-container-3d {
+ -webkit-perspective: 1200px;
+ perspective: 1200px;
+ }
+ .swiper-container-3d .swiper-wrapper,
+ .swiper-container-3d .swiper-slide,
+ .swiper-container-3d .swiper-slide-shadow-left,
+ .swiper-container-3d .swiper-slide-shadow-right,
+ .swiper-container-3d .swiper-slide-shadow-top,
+ .swiper-container-3d .swiper-slide-shadow-bottom,
+ .swiper-container-3d .swiper-cube-shadow {
+ -webkit-transform-style: preserve-3d;
+ transform-style: preserve-3d;
+ }
+ .swiper-container-3d .swiper-slide-shadow-left,
+ .swiper-container-3d .swiper-slide-shadow-right,
+ .swiper-container-3d .swiper-slide-shadow-top,
+ .swiper-container-3d .swiper-slide-shadow-bottom {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ z-index: 10;
+ }
+ .swiper-container-3d .swiper-slide-shadow-left {
+ background-image: -webkit-gradient(
+ linear,
+ right top,
+ left top,
+ from(rgba(0, 0, 0, 0.5)),
+ to(rgba(0, 0, 0, 0))
+ );
+ background-image: -webkit-linear-gradient(
+ right,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ background-image: -o-linear-gradient(
+ right,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ background-image: linear-gradient(
+ to left,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ }
+ .swiper-container-3d .swiper-slide-shadow-right {
+ background-image: -webkit-gradient(
+ linear,
+ left top,
+ right top,
+ from(rgba(0, 0, 0, 0.5)),
+ to(rgba(0, 0, 0, 0))
+ );
+ background-image: -webkit-linear-gradient(
+ left,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ background-image: -o-linear-gradient(
+ left,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ background-image: linear-gradient(
+ to right,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ }
+ .swiper-container-3d .swiper-slide-shadow-top {
+ background-image: -webkit-gradient(
+ linear,
+ left bottom,
+ left top,
+ from(rgba(0, 0, 0, 0.5)),
+ to(rgba(0, 0, 0, 0))
+ );
+ background-image: -webkit-linear-gradient(
+ bottom,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ background-image: -o-linear-gradient(
+ bottom,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ background-image: linear-gradient(
+ to top,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ }
+ .swiper-container-3d .swiper-slide-shadow-bottom {
+ background-image: -webkit-gradient(
+ linear,
+ left top,
+ left bottom,
+ from(rgba(0, 0, 0, 0.5)),
+ to(rgba(0, 0, 0, 0))
+ );
+ background-image: -webkit-linear-gradient(
+ top,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ background-image: -o-linear-gradient(
+ top,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ background-image: linear-gradient(
+ to bottom,
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0)
+ );
+ }
+ /* IE10 Windows Phone 8 Fixes */
+ .swiper-container-wp8-horizontal,
+ .swiper-container-wp8-horizontal > .swiper-wrapper {
+ -ms-touch-action: pan-y;
+ touch-action: pan-y;
+ }
+ .swiper-container-wp8-vertical,
+ .swiper-container-wp8-vertical > .swiper-wrapper {
+ -ms-touch-action: pan-x;
+ touch-action: pan-x;
+ }
+ .swiper-button-prev,
+ .swiper-button-next {
+ position: absolute;
+ top: 50%;
+ width: 27px;
+ height: 44px;
+ margin-top: -22px;
+ z-index: 10;
+ cursor: pointer;
+ background-size: 27px 44px;
+ background-position: center;
+ background-repeat: no-repeat;
+ }
+ .swiper-button-prev.swiper-button-disabled,
+ .swiper-button-next.swiper-button-disabled {
+ opacity: 0.35;
+ cursor: auto;
+ pointer-events: none;
+ }
+ .swiper-button-prev,
+ .swiper-container-rtl .swiper-button-next {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");
+ left: 10px;
+ right: auto;
+ }
+ .swiper-button-next,
+ .swiper-container-rtl .swiper-button-prev {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");
+ right: 10px;
+ left: auto;
+ }
+ .swiper-button-prev.swiper-button-white,
+ .swiper-container-rtl .swiper-button-next.swiper-button-white {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E");
+ }
+ .swiper-button-next.swiper-button-white,
+ .swiper-container-rtl .swiper-button-prev.swiper-button-white {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E");
+ }
+ .swiper-button-prev.swiper-button-black,
+ .swiper-container-rtl .swiper-button-next.swiper-button-black {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E");
+ }
+ .swiper-button-next.swiper-button-black,
+ .swiper-container-rtl .swiper-button-prev.swiper-button-black {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E");
+ }
+ .swiper-button-lock {
+ display: none;
+ }
+ .swiper-pagination {
+ position: absolute;
+ text-align: center;
+ -webkit-transition: 300ms opacity;
+ -o-transition: 300ms opacity;
+ transition: 300ms opacity;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ z-index: 10;
+ }
+ .swiper-pagination.swiper-pagination-hidden {
+ opacity: 0;
+ }
+ /* Common Styles */
+ .swiper-pagination-fraction,
+ .swiper-pagination-custom,
+ .swiper-container-horizontal > .swiper-pagination-bullets {
+ bottom: 10px;
+ left: 0;
+ width: 100%;
+ }
+ /* Bullets */
+ .swiper-pagination-bullets-dynamic {
+ overflow: hidden;
+ font-size: 0;
+ }
+ .swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
+ -webkit-transform: scale(0.33);
+ -ms-transform: scale(0.33);
+ transform: scale(0.33);
+ position: relative;
+ }
+ .swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active {
+ -webkit-transform: scale(1);
+ -ms-transform: scale(1);
+ transform: scale(1);
+ }
+ .swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main {
+ -webkit-transform: scale(1);
+ -ms-transform: scale(1);
+ transform: scale(1);
+ }
+ .swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev {
+ -webkit-transform: scale(0.66);
+ -ms-transform: scale(0.66);
+ transform: scale(0.66);
+ }
+ .swiper-pagination-bullets-dynamic
+ .swiper-pagination-bullet-active-prev-prev {
+ -webkit-transform: scale(0.33);
+ -ms-transform: scale(0.33);
+ transform: scale(0.33);
+ }
+ .swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next {
+ -webkit-transform: scale(0.66);
+ -ms-transform: scale(0.66);
+ transform: scale(0.66);
+ }
+ .swiper-pagination-bullets-dynamic
+ .swiper-pagination-bullet-active-next-next {
+ -webkit-transform: scale(0.33);
+ -ms-transform: scale(0.33);
+ transform: scale(0.33);
+ }
+ .swiper-pagination-bullet {
+ width: 8px;
+ height: 8px;
+ display: inline-block;
+ border-radius: 100%;
+ background: #000;
+ opacity: 0.2;
+ }
+ button.swiper-pagination-bullet {
+ border: none;
+ margin: 0;
+ padding: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ }
+ .swiper-pagination-clickable .swiper-pagination-bullet {
+ cursor: pointer;
+ }
+ .swiper-pagination-bullet-active {
+ opacity: 1;
+ background: #007aff;
+ }
+ .swiper-container-vertical > .swiper-pagination-bullets {
+ right: 10px;
+ top: 50%;
+ -webkit-transform: translate3d(0px, -50%, 0);
+ transform: translate3d(0px, -50%, 0);
+ }
+ .swiper-container-vertical
+ > .swiper-pagination-bullets
+ .swiper-pagination-bullet {
+ margin: 6px 0;
+ display: block;
+ }
+ .swiper-container-vertical
+ > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic {
+ top: 50%;
+ -webkit-transform: translateY(-50%);
+ -ms-transform: translateY(-50%);
+ transform: translateY(-50%);
+ width: 8px;
+ }
+ .swiper-container-vertical
+ > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic
+ .swiper-pagination-bullet {
+ display: inline-block;
+ -webkit-transition: 200ms top, 200ms -webkit-transform;
+ transition: 200ms top, 200ms -webkit-transform;
+ -o-transition: 200ms transform, 200ms top;
+ transition: 200ms transform, 200ms top;
+ transition: 200ms transform, 200ms top, 200ms -webkit-transform;
+ }
+ .swiper-container-horizontal
+ > .swiper-pagination-bullets
+ .swiper-pagination-bullet {
+ margin: 0 4px;
+ }
+ .swiper-container-horizontal
+ > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic {
+ left: 50%;
+ -webkit-transform: translateX(-50%);
+ -ms-transform: translateX(-50%);
+ transform: translateX(-50%);
+ white-space: nowrap;
+ }
+ .swiper-container-horizontal
+ > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic
+ .swiper-pagination-bullet {
+ -webkit-transition: 200ms left, 200ms -webkit-transform;
+ transition: 200ms left, 200ms -webkit-transform;
+ -o-transition: 200ms transform, 200ms left;
+ transition: 200ms transform, 200ms left;
+ transition: 200ms transform, 200ms left, 200ms -webkit-transform;
+ }
+ .swiper-container-horizontal.swiper-container-rtl
+ > .swiper-pagination-bullets-dynamic
+ .swiper-pagination-bullet {
+ -webkit-transition: 200ms right, 200ms -webkit-transform;
+ transition: 200ms right, 200ms -webkit-transform;
+ -o-transition: 200ms transform, 200ms right;
+ transition: 200ms transform, 200ms right;
+ transition: 200ms transform, 200ms right, 200ms -webkit-transform;
+ }
+ /* Progress */
+ .swiper-pagination-progressbar {
+ background: rgba(0, 0, 0, 0.25);
+ position: absolute;
+ }
+ .swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
+ background: #007aff;
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ -webkit-transform: scale(0);
+ -ms-transform: scale(0);
+ transform: scale(0);
+ -webkit-transform-origin: left top;
+ -ms-transform-origin: left top;
+ transform-origin: left top;
+ }
+ .swiper-container-rtl
+ .swiper-pagination-progressbar
+ .swiper-pagination-progressbar-fill {
+ -webkit-transform-origin: right top;
+ -ms-transform-origin: right top;
+ transform-origin: right top;
+ }
+ .swiper-container-horizontal > .swiper-pagination-progressbar,
+ .swiper-container-vertical
+ > .swiper-pagination-progressbar.swiper-pagination-progressbar-opposite {
+ width: 100%;
+ height: 4px;
+ left: 0;
+ top: 0;
+ }
+ .swiper-container-vertical > .swiper-pagination-progressbar,
+ .swiper-container-horizontal
+ > .swiper-pagination-progressbar.swiper-pagination-progressbar-opposite {
+ width: 4px;
+ height: 100%;
+ left: 0;
+ top: 0;
+ }
+ .swiper-pagination-white .swiper-pagination-bullet-active {
+ background: #ffffff;
+ }
+ .swiper-pagination-progressbar.swiper-pagination-white {
+ background: rgba(255, 255, 255, 0.25);
+ }
+ .swiper-pagination-progressbar.swiper-pagination-white
+ .swiper-pagination-progressbar-fill {
+ background: #ffffff;
+ }
+ .swiper-pagination-black .swiper-pagination-bullet-active {
+ background: #000000;
+ }
+ .swiper-pagination-progressbar.swiper-pagination-black {
+ background: rgba(0, 0, 0, 0.25);
+ }
+ .swiper-pagination-progressbar.swiper-pagination-black
+ .swiper-pagination-progressbar-fill {
+ background: #000000;
+ }
+ .swiper-pagination-lock {
+ display: none;
+ }
+ /* Scrollbar */
+ .swiper-scrollbar {
+ border-radius: 10px;
+ position: relative;
+ -ms-touch-action: none;
+ background: rgba(0, 0, 0, 0.1);
+ }
+ .swiper-container-horizontal > .swiper-scrollbar {
+ position: absolute;
+ left: 1%;
+ bottom: 3px;
+ z-index: 50;
+ height: 5px;
+ width: 98%;
+ }
+ .swiper-container-vertical > .swiper-scrollbar {
+ position: absolute;
+ right: 3px;
+ top: 1%;
+ z-index: 50;
+ width: 5px;
+ height: 98%;
+ }
+ .swiper-scrollbar-drag {
+ height: 100%;
+ width: 100%;
+ position: relative;
+ background: rgba(0, 0, 0, 0.5);
+ border-radius: 10px;
+ left: 0;
+ top: 0;
+ }
+ .swiper-scrollbar-cursor-drag {
+ cursor: move;
+ }
+ .swiper-scrollbar-lock {
+ display: none;
+ }
+ .swiper-zoom-container {
+ width: 100%;
+ height: 100%;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -webkit-justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ text-align: center;
+ }
+ .swiper-zoom-container > img,
+ .swiper-zoom-container > svg,
+ .swiper-zoom-container > canvas {
+ max-width: 100%;
+ max-height: 100%;
+ -o-object-fit: contain;
+ object-fit: contain;
+ }
+ .swiper-slide-zoomed {
+ cursor: move;
+ }
+ /* Preloader */
+ .swiper-lazy-preloader {
+ width: 42px;
+ height: 42px;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ margin-left: -21px;
+ margin-top: -21px;
+ z-index: 10;
+ -webkit-transform-origin: 50%;
+ -ms-transform-origin: 50%;
+ transform-origin: 50%;
+ -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite;
+ animation: swiper-preloader-spin 1s steps(12, end) infinite;
+ }
+ .swiper-lazy-preloader:after {
+ display: block;
+ content: '';
+ width: 100%;
+ height: 100%;
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
+ background-position: 50%;
+ background-size: 100%;
+ background-repeat: no-repeat;
+ }
+ .swiper-lazy-preloader-white:after {
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
+ }
+ @-webkit-keyframes swiper-preloader-spin {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+ }
+ @keyframes swiper-preloader-spin {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+ }
+ /* a11y */
+ .swiper-container .swiper-notification {
+ position: absolute;
+ left: 0;
+ top: 0;
+ pointer-events: none;
+ opacity: 0;
+ z-index: -1000;
+ }
+ .swiper-container-fade.swiper-container-free-mode .swiper-slide {
+ -webkit-transition-timing-function: ease-out;
+ -o-transition-timing-function: ease-out;
+ transition-timing-function: ease-out;
+ }
+ .swiper-container-fade .swiper-slide {
+ pointer-events: none;
+ -webkit-transition-property: opacity;
+ -o-transition-property: opacity;
+ transition-property: opacity;
+ }
+ .swiper-container-fade .swiper-slide .swiper-slide {
+ pointer-events: none;
+ }
+ .swiper-container-fade .swiper-slide-active,
+ .swiper-container-fade .swiper-slide-active .swiper-slide-active {
+ pointer-events: auto;
+ }
+ .swiper-container-cube {
+ overflow: visible;
+ }
+ .swiper-container-cube .swiper-slide {
+ pointer-events: none;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ z-index: 1;
+ visibility: hidden;
+ -webkit-transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ transform-origin: 0 0;
+ width: 100%;
+ height: 100%;
+ }
+ .swiper-container-cube .swiper-slide .swiper-slide {
+ pointer-events: none;
+ }
+ .swiper-container-cube.swiper-container-rtl .swiper-slide {
+ -webkit-transform-origin: 100% 0;
+ -ms-transform-origin: 100% 0;
+ transform-origin: 100% 0;
+ }
+ .swiper-container-cube .swiper-slide-active,
+ .swiper-container-cube .swiper-slide-active .swiper-slide-active {
+ pointer-events: auto;
+ }
+ .swiper-container-cube .swiper-slide-active,
+ .swiper-container-cube .swiper-slide-next,
+ .swiper-container-cube .swiper-slide-prev,
+ .swiper-container-cube .swiper-slide-next + .swiper-slide {
+ pointer-events: auto;
+ visibility: visible;
+ }
+ .swiper-container-cube .swiper-slide-shadow-top,
+ .swiper-container-cube .swiper-slide-shadow-bottom,
+ .swiper-container-cube .swiper-slide-shadow-left,
+ .swiper-container-cube .swiper-slide-shadow-right {
+ z-index: 0;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ }
+ .swiper-container-cube .swiper-cube-shadow {
+ position: absolute;
+ left: 0;
+ bottom: 0px;
+ width: 100%;
+ height: 100%;
+ background: #000;
+ opacity: 0.6;
+ -webkit-filter: blur(50px);
+ filter: blur(50px);
+ z-index: 0;
+ }
+ .swiper-container-flip {
+ overflow: visible;
+ }
+ .swiper-container-flip .swiper-slide {
+ pointer-events: none;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ z-index: 1;
+ }
+ .swiper-container-flip .swiper-slide .swiper-slide {
+ pointer-events: none;
+ }
+ .swiper-container-flip .swiper-slide-active,
+ .swiper-container-flip .swiper-slide-active .swiper-slide-active {
+ pointer-events: auto;
+ }
+ .swiper-container-flip .swiper-slide-shadow-top,
+ .swiper-container-flip .swiper-slide-shadow-bottom,
+ .swiper-container-flip .swiper-slide-shadow-left,
+ .swiper-container-flip .swiper-slide-shadow-right {
+ z-index: 0;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ }
+ .swiper-container-coverflow .swiper-wrapper {
+ /* Windows 8 IE 10 fix */
+ -ms-perspective: 1200px;
+ }
+`;
diff --git a/src/action-control/swiper/swiper.min.d.ts b/src/action-control/swiper/swiper.min.d.ts
new file mode 100644
index 0000000..43dacdb
--- /dev/null
+++ b/src/action-control/swiper/swiper.min.d.ts
@@ -0,0 +1,1888 @@
+// Type definitions for Swiper 4.4
+// Project: https://github.com/nolimits4web/Swiper, http://www.idangero.us/swiper
+// Definitions by: Sebastián Galiano
+// Luca Trazzi
+// Eugene Matseruk
+// Luiz M.
+// Justin Abene
+// Asif Rahman
+// Liad Idan
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+// TypeScript Version: 2.9
+
+/**
+ * Common Swiper events.
+ */
+export type CommonEvent =
+ | 'init'
+ | 'beforeDestroy'
+ | 'slideChange'
+ | 'slideChangeTransitionStart'
+ | 'slideChangeTransitionEnd'
+ | 'slideNextTransitionStart'
+ | 'slideNextTransitionEnd'
+ | 'slidePrevTransitionStart'
+ | 'slidePrevTransitionEnd'
+ | 'transitionStart'
+ | 'transitionEnd'
+ | 'touchStart'
+ | 'touchMove'
+ | 'touchMoveOpposite'
+ | 'sliderMove'
+ | 'touchEnd'
+ | 'click'
+ | 'tap'
+ | 'doubleTap'
+ | 'imagesReady'
+ | 'progress'
+ | 'reachBeginning'
+ | 'reachEnd'
+ | 'fromEdge'
+ | 'setTranslate'
+ | 'setTransition'
+ | 'resize';
+
+/**
+ * Swiper pagination event names.
+ */
+export type PaginationEvent = 'paginationRender' | 'paginationUpdate';
+
+/**
+ * Swiper autoplay event names.
+ */
+export type AutoplayEvent = 'autoplayStart' | 'autoplayStop' | 'autoplay';
+
+/**
+ * Swiper lazy-loading event names.
+ */
+export type LazyLoadingEvent = 'lazyImageLoad' | 'lazyImageReady';
+
+/**
+ * Swiper event names.
+ */
+export type SwiperEvent =
+ | CommonEvent
+ | PaginationEvent
+ | AutoplayEvent
+ | LazyLoadingEvent;
+
+/**
+ * Swiper module types.
+ */
+export type SwiperModule =
+ | Navigation
+ | Pagination
+ | Scrollbar
+ | Autoplay
+ | Parallax
+ | Lazy
+ | EffectFade
+ | EffectCoverflow
+ | EffectFlip
+ | EffectCube
+ | Zoom
+ | Keyboard
+ | Mousewheel
+ | Virtual
+ | HashNavigation
+ | History
+ | Controller
+ | A11y;
+
+export type DOM7Element = any;
+export type SelectableElement = string | HTMLElement;
+
+/*
+ * Swiper options and events.
+ */
+
+/**
+ * Main constructor options.
+ */
+export interface SwiperOptions {
+ /**
+ * Whether Swiper should be initialised automatically when you create an instance.
+ * If disabled, then you need to init it manually by calling mySwiper.init()
+ *
+ * @default true
+ */
+ init?: boolean;
+
+ /**
+ * Index number of initial slide.
+ *
+ * @default 0
+ */
+ initialSlide?: number;
+
+ /**
+ * Could be 'horizontal' or 'vertical' (for vertical slider).
+ *
+ * @default 'horizontal'
+ */
+ direction?: 'horizontal' | 'vertical';
+
+ /**
+ * Duration of transition between slides (in ms)
+ *
+ * @default 300
+ */
+ speed?: number;
+
+ /**
+ * Enabled this option and plugin will set width/height on swiper wrapper equal to total size of all slides.
+ * Mostly should be used as compatibility fallback option for browser that don't support flexbox layout well
+ */
+ setWrapperSize?: boolean;
+
+ /**
+ * Enabled this option and swiper will be operated as usual except it will not move, real translate values on wrapper will not be set.
+ * Useful when you may need to create custom slide transition
+ */
+ virtualTranslate?: boolean;
+
+ /**
+ * Swiper width (in px). Parameter allows to force Swiper width.
+ * Useful only if you initialize Swiper when it is hidden.
+ *
+ * @note Setting this parameter will make Swiper not responsive
+ */
+ width?: number;
+
+ /**
+ * Swiper height (in px). Parameter allows to force Swiper height.
+ * Useful only if you initialize Swiper when it is hidden.
+ *
+ * @note Setting this parameter will make Swiper not responsive
+ */
+ height?: number;
+
+ /**
+ * Set to true and slider wrapper will adopt its height to the height of the currently active slide
+ *
+ * @default false
+ */
+ autoHeight?: boolean;
+
+ /**
+ * Set to true to round values of slides width and height to prevent blurry texts on usual
+ * resolution screens (if you have such)
+ *
+ * @default false
+ */
+ roundLengths?: boolean;
+
+ /**
+ * Set to true on Swiper for correct touch events interception. Use only on
+ * swipers that use same direction as the parent one
+ *
+ * @default false
+ */
+ nested?: boolean;
+
+ /**
+ * If enabled (by default) and navigation elements' parameters passed as a string (like ".pagination")
+ * then Swiper will look for such elements through child elements first.
+ * Applies for pagination, prev/next buttons and scrollbar elements
+ *
+ * @default true
+ */
+ uniqueNavElements?: boolean;
+
+ /**
+ * Tranisition effect. Could be "slide", "fade", "cube", "coverflow" or "flip"
+ *
+ * @default 'slide'
+ */
+ effect?: 'slide' | 'fade' | 'cube' | 'coverflow' | 'flip';
+
+ /**
+ * Fire [Transition/SlideChange][Start/End] events on swiper initialization.
+ * Such events will be fired on initialization in case of your initialSlide is not 0, or you use loop mode
+ *
+ * @default true
+ */
+ runCallbacksOnInit?: boolean;
+
+ /**
+ * When enabled Swiper will be disabled and hide navigation buttons on
+ * case there are not enough slides for sliding.
+ *
+ * @default false
+ */
+ watchOverflow?: boolean;
+
+ /**
+ * Register event handlers.
+ */
+ on?: { [key in SwiperEvent]?: () => void };
+
+ // Slides grid
+
+ /**
+ * Distance between slides in px.
+ */
+ spaceBetween?: number;
+
+ /**
+ * Number of slides per view (slides visible at the same time on slider's container).
+ * If you use it with "auto" value and along with loop: true then you need to specify loopedSlides parameter with amount of slides to loop (duplicate)
+ * slidesPerView: 'auto' is currently not compatible with multirow mode, when slidesPerColumn > 1
+ */
+ slidesPerView?: number | 'auto';
+
+ /**
+ * Number of slides per column, for multirow layout
+ * slidesPerColumn > 1 is currently not compatible with loop mode (loop: true)
+ */
+ slidesPerColumn?: number;
+
+ /**
+ * Could be 'column' or 'row'. Defines how slides should fill rows, by column or by row
+ */
+ slidesPerColumnFill?: 'row' | 'column';
+
+ /**
+ * Set numbers of slides to define and enable group sliding. Useful to use with slidesPerView > 1
+ */
+ slidesPerGroup?: number;
+
+ /**
+ * If true, then active slide will be centered, not always on the left side.
+ */
+ centeredSlides?: boolean;
+
+ /**
+ * Add (in px) additional slide offset in the beginning of the container (before all slides)
+ */
+ slidesOffsetBefore?: number;
+
+ /**
+ * Add (in px) additional slide offset in the end of the container (after all slides)
+ */
+ slidesOffsetAfter?: number;
+
+ /**
+ * Normalize slide index.
+ */
+ normalizeSlideIndex?: boolean;
+
+ /**
+ * When enabled it center slides if the amount of slides less than `slidesPerView`. Not intended to be used loop mode and slidesPerColumn
+ */
+ centerInsufficientSlides?: boolean;
+
+ // Grab Cursor
+ grabCursor?: boolean;
+
+ // Touches
+
+ /**
+ * Target element to listen touch events on. Can be 'container' (to listen for touch events on swiper-container) or 'wrapper'
+ * (to listen for touch events on swiper-wrapper)
+ */
+ touchEventsTarget?: 'container' | 'wrapper';
+
+ /**
+ * Touch ratio
+ */
+ touchRatio?: number;
+
+ /**
+ * Allowable angle (in degrees) to trigger touch move
+ */
+ touchAngle?: number;
+
+ /**
+ * If true, Swiper will accept mouse events like touch events (click and drag to change slides)
+ */
+ simulateTouch?: boolean;
+
+ /**
+ * Set to false if you want to disable short swipes
+ */
+ shortSwipes?: boolean;
+
+ /**
+ * Set to false if you want to disable long swipes
+ */
+ longSwipes?: boolean;
+
+ /**
+ * Ratio to trigger swipe to next/previous slide during long swipes
+ */
+ longSwipesRatio?: number;
+
+ /**
+ * Minimal duration (in ms) to trigger swipe to next/previous slide during long swipes
+ */
+ longSwipesMs?: number;
+
+ /**
+ * If disabled, then slider will be animated only when you release it, it will not move while you hold your finger on it
+ */
+ followFinger?: boolean;
+
+ /**
+ * If false, then the only way to switch the slide is use of external API functions like slidePrev or slideNext
+ */
+ allowTouchMove?: boolean;
+
+ /**
+ * Threshold value in px. If "touch distance" will be lower than this value then swiper will not move
+ */
+ threshold?: number;
+
+ /**
+ * If disabled, `touchstart` (`mousedown`) event won't be prevented
+ */
+ touchStartPreventDefault?: boolean;
+
+ /**
+ * Force to always prevent default for `touchstart` (`mousedown`) event
+ */
+ touchStartForcePreventDefault?: boolean;
+
+ /**
+ * If enabled, then propagation of "touchmove" will be stopped
+ */
+ touchMoveStopPropagation?: boolean;
+
+ /**
+ * Enable to release Swiper events for swipe-to-go-back work in iOS UIWebView
+ */
+ iOSEdgeSwipeDetection?: boolean;
+
+ /**
+ * Area (in px) from left edge of the screen to release touch events for swipe-to-go-back in iOS UIWebView
+ */
+ iOSEdgeSwipeThreshold?: number;
+
+ /**
+ * Enable to release touch events on slider edge position (beginning, end) to allow for further page scrolling
+ */
+ touchReleaseOnEdges?: boolean;
+
+ /**
+ * Passive event listeners will be used by default where possible to improve scrolling performance on mobile devices.
+ * But if you need to use `e.preventDefault` and you have conflict with it, then you should disable this parameter
+ */
+ passiveListeners?: boolean;
+
+ // Touch Resistance
+
+ /**
+ * Set to false if you want to disable resistant bounds
+ */
+ resistance?: boolean;
+
+ /**
+ * This option allows you to control resistance ratio
+ */
+ resistanceRatio?: number;
+
+ // Swiping / No swiping
+ preventInteractionOnTransition?: boolean;
+ allowSlidePrev?: boolean;
+ allowSlideNext?: boolean;
+ noSwiping?: boolean;
+ noSwipingClass?: string;
+ noSwipingSelector?: string;
+ swipeHandler?: SelectableElement;
+
+ // Clicks
+ preventClicks?: boolean;
+ preventClicksPropagation?: boolean;
+ slideToClickedSlide?: boolean;
+
+ // Freemode
+ freeMode?: boolean;
+ freeModeMomentum?: boolean;
+ freeModeMomentumRatio?: number;
+ freeModeMomentumVelocityRatio?: number;
+ freeModeMomentumBounce?: boolean;
+ freeModeMomentumBounceRatio?: number;
+ freeModeMinimumVelocity?: number;
+ freeModeSticky?: boolean;
+
+ // Progress
+ watchSlidesProgress?: boolean;
+ watchSlidesVisibility?: boolean;
+
+ // Images
+ preloadImages?: boolean;
+ updateOnImagesReady?: boolean;
+
+ // Loop
+ loop?: boolean;
+ loopAdditionalSlides?: number;
+ loopedSlides?: number;
+ loopFillGroupWithBlank?: boolean;
+
+ // Breakpoints
+ breakpoints?: {
+ [index: number]: SwiperOptions;
+ };
+ breakpointsInverse?: boolean;
+
+ // Observer
+ observer?: boolean;
+ observeParents?: boolean;
+
+ // Namespace
+ containerModifierClass?: string;
+ slideClass?: string;
+ slideActiveClass?: string;
+ slideDuplicateActiveClass?: string;
+ slideVisibleClass?: string;
+ slideDuplicateClass?: string;
+ slideNextClass?: string;
+ slideDuplicateNextClass?: string;
+ slidePrevClass?: string;
+ slideDuplicatePrevClass?: string;
+ wrapperClass?: string;
+
+ // Components
+ navigation?: NavigationOptions;
+ pagination?: PaginationOptions;
+ scrollbar?: ScrollbarOptions;
+ autoplay?: AutoplayOptions | boolean;
+ parallax?: boolean;
+ lazy?: LazyOptions | boolean;
+ fadeEffect?: FadeEffectOptions;
+ coverflowEffect?: CoverflowEffectOptions;
+ flipEffect?: FlipEffectOptions;
+ cubeEffect?: CubeEffectOptions;
+ thumbs?: ThumbsOptions;
+ zoom?: ZoomOptions | boolean;
+ keyboard?: KeyboardOptions | boolean;
+ mousewheel?: MousewheelOptions | boolean;
+ virtual?: VirtualOptions | boolean;
+ hashNavigation?: HashNavigationOptions | boolean;
+ history?: HistoryNavigationOptions | boolean;
+ a11y?: A11yOptions | boolean;
+}
+
+export interface EventsOptions {
+ /**
+ * Fired right after Swiper initialization.
+ * Note that with swiper.on('init') syntax it will
+ * work only in case you set init: false parameter.
+ *
+ * @example
+ * var swiper = new Swiper('.swiper-container', {
+ * init: false,
+ * // other parameters
+ * });
+ *
+ * @example
+ * swiper.on('init', function() {
+ * // do something
+ * });
+ *
+ * @example
+ * // init Swiper
+ * swiper.init();
+ *
+ * @example
+ * // Otherwise use it as the parameter:
+ * var swiper = new Swiper('.swiper-container', {
+ * // other parameters
+ * on: {
+ * init: function () {
+ * // do something
+ * },
+ * }
+ * });
+ */
+ init?: () => any;
+
+ /**
+ * Triggered right beforey Swiper destoryed
+ */
+ beforeDestroy?: () => any;
+
+ /**
+ * Triggered when currently active slide is changed
+ */
+ slideChange?: () => any;
+
+ /**
+ * Triggered in the beginning of animation to other slide (next or previous).
+ */
+ slideChangeTransitionStart?: () => any;
+
+ /**
+ * Triggered after animation to other slide (next or previous).
+ */
+ slideChangeTransitionEnd?: () => any;
+
+ /**
+ * Same as "slideChangeTransitionStart" but for "forward" direction only
+ */
+ slideNextTransitionStart?: () => any;
+
+ /**
+ * Same as "slideChangeTransitionEnd" but for "forward" direction only
+ */
+ slideNextTransitionEnd?: () => any;
+
+ /**
+ * Same as "slideChangeTransitionStart" but for "backward" direction only
+ */
+ slidePrevTransitionStart?: () => any;
+
+ /**
+ * Same as "slideChangeTransitionEnd" but for "backward" direction only
+ */
+ slidePrevTransitionEnd?: () => any;
+
+ /**
+ * Triggered in the beginning of transition.
+ */
+ transitionStart?: () => any;
+
+ /**
+ * Triggered after transition.
+ */
+ transitionEnd?: () => any;
+
+ /**
+ * Triggered when user touch Swiper. Receives 'touchstart' event as an arguments.
+ */
+ touchStart?: (event: any) => any;
+
+ /**
+ * Triggered when user touch and move finger over Swiper. Receives 'touchmove' event as an arguments.
+ */
+ touchMove?: (event: any) => any;
+
+ /**
+ * Fired when user touch and move finger over
+ * Swiper in direction opposite to direction parameter.
+ * Receives 'touchmove' event as an arguments.
+ */
+ touchMoveOpposite?: (event: any) => any;
+
+ /**
+ * Triggered when user touch and move finger over Swiper and move it.
+ * Receives 'touchmove' event as an arguments.
+ */
+ sliderMove?: (event: any) => any;
+
+ /**
+ * Triggered when user release Swiper. Receives 'touchend' event as an arguments.
+ */
+ touchEnd?: (event: any) => any;
+
+ /**
+ * Triggered when user click/tap on Swiper after 300ms delay. Receives 'touchend' event as an arguments.
+ */
+ click?: (event: any) => any;
+
+ /**
+ * Triggered when user click/tap on Swiper. Receives 'touchend' event as an arguments.
+ */
+ tap?: (event: any) => any;
+
+ /**
+ * Triggered when user double tap on Swiper's container. Receives 'touchend' event as an arguments
+ */
+ doubleTap?: (event: any) => any;
+
+ /**
+ * Triggered right after all inner images are loaded. updateOnImagesReady should be also enabled
+ */
+ imagesReady?: () => any;
+
+ /**
+ * Triggered when Swiper progress is changed, as an arguments it receives
+ * progress that is always from 0 to 1
+ */
+ progress?: (progress: any) => any;
+
+ /**
+ * Triggered when Swiper reach its beginning (initial position)
+ */
+ reachBeginning?: () => any;
+
+ /**
+ * Triggered when Swiper reach last slide
+ */
+ reachEnd?: () => any;
+
+ /**
+ * Triggered when Swiper goes from beginning or end position
+ */
+ fromEdge?: () => any;
+
+ /**
+ * Triggered when swiper's wrapper change its position. Receives current translate value as an arguments
+ */
+ setTranslate?: (translate: any) => any;
+
+ /**
+ * Triggered everytime when swiper starts animation.
+ * Receives current transition duration (in ms) as an arguments,
+ */
+ setTransition?: (transition: any) => any;
+
+ /**
+ * Triggered on window resize right before swiper's onresize manipulation
+ */
+ resize?: () => any;
+}
+
+export interface NavigationOptions {
+ /**
+ * String with CSS selector or HTML element of the element that will work
+ * like "next" button after click on it
+ *
+ * @default null
+ */
+ nextEl?: SelectableElement;
+
+ /**
+ * String with CSS selector or HTML element of the element that will work
+ * like "prev" button after click on it
+ *
+ * @default null
+ */
+ prevEl?: SelectableElement;
+
+ /**
+ * buttons visibility after click on Slider's container
+ *
+ * @default false Toggle navigation
+ */
+ hideOnClick?: boolean;
+
+ /**
+ * CSS class name added to navigation button when it becomes disabled
+ *
+ * @default 'swiper-button-disabled'
+ */
+ disabledClass?: string;
+
+ /**
+ * CSS class name added to navigation button when it becomes hidden
+ *
+ * @default 'swiper-button-hidden'
+ */
+ hiddenClass?: string;
+}
+
+export interface PaginationOptions {
+ /**
+ * String with CSS selector or HTML element of the container with pagination
+ */
+ el: SelectableElement | Element;
+
+ /**
+ * String with type of pagination. Can be "bullets", "fraction", "progressbar" or "custom"
+ */
+ type?: 'bullets' | 'fraction' | 'progressbar' | 'custom';
+
+ /**
+ * Defines which HTML tag will be use to represent single pagination bullet. Only for bullets pagination type.
+ */
+ bulletElement?: string;
+
+ /**
+ * Good to enable if you use bullets pagination with a lot of slides. So it will keep only few bullets visible at the same time.
+ */
+ dynamicBullets?: boolean;
+
+ /**
+ * The number of main bullets visible when dynamicBullets enabled.
+ */
+ dynamicMainBullets?: number;
+
+ /**
+ * Toggle (hide/true) pagination container visibility after click on Slider's container
+ */
+ hideOnClick?: boolean;
+
+ /**
+ * If true then clicking on pagination button will cause transition to appropriate slide. Only for bullets pagination type
+ */
+ clickable?: boolean;
+
+ /**
+ * Makes pagination progressbar opposite to Swiper's `direction` parameter, means vertical progressbar for horizontal swiper
+ * direction and horizontal progressbar for vertical swiper direction
+ */
+ progressbarOpposite?: boolean;
+
+ /**
+ * format fraction pagination current number. Function receives current number,
+ * and you need to return formatted value
+ */
+ formatFractionCurrent?: (number: number) => number;
+
+ /**
+ * format fraction pagination total number. Function receives total number, and you
+ * need to return formatted value
+ */
+ formatFractionTotal?: (number: number) => number;
+
+ /**
+ * This parameter allows totally customize pagination bullets, you need to pass here a function that accepts index number of
+ * pagination bullet and required element class name (className). Only for bullets pagination type
+ */
+ renderBullet?: (index: number, className: string) => void;
+
+ /**
+ * This parameter allows to customize "fraction" pagination html. Only for fraction pagination type
+ */
+ renderFraction?: (currentClass: string, totalClass: string) => void;
+
+ /**
+ * This parameter allows to customize "progress" pagination. Only for progress pagination type
+ */
+ renderProgressbar?: (progressbarFillClass: string) => void;
+
+ /**
+ * This parameter is required for custom pagination type where you have to specify
+ * how it should be rendered.
+ *
+ * @example
+ * var swiper = new Swiper('.swiper-container', {
+ * //...
+ * renderCustom: function (swiper, current, total) {
+ * return current + ' of ' + total;
+ * }
+ * });
+ */
+ renderCustom?: (swiper: Swiper, current: number, total: number) => void;
+
+ /**
+ * CSS class name of single pagination bullet
+ */
+ bulletClass?: string;
+
+ /**
+ * CSS class name of currently active pagination bullet
+ */
+ bulletActiveClass?: string;
+
+ /**
+ * The beginning of the modifier CSS class name that will be added to pagination depending on parameters
+ */
+ modifierClass?: string;
+
+ /**
+ * CSS class name of the element with currently active index in "fraction" pagination
+ */
+ currentClass?: string;
+
+ /**
+ * CSS class name of the element with total number of "snaps" in "fraction" pagination
+ */
+ totalClass?: string;
+
+ /**
+ * CSS class name of pagination when it becomes inactive
+ */
+ hiddenClass?: string;
+
+ /**
+ * CSS class name of pagination progressbar fill element
+ */
+ progressbarFillClass?: string;
+
+ /**
+ * CSS class name set to pagination when it is clickable
+ */
+ clickableClass?: string;
+}
+
+/**
+ * Object with scrollbar parameters.
+ *
+ * @example
+ * var mySwiper = new Swiper('.swiper-container', {
+ * scrollbar: {
+ * el: '.swiper-scrollbar',
+ * draggable: true,
+ * },
+ * });
+ */
+export interface ScrollbarOptions {
+ /**
+ * String with CSS selector or HTML element of the container with scrollbar.
+ */
+ el: SelectableElement;
+
+ /**
+ * Hide scrollbar automatically after user interaction
+ *
+ * @default true
+ */
+ hide?: boolean;
+
+ /**
+ * Set to true to enable make scrollbar draggable that allows you to control slider position
+ *
+ * @default true
+ */
+ draggable?: boolean;
+
+ /**
+ * Set to true to snap slider position to slides when you release scrollbar
+ *
+ * @default false
+ */
+ snapOnRelease?: boolean;
+
+ /**
+ * Size of scrollbar draggable element in px
+ *
+ * @default 'auto'
+ */
+ dragSize?: 'auto' | number;
+
+ /**
+ * Scrollbar element additional CSS class when it is disabled
+ *
+ * @default 'swiper-scrollbar-lock'
+ */
+ lockClass?: string;
+
+ /**
+ * Scrollbar draggable element CSS class
+ *
+ * @default 'swiper-scrollbar-drag'
+ */
+ dragClass?: string;
+}
+
+/**
+ * Object with autoplay parameters or boolean true to enable with default settings.
+ *
+ * @example
+ * var mySwiper = new Swiper('.swiper-container', {
+ * autoplay: {
+ * delay: 5000,
+ * },
+ * });
+ */
+export interface AutoplayOptions {
+ /**
+ * Delay between transitions (in ms). If this parameter is not specified, auto play will be disabled
+ *
+ * If you need to specify different delay for specifi slides you can do it by using
+ * data-swiper-autoplay (in ms) attribute on slide.
+ *
+ * @example
+ *
+ *
+ *
+ * @default 3000
+ */
+ delay?: number;
+
+ /**
+ * Enable this parameter and autoplay will be stopped when it reaches last slide (has no effect in loop mode)
+ *
+ * @default false
+ */
+ stopOnLastSlide?: boolean;
+
+ /**
+ * Set to false and autoplay will not be disabled after
+ * user interactions (swipes), it will be restarted
+ * every time after interaction
+ *
+ * @default true
+ */
+ disableOnInteraction?: boolean;
+
+ /**
+ * Enables autoplay in reverse direction
+ *
+ * @default false
+ */
+ reverseDirection?: boolean;
+
+ /**
+ * When enabled autoplay will wait for wrapper transition to continue.
+ * Can be disabled in case of using Virtual Translate when your
+ * slider may not have transition
+ *
+ * @default true
+ */
+ waitForTransition?: boolean;
+}
+
+export interface LazyOptions {
+ loadPrevNext?: boolean;
+ loadPrevNextAmount?: number;
+ loadOnTransitionStart?: boolean;
+ elementClass?: string;
+ loadingClass?: string;
+ loadedClass?: string;
+ preloaderClass?: string;
+}
+
+/*
+ * Options - Effect
+ */
+
+export interface FadeEffectOptions {
+ crossFade?: boolean;
+}
+
+export interface CoverflowEffectOptions {
+ slideShadows?: boolean;
+ rotate?: number;
+ stretch?: number;
+ depth?: number;
+ modifier?: number;
+}
+
+export interface FlipEffectOptions {
+ slideShadows?: boolean;
+ limitRotation?: boolean;
+}
+
+export interface CubeEffectOptions {
+ slideShadows?: boolean;
+ shadow?: boolean;
+ shadowOffset?: number;
+ shadowScale?: number;
+}
+
+export interface ThumbsOptions {
+ swiper?: Swiper;
+ slideThumbActiveClass?: string;
+ thumbsContainerClass?: string;
+}
+
+export interface ZoomOptions {
+ maxRatio?: number;
+ minRatio?: number;
+ toggle?: boolean;
+ containerClass?: string;
+ zoomedSlideClass?: string;
+}
+
+export interface KeyboardOptions {
+ enabled?: boolean;
+ onlyInViewport?: boolean;
+}
+
+export interface MousewheelOptions {
+ forceToAxis?: boolean;
+ releaseOnEdges?: boolean;
+ invert?: boolean;
+ sensitivity?: number;
+ eventsTarged?: SelectableElement;
+}
+
+export interface VirtualOptions {
+ slides?: any[];
+ cache?: boolean;
+ addSlidesBefore?: number;
+ addSlidesAfter?: number;
+ renderSlide?: (slide: any, index: any) => any;
+ renderExternal?: (data: any) => any;
+}
+
+export interface HashNavigationOptions {
+ /**
+ * Set to true to enable also navigation through slides (when hashnav
+ * is enabled) by browser history or by setting directly hash on document location
+ *
+ * @default false
+ */
+ watchState?: boolean;
+
+ /**
+ * Works in addition to hashnav to replace current url state with the
+ * new one instead of adding it to history
+ *
+ * @default false
+ */
+ replaceState?: boolean;
+}
+
+export interface HistoryNavigationOptions {
+ /**
+ * Works in addition to hashnav or history to replace current url state with the
+ * new one instead of adding it to history
+ *
+ * @default false
+ */
+ replaceState?: boolean;
+
+ /**
+ * Url key for slides
+ *
+ * @default 'slides'
+ */
+ key?: string;
+}
+
+/**
+ * Object with controller parameters or boolean true to enable with default settings. For example:
+ *
+ * @example
+ * var mySwiper = new Swiper('.swiper-container', {
+ * controller: {
+ * inverse: true,
+ * },
+ * });
+ */
+export interface ControllerOptions {
+ /**
+ * Pass here another Swiper instance or array with Swiper instances that should be controlled
+ * by this Swiper
+ */
+ control?: Swiper;
+
+ /**
+ * Set to true and controlling will be in inverse direction
+ *
+ * @default false
+ */
+ inverse?: boolean;
+
+ /**
+ * Can be 'slide' or 'container'. Defines a way how to control another slider: slide by slide
+ * (with respect to other slider's grid) or depending on all slides/container
+ * (depending on total slider percentage).
+ *
+ * @default 'slide'
+ */
+ by?: 'slide' | 'container';
+}
+
+export interface A11yOptions {
+ /**
+ * Enables A11y
+ *
+ * @default true
+ */
+ enabled?: boolean;
+
+ /**
+ * Message for screen readers for previous button
+ *
+ * @default 'Previous slide'
+ */
+ prevSlideMessage?: string;
+
+ /**
+ * Message for screen readers for next button
+ *
+ * @default 'Next slide'
+ */
+ nextSlideMessage?: string;
+
+ /**
+ * Message for screen readers for previous button when swiper is on first slide
+ *
+ * @default 'This is the first slide'
+ */
+ firstSlideMessage?: string;
+
+ /**
+ * Message for screen readers for previous button when swiper is on last slide
+ *
+ * @default 'This is the last slide'
+ */
+ lastSlideMessage?: string;
+
+ /**
+ * Message for screen readers for single pagination bullet
+ *
+ * @default 'Go to slide {{index}}'
+ */
+ paginationBulletMessage?: string;
+
+ /**
+ * CSS class name of a11 notification
+ *
+ * @default 'swiper-notification'
+ */
+ notificationClass?: string;
+}
+
+// "Multiple imports from './dist/js/swiper.esm' can be combined into one" + "Line breaks are not allowed in import declaration" = ...
+// tslint:disable-next-line:max-line-length
+export class Virtual {
+ /**
+ * Object with cached slides HTML elements
+ */
+ cache: object;
+
+ /**
+ * Index of first rendered slide
+ */
+ from: number;
+
+ /**
+ * Index of last rendered slide
+ */
+ to: number;
+
+ /**
+ * Array with slide items passed by virtual.slides parameter
+ */
+ slides: any[];
+
+ /*
+ * Methods
+ */
+
+ /**
+ * Add new slides to the end. slides could be HTMLElement or HTML string with new slide or array
+ * with such slides, for example:
+ *
+ * @example
+ * mySwiper.appendSlide('
Slide 10"
')
+ * mySwiper.appendSlide([
+ * '
Slide 10"
',
+ * '
Slide 11"
'
+ * ]);
+ */
+ appendSlide(slide: HTMLElement | string): void;
+
+ /**
+ * Add new slides to the beginning. slides could be HTMLElement or HTML string with new slide or
+ * array with such slides, for example:
+ *
+ * @example
+ * mySwiper.prependSlide('
Slide 0"
')
+ * mySwiper.prependSlide([
+ * '
Slide 1"
',
+ * '
Slide 2"
'
+ * ]);
+ */
+ prependSlide(slide: HTMLElement | string): void;
+
+ /**
+ * Update virutal slides state
+ */
+ update(): void;
+}
+
+/**
+ * Keyboard Control module.
+ */
+export class Keyboard {
+ /**
+ * Whether the keyboard control is enabled
+ */
+ enabled: boolean;
+
+ // Methods
+ /**
+ * Enable keyboard control
+ */
+ enable(): void;
+
+ /**
+ * Disable keyboard control
+ */
+ disable(): void;
+}
+
+/**
+ * Mousewheel Control module.
+ */
+export class Mousewheel {
+ /**
+ * Whether the mousewheel control is enabled
+ */
+ enabled: boolean;
+
+ // Methods
+ /**
+ * Enable mousewheel control
+ */
+ enable(): void;
+
+ /**
+ * Disable mousewheel control
+ */
+ disable(): void;
+}
+
+/**
+ * Navigation module.
+ */
+export class Navigation {
+ /**
+ * HTMLElement of "next" navigation button
+ */
+ nextEl: HTMLElement;
+
+ /**
+ * HTMLElement of "previous" navigation button
+ */
+ prevEl: HTMLElement;
+
+ /**
+ * Update navigation buttons state (enabled/disabled)
+ */
+ update(): void;
+}
+
+/**
+ * Pagination module.
+ */
+export class Pagination {
+ /**
+ * HTMLElement of pagination container element
+ */
+ el: HTMLElement;
+
+ /**
+ * Dom7 array-like collection of pagination bullets
+ * HTML elements. To get specific slide HTMLElement
+ * use `mySwiper.pagination.bullets[1]`.
+ */
+ bullets: DOM7Element[];
+
+ /**
+ * Render pagination layout
+ */
+ render(): void;
+
+ /**
+ * Update pagination state (enabled/disabled/active)
+ */
+ update(): void;
+}
+
+/**
+ * Scrollbar module.
+ */
+export class Scrollbar {
+ // Properties
+ /**
+ * HTMLElement of Scrollbar container element
+ */
+ el: HTMLElement;
+
+ /**
+ * HTMLElement of Scrollbar draggable handler element
+ */
+ dragEl: HTMLElement;
+
+ // Methods
+ /**
+ * Updates scrollbar track and handler sizes
+ */
+ updateSize(): void;
+}
+
+/**
+ * Parallax module.
+ */
+export class Parallax {}
+
+/**
+ * Zoom module.
+ */
+export class Zoom {
+ /**
+ * Whether the zoom module is enabled
+ */
+ enabled: boolean;
+
+ /**
+ * Current image scale ratio
+ */
+ scale: number;
+
+ /**
+ * Enable zoom module
+ */
+ enable(): void;
+
+ /**
+ * Disable zoom module
+ */
+ disable(): void;
+
+ /**
+ * Zoom in image of the currently active slide
+ */
+ in(): void;
+
+ /**
+ * Zoom out image of the currently active slide
+ */
+ out(): void;
+
+ /**
+ * Toggle image zoom of the currently active slide
+ */
+ toggle(): void;
+}
+
+/**
+ * Lazy module.
+ */
+export class Lazy {
+ /**
+ * Load/update lazy images based on current slider state (position)
+ */
+ load(): void;
+
+ /**
+ * Force to load lazy images in slide by specified index
+ * @param number index number of slide to load lazy images in
+ */
+ loadInSlide(index: number): void;
+}
+
+/**
+ * Controller module.
+ */
+export class Controller {
+ /**
+ * Pass here another Swiper instance or array with Swiper instances that should be controlled
+ * by this Swiper
+ */
+ control?: Swiper;
+}
+
+/**
+ * Accessibility module (a11y$)
+ */
+export class A11y {}
+
+/**
+ * History Navigation module.
+ */
+export class History {}
+
+/**
+ * Hash Navigation module.
+ */
+export class HashNavigation {}
+
+/**
+ * Autoplay module.
+ */
+export class Autoplay {
+ // Properties
+ /**
+ * Whether autoplay enabled and running
+ */
+ running: boolean;
+
+ // Methods
+ /**
+ * Start autoplay
+ */
+ start(): boolean;
+
+ /**
+ * Stop autoplay
+ */
+ stop(): boolean;
+}
+
+/**
+ * Fade Effect module.
+ */
+export class EffectFade {}
+
+/**
+ * Cube Effect module.
+ */
+export class EffectCube {}
+
+/**
+ * Flip Effect module.
+ */
+export class EffectFlip {}
+
+/**
+ * Coverflow Effect module.
+ */
+export class EffectCoverflow {}
+/**
+ * Core module
+ */
+// XXX: This is an export assignment in `dist/js/swiper.js` (referenced by
+// the "main" field of package.json) but a default export in
+// `dist/js/swiper.esm.bundle.js` (referenced by the "module" field). Short
+// of trying to convince upstream to change their packaging, the best we can
+// do is choose one or the other and hope that users use `esModuleInterop`.
+export default class Swiper {
+ /**
+ * Constructs a new Swiper instance.
+ *
+ * @param container Where Swiper applies to.
+ * @param options Instance options.
+ */
+ constructor(container: SelectableElement | Element, options?: SwiperOptions);
+
+ /**
+ * Object with passed initialization parameters
+ */
+ params: SwiperOptions;
+
+ /**
+ * Element with slider container.
+ */
+ el: HTMLElement;
+
+ /**
+ * Dom7 element with slider container HTML element. To get vanilla HTMLElement use el
+ */
+ $el: DOM7Element;
+
+ /**
+ * Slider wrapper HTML element.
+ */
+ wrapperEl: HTMLElement;
+
+ /**
+ * Dom7 element with slider wrapper HTML element. To get vanilla HTMLElement use wrapperEl
+ */
+ $wrapperEl: DOM7Element;
+
+ /**
+ * Dom7 array-like collection of slides HTML elements. To get specific slide HTMLElement use slides[1]
+ */
+ slides: DOM7Element[];
+
+ /**
+ * Width of container
+ */
+ width: number;
+
+ /**
+ * Height of container
+ */
+ height: number;
+
+ /**
+ * Current value of wrapper translate
+ */
+ translate: number;
+
+ /**
+ * Current progress of wrapper translate (from 0 to 1)
+ */
+ progress: number;
+
+ /**
+ * Index number of currently active slide.
+ *
+ * @note Note, that in loop mode active index value will be always shifted
+ * on a number of looped/duplicated slides.
+ */
+ activeIndex: number;
+
+ /**
+ * Index number of currently active slide considering duplicated slides in loop mode
+ */
+ realIndex: number;
+
+ /**
+ * Index number of previously active slide
+ */
+ previousIndex: number;
+
+ /**
+ * true if slider on most "left"/"top" position
+ */
+ isBeginning: true;
+
+ /**
+ * true if slider on most "right"/"bottom" position
+ */
+ isEnd: boolean;
+
+ /**
+ * true if swiper is in transition
+ */
+ animating: boolean;
+
+ /**
+ * Object with the following touch event properties:
+ */
+ touches: {
+ startX: number;
+ startY: number;
+ currentX: number;
+ currentY: number;
+ diff: number;
+ };
+
+ /**
+ * Index number of last clicked slide
+ */
+ clickedIndex: number;
+
+ /**
+ * Link to last clicked slide (HTMLElement)
+ */
+ clickedSlide: HTMLElement;
+
+ /**
+ * Disable/enable ability to slide to the next slides by assigning false/true to this property
+ *
+ * @default true
+ */
+ allowSlideNext: boolean;
+
+ /**
+ * Disable/enable ability to slide to the previous slides by assigning false/true to this property
+ *
+ * @default true
+ */
+ allowSlidePrev: boolean;
+
+ /**
+ * Disable/enable ability move slider by grabbing it with
+ * mouse or by touching it with finger (on touch screens)
+ * by assigning false/true to this property
+ *
+ * @default true
+ */
+ allowTouchMove: boolean;
+
+ // Methods
+ /**
+ * Run transition to next slide.
+ *
+ * @param speed Transition duration (in ms).
+ * @param runCallbacks Set it to false (by default it is true) and transition will
+ * not produce transition events.
+ */
+ slideNext(speed?: number, runCallbacks?: boolean): void;
+
+ /**
+ * Run transition to previous slide.
+ *
+ * @param speed Transition duration (in ms).
+ * @param runCallbacks Set it to false (by default it is true) and transition will
+ * not produce transition events.
+ */
+ slidePrev(speed?: number, runCallbacks?: boolean): void;
+
+ /**
+ * Run transition to the slide with index number equal to 'index' parameter for the
+ * duration equal to 'speed' parameter.
+ *
+ * @param index Index number of slide.
+ * @param speed Transition duration (in ms).
+ * @param runCallbacks Set it to false (by default it is true) and transition will
+ * not produce transition events.
+ */
+ slideTo(index: number, speed?: number, runCallbacks?: boolean): void;
+
+ /**
+ * Does the same as .slideTo but for the case when used with enabled loop. So this
+ * method will slide to slides with realIndex matching to passed index
+ *
+ * @param index Index number of slide.
+ * @param speed Transition duration (in ms).
+ * @param runCallbacks Set it to false (by default it is true) and transition will
+ * not produce transition events.
+ */
+ slideToLoop(index: number, speed?: number, runCallbacks?: boolean): void;
+
+ /**
+ * Reset swiper position to currently active slide for the duration equal to 'speed'
+ * parameter.
+ *
+ * @param speed Transition duration (in ms).
+ * @param runCallbacks Set it to false (by default it is true) and transition will
+ * not produce transition events.
+ */
+ slideReset(speed?: number, runCallbacks?: boolean): void;
+
+ /**
+ * Reset swiper position to closest slide/snap point for the duration equal to 'speed' parameter.
+ *
+ * @param speed Transition duration (in ms).
+ * @param runCallbacks Set it to false (by default it is true) and transition will
+ * not produce transition events.
+ */
+ slideToClosest(speed?: number, runCallbacks?: boolean): void;
+
+ /**
+ * Force swiper to update its height (when autoHeight enabled) for the duration equal to
+ * 'speed' parameter
+ *
+ * @param speed Transition duration (in ms).
+ */
+ updateAutoHeight(speed?: number): void;
+
+ /**
+ * You should call it after you add/remove slides
+ * manually, or after you hide/show it, or do any
+ * custom DOM modifications with Swiper
+ * This method also includes subcall of the following
+ * methods which you can use separately:
+ */
+ update(): void;
+
+ /**
+ * recalculate size of swiper container
+ */
+ updateSize(): void;
+
+ /**
+ * recalculate number of slides and their offsets. Useful after you add/remove slides with JavaScript
+ */
+ updateSlides(): void;
+
+ /**
+ * recalculate swiper progress
+ */
+ updateProgress(): void;
+
+ /**
+ * update active/prev/next classes on slides and bullets
+ */
+ updateSlidesClasses(): void;
+
+ /**
+ * tach all events listeners
+ */
+ detachEvents(): void;
+
+ /**
+ * Atach all events listeners again
+ */
+ attachEvents(): void;
+
+ /**
+ * Destroy slider instance and detach all events listeners, where
+ */
+ destroy(deleteInstance: boolean, cleanupStyles: boolean): void;
+
+ /**
+ * Set it to false (by default it is true) to not to delete Swiper instance
+ */
+ deleteInstance: boolean;
+
+ /**
+ * Set it to true (by default it is true) and all
+ * custom styles will be removed from slides,
+ * wrapper and container. Useful if you need to
+ * destroy Swiper and to init again with new
+ * options or in different direction
+ */
+ cleanStyles: boolean;
+
+ /**
+ * Installs modules on Swiper in runtime.
+ */
+ static use(modules: SwiperModule[]): void;
+
+ /**
+ * Add new slides to the end. slides could be
+ * HTMLElement or HTML string with new slide or
+ * array with such slides, for example:
+ *
+ * @example appendSlide('
Slide 10"
')
+ * @example
+ * appendSlide([
+ * '
Slide 10"
',
+ * '
Slide 11"
'
+ * ]);
+ */
+ appendSlide(slides: HTMLElement | string | string[]): void;
+
+ /**
+ * Add new slides to the beginning. slides could be
+ * HTMLElement or HTML string with new slide or array with such slides, for example:
+ *
+ * @example prependSlide('
Slide 0"
')
+ * @example prependSlide([
+ * '
Slide 1"
',
+ * '
Slide 2"
'
+ * ]);
+ */
+ prependSlide(slides: HTMLElement | string | string[]): void;
+
+ /**
+ * Add new slides to the required index. slides could be HTMLElement or HTML string with new slide or array with such slides, for example:
+ *
+ * @example addSlide(1, '