swiper.js 146 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344
  1. /**
  2. * Swiper 11.1.15
  3. * Most modern mobile touch slider and framework with hardware accelerated transitions
  4. * https://swiperjs.com
  5. *
  6. * Copyright 2014-2024 Vladimir Kharlampidi
  7. *
  8. * Released under the MIT License
  9. *
  10. * Released on: November 18, 2024
  11. */
  12. var Swiper = (function () {
  13. 'use strict';
  14. /**
  15. * SSR Window 4.0.2
  16. * Better handling for window object in SSR environment
  17. * https://github.com/nolimits4web/ssr-window
  18. *
  19. * Copyright 2021, Vladimir Kharlampidi
  20. *
  21. * Licensed under MIT
  22. *
  23. * Released on: December 13, 2021
  24. */
  25. /* eslint-disable no-param-reassign */
  26. function isObject$1(obj) {
  27. return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;
  28. }
  29. function extend$1(target, src) {
  30. if (target === void 0) {
  31. target = {};
  32. }
  33. if (src === void 0) {
  34. src = {};
  35. }
  36. Object.keys(src).forEach(key => {
  37. if (typeof target[key] === 'undefined') target[key] = src[key];else if (isObject$1(src[key]) && isObject$1(target[key]) && Object.keys(src[key]).length > 0) {
  38. extend$1(target[key], src[key]);
  39. }
  40. });
  41. }
  42. const ssrDocument = {
  43. body: {},
  44. addEventListener() {},
  45. removeEventListener() {},
  46. activeElement: {
  47. blur() {},
  48. nodeName: ''
  49. },
  50. querySelector() {
  51. return null;
  52. },
  53. querySelectorAll() {
  54. return [];
  55. },
  56. getElementById() {
  57. return null;
  58. },
  59. createEvent() {
  60. return {
  61. initEvent() {}
  62. };
  63. },
  64. createElement() {
  65. return {
  66. children: [],
  67. childNodes: [],
  68. style: {},
  69. setAttribute() {},
  70. getElementsByTagName() {
  71. return [];
  72. }
  73. };
  74. },
  75. createElementNS() {
  76. return {};
  77. },
  78. importNode() {
  79. return null;
  80. },
  81. location: {
  82. hash: '',
  83. host: '',
  84. hostname: '',
  85. href: '',
  86. origin: '',
  87. pathname: '',
  88. protocol: '',
  89. search: ''
  90. }
  91. };
  92. function getDocument() {
  93. const doc = typeof document !== 'undefined' ? document : {};
  94. extend$1(doc, ssrDocument);
  95. return doc;
  96. }
  97. const ssrWindow = {
  98. document: ssrDocument,
  99. navigator: {
  100. userAgent: ''
  101. },
  102. location: {
  103. hash: '',
  104. host: '',
  105. hostname: '',
  106. href: '',
  107. origin: '',
  108. pathname: '',
  109. protocol: '',
  110. search: ''
  111. },
  112. history: {
  113. replaceState() {},
  114. pushState() {},
  115. go() {},
  116. back() {}
  117. },
  118. CustomEvent: function CustomEvent() {
  119. return this;
  120. },
  121. addEventListener() {},
  122. removeEventListener() {},
  123. getComputedStyle() {
  124. return {
  125. getPropertyValue() {
  126. return '';
  127. }
  128. };
  129. },
  130. Image() {},
  131. Date() {},
  132. screen: {},
  133. setTimeout() {},
  134. clearTimeout() {},
  135. matchMedia() {
  136. return {};
  137. },
  138. requestAnimationFrame(callback) {
  139. if (typeof setTimeout === 'undefined') {
  140. callback();
  141. return null;
  142. }
  143. return setTimeout(callback, 0);
  144. },
  145. cancelAnimationFrame(id) {
  146. if (typeof setTimeout === 'undefined') {
  147. return;
  148. }
  149. clearTimeout(id);
  150. }
  151. };
  152. function getWindow() {
  153. const win = typeof window !== 'undefined' ? window : {};
  154. extend$1(win, ssrWindow);
  155. return win;
  156. }
  157. function classesToTokens(classes) {
  158. if (classes === void 0) {
  159. classes = '';
  160. }
  161. return classes.trim().split(' ').filter(c => !!c.trim());
  162. }
  163. function deleteProps(obj) {
  164. const object = obj;
  165. Object.keys(object).forEach(key => {
  166. try {
  167. object[key] = null;
  168. } catch (e) {
  169. // no getter for object
  170. }
  171. try {
  172. delete object[key];
  173. } catch (e) {
  174. // something got wrong
  175. }
  176. });
  177. }
  178. function nextTick(callback, delay) {
  179. if (delay === void 0) {
  180. delay = 0;
  181. }
  182. return setTimeout(callback, delay);
  183. }
  184. function now() {
  185. return Date.now();
  186. }
  187. function getComputedStyle$1(el) {
  188. const window = getWindow();
  189. let style;
  190. if (window.getComputedStyle) {
  191. style = window.getComputedStyle(el, null);
  192. }
  193. if (!style && el.currentStyle) {
  194. style = el.currentStyle;
  195. }
  196. if (!style) {
  197. style = el.style;
  198. }
  199. return style;
  200. }
  201. function getTranslate(el, axis) {
  202. if (axis === void 0) {
  203. axis = 'x';
  204. }
  205. const window = getWindow();
  206. let matrix;
  207. let curTransform;
  208. let transformMatrix;
  209. const curStyle = getComputedStyle$1(el);
  210. if (window.WebKitCSSMatrix) {
  211. curTransform = curStyle.transform || curStyle.webkitTransform;
  212. if (curTransform.split(',').length > 6) {
  213. curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', ');
  214. }
  215. // Some old versions of Webkit choke when 'none' is passed; pass
  216. // empty string instead in this case
  217. transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
  218. } else {
  219. transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
  220. matrix = transformMatrix.toString().split(',');
  221. }
  222. if (axis === 'x') {
  223. // Latest Chrome and webkits Fix
  224. if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;
  225. // Crazy IE10 Matrix
  226. else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
  227. // Normal Browsers
  228. else curTransform = parseFloat(matrix[4]);
  229. }
  230. if (axis === 'y') {
  231. // Latest Chrome and webkits Fix
  232. if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;
  233. // Crazy IE10 Matrix
  234. else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
  235. // Normal Browsers
  236. else curTransform = parseFloat(matrix[5]);
  237. }
  238. return curTransform || 0;
  239. }
  240. function isObject(o) {
  241. return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';
  242. }
  243. function isNode(node) {
  244. // eslint-disable-next-line
  245. if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
  246. return node instanceof HTMLElement;
  247. }
  248. return node && (node.nodeType === 1 || node.nodeType === 11);
  249. }
  250. function extend() {
  251. const to = Object(arguments.length <= 0 ? undefined : arguments[0]);
  252. const noExtend = ['__proto__', 'constructor', 'prototype'];
  253. for (let i = 1; i < arguments.length; i += 1) {
  254. const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];
  255. if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
  256. const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);
  257. for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
  258. const nextKey = keysArray[nextIndex];
  259. const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
  260. if (desc !== undefined && desc.enumerable) {
  261. if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
  262. if (nextSource[nextKey].__swiper__) {
  263. to[nextKey] = nextSource[nextKey];
  264. } else {
  265. extend(to[nextKey], nextSource[nextKey]);
  266. }
  267. } else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
  268. to[nextKey] = {};
  269. if (nextSource[nextKey].__swiper__) {
  270. to[nextKey] = nextSource[nextKey];
  271. } else {
  272. extend(to[nextKey], nextSource[nextKey]);
  273. }
  274. } else {
  275. to[nextKey] = nextSource[nextKey];
  276. }
  277. }
  278. }
  279. }
  280. }
  281. return to;
  282. }
  283. function setCSSProperty(el, varName, varValue) {
  284. el.style.setProperty(varName, varValue);
  285. }
  286. function animateCSSModeScroll(_ref) {
  287. let {
  288. swiper,
  289. targetPosition,
  290. side
  291. } = _ref;
  292. const window = getWindow();
  293. const startPosition = -swiper.translate;
  294. let startTime = null;
  295. let time;
  296. const duration = swiper.params.speed;
  297. swiper.wrapperEl.style.scrollSnapType = 'none';
  298. window.cancelAnimationFrame(swiper.cssModeFrameID);
  299. const dir = targetPosition > startPosition ? 'next' : 'prev';
  300. const isOutOfBound = (current, target) => {
  301. return dir === 'next' && current >= target || dir === 'prev' && current <= target;
  302. };
  303. const animate = () => {
  304. time = new Date().getTime();
  305. if (startTime === null) {
  306. startTime = time;
  307. }
  308. const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
  309. const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
  310. let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
  311. if (isOutOfBound(currentPosition, targetPosition)) {
  312. currentPosition = targetPosition;
  313. }
  314. swiper.wrapperEl.scrollTo({
  315. [side]: currentPosition
  316. });
  317. if (isOutOfBound(currentPosition, targetPosition)) {
  318. swiper.wrapperEl.style.overflow = 'hidden';
  319. swiper.wrapperEl.style.scrollSnapType = '';
  320. setTimeout(() => {
  321. swiper.wrapperEl.style.overflow = '';
  322. swiper.wrapperEl.scrollTo({
  323. [side]: currentPosition
  324. });
  325. });
  326. window.cancelAnimationFrame(swiper.cssModeFrameID);
  327. return;
  328. }
  329. swiper.cssModeFrameID = window.requestAnimationFrame(animate);
  330. };
  331. animate();
  332. }
  333. function elementChildren(element, selector) {
  334. if (selector === void 0) {
  335. selector = '';
  336. }
  337. const children = [...element.children];
  338. if (element instanceof HTMLSlotElement) {
  339. children.push(...element.assignedElements());
  340. }
  341. if (!selector) {
  342. return children;
  343. }
  344. return children.filter(el => el.matches(selector));
  345. }
  346. function elementIsChildOf(el, parent) {
  347. const isChild = parent.contains(el);
  348. if (!isChild && parent instanceof HTMLSlotElement) {
  349. const children = [...parent.assignedElements()];
  350. return children.includes(el);
  351. }
  352. return isChild;
  353. }
  354. function showWarning(text) {
  355. try {
  356. console.warn(text);
  357. return;
  358. } catch (err) {
  359. // err
  360. }
  361. }
  362. function createElement(tag, classes) {
  363. if (classes === void 0) {
  364. classes = [];
  365. }
  366. const el = document.createElement(tag);
  367. el.classList.add(...(Array.isArray(classes) ? classes : classesToTokens(classes)));
  368. return el;
  369. }
  370. function elementPrevAll(el, selector) {
  371. const prevEls = [];
  372. while (el.previousElementSibling) {
  373. const prev = el.previousElementSibling; // eslint-disable-line
  374. if (selector) {
  375. if (prev.matches(selector)) prevEls.push(prev);
  376. } else prevEls.push(prev);
  377. el = prev;
  378. }
  379. return prevEls;
  380. }
  381. function elementNextAll(el, selector) {
  382. const nextEls = [];
  383. while (el.nextElementSibling) {
  384. const next = el.nextElementSibling; // eslint-disable-line
  385. if (selector) {
  386. if (next.matches(selector)) nextEls.push(next);
  387. } else nextEls.push(next);
  388. el = next;
  389. }
  390. return nextEls;
  391. }
  392. function elementStyle(el, prop) {
  393. const window = getWindow();
  394. return window.getComputedStyle(el, null).getPropertyValue(prop);
  395. }
  396. function elementIndex(el) {
  397. let child = el;
  398. let i;
  399. if (child) {
  400. i = 0;
  401. // eslint-disable-next-line
  402. while ((child = child.previousSibling) !== null) {
  403. if (child.nodeType === 1) i += 1;
  404. }
  405. return i;
  406. }
  407. return undefined;
  408. }
  409. function elementParents(el, selector) {
  410. const parents = []; // eslint-disable-line
  411. let parent = el.parentElement; // eslint-disable-line
  412. while (parent) {
  413. if (selector) {
  414. if (parent.matches(selector)) parents.push(parent);
  415. } else {
  416. parents.push(parent);
  417. }
  418. parent = parent.parentElement;
  419. }
  420. return parents;
  421. }
  422. function elementOuterSize(el, size, includeMargins) {
  423. const window = getWindow();
  424. if (includeMargins) {
  425. return el[size === 'width' ? 'offsetWidth' : 'offsetHeight'] + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-right' : 'margin-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-left' : 'margin-bottom'));
  426. }
  427. return el.offsetWidth;
  428. }
  429. let support;
  430. function calcSupport() {
  431. const window = getWindow();
  432. const document = getDocument();
  433. return {
  434. smoothScroll: document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style,
  435. touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch)
  436. };
  437. }
  438. function getSupport() {
  439. if (!support) {
  440. support = calcSupport();
  441. }
  442. return support;
  443. }
  444. let deviceCached;
  445. function calcDevice(_temp) {
  446. let {
  447. userAgent
  448. } = _temp === void 0 ? {} : _temp;
  449. const support = getSupport();
  450. const window = getWindow();
  451. const platform = window.navigator.platform;
  452. const ua = userAgent || window.navigator.userAgent;
  453. const device = {
  454. ios: false,
  455. android: false
  456. };
  457. const screenWidth = window.screen.width;
  458. const screenHeight = window.screen.height;
  459. const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
  460. let ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
  461. const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
  462. const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
  463. const windows = platform === 'Win32';
  464. let macos = platform === 'MacIntel';
  465. // iPadOs 13 fix
  466. const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];
  467. if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {
  468. ipad = ua.match(/(Version)\/([\d.]+)/);
  469. if (!ipad) ipad = [0, 1, '13_0_0'];
  470. macos = false;
  471. }
  472. // Android
  473. if (android && !windows) {
  474. device.os = 'android';
  475. device.android = true;
  476. }
  477. if (ipad || iphone || ipod) {
  478. device.os = 'ios';
  479. device.ios = true;
  480. }
  481. // Export object
  482. return device;
  483. }
  484. function getDevice(overrides) {
  485. if (overrides === void 0) {
  486. overrides = {};
  487. }
  488. if (!deviceCached) {
  489. deviceCached = calcDevice(overrides);
  490. }
  491. return deviceCached;
  492. }
  493. let browser;
  494. function calcBrowser() {
  495. const window = getWindow();
  496. const device = getDevice();
  497. let needPerspectiveFix = false;
  498. function isSafari() {
  499. const ua = window.navigator.userAgent.toLowerCase();
  500. return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
  501. }
  502. if (isSafari()) {
  503. const ua = String(window.navigator.userAgent);
  504. if (ua.includes('Version/')) {
  505. const [major, minor] = ua.split('Version/')[1].split(' ')[0].split('.').map(num => Number(num));
  506. needPerspectiveFix = major < 16 || major === 16 && minor < 2;
  507. }
  508. }
  509. const isWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent);
  510. const isSafariBrowser = isSafari();
  511. const need3dFix = isSafariBrowser || isWebView && device.ios;
  512. return {
  513. isSafari: needPerspectiveFix || isSafariBrowser,
  514. needPerspectiveFix,
  515. need3dFix,
  516. isWebView
  517. };
  518. }
  519. function getBrowser() {
  520. if (!browser) {
  521. browser = calcBrowser();
  522. }
  523. return browser;
  524. }
  525. function Resize(_ref) {
  526. let {
  527. swiper,
  528. on,
  529. emit
  530. } = _ref;
  531. const window = getWindow();
  532. let observer = null;
  533. let animationFrame = null;
  534. const resizeHandler = () => {
  535. if (!swiper || swiper.destroyed || !swiper.initialized) return;
  536. emit('beforeResize');
  537. emit('resize');
  538. };
  539. const createObserver = () => {
  540. if (!swiper || swiper.destroyed || !swiper.initialized) return;
  541. observer = new ResizeObserver(entries => {
  542. animationFrame = window.requestAnimationFrame(() => {
  543. const {
  544. width,
  545. height
  546. } = swiper;
  547. let newWidth = width;
  548. let newHeight = height;
  549. entries.forEach(_ref2 => {
  550. let {
  551. contentBoxSize,
  552. contentRect,
  553. target
  554. } = _ref2;
  555. if (target && target !== swiper.el) return;
  556. newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
  557. newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
  558. });
  559. if (newWidth !== width || newHeight !== height) {
  560. resizeHandler();
  561. }
  562. });
  563. });
  564. observer.observe(swiper.el);
  565. };
  566. const removeObserver = () => {
  567. if (animationFrame) {
  568. window.cancelAnimationFrame(animationFrame);
  569. }
  570. if (observer && observer.unobserve && swiper.el) {
  571. observer.unobserve(swiper.el);
  572. observer = null;
  573. }
  574. };
  575. const orientationChangeHandler = () => {
  576. if (!swiper || swiper.destroyed || !swiper.initialized) return;
  577. emit('orientationchange');
  578. };
  579. on('init', () => {
  580. if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {
  581. createObserver();
  582. return;
  583. }
  584. window.addEventListener('resize', resizeHandler);
  585. window.addEventListener('orientationchange', orientationChangeHandler);
  586. });
  587. on('destroy', () => {
  588. removeObserver();
  589. window.removeEventListener('resize', resizeHandler);
  590. window.removeEventListener('orientationchange', orientationChangeHandler);
  591. });
  592. }
  593. function Observer(_ref) {
  594. let {
  595. swiper,
  596. extendParams,
  597. on,
  598. emit
  599. } = _ref;
  600. const observers = [];
  601. const window = getWindow();
  602. const attach = function (target, options) {
  603. if (options === void 0) {
  604. options = {};
  605. }
  606. const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
  607. const observer = new ObserverFunc(mutations => {
  608. // The observerUpdate event should only be triggered
  609. // once despite the number of mutations. Additional
  610. // triggers are redundant and are very costly
  611. if (swiper.__preventObserver__) return;
  612. if (mutations.length === 1) {
  613. emit('observerUpdate', mutations[0]);
  614. return;
  615. }
  616. const observerUpdate = function observerUpdate() {
  617. emit('observerUpdate', mutations[0]);
  618. };
  619. if (window.requestAnimationFrame) {
  620. window.requestAnimationFrame(observerUpdate);
  621. } else {
  622. window.setTimeout(observerUpdate, 0);
  623. }
  624. });
  625. observer.observe(target, {
  626. attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
  627. childList: swiper.isElement || (typeof options.childList === 'undefined' ? true : options).childList,
  628. characterData: typeof options.characterData === 'undefined' ? true : options.characterData
  629. });
  630. observers.push(observer);
  631. };
  632. const init = () => {
  633. if (!swiper.params.observer) return;
  634. if (swiper.params.observeParents) {
  635. const containerParents = elementParents(swiper.hostEl);
  636. for (let i = 0; i < containerParents.length; i += 1) {
  637. attach(containerParents[i]);
  638. }
  639. }
  640. // Observe container
  641. attach(swiper.hostEl, {
  642. childList: swiper.params.observeSlideChildren
  643. });
  644. // Observe wrapper
  645. attach(swiper.wrapperEl, {
  646. attributes: false
  647. });
  648. };
  649. const destroy = () => {
  650. observers.forEach(observer => {
  651. observer.disconnect();
  652. });
  653. observers.splice(0, observers.length);
  654. };
  655. extendParams({
  656. observer: false,
  657. observeParents: false,
  658. observeSlideChildren: false
  659. });
  660. on('init', init);
  661. on('destroy', destroy);
  662. }
  663. /* eslint-disable no-underscore-dangle */
  664. var eventsEmitter = {
  665. on(events, handler, priority) {
  666. const self = this;
  667. if (!self.eventsListeners || self.destroyed) return self;
  668. if (typeof handler !== 'function') return self;
  669. const method = priority ? 'unshift' : 'push';
  670. events.split(' ').forEach(event => {
  671. if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
  672. self.eventsListeners[event][method](handler);
  673. });
  674. return self;
  675. },
  676. once(events, handler, priority) {
  677. const self = this;
  678. if (!self.eventsListeners || self.destroyed) return self;
  679. if (typeof handler !== 'function') return self;
  680. function onceHandler() {
  681. self.off(events, onceHandler);
  682. if (onceHandler.__emitterProxy) {
  683. delete onceHandler.__emitterProxy;
  684. }
  685. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  686. args[_key] = arguments[_key];
  687. }
  688. handler.apply(self, args);
  689. }
  690. onceHandler.__emitterProxy = handler;
  691. return self.on(events, onceHandler, priority);
  692. },
  693. onAny(handler, priority) {
  694. const self = this;
  695. if (!self.eventsListeners || self.destroyed) return self;
  696. if (typeof handler !== 'function') return self;
  697. const method = priority ? 'unshift' : 'push';
  698. if (self.eventsAnyListeners.indexOf(handler) < 0) {
  699. self.eventsAnyListeners[method](handler);
  700. }
  701. return self;
  702. },
  703. offAny(handler) {
  704. const self = this;
  705. if (!self.eventsListeners || self.destroyed) return self;
  706. if (!self.eventsAnyListeners) return self;
  707. const index = self.eventsAnyListeners.indexOf(handler);
  708. if (index >= 0) {
  709. self.eventsAnyListeners.splice(index, 1);
  710. }
  711. return self;
  712. },
  713. off(events, handler) {
  714. const self = this;
  715. if (!self.eventsListeners || self.destroyed) return self;
  716. if (!self.eventsListeners) return self;
  717. events.split(' ').forEach(event => {
  718. if (typeof handler === 'undefined') {
  719. self.eventsListeners[event] = [];
  720. } else if (self.eventsListeners[event]) {
  721. self.eventsListeners[event].forEach((eventHandler, index) => {
  722. if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {
  723. self.eventsListeners[event].splice(index, 1);
  724. }
  725. });
  726. }
  727. });
  728. return self;
  729. },
  730. emit() {
  731. const self = this;
  732. if (!self.eventsListeners || self.destroyed) return self;
  733. if (!self.eventsListeners) return self;
  734. let events;
  735. let data;
  736. let context;
  737. for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  738. args[_key2] = arguments[_key2];
  739. }
  740. if (typeof args[0] === 'string' || Array.isArray(args[0])) {
  741. events = args[0];
  742. data = args.slice(1, args.length);
  743. context = self;
  744. } else {
  745. events = args[0].events;
  746. data = args[0].data;
  747. context = args[0].context || self;
  748. }
  749. data.unshift(context);
  750. const eventsArray = Array.isArray(events) ? events : events.split(' ');
  751. eventsArray.forEach(event => {
  752. if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
  753. self.eventsAnyListeners.forEach(eventHandler => {
  754. eventHandler.apply(context, [event, ...data]);
  755. });
  756. }
  757. if (self.eventsListeners && self.eventsListeners[event]) {
  758. self.eventsListeners[event].forEach(eventHandler => {
  759. eventHandler.apply(context, data);
  760. });
  761. }
  762. });
  763. return self;
  764. }
  765. };
  766. function updateSize() {
  767. const swiper = this;
  768. let width;
  769. let height;
  770. const el = swiper.el;
  771. if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
  772. width = swiper.params.width;
  773. } else {
  774. width = el.clientWidth;
  775. }
  776. if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
  777. height = swiper.params.height;
  778. } else {
  779. height = el.clientHeight;
  780. }
  781. if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
  782. return;
  783. }
  784. // Subtract paddings
  785. width = width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10);
  786. height = height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10);
  787. if (Number.isNaN(width)) width = 0;
  788. if (Number.isNaN(height)) height = 0;
  789. Object.assign(swiper, {
  790. width,
  791. height,
  792. size: swiper.isHorizontal() ? width : height
  793. });
  794. }
  795. function updateSlides() {
  796. const swiper = this;
  797. function getDirectionPropertyValue(node, label) {
  798. return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0);
  799. }
  800. const params = swiper.params;
  801. const {
  802. wrapperEl,
  803. slidesEl,
  804. size: swiperSize,
  805. rtlTranslate: rtl,
  806. wrongRTL
  807. } = swiper;
  808. const isVirtual = swiper.virtual && params.virtual.enabled;
  809. const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
  810. const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
  811. const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
  812. let snapGrid = [];
  813. const slidesGrid = [];
  814. const slidesSizesGrid = [];
  815. let offsetBefore = params.slidesOffsetBefore;
  816. if (typeof offsetBefore === 'function') {
  817. offsetBefore = params.slidesOffsetBefore.call(swiper);
  818. }
  819. let offsetAfter = params.slidesOffsetAfter;
  820. if (typeof offsetAfter === 'function') {
  821. offsetAfter = params.slidesOffsetAfter.call(swiper);
  822. }
  823. const previousSnapGridLength = swiper.snapGrid.length;
  824. const previousSlidesGridLength = swiper.slidesGrid.length;
  825. let spaceBetween = params.spaceBetween;
  826. let slidePosition = -offsetBefore;
  827. let prevSlideSize = 0;
  828. let index = 0;
  829. if (typeof swiperSize === 'undefined') {
  830. return;
  831. }
  832. if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
  833. spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
  834. } else if (typeof spaceBetween === 'string') {
  835. spaceBetween = parseFloat(spaceBetween);
  836. }
  837. swiper.virtualSize = -spaceBetween;
  838. // reset margins
  839. slides.forEach(slideEl => {
  840. if (rtl) {
  841. slideEl.style.marginLeft = '';
  842. } else {
  843. slideEl.style.marginRight = '';
  844. }
  845. slideEl.style.marginBottom = '';
  846. slideEl.style.marginTop = '';
  847. });
  848. // reset cssMode offsets
  849. if (params.centeredSlides && params.cssMode) {
  850. setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
  851. setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
  852. }
  853. const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
  854. if (gridEnabled) {
  855. swiper.grid.initSlides(slides);
  856. } else if (swiper.grid) {
  857. swiper.grid.unsetSlides();
  858. }
  859. // Calc slides
  860. let slideSize;
  861. const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
  862. return typeof params.breakpoints[key].slidesPerView !== 'undefined';
  863. }).length > 0;
  864. for (let i = 0; i < slidesLength; i += 1) {
  865. slideSize = 0;
  866. let slide;
  867. if (slides[i]) slide = slides[i];
  868. if (gridEnabled) {
  869. swiper.grid.updateSlide(i, slide, slides);
  870. }
  871. if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
  872. if (params.slidesPerView === 'auto') {
  873. if (shouldResetSlideSize) {
  874. slides[i].style[swiper.getDirectionLabel('width')] = ``;
  875. }
  876. const slideStyles = getComputedStyle(slide);
  877. const currentTransform = slide.style.transform;
  878. const currentWebKitTransform = slide.style.webkitTransform;
  879. if (currentTransform) {
  880. slide.style.transform = 'none';
  881. }
  882. if (currentWebKitTransform) {
  883. slide.style.webkitTransform = 'none';
  884. }
  885. if (params.roundLengths) {
  886. slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true);
  887. } else {
  888. // eslint-disable-next-line
  889. const width = getDirectionPropertyValue(slideStyles, 'width');
  890. const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
  891. const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
  892. const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
  893. const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
  894. const boxSizing = slideStyles.getPropertyValue('box-sizing');
  895. if (boxSizing && boxSizing === 'border-box') {
  896. slideSize = width + marginLeft + marginRight;
  897. } else {
  898. const {
  899. clientWidth,
  900. offsetWidth
  901. } = slide;
  902. slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
  903. }
  904. }
  905. if (currentTransform) {
  906. slide.style.transform = currentTransform;
  907. }
  908. if (currentWebKitTransform) {
  909. slide.style.webkitTransform = currentWebKitTransform;
  910. }
  911. if (params.roundLengths) slideSize = Math.floor(slideSize);
  912. } else {
  913. slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
  914. if (params.roundLengths) slideSize = Math.floor(slideSize);
  915. if (slides[i]) {
  916. slides[i].style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
  917. }
  918. }
  919. if (slides[i]) {
  920. slides[i].swiperSlideSize = slideSize;
  921. }
  922. slidesSizesGrid.push(slideSize);
  923. if (params.centeredSlides) {
  924. slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
  925. if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
  926. if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
  927. if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
  928. if (params.roundLengths) slidePosition = Math.floor(slidePosition);
  929. if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
  930. slidesGrid.push(slidePosition);
  931. } else {
  932. if (params.roundLengths) slidePosition = Math.floor(slidePosition);
  933. if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
  934. slidesGrid.push(slidePosition);
  935. slidePosition = slidePosition + slideSize + spaceBetween;
  936. }
  937. swiper.virtualSize += slideSize + spaceBetween;
  938. prevSlideSize = slideSize;
  939. index += 1;
  940. }
  941. swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
  942. if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
  943. wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
  944. }
  945. if (params.setWrapperSize) {
  946. wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
  947. }
  948. if (gridEnabled) {
  949. swiper.grid.updateWrapperSize(slideSize, snapGrid);
  950. }
  951. // Remove last grid elements depending on width
  952. if (!params.centeredSlides) {
  953. const newSlidesGrid = [];
  954. for (let i = 0; i < snapGrid.length; i += 1) {
  955. let slidesGridItem = snapGrid[i];
  956. if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
  957. if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
  958. newSlidesGrid.push(slidesGridItem);
  959. }
  960. }
  961. snapGrid = newSlidesGrid;
  962. if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
  963. snapGrid.push(swiper.virtualSize - swiperSize);
  964. }
  965. }
  966. if (isVirtual && params.loop) {
  967. const size = slidesSizesGrid[0] + spaceBetween;
  968. if (params.slidesPerGroup > 1) {
  969. const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
  970. const groupSize = size * params.slidesPerGroup;
  971. for (let i = 0; i < groups; i += 1) {
  972. snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
  973. }
  974. }
  975. for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
  976. if (params.slidesPerGroup === 1) {
  977. snapGrid.push(snapGrid[snapGrid.length - 1] + size);
  978. }
  979. slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
  980. swiper.virtualSize += size;
  981. }
  982. }
  983. if (snapGrid.length === 0) snapGrid = [0];
  984. if (spaceBetween !== 0) {
  985. const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight');
  986. slides.filter((_, slideIndex) => {
  987. if (!params.cssMode || params.loop) return true;
  988. if (slideIndex === slides.length - 1) {
  989. return false;
  990. }
  991. return true;
  992. }).forEach(slideEl => {
  993. slideEl.style[key] = `${spaceBetween}px`;
  994. });
  995. }
  996. if (params.centeredSlides && params.centeredSlidesBounds) {
  997. let allSlidesSize = 0;
  998. slidesSizesGrid.forEach(slideSizeValue => {
  999. allSlidesSize += slideSizeValue + (spaceBetween || 0);
  1000. });
  1001. allSlidesSize -= spaceBetween;
  1002. const maxSnap = allSlidesSize > swiperSize ? allSlidesSize - swiperSize : 0;
  1003. snapGrid = snapGrid.map(snap => {
  1004. if (snap <= 0) return -offsetBefore;
  1005. if (snap > maxSnap) return maxSnap + offsetAfter;
  1006. return snap;
  1007. });
  1008. }
  1009. if (params.centerInsufficientSlides) {
  1010. let allSlidesSize = 0;
  1011. slidesSizesGrid.forEach(slideSizeValue => {
  1012. allSlidesSize += slideSizeValue + (spaceBetween || 0);
  1013. });
  1014. allSlidesSize -= spaceBetween;
  1015. const offsetSize = (params.slidesOffsetBefore || 0) + (params.slidesOffsetAfter || 0);
  1016. if (allSlidesSize + offsetSize < swiperSize) {
  1017. const allSlidesOffset = (swiperSize - allSlidesSize - offsetSize) / 2;
  1018. snapGrid.forEach((snap, snapIndex) => {
  1019. snapGrid[snapIndex] = snap - allSlidesOffset;
  1020. });
  1021. slidesGrid.forEach((snap, snapIndex) => {
  1022. slidesGrid[snapIndex] = snap + allSlidesOffset;
  1023. });
  1024. }
  1025. }
  1026. Object.assign(swiper, {
  1027. slides,
  1028. snapGrid,
  1029. slidesGrid,
  1030. slidesSizesGrid
  1031. });
  1032. if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
  1033. setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
  1034. setCSSProperty(wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
  1035. const addToSnapGrid = -swiper.snapGrid[0];
  1036. const addToSlidesGrid = -swiper.slidesGrid[0];
  1037. swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
  1038. swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
  1039. }
  1040. if (slidesLength !== previousSlidesLength) {
  1041. swiper.emit('slidesLengthChange');
  1042. }
  1043. if (snapGrid.length !== previousSnapGridLength) {
  1044. if (swiper.params.watchOverflow) swiper.checkOverflow();
  1045. swiper.emit('snapGridLengthChange');
  1046. }
  1047. if (slidesGrid.length !== previousSlidesGridLength) {
  1048. swiper.emit('slidesGridLengthChange');
  1049. }
  1050. if (params.watchSlidesProgress) {
  1051. swiper.updateSlidesOffset();
  1052. }
  1053. swiper.emit('slidesUpdated');
  1054. if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
  1055. const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
  1056. const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
  1057. if (slidesLength <= params.maxBackfaceHiddenSlides) {
  1058. if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass);
  1059. } else if (hasClassBackfaceClassAdded) {
  1060. swiper.el.classList.remove(backFaceHiddenClass);
  1061. }
  1062. }
  1063. }
  1064. function updateAutoHeight(speed) {
  1065. const swiper = this;
  1066. const activeSlides = [];
  1067. const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
  1068. let newHeight = 0;
  1069. let i;
  1070. if (typeof speed === 'number') {
  1071. swiper.setTransition(speed);
  1072. } else if (speed === true) {
  1073. swiper.setTransition(swiper.params.speed);
  1074. }
  1075. const getSlideByIndex = index => {
  1076. if (isVirtual) {
  1077. return swiper.slides[swiper.getSlideIndexByData(index)];
  1078. }
  1079. return swiper.slides[index];
  1080. };
  1081. // Find slides currently in view
  1082. if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
  1083. if (swiper.params.centeredSlides) {
  1084. (swiper.visibleSlides || []).forEach(slide => {
  1085. activeSlides.push(slide);
  1086. });
  1087. } else {
  1088. for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
  1089. const index = swiper.activeIndex + i;
  1090. if (index > swiper.slides.length && !isVirtual) break;
  1091. activeSlides.push(getSlideByIndex(index));
  1092. }
  1093. }
  1094. } else {
  1095. activeSlides.push(getSlideByIndex(swiper.activeIndex));
  1096. }
  1097. // Find new height from highest slide in view
  1098. for (i = 0; i < activeSlides.length; i += 1) {
  1099. if (typeof activeSlides[i] !== 'undefined') {
  1100. const height = activeSlides[i].offsetHeight;
  1101. newHeight = height > newHeight ? height : newHeight;
  1102. }
  1103. }
  1104. // Update Height
  1105. if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
  1106. }
  1107. function updateSlidesOffset() {
  1108. const swiper = this;
  1109. const slides = swiper.slides;
  1110. // eslint-disable-next-line
  1111. const minusOffset = swiper.isElement ? swiper.isHorizontal() ? swiper.wrapperEl.offsetLeft : swiper.wrapperEl.offsetTop : 0;
  1112. for (let i = 0; i < slides.length; i += 1) {
  1113. slides[i].swiperSlideOffset = (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) - minusOffset - swiper.cssOverflowAdjustment();
  1114. }
  1115. }
  1116. const toggleSlideClasses$1 = (slideEl, condition, className) => {
  1117. if (condition && !slideEl.classList.contains(className)) {
  1118. slideEl.classList.add(className);
  1119. } else if (!condition && slideEl.classList.contains(className)) {
  1120. slideEl.classList.remove(className);
  1121. }
  1122. };
  1123. function updateSlidesProgress(translate) {
  1124. if (translate === void 0) {
  1125. translate = this && this.translate || 0;
  1126. }
  1127. const swiper = this;
  1128. const params = swiper.params;
  1129. const {
  1130. slides,
  1131. rtlTranslate: rtl,
  1132. snapGrid
  1133. } = swiper;
  1134. if (slides.length === 0) return;
  1135. if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
  1136. let offsetCenter = -translate;
  1137. if (rtl) offsetCenter = translate;
  1138. swiper.visibleSlidesIndexes = [];
  1139. swiper.visibleSlides = [];
  1140. let spaceBetween = params.spaceBetween;
  1141. if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
  1142. spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
  1143. } else if (typeof spaceBetween === 'string') {
  1144. spaceBetween = parseFloat(spaceBetween);
  1145. }
  1146. for (let i = 0; i < slides.length; i += 1) {
  1147. const slide = slides[i];
  1148. let slideOffset = slide.swiperSlideOffset;
  1149. if (params.cssMode && params.centeredSlides) {
  1150. slideOffset -= slides[0].swiperSlideOffset;
  1151. }
  1152. const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
  1153. const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
  1154. const slideBefore = -(offsetCenter - slideOffset);
  1155. const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
  1156. const isFullyVisible = slideBefore >= 0 && slideBefore <= swiper.size - swiper.slidesSizesGrid[i];
  1157. const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;
  1158. if (isVisible) {
  1159. swiper.visibleSlides.push(slide);
  1160. swiper.visibleSlidesIndexes.push(i);
  1161. }
  1162. toggleSlideClasses$1(slide, isVisible, params.slideVisibleClass);
  1163. toggleSlideClasses$1(slide, isFullyVisible, params.slideFullyVisibleClass);
  1164. slide.progress = rtl ? -slideProgress : slideProgress;
  1165. slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
  1166. }
  1167. }
  1168. function updateProgress(translate) {
  1169. const swiper = this;
  1170. if (typeof translate === 'undefined') {
  1171. const multiplier = swiper.rtlTranslate ? -1 : 1;
  1172. // eslint-disable-next-line
  1173. translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
  1174. }
  1175. const params = swiper.params;
  1176. const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
  1177. let {
  1178. progress,
  1179. isBeginning,
  1180. isEnd,
  1181. progressLoop
  1182. } = swiper;
  1183. const wasBeginning = isBeginning;
  1184. const wasEnd = isEnd;
  1185. if (translatesDiff === 0) {
  1186. progress = 0;
  1187. isBeginning = true;
  1188. isEnd = true;
  1189. } else {
  1190. progress = (translate - swiper.minTranslate()) / translatesDiff;
  1191. const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1;
  1192. const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1;
  1193. isBeginning = isBeginningRounded || progress <= 0;
  1194. isEnd = isEndRounded || progress >= 1;
  1195. if (isBeginningRounded) progress = 0;
  1196. if (isEndRounded) progress = 1;
  1197. }
  1198. if (params.loop) {
  1199. const firstSlideIndex = swiper.getSlideIndexByData(0);
  1200. const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1);
  1201. const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex];
  1202. const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex];
  1203. const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1];
  1204. const translateAbs = Math.abs(translate);
  1205. if (translateAbs >= firstSlideTranslate) {
  1206. progressLoop = (translateAbs - firstSlideTranslate) / translateMax;
  1207. } else {
  1208. progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax;
  1209. }
  1210. if (progressLoop > 1) progressLoop -= 1;
  1211. }
  1212. Object.assign(swiper, {
  1213. progress,
  1214. progressLoop,
  1215. isBeginning,
  1216. isEnd
  1217. });
  1218. if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
  1219. if (isBeginning && !wasBeginning) {
  1220. swiper.emit('reachBeginning toEdge');
  1221. }
  1222. if (isEnd && !wasEnd) {
  1223. swiper.emit('reachEnd toEdge');
  1224. }
  1225. if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
  1226. swiper.emit('fromEdge');
  1227. }
  1228. swiper.emit('progress', progress);
  1229. }
  1230. const toggleSlideClasses = (slideEl, condition, className) => {
  1231. if (condition && !slideEl.classList.contains(className)) {
  1232. slideEl.classList.add(className);
  1233. } else if (!condition && slideEl.classList.contains(className)) {
  1234. slideEl.classList.remove(className);
  1235. }
  1236. };
  1237. function updateSlidesClasses() {
  1238. const swiper = this;
  1239. const {
  1240. slides,
  1241. params,
  1242. slidesEl,
  1243. activeIndex
  1244. } = swiper;
  1245. const isVirtual = swiper.virtual && params.virtual.enabled;
  1246. const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
  1247. const getFilteredSlide = selector => {
  1248. return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
  1249. };
  1250. let activeSlide;
  1251. let prevSlide;
  1252. let nextSlide;
  1253. if (isVirtual) {
  1254. if (params.loop) {
  1255. let slideIndex = activeIndex - swiper.virtual.slidesBefore;
  1256. if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
  1257. if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
  1258. activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
  1259. } else {
  1260. activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
  1261. }
  1262. } else {
  1263. if (gridEnabled) {
  1264. activeSlide = slides.filter(slideEl => slideEl.column === activeIndex)[0];
  1265. nextSlide = slides.filter(slideEl => slideEl.column === activeIndex + 1)[0];
  1266. prevSlide = slides.filter(slideEl => slideEl.column === activeIndex - 1)[0];
  1267. } else {
  1268. activeSlide = slides[activeIndex];
  1269. }
  1270. }
  1271. if (activeSlide) {
  1272. if (!gridEnabled) {
  1273. // Next Slide
  1274. nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
  1275. if (params.loop && !nextSlide) {
  1276. nextSlide = slides[0];
  1277. }
  1278. // Prev Slide
  1279. prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
  1280. if (params.loop && !prevSlide === 0) {
  1281. prevSlide = slides[slides.length - 1];
  1282. }
  1283. }
  1284. }
  1285. slides.forEach(slideEl => {
  1286. toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
  1287. toggleSlideClasses(slideEl, slideEl === nextSlide, params.slideNextClass);
  1288. toggleSlideClasses(slideEl, slideEl === prevSlide, params.slidePrevClass);
  1289. });
  1290. swiper.emitSlidesClasses();
  1291. }
  1292. const processLazyPreloader = (swiper, imageEl) => {
  1293. if (!swiper || swiper.destroyed || !swiper.params) return;
  1294. const slideSelector = () => swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
  1295. const slideEl = imageEl.closest(slideSelector());
  1296. if (slideEl) {
  1297. let lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`);
  1298. if (!lazyEl && swiper.isElement) {
  1299. if (slideEl.shadowRoot) {
  1300. lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
  1301. } else {
  1302. // init later
  1303. requestAnimationFrame(() => {
  1304. if (slideEl.shadowRoot) {
  1305. lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
  1306. if (lazyEl) lazyEl.remove();
  1307. }
  1308. });
  1309. }
  1310. }
  1311. if (lazyEl) lazyEl.remove();
  1312. }
  1313. };
  1314. const unlazy = (swiper, index) => {
  1315. if (!swiper.slides[index]) return;
  1316. const imageEl = swiper.slides[index].querySelector('[loading="lazy"]');
  1317. if (imageEl) imageEl.removeAttribute('loading');
  1318. };
  1319. const preload = swiper => {
  1320. if (!swiper || swiper.destroyed || !swiper.params) return;
  1321. let amount = swiper.params.lazyPreloadPrevNext;
  1322. const len = swiper.slides.length;
  1323. if (!len || !amount || amount < 0) return;
  1324. amount = Math.min(amount, len);
  1325. const slidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView);
  1326. const activeIndex = swiper.activeIndex;
  1327. if (swiper.params.grid && swiper.params.grid.rows > 1) {
  1328. const activeColumn = activeIndex;
  1329. const preloadColumns = [activeColumn - amount];
  1330. preloadColumns.push(...Array.from({
  1331. length: amount
  1332. }).map((_, i) => {
  1333. return activeColumn + slidesPerView + i;
  1334. }));
  1335. swiper.slides.forEach((slideEl, i) => {
  1336. if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i);
  1337. });
  1338. return;
  1339. }
  1340. const slideIndexLastInView = activeIndex + slidesPerView - 1;
  1341. if (swiper.params.rewind || swiper.params.loop) {
  1342. for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) {
  1343. const realIndex = (i % len + len) % len;
  1344. if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex);
  1345. }
  1346. } else {
  1347. for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) {
  1348. if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) {
  1349. unlazy(swiper, i);
  1350. }
  1351. }
  1352. }
  1353. };
  1354. function getActiveIndexByTranslate(swiper) {
  1355. const {
  1356. slidesGrid,
  1357. params
  1358. } = swiper;
  1359. const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
  1360. let activeIndex;
  1361. for (let i = 0; i < slidesGrid.length; i += 1) {
  1362. if (typeof slidesGrid[i + 1] !== 'undefined') {
  1363. if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
  1364. activeIndex = i;
  1365. } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
  1366. activeIndex = i + 1;
  1367. }
  1368. } else if (translate >= slidesGrid[i]) {
  1369. activeIndex = i;
  1370. }
  1371. }
  1372. // Normalize slideIndex
  1373. if (params.normalizeSlideIndex) {
  1374. if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
  1375. }
  1376. return activeIndex;
  1377. }
  1378. function updateActiveIndex(newActiveIndex) {
  1379. const swiper = this;
  1380. const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
  1381. const {
  1382. snapGrid,
  1383. params,
  1384. activeIndex: previousIndex,
  1385. realIndex: previousRealIndex,
  1386. snapIndex: previousSnapIndex
  1387. } = swiper;
  1388. let activeIndex = newActiveIndex;
  1389. let snapIndex;
  1390. const getVirtualRealIndex = aIndex => {
  1391. let realIndex = aIndex - swiper.virtual.slidesBefore;
  1392. if (realIndex < 0) {
  1393. realIndex = swiper.virtual.slides.length + realIndex;
  1394. }
  1395. if (realIndex >= swiper.virtual.slides.length) {
  1396. realIndex -= swiper.virtual.slides.length;
  1397. }
  1398. return realIndex;
  1399. };
  1400. if (typeof activeIndex === 'undefined') {
  1401. activeIndex = getActiveIndexByTranslate(swiper);
  1402. }
  1403. if (snapGrid.indexOf(translate) >= 0) {
  1404. snapIndex = snapGrid.indexOf(translate);
  1405. } else {
  1406. const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
  1407. snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
  1408. }
  1409. if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
  1410. if (activeIndex === previousIndex && !swiper.params.loop) {
  1411. if (snapIndex !== previousSnapIndex) {
  1412. swiper.snapIndex = snapIndex;
  1413. swiper.emit('snapIndexChange');
  1414. }
  1415. return;
  1416. }
  1417. if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
  1418. swiper.realIndex = getVirtualRealIndex(activeIndex);
  1419. return;
  1420. }
  1421. const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
  1422. // Get real index
  1423. let realIndex;
  1424. if (swiper.virtual && params.virtual.enabled && params.loop) {
  1425. realIndex = getVirtualRealIndex(activeIndex);
  1426. } else if (gridEnabled) {
  1427. const firstSlideInColumn = swiper.slides.filter(slideEl => slideEl.column === activeIndex)[0];
  1428. let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10);
  1429. if (Number.isNaN(activeSlideIndex)) {
  1430. activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0);
  1431. }
  1432. realIndex = Math.floor(activeSlideIndex / params.grid.rows);
  1433. } else if (swiper.slides[activeIndex]) {
  1434. const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index');
  1435. if (slideIndex) {
  1436. realIndex = parseInt(slideIndex, 10);
  1437. } else {
  1438. realIndex = activeIndex;
  1439. }
  1440. } else {
  1441. realIndex = activeIndex;
  1442. }
  1443. Object.assign(swiper, {
  1444. previousSnapIndex,
  1445. snapIndex,
  1446. previousRealIndex,
  1447. realIndex,
  1448. previousIndex,
  1449. activeIndex
  1450. });
  1451. if (swiper.initialized) {
  1452. preload(swiper);
  1453. }
  1454. swiper.emit('activeIndexChange');
  1455. swiper.emit('snapIndexChange');
  1456. if (swiper.initialized || swiper.params.runCallbacksOnInit) {
  1457. if (previousRealIndex !== realIndex) {
  1458. swiper.emit('realIndexChange');
  1459. }
  1460. swiper.emit('slideChange');
  1461. }
  1462. }
  1463. function updateClickedSlide(el, path) {
  1464. const swiper = this;
  1465. const params = swiper.params;
  1466. let slide = el.closest(`.${params.slideClass}, swiper-slide`);
  1467. if (!slide && swiper.isElement && path && path.length > 1 && path.includes(el)) {
  1468. [...path.slice(path.indexOf(el) + 1, path.length)].forEach(pathEl => {
  1469. if (!slide && pathEl.matches && pathEl.matches(`.${params.slideClass}, swiper-slide`)) {
  1470. slide = pathEl;
  1471. }
  1472. });
  1473. }
  1474. let slideFound = false;
  1475. let slideIndex;
  1476. if (slide) {
  1477. for (let i = 0; i < swiper.slides.length; i += 1) {
  1478. if (swiper.slides[i] === slide) {
  1479. slideFound = true;
  1480. slideIndex = i;
  1481. break;
  1482. }
  1483. }
  1484. }
  1485. if (slide && slideFound) {
  1486. swiper.clickedSlide = slide;
  1487. if (swiper.virtual && swiper.params.virtual.enabled) {
  1488. swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
  1489. } else {
  1490. swiper.clickedIndex = slideIndex;
  1491. }
  1492. } else {
  1493. swiper.clickedSlide = undefined;
  1494. swiper.clickedIndex = undefined;
  1495. return;
  1496. }
  1497. if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
  1498. swiper.slideToClickedSlide();
  1499. }
  1500. }
  1501. var update = {
  1502. updateSize,
  1503. updateSlides,
  1504. updateAutoHeight,
  1505. updateSlidesOffset,
  1506. updateSlidesProgress,
  1507. updateProgress,
  1508. updateSlidesClasses,
  1509. updateActiveIndex,
  1510. updateClickedSlide
  1511. };
  1512. function getSwiperTranslate(axis) {
  1513. if (axis === void 0) {
  1514. axis = this.isHorizontal() ? 'x' : 'y';
  1515. }
  1516. const swiper = this;
  1517. const {
  1518. params,
  1519. rtlTranslate: rtl,
  1520. translate,
  1521. wrapperEl
  1522. } = swiper;
  1523. if (params.virtualTranslate) {
  1524. return rtl ? -translate : translate;
  1525. }
  1526. if (params.cssMode) {
  1527. return translate;
  1528. }
  1529. let currentTranslate = getTranslate(wrapperEl, axis);
  1530. currentTranslate += swiper.cssOverflowAdjustment();
  1531. if (rtl) currentTranslate = -currentTranslate;
  1532. return currentTranslate || 0;
  1533. }
  1534. function setTranslate(translate, byController) {
  1535. const swiper = this;
  1536. const {
  1537. rtlTranslate: rtl,
  1538. params,
  1539. wrapperEl,
  1540. progress
  1541. } = swiper;
  1542. let x = 0;
  1543. let y = 0;
  1544. const z = 0;
  1545. if (swiper.isHorizontal()) {
  1546. x = rtl ? -translate : translate;
  1547. } else {
  1548. y = translate;
  1549. }
  1550. if (params.roundLengths) {
  1551. x = Math.floor(x);
  1552. y = Math.floor(y);
  1553. }
  1554. swiper.previousTranslate = swiper.translate;
  1555. swiper.translate = swiper.isHorizontal() ? x : y;
  1556. if (params.cssMode) {
  1557. wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
  1558. } else if (!params.virtualTranslate) {
  1559. if (swiper.isHorizontal()) {
  1560. x -= swiper.cssOverflowAdjustment();
  1561. } else {
  1562. y -= swiper.cssOverflowAdjustment();
  1563. }
  1564. wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
  1565. }
  1566. // Check if we need to update progress
  1567. let newProgress;
  1568. const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
  1569. if (translatesDiff === 0) {
  1570. newProgress = 0;
  1571. } else {
  1572. newProgress = (translate - swiper.minTranslate()) / translatesDiff;
  1573. }
  1574. if (newProgress !== progress) {
  1575. swiper.updateProgress(translate);
  1576. }
  1577. swiper.emit('setTranslate', swiper.translate, byController);
  1578. }
  1579. function minTranslate() {
  1580. return -this.snapGrid[0];
  1581. }
  1582. function maxTranslate() {
  1583. return -this.snapGrid[this.snapGrid.length - 1];
  1584. }
  1585. function translateTo(translate, speed, runCallbacks, translateBounds, internal) {
  1586. if (translate === void 0) {
  1587. translate = 0;
  1588. }
  1589. if (speed === void 0) {
  1590. speed = this.params.speed;
  1591. }
  1592. if (runCallbacks === void 0) {
  1593. runCallbacks = true;
  1594. }
  1595. if (translateBounds === void 0) {
  1596. translateBounds = true;
  1597. }
  1598. const swiper = this;
  1599. const {
  1600. params,
  1601. wrapperEl
  1602. } = swiper;
  1603. if (swiper.animating && params.preventInteractionOnTransition) {
  1604. return false;
  1605. }
  1606. const minTranslate = swiper.minTranslate();
  1607. const maxTranslate = swiper.maxTranslate();
  1608. let newTranslate;
  1609. if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate;
  1610. // Update progress
  1611. swiper.updateProgress(newTranslate);
  1612. if (params.cssMode) {
  1613. const isH = swiper.isHorizontal();
  1614. if (speed === 0) {
  1615. wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
  1616. } else {
  1617. if (!swiper.support.smoothScroll) {
  1618. animateCSSModeScroll({
  1619. swiper,
  1620. targetPosition: -newTranslate,
  1621. side: isH ? 'left' : 'top'
  1622. });
  1623. return true;
  1624. }
  1625. wrapperEl.scrollTo({
  1626. [isH ? 'left' : 'top']: -newTranslate,
  1627. behavior: 'smooth'
  1628. });
  1629. }
  1630. return true;
  1631. }
  1632. if (speed === 0) {
  1633. swiper.setTransition(0);
  1634. swiper.setTranslate(newTranslate);
  1635. if (runCallbacks) {
  1636. swiper.emit('beforeTransitionStart', speed, internal);
  1637. swiper.emit('transitionEnd');
  1638. }
  1639. } else {
  1640. swiper.setTransition(speed);
  1641. swiper.setTranslate(newTranslate);
  1642. if (runCallbacks) {
  1643. swiper.emit('beforeTransitionStart', speed, internal);
  1644. swiper.emit('transitionStart');
  1645. }
  1646. if (!swiper.animating) {
  1647. swiper.animating = true;
  1648. if (!swiper.onTranslateToWrapperTransitionEnd) {
  1649. swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
  1650. if (!swiper || swiper.destroyed) return;
  1651. if (e.target !== this) return;
  1652. swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
  1653. swiper.onTranslateToWrapperTransitionEnd = null;
  1654. delete swiper.onTranslateToWrapperTransitionEnd;
  1655. swiper.animating = false;
  1656. if (runCallbacks) {
  1657. swiper.emit('transitionEnd');
  1658. }
  1659. };
  1660. }
  1661. swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
  1662. }
  1663. }
  1664. return true;
  1665. }
  1666. var translate = {
  1667. getTranslate: getSwiperTranslate,
  1668. setTranslate,
  1669. minTranslate,
  1670. maxTranslate,
  1671. translateTo
  1672. };
  1673. function setTransition(duration, byController) {
  1674. const swiper = this;
  1675. if (!swiper.params.cssMode) {
  1676. swiper.wrapperEl.style.transitionDuration = `${duration}ms`;
  1677. swiper.wrapperEl.style.transitionDelay = duration === 0 ? `0ms` : '';
  1678. }
  1679. swiper.emit('setTransition', duration, byController);
  1680. }
  1681. function transitionEmit(_ref) {
  1682. let {
  1683. swiper,
  1684. runCallbacks,
  1685. direction,
  1686. step
  1687. } = _ref;
  1688. const {
  1689. activeIndex,
  1690. previousIndex
  1691. } = swiper;
  1692. let dir = direction;
  1693. if (!dir) {
  1694. if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';
  1695. }
  1696. swiper.emit(`transition${step}`);
  1697. if (runCallbacks && activeIndex !== previousIndex) {
  1698. if (dir === 'reset') {
  1699. swiper.emit(`slideResetTransition${step}`);
  1700. return;
  1701. }
  1702. swiper.emit(`slideChangeTransition${step}`);
  1703. if (dir === 'next') {
  1704. swiper.emit(`slideNextTransition${step}`);
  1705. } else {
  1706. swiper.emit(`slidePrevTransition${step}`);
  1707. }
  1708. }
  1709. }
  1710. function transitionStart(runCallbacks, direction) {
  1711. if (runCallbacks === void 0) {
  1712. runCallbacks = true;
  1713. }
  1714. const swiper = this;
  1715. const {
  1716. params
  1717. } = swiper;
  1718. if (params.cssMode) return;
  1719. if (params.autoHeight) {
  1720. swiper.updateAutoHeight();
  1721. }
  1722. transitionEmit({
  1723. swiper,
  1724. runCallbacks,
  1725. direction,
  1726. step: 'Start'
  1727. });
  1728. }
  1729. function transitionEnd(runCallbacks, direction) {
  1730. if (runCallbacks === void 0) {
  1731. runCallbacks = true;
  1732. }
  1733. const swiper = this;
  1734. const {
  1735. params
  1736. } = swiper;
  1737. swiper.animating = false;
  1738. if (params.cssMode) return;
  1739. swiper.setTransition(0);
  1740. transitionEmit({
  1741. swiper,
  1742. runCallbacks,
  1743. direction,
  1744. step: 'End'
  1745. });
  1746. }
  1747. var transition = {
  1748. setTransition,
  1749. transitionStart,
  1750. transitionEnd
  1751. };
  1752. function slideTo(index, speed, runCallbacks, internal, initial) {
  1753. if (index === void 0) {
  1754. index = 0;
  1755. }
  1756. if (runCallbacks === void 0) {
  1757. runCallbacks = true;
  1758. }
  1759. if (typeof index === 'string') {
  1760. index = parseInt(index, 10);
  1761. }
  1762. const swiper = this;
  1763. let slideIndex = index;
  1764. if (slideIndex < 0) slideIndex = 0;
  1765. const {
  1766. params,
  1767. snapGrid,
  1768. slidesGrid,
  1769. previousIndex,
  1770. activeIndex,
  1771. rtlTranslate: rtl,
  1772. wrapperEl,
  1773. enabled
  1774. } = swiper;
  1775. if (!enabled && !internal && !initial || swiper.destroyed || swiper.animating && params.preventInteractionOnTransition) {
  1776. return false;
  1777. }
  1778. if (typeof speed === 'undefined') {
  1779. speed = swiper.params.speed;
  1780. }
  1781. const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
  1782. let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
  1783. if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
  1784. const translate = -snapGrid[snapIndex];
  1785. // Normalize slideIndex
  1786. if (params.normalizeSlideIndex) {
  1787. for (let i = 0; i < slidesGrid.length; i += 1) {
  1788. const normalizedTranslate = -Math.floor(translate * 100);
  1789. const normalizedGrid = Math.floor(slidesGrid[i] * 100);
  1790. const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
  1791. if (typeof slidesGrid[i + 1] !== 'undefined') {
  1792. if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
  1793. slideIndex = i;
  1794. } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
  1795. slideIndex = i + 1;
  1796. }
  1797. } else if (normalizedTranslate >= normalizedGrid) {
  1798. slideIndex = i;
  1799. }
  1800. }
  1801. }
  1802. // Directions locks
  1803. if (swiper.initialized && slideIndex !== activeIndex) {
  1804. if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
  1805. return false;
  1806. }
  1807. if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
  1808. if ((activeIndex || 0) !== slideIndex) {
  1809. return false;
  1810. }
  1811. }
  1812. }
  1813. if (slideIndex !== (previousIndex || 0) && runCallbacks) {
  1814. swiper.emit('beforeSlideChangeStart');
  1815. }
  1816. // Update progress
  1817. swiper.updateProgress(translate);
  1818. let direction;
  1819. if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
  1820. // initial virtual
  1821. const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
  1822. const isInitialVirtual = isVirtual && initial;
  1823. // Update Index
  1824. if (!isInitialVirtual && (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate)) {
  1825. swiper.updateActiveIndex(slideIndex);
  1826. // Update Height
  1827. if (params.autoHeight) {
  1828. swiper.updateAutoHeight();
  1829. }
  1830. swiper.updateSlidesClasses();
  1831. if (params.effect !== 'slide') {
  1832. swiper.setTranslate(translate);
  1833. }
  1834. if (direction !== 'reset') {
  1835. swiper.transitionStart(runCallbacks, direction);
  1836. swiper.transitionEnd(runCallbacks, direction);
  1837. }
  1838. return false;
  1839. }
  1840. if (params.cssMode) {
  1841. const isH = swiper.isHorizontal();
  1842. const t = rtl ? translate : -translate;
  1843. if (speed === 0) {
  1844. if (isVirtual) {
  1845. swiper.wrapperEl.style.scrollSnapType = 'none';
  1846. swiper._immediateVirtual = true;
  1847. }
  1848. if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
  1849. swiper._cssModeVirtualInitialSet = true;
  1850. requestAnimationFrame(() => {
  1851. wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
  1852. });
  1853. } else {
  1854. wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
  1855. }
  1856. if (isVirtual) {
  1857. requestAnimationFrame(() => {
  1858. swiper.wrapperEl.style.scrollSnapType = '';
  1859. swiper._immediateVirtual = false;
  1860. });
  1861. }
  1862. } else {
  1863. if (!swiper.support.smoothScroll) {
  1864. animateCSSModeScroll({
  1865. swiper,
  1866. targetPosition: t,
  1867. side: isH ? 'left' : 'top'
  1868. });
  1869. return true;
  1870. }
  1871. wrapperEl.scrollTo({
  1872. [isH ? 'left' : 'top']: t,
  1873. behavior: 'smooth'
  1874. });
  1875. }
  1876. return true;
  1877. }
  1878. swiper.setTransition(speed);
  1879. swiper.setTranslate(translate);
  1880. swiper.updateActiveIndex(slideIndex);
  1881. swiper.updateSlidesClasses();
  1882. swiper.emit('beforeTransitionStart', speed, internal);
  1883. swiper.transitionStart(runCallbacks, direction);
  1884. if (speed === 0) {
  1885. swiper.transitionEnd(runCallbacks, direction);
  1886. } else if (!swiper.animating) {
  1887. swiper.animating = true;
  1888. if (!swiper.onSlideToWrapperTransitionEnd) {
  1889. swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
  1890. if (!swiper || swiper.destroyed) return;
  1891. if (e.target !== this) return;
  1892. swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
  1893. swiper.onSlideToWrapperTransitionEnd = null;
  1894. delete swiper.onSlideToWrapperTransitionEnd;
  1895. swiper.transitionEnd(runCallbacks, direction);
  1896. };
  1897. }
  1898. swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
  1899. }
  1900. return true;
  1901. }
  1902. function slideToLoop(index, speed, runCallbacks, internal) {
  1903. if (index === void 0) {
  1904. index = 0;
  1905. }
  1906. if (runCallbacks === void 0) {
  1907. runCallbacks = true;
  1908. }
  1909. if (typeof index === 'string') {
  1910. const indexAsNumber = parseInt(index, 10);
  1911. index = indexAsNumber;
  1912. }
  1913. const swiper = this;
  1914. if (swiper.destroyed) return;
  1915. if (typeof speed === 'undefined') {
  1916. speed = swiper.params.speed;
  1917. }
  1918. const gridEnabled = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
  1919. let newIndex = index;
  1920. if (swiper.params.loop) {
  1921. if (swiper.virtual && swiper.params.virtual.enabled) {
  1922. // eslint-disable-next-line
  1923. newIndex = newIndex + swiper.virtual.slidesBefore;
  1924. } else {
  1925. let targetSlideIndex;
  1926. if (gridEnabled) {
  1927. const slideIndex = newIndex * swiper.params.grid.rows;
  1928. targetSlideIndex = swiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex)[0].column;
  1929. } else {
  1930. targetSlideIndex = swiper.getSlideIndexByData(newIndex);
  1931. }
  1932. const cols = gridEnabled ? Math.ceil(swiper.slides.length / swiper.params.grid.rows) : swiper.slides.length;
  1933. const {
  1934. centeredSlides
  1935. } = swiper.params;
  1936. let slidesPerView = swiper.params.slidesPerView;
  1937. if (slidesPerView === 'auto') {
  1938. slidesPerView = swiper.slidesPerViewDynamic();
  1939. } else {
  1940. slidesPerView = Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
  1941. if (centeredSlides && slidesPerView % 2 === 0) {
  1942. slidesPerView = slidesPerView + 1;
  1943. }
  1944. }
  1945. let needLoopFix = cols - targetSlideIndex < slidesPerView;
  1946. if (centeredSlides) {
  1947. needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2);
  1948. }
  1949. if (internal && centeredSlides && swiper.params.slidesPerView !== 'auto' && !gridEnabled) {
  1950. needLoopFix = false;
  1951. }
  1952. if (needLoopFix) {
  1953. const direction = centeredSlides ? targetSlideIndex < swiper.activeIndex ? 'prev' : 'next' : targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView ? 'next' : 'prev';
  1954. swiper.loopFix({
  1955. direction,
  1956. slideTo: true,
  1957. activeSlideIndex: direction === 'next' ? targetSlideIndex + 1 : targetSlideIndex - cols + 1,
  1958. slideRealIndex: direction === 'next' ? swiper.realIndex : undefined
  1959. });
  1960. }
  1961. if (gridEnabled) {
  1962. const slideIndex = newIndex * swiper.params.grid.rows;
  1963. newIndex = swiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex)[0].column;
  1964. } else {
  1965. newIndex = swiper.getSlideIndexByData(newIndex);
  1966. }
  1967. }
  1968. }
  1969. requestAnimationFrame(() => {
  1970. swiper.slideTo(newIndex, speed, runCallbacks, internal);
  1971. });
  1972. return swiper;
  1973. }
  1974. /* eslint no-unused-vars: "off" */
  1975. function slideNext(speed, runCallbacks, internal) {
  1976. if (runCallbacks === void 0) {
  1977. runCallbacks = true;
  1978. }
  1979. const swiper = this;
  1980. const {
  1981. enabled,
  1982. params,
  1983. animating
  1984. } = swiper;
  1985. if (!enabled || swiper.destroyed) return swiper;
  1986. if (typeof speed === 'undefined') {
  1987. speed = swiper.params.speed;
  1988. }
  1989. let perGroup = params.slidesPerGroup;
  1990. if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
  1991. perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
  1992. }
  1993. const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
  1994. const isVirtual = swiper.virtual && params.virtual.enabled;
  1995. if (params.loop) {
  1996. if (animating && !isVirtual && params.loopPreventsSliding) return false;
  1997. swiper.loopFix({
  1998. direction: 'next'
  1999. });
  2000. // eslint-disable-next-line
  2001. swiper._clientLeft = swiper.wrapperEl.clientLeft;
  2002. if (swiper.activeIndex === swiper.slides.length - 1 && params.cssMode) {
  2003. requestAnimationFrame(() => {
  2004. swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
  2005. });
  2006. return true;
  2007. }
  2008. }
  2009. if (params.rewind && swiper.isEnd) {
  2010. return swiper.slideTo(0, speed, runCallbacks, internal);
  2011. }
  2012. return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
  2013. }
  2014. /* eslint no-unused-vars: "off" */
  2015. function slidePrev(speed, runCallbacks, internal) {
  2016. if (runCallbacks === void 0) {
  2017. runCallbacks = true;
  2018. }
  2019. const swiper = this;
  2020. const {
  2021. params,
  2022. snapGrid,
  2023. slidesGrid,
  2024. rtlTranslate,
  2025. enabled,
  2026. animating
  2027. } = swiper;
  2028. if (!enabled || swiper.destroyed) return swiper;
  2029. if (typeof speed === 'undefined') {
  2030. speed = swiper.params.speed;
  2031. }
  2032. const isVirtual = swiper.virtual && params.virtual.enabled;
  2033. if (params.loop) {
  2034. if (animating && !isVirtual && params.loopPreventsSliding) return false;
  2035. swiper.loopFix({
  2036. direction: 'prev'
  2037. });
  2038. // eslint-disable-next-line
  2039. swiper._clientLeft = swiper.wrapperEl.clientLeft;
  2040. }
  2041. const translate = rtlTranslate ? swiper.translate : -swiper.translate;
  2042. function normalize(val) {
  2043. if (val < 0) return -Math.floor(Math.abs(val));
  2044. return Math.floor(val);
  2045. }
  2046. const normalizedTranslate = normalize(translate);
  2047. const normalizedSnapGrid = snapGrid.map(val => normalize(val));
  2048. let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
  2049. if (typeof prevSnap === 'undefined' && params.cssMode) {
  2050. let prevSnapIndex;
  2051. snapGrid.forEach((snap, snapIndex) => {
  2052. if (normalizedTranslate >= snap) {
  2053. // prevSnap = snap;
  2054. prevSnapIndex = snapIndex;
  2055. }
  2056. });
  2057. if (typeof prevSnapIndex !== 'undefined') {
  2058. prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
  2059. }
  2060. }
  2061. let prevIndex = 0;
  2062. if (typeof prevSnap !== 'undefined') {
  2063. prevIndex = slidesGrid.indexOf(prevSnap);
  2064. if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
  2065. if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
  2066. prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
  2067. prevIndex = Math.max(prevIndex, 0);
  2068. }
  2069. }
  2070. if (params.rewind && swiper.isBeginning) {
  2071. const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
  2072. return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
  2073. } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) {
  2074. requestAnimationFrame(() => {
  2075. swiper.slideTo(prevIndex, speed, runCallbacks, internal);
  2076. });
  2077. return true;
  2078. }
  2079. return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
  2080. }
  2081. /* eslint no-unused-vars: "off" */
  2082. function slideReset(speed, runCallbacks, internal) {
  2083. if (runCallbacks === void 0) {
  2084. runCallbacks = true;
  2085. }
  2086. const swiper = this;
  2087. if (swiper.destroyed) return;
  2088. if (typeof speed === 'undefined') {
  2089. speed = swiper.params.speed;
  2090. }
  2091. return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
  2092. }
  2093. /* eslint no-unused-vars: "off" */
  2094. function slideToClosest(speed, runCallbacks, internal, threshold) {
  2095. if (runCallbacks === void 0) {
  2096. runCallbacks = true;
  2097. }
  2098. if (threshold === void 0) {
  2099. threshold = 0.5;
  2100. }
  2101. const swiper = this;
  2102. if (swiper.destroyed) return;
  2103. if (typeof speed === 'undefined') {
  2104. speed = swiper.params.speed;
  2105. }
  2106. let index = swiper.activeIndex;
  2107. const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
  2108. const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
  2109. const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
  2110. if (translate >= swiper.snapGrid[snapIndex]) {
  2111. // The current translate is on or after the current snap index, so the choice
  2112. // is between the current index and the one after it.
  2113. const currentSnap = swiper.snapGrid[snapIndex];
  2114. const nextSnap = swiper.snapGrid[snapIndex + 1];
  2115. if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
  2116. index += swiper.params.slidesPerGroup;
  2117. }
  2118. } else {
  2119. // The current translate is before the current snap index, so the choice
  2120. // is between the current index and the one before it.
  2121. const prevSnap = swiper.snapGrid[snapIndex - 1];
  2122. const currentSnap = swiper.snapGrid[snapIndex];
  2123. if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
  2124. index -= swiper.params.slidesPerGroup;
  2125. }
  2126. }
  2127. index = Math.max(index, 0);
  2128. index = Math.min(index, swiper.slidesGrid.length - 1);
  2129. return swiper.slideTo(index, speed, runCallbacks, internal);
  2130. }
  2131. function slideToClickedSlide() {
  2132. const swiper = this;
  2133. if (swiper.destroyed) return;
  2134. const {
  2135. params,
  2136. slidesEl
  2137. } = swiper;
  2138. const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
  2139. let slideToIndex = swiper.clickedIndex;
  2140. let realIndex;
  2141. const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
  2142. if (params.loop) {
  2143. if (swiper.animating) return;
  2144. realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
  2145. if (params.centeredSlides) {
  2146. if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2) {
  2147. swiper.loopFix();
  2148. slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
  2149. nextTick(() => {
  2150. swiper.slideTo(slideToIndex);
  2151. });
  2152. } else {
  2153. swiper.slideTo(slideToIndex);
  2154. }
  2155. } else if (slideToIndex > swiper.slides.length - slidesPerView) {
  2156. swiper.loopFix();
  2157. slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
  2158. nextTick(() => {
  2159. swiper.slideTo(slideToIndex);
  2160. });
  2161. } else {
  2162. swiper.slideTo(slideToIndex);
  2163. }
  2164. } else {
  2165. swiper.slideTo(slideToIndex);
  2166. }
  2167. }
  2168. var slide = {
  2169. slideTo,
  2170. slideToLoop,
  2171. slideNext,
  2172. slidePrev,
  2173. slideReset,
  2174. slideToClosest,
  2175. slideToClickedSlide
  2176. };
  2177. function loopCreate(slideRealIndex) {
  2178. const swiper = this;
  2179. const {
  2180. params,
  2181. slidesEl
  2182. } = swiper;
  2183. if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
  2184. const initSlides = () => {
  2185. const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
  2186. slides.forEach((el, index) => {
  2187. el.setAttribute('data-swiper-slide-index', index);
  2188. });
  2189. };
  2190. const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
  2191. const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1);
  2192. const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0;
  2193. const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0;
  2194. const addBlankSlides = amountOfSlides => {
  2195. for (let i = 0; i < amountOfSlides; i += 1) {
  2196. const slideEl = swiper.isElement ? createElement('swiper-slide', [params.slideBlankClass]) : createElement('div', [params.slideClass, params.slideBlankClass]);
  2197. swiper.slidesEl.append(slideEl);
  2198. }
  2199. };
  2200. if (shouldFillGroup) {
  2201. if (params.loopAddBlankSlides) {
  2202. const slidesToAdd = slidesPerGroup - swiper.slides.length % slidesPerGroup;
  2203. addBlankSlides(slidesToAdd);
  2204. swiper.recalcSlides();
  2205. swiper.updateSlides();
  2206. } else {
  2207. showWarning('Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
  2208. }
  2209. initSlides();
  2210. } else if (shouldFillGrid) {
  2211. if (params.loopAddBlankSlides) {
  2212. const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows;
  2213. addBlankSlides(slidesToAdd);
  2214. swiper.recalcSlides();
  2215. swiper.updateSlides();
  2216. } else {
  2217. showWarning('Swiper Loop Warning: The number of slides is not even to grid.rows, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
  2218. }
  2219. initSlides();
  2220. } else {
  2221. initSlides();
  2222. }
  2223. swiper.loopFix({
  2224. slideRealIndex,
  2225. direction: params.centeredSlides ? undefined : 'next'
  2226. });
  2227. }
  2228. function loopFix(_temp) {
  2229. let {
  2230. slideRealIndex,
  2231. slideTo = true,
  2232. direction,
  2233. setTranslate,
  2234. activeSlideIndex,
  2235. byController,
  2236. byMousewheel
  2237. } = _temp === void 0 ? {} : _temp;
  2238. const swiper = this;
  2239. if (!swiper.params.loop) return;
  2240. swiper.emit('beforeLoopFix');
  2241. const {
  2242. slides,
  2243. allowSlidePrev,
  2244. allowSlideNext,
  2245. slidesEl,
  2246. params
  2247. } = swiper;
  2248. const {
  2249. centeredSlides
  2250. } = params;
  2251. swiper.allowSlidePrev = true;
  2252. swiper.allowSlideNext = true;
  2253. if (swiper.virtual && params.virtual.enabled) {
  2254. if (slideTo) {
  2255. if (!params.centeredSlides && swiper.snapIndex === 0) {
  2256. swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
  2257. } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
  2258. swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
  2259. } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
  2260. swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
  2261. }
  2262. }
  2263. swiper.allowSlidePrev = allowSlidePrev;
  2264. swiper.allowSlideNext = allowSlideNext;
  2265. swiper.emit('loopFix');
  2266. return;
  2267. }
  2268. let slidesPerView = params.slidesPerView;
  2269. if (slidesPerView === 'auto') {
  2270. slidesPerView = swiper.slidesPerViewDynamic();
  2271. } else {
  2272. slidesPerView = Math.ceil(parseFloat(params.slidesPerView, 10));
  2273. if (centeredSlides && slidesPerView % 2 === 0) {
  2274. slidesPerView = slidesPerView + 1;
  2275. }
  2276. }
  2277. const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup;
  2278. let loopedSlides = slidesPerGroup;
  2279. if (loopedSlides % slidesPerGroup !== 0) {
  2280. loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup;
  2281. }
  2282. loopedSlides += params.loopAdditionalSlides;
  2283. swiper.loopedSlides = loopedSlides;
  2284. const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
  2285. if (slides.length < slidesPerView + loopedSlides) {
  2286. showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled and not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
  2287. } else if (gridEnabled && params.grid.fill === 'row') {
  2288. showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
  2289. }
  2290. const prependSlidesIndexes = [];
  2291. const appendSlidesIndexes = [];
  2292. let activeIndex = swiper.activeIndex;
  2293. if (typeof activeSlideIndex === 'undefined') {
  2294. activeSlideIndex = swiper.getSlideIndex(slides.filter(el => el.classList.contains(params.slideActiveClass))[0]);
  2295. } else {
  2296. activeIndex = activeSlideIndex;
  2297. }
  2298. const isNext = direction === 'next' || !direction;
  2299. const isPrev = direction === 'prev' || !direction;
  2300. let slidesPrepended = 0;
  2301. let slidesAppended = 0;
  2302. const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length;
  2303. const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex;
  2304. const activeColIndexWithShift = activeColIndex + (centeredSlides && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0);
  2305. // prepend last slides before start
  2306. if (activeColIndexWithShift < loopedSlides) {
  2307. slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup);
  2308. for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) {
  2309. const index = i - Math.floor(i / cols) * cols;
  2310. if (gridEnabled) {
  2311. const colIndexToPrepend = cols - index - 1;
  2312. for (let i = slides.length - 1; i >= 0; i -= 1) {
  2313. if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i);
  2314. }
  2315. // slides.forEach((slide, slideIndex) => {
  2316. // if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex);
  2317. // });
  2318. } else {
  2319. prependSlidesIndexes.push(cols - index - 1);
  2320. }
  2321. }
  2322. } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) {
  2323. slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup);
  2324. for (let i = 0; i < slidesAppended; i += 1) {
  2325. const index = i - Math.floor(i / cols) * cols;
  2326. if (gridEnabled) {
  2327. slides.forEach((slide, slideIndex) => {
  2328. if (slide.column === index) appendSlidesIndexes.push(slideIndex);
  2329. });
  2330. } else {
  2331. appendSlidesIndexes.push(index);
  2332. }
  2333. }
  2334. }
  2335. swiper.__preventObserver__ = true;
  2336. requestAnimationFrame(() => {
  2337. swiper.__preventObserver__ = false;
  2338. });
  2339. if (isPrev) {
  2340. prependSlidesIndexes.forEach(index => {
  2341. slides[index].swiperLoopMoveDOM = true;
  2342. slidesEl.prepend(slides[index]);
  2343. slides[index].swiperLoopMoveDOM = false;
  2344. });
  2345. }
  2346. if (isNext) {
  2347. appendSlidesIndexes.forEach(index => {
  2348. slides[index].swiperLoopMoveDOM = true;
  2349. slidesEl.append(slides[index]);
  2350. slides[index].swiperLoopMoveDOM = false;
  2351. });
  2352. }
  2353. swiper.recalcSlides();
  2354. if (params.slidesPerView === 'auto') {
  2355. swiper.updateSlides();
  2356. } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) {
  2357. swiper.slides.forEach((slide, slideIndex) => {
  2358. swiper.grid.updateSlide(slideIndex, slide, swiper.slides);
  2359. });
  2360. }
  2361. if (params.watchSlidesProgress) {
  2362. swiper.updateSlidesOffset();
  2363. }
  2364. if (slideTo) {
  2365. if (prependSlidesIndexes.length > 0 && isPrev) {
  2366. if (typeof slideRealIndex === 'undefined') {
  2367. const currentSlideTranslate = swiper.slidesGrid[activeIndex];
  2368. const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
  2369. const diff = newSlideTranslate - currentSlideTranslate;
  2370. if (byMousewheel) {
  2371. swiper.setTranslate(swiper.translate - diff);
  2372. } else {
  2373. swiper.slideTo(activeIndex + Math.ceil(slidesPrepended), 0, false, true);
  2374. if (setTranslate) {
  2375. swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
  2376. swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
  2377. }
  2378. }
  2379. } else {
  2380. if (setTranslate) {
  2381. const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length;
  2382. swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
  2383. swiper.touchEventsData.currentTranslate = swiper.translate;
  2384. }
  2385. }
  2386. } else if (appendSlidesIndexes.length > 0 && isNext) {
  2387. if (typeof slideRealIndex === 'undefined') {
  2388. const currentSlideTranslate = swiper.slidesGrid[activeIndex];
  2389. const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
  2390. const diff = newSlideTranslate - currentSlideTranslate;
  2391. if (byMousewheel) {
  2392. swiper.setTranslate(swiper.translate - diff);
  2393. } else {
  2394. swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
  2395. if (setTranslate) {
  2396. swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
  2397. swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
  2398. }
  2399. }
  2400. } else {
  2401. const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length;
  2402. swiper.slideTo(swiper.activeIndex - shift, 0, false, true);
  2403. }
  2404. }
  2405. }
  2406. swiper.allowSlidePrev = allowSlidePrev;
  2407. swiper.allowSlideNext = allowSlideNext;
  2408. if (swiper.controller && swiper.controller.control && !byController) {
  2409. const loopParams = {
  2410. slideRealIndex,
  2411. direction,
  2412. setTranslate,
  2413. activeSlideIndex,
  2414. byController: true
  2415. };
  2416. if (Array.isArray(swiper.controller.control)) {
  2417. swiper.controller.control.forEach(c => {
  2418. if (!c.destroyed && c.params.loop) c.loopFix({
  2419. ...loopParams,
  2420. slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false
  2421. });
  2422. });
  2423. } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
  2424. swiper.controller.control.loopFix({
  2425. ...loopParams,
  2426. slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false
  2427. });
  2428. }
  2429. }
  2430. swiper.emit('loopFix');
  2431. }
  2432. function loopDestroy() {
  2433. const swiper = this;
  2434. const {
  2435. params,
  2436. slidesEl
  2437. } = swiper;
  2438. if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
  2439. swiper.recalcSlides();
  2440. const newSlidesOrder = [];
  2441. swiper.slides.forEach(slideEl => {
  2442. const index = typeof slideEl.swiperSlideIndex === 'undefined' ? slideEl.getAttribute('data-swiper-slide-index') * 1 : slideEl.swiperSlideIndex;
  2443. newSlidesOrder[index] = slideEl;
  2444. });
  2445. swiper.slides.forEach(slideEl => {
  2446. slideEl.removeAttribute('data-swiper-slide-index');
  2447. });
  2448. newSlidesOrder.forEach(slideEl => {
  2449. slidesEl.append(slideEl);
  2450. });
  2451. swiper.recalcSlides();
  2452. swiper.slideTo(swiper.realIndex, 0);
  2453. }
  2454. var loop = {
  2455. loopCreate,
  2456. loopFix,
  2457. loopDestroy
  2458. };
  2459. function setGrabCursor(moving) {
  2460. const swiper = this;
  2461. if (!swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;
  2462. const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;
  2463. if (swiper.isElement) {
  2464. swiper.__preventObserver__ = true;
  2465. }
  2466. el.style.cursor = 'move';
  2467. el.style.cursor = moving ? 'grabbing' : 'grab';
  2468. if (swiper.isElement) {
  2469. requestAnimationFrame(() => {
  2470. swiper.__preventObserver__ = false;
  2471. });
  2472. }
  2473. }
  2474. function unsetGrabCursor() {
  2475. const swiper = this;
  2476. if (swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
  2477. return;
  2478. }
  2479. if (swiper.isElement) {
  2480. swiper.__preventObserver__ = true;
  2481. }
  2482. swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';
  2483. if (swiper.isElement) {
  2484. requestAnimationFrame(() => {
  2485. swiper.__preventObserver__ = false;
  2486. });
  2487. }
  2488. }
  2489. var grabCursor = {
  2490. setGrabCursor,
  2491. unsetGrabCursor
  2492. };
  2493. // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
  2494. function closestElement(selector, base) {
  2495. if (base === void 0) {
  2496. base = this;
  2497. }
  2498. function __closestFrom(el) {
  2499. if (!el || el === getDocument() || el === getWindow()) return null;
  2500. if (el.assignedSlot) el = el.assignedSlot;
  2501. const found = el.closest(selector);
  2502. if (!found && !el.getRootNode) {
  2503. return null;
  2504. }
  2505. return found || __closestFrom(el.getRootNode().host);
  2506. }
  2507. return __closestFrom(base);
  2508. }
  2509. function preventEdgeSwipe(swiper, event, startX) {
  2510. const window = getWindow();
  2511. const {
  2512. params
  2513. } = swiper;
  2514. const edgeSwipeDetection = params.edgeSwipeDetection;
  2515. const edgeSwipeThreshold = params.edgeSwipeThreshold;
  2516. if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
  2517. if (edgeSwipeDetection === 'prevent') {
  2518. event.preventDefault();
  2519. return true;
  2520. }
  2521. return false;
  2522. }
  2523. return true;
  2524. }
  2525. function onTouchStart(event) {
  2526. const swiper = this;
  2527. const document = getDocument();
  2528. let e = event;
  2529. if (e.originalEvent) e = e.originalEvent;
  2530. const data = swiper.touchEventsData;
  2531. if (e.type === 'pointerdown') {
  2532. if (data.pointerId !== null && data.pointerId !== e.pointerId) {
  2533. return;
  2534. }
  2535. data.pointerId = e.pointerId;
  2536. } else if (e.type === 'touchstart' && e.targetTouches.length === 1) {
  2537. data.touchId = e.targetTouches[0].identifier;
  2538. }
  2539. if (e.type === 'touchstart') {
  2540. // don't proceed touch event
  2541. preventEdgeSwipe(swiper, e, e.targetTouches[0].pageX);
  2542. return;
  2543. }
  2544. const {
  2545. params,
  2546. touches,
  2547. enabled
  2548. } = swiper;
  2549. if (!enabled) return;
  2550. if (!params.simulateTouch && e.pointerType === 'mouse') return;
  2551. if (swiper.animating && params.preventInteractionOnTransition) {
  2552. return;
  2553. }
  2554. if (!swiper.animating && params.cssMode && params.loop) {
  2555. swiper.loopFix();
  2556. }
  2557. let targetEl = e.target;
  2558. if (params.touchEventsTarget === 'wrapper') {
  2559. if (!elementIsChildOf(targetEl, swiper.wrapperEl)) return;
  2560. }
  2561. if ('which' in e && e.which === 3) return;
  2562. if ('button' in e && e.button > 0) return;
  2563. if (data.isTouched && data.isMoved) return;
  2564. // change target el for shadow root component
  2565. const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
  2566. // eslint-disable-next-line
  2567. const eventPath = e.composedPath ? e.composedPath() : e.path;
  2568. if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
  2569. targetEl = eventPath[0];
  2570. }
  2571. const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
  2572. const isTargetShadow = !!(e.target && e.target.shadowRoot);
  2573. // use closestElement for shadow root element to get the actual closest for nested shadow root element
  2574. if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
  2575. swiper.allowClick = true;
  2576. return;
  2577. }
  2578. if (params.swipeHandler) {
  2579. if (!targetEl.closest(params.swipeHandler)) return;
  2580. }
  2581. touches.currentX = e.pageX;
  2582. touches.currentY = e.pageY;
  2583. const startX = touches.currentX;
  2584. const startY = touches.currentY;
  2585. // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
  2586. if (!preventEdgeSwipe(swiper, e, startX)) {
  2587. return;
  2588. }
  2589. Object.assign(data, {
  2590. isTouched: true,
  2591. isMoved: false,
  2592. allowTouchCallbacks: true,
  2593. isScrolling: undefined,
  2594. startMoving: undefined
  2595. });
  2596. touches.startX = startX;
  2597. touches.startY = startY;
  2598. data.touchStartTime = now();
  2599. swiper.allowClick = true;
  2600. swiper.updateSize();
  2601. swiper.swipeDirection = undefined;
  2602. if (params.threshold > 0) data.allowThresholdMove = false;
  2603. let preventDefault = true;
  2604. if (targetEl.matches(data.focusableElements)) {
  2605. preventDefault = false;
  2606. if (targetEl.nodeName === 'SELECT') {
  2607. data.isTouched = false;
  2608. }
  2609. }
  2610. if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl && (e.pointerType === 'mouse' || e.pointerType !== 'mouse' && !targetEl.matches(data.focusableElements))) {
  2611. document.activeElement.blur();
  2612. }
  2613. const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
  2614. if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
  2615. e.preventDefault();
  2616. }
  2617. if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
  2618. swiper.freeMode.onTouchStart();
  2619. }
  2620. swiper.emit('touchStart', e);
  2621. }
  2622. function onTouchMove(event) {
  2623. const document = getDocument();
  2624. const swiper = this;
  2625. const data = swiper.touchEventsData;
  2626. const {
  2627. params,
  2628. touches,
  2629. rtlTranslate: rtl,
  2630. enabled
  2631. } = swiper;
  2632. if (!enabled) return;
  2633. if (!params.simulateTouch && event.pointerType === 'mouse') return;
  2634. let e = event;
  2635. if (e.originalEvent) e = e.originalEvent;
  2636. if (e.type === 'pointermove') {
  2637. if (data.touchId !== null) return; // return from pointer if we use touch
  2638. const id = e.pointerId;
  2639. if (id !== data.pointerId) return;
  2640. }
  2641. let targetTouch;
  2642. if (e.type === 'touchmove') {
  2643. targetTouch = [...e.changedTouches].filter(t => t.identifier === data.touchId)[0];
  2644. if (!targetTouch || targetTouch.identifier !== data.touchId) return;
  2645. } else {
  2646. targetTouch = e;
  2647. }
  2648. if (!data.isTouched) {
  2649. if (data.startMoving && data.isScrolling) {
  2650. swiper.emit('touchMoveOpposite', e);
  2651. }
  2652. return;
  2653. }
  2654. const pageX = targetTouch.pageX;
  2655. const pageY = targetTouch.pageY;
  2656. if (e.preventedByNestedSwiper) {
  2657. touches.startX = pageX;
  2658. touches.startY = pageY;
  2659. return;
  2660. }
  2661. if (!swiper.allowTouchMove) {
  2662. if (!e.target.matches(data.focusableElements)) {
  2663. swiper.allowClick = false;
  2664. }
  2665. if (data.isTouched) {
  2666. Object.assign(touches, {
  2667. startX: pageX,
  2668. startY: pageY,
  2669. currentX: pageX,
  2670. currentY: pageY
  2671. });
  2672. data.touchStartTime = now();
  2673. }
  2674. return;
  2675. }
  2676. if (params.touchReleaseOnEdges && !params.loop) {
  2677. if (swiper.isVertical()) {
  2678. // Vertical
  2679. if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
  2680. data.isTouched = false;
  2681. data.isMoved = false;
  2682. return;
  2683. }
  2684. } else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate()) {
  2685. return;
  2686. }
  2687. }
  2688. if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== e.target && e.pointerType !== 'mouse') {
  2689. document.activeElement.blur();
  2690. }
  2691. if (document.activeElement) {
  2692. if (e.target === document.activeElement && e.target.matches(data.focusableElements)) {
  2693. data.isMoved = true;
  2694. swiper.allowClick = false;
  2695. return;
  2696. }
  2697. }
  2698. if (data.allowTouchCallbacks) {
  2699. swiper.emit('touchMove', e);
  2700. }
  2701. touches.previousX = touches.currentX;
  2702. touches.previousY = touches.currentY;
  2703. touches.currentX = pageX;
  2704. touches.currentY = pageY;
  2705. const diffX = touches.currentX - touches.startX;
  2706. const diffY = touches.currentY - touches.startY;
  2707. if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
  2708. if (typeof data.isScrolling === 'undefined') {
  2709. let touchAngle;
  2710. if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {
  2711. data.isScrolling = false;
  2712. } else {
  2713. // eslint-disable-next-line
  2714. if (diffX * diffX + diffY * diffY >= 25) {
  2715. touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
  2716. data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
  2717. }
  2718. }
  2719. }
  2720. if (data.isScrolling) {
  2721. swiper.emit('touchMoveOpposite', e);
  2722. }
  2723. if (typeof data.startMoving === 'undefined') {
  2724. if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
  2725. data.startMoving = true;
  2726. }
  2727. }
  2728. if (data.isScrolling || e.type === 'touchmove' && data.preventTouchMoveFromPointerMove) {
  2729. data.isTouched = false;
  2730. return;
  2731. }
  2732. if (!data.startMoving) {
  2733. return;
  2734. }
  2735. swiper.allowClick = false;
  2736. if (!params.cssMode && e.cancelable) {
  2737. e.preventDefault();
  2738. }
  2739. if (params.touchMoveStopPropagation && !params.nested) {
  2740. e.stopPropagation();
  2741. }
  2742. let diff = swiper.isHorizontal() ? diffX : diffY;
  2743. let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY;
  2744. if (params.oneWayMovement) {
  2745. diff = Math.abs(diff) * (rtl ? 1 : -1);
  2746. touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1);
  2747. }
  2748. touches.diff = diff;
  2749. diff *= params.touchRatio;
  2750. if (rtl) {
  2751. diff = -diff;
  2752. touchesDiff = -touchesDiff;
  2753. }
  2754. const prevTouchesDirection = swiper.touchesDirection;
  2755. swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
  2756. swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next';
  2757. const isLoop = swiper.params.loop && !params.cssMode;
  2758. const allowLoopFix = swiper.touchesDirection === 'next' && swiper.allowSlideNext || swiper.touchesDirection === 'prev' && swiper.allowSlidePrev;
  2759. if (!data.isMoved) {
  2760. if (isLoop && allowLoopFix) {
  2761. swiper.loopFix({
  2762. direction: swiper.swipeDirection
  2763. });
  2764. }
  2765. data.startTranslate = swiper.getTranslate();
  2766. swiper.setTransition(0);
  2767. if (swiper.animating) {
  2768. const evt = new window.CustomEvent('transitionend', {
  2769. bubbles: true,
  2770. cancelable: true,
  2771. detail: {
  2772. bySwiperTouchMove: true
  2773. }
  2774. });
  2775. swiper.wrapperEl.dispatchEvent(evt);
  2776. }
  2777. data.allowMomentumBounce = false;
  2778. // Grab Cursor
  2779. if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
  2780. swiper.setGrabCursor(true);
  2781. }
  2782. swiper.emit('sliderFirstMove', e);
  2783. }
  2784. let loopFixed;
  2785. new Date().getTime();
  2786. if (data.isMoved && data.allowThresholdMove && prevTouchesDirection !== swiper.touchesDirection && isLoop && allowLoopFix && Math.abs(diff) >= 1) {
  2787. Object.assign(touches, {
  2788. startX: pageX,
  2789. startY: pageY,
  2790. currentX: pageX,
  2791. currentY: pageY,
  2792. startTranslate: data.currentTranslate
  2793. });
  2794. data.loopSwapReset = true;
  2795. data.startTranslate = data.currentTranslate;
  2796. return;
  2797. }
  2798. swiper.emit('sliderMove', e);
  2799. data.isMoved = true;
  2800. data.currentTranslate = diff + data.startTranslate;
  2801. let disableParentSwiper = true;
  2802. let resistanceRatio = params.resistanceRatio;
  2803. if (params.touchReleaseOnEdges) {
  2804. resistanceRatio = 0;
  2805. }
  2806. if (diff > 0) {
  2807. if (isLoop && allowLoopFix && !loopFixed && data.allowThresholdMove && data.currentTranslate > (params.centeredSlides ? swiper.minTranslate() - swiper.slidesSizesGrid[swiper.activeIndex + 1] - (params.slidesPerView !== 'auto' && swiper.slides.length - params.slidesPerView >= 2 ? swiper.slidesSizesGrid[swiper.activeIndex + 1] + swiper.params.spaceBetween : 0) - swiper.params.spaceBetween : swiper.minTranslate())) {
  2808. swiper.loopFix({
  2809. direction: 'prev',
  2810. setTranslate: true,
  2811. activeSlideIndex: 0
  2812. });
  2813. }
  2814. if (data.currentTranslate > swiper.minTranslate()) {
  2815. disableParentSwiper = false;
  2816. if (params.resistance) {
  2817. data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;
  2818. }
  2819. }
  2820. } else if (diff < 0) {
  2821. if (isLoop && allowLoopFix && !loopFixed && data.allowThresholdMove && data.currentTranslate < (params.centeredSlides ? swiper.maxTranslate() + swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] + swiper.params.spaceBetween + (params.slidesPerView !== 'auto' && swiper.slides.length - params.slidesPerView >= 2 ? swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] + swiper.params.spaceBetween : 0) : swiper.maxTranslate())) {
  2822. swiper.loopFix({
  2823. direction: 'next',
  2824. setTranslate: true,
  2825. activeSlideIndex: swiper.slides.length - (params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10)))
  2826. });
  2827. }
  2828. if (data.currentTranslate < swiper.maxTranslate()) {
  2829. disableParentSwiper = false;
  2830. if (params.resistance) {
  2831. data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;
  2832. }
  2833. }
  2834. }
  2835. if (disableParentSwiper) {
  2836. e.preventedByNestedSwiper = true;
  2837. }
  2838. // Directions locks
  2839. if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
  2840. data.currentTranslate = data.startTranslate;
  2841. }
  2842. if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
  2843. data.currentTranslate = data.startTranslate;
  2844. }
  2845. if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
  2846. data.currentTranslate = data.startTranslate;
  2847. }
  2848. // Threshold
  2849. if (params.threshold > 0) {
  2850. if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
  2851. if (!data.allowThresholdMove) {
  2852. data.allowThresholdMove = true;
  2853. touches.startX = touches.currentX;
  2854. touches.startY = touches.currentY;
  2855. data.currentTranslate = data.startTranslate;
  2856. touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
  2857. return;
  2858. }
  2859. } else {
  2860. data.currentTranslate = data.startTranslate;
  2861. return;
  2862. }
  2863. }
  2864. if (!params.followFinger || params.cssMode) return;
  2865. // Update active index in free mode
  2866. if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
  2867. swiper.updateActiveIndex();
  2868. swiper.updateSlidesClasses();
  2869. }
  2870. if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
  2871. swiper.freeMode.onTouchMove();
  2872. }
  2873. // Update progress
  2874. swiper.updateProgress(data.currentTranslate);
  2875. // Update translate
  2876. swiper.setTranslate(data.currentTranslate);
  2877. }
  2878. function onTouchEnd(event) {
  2879. const swiper = this;
  2880. const data = swiper.touchEventsData;
  2881. let e = event;
  2882. if (e.originalEvent) e = e.originalEvent;
  2883. let targetTouch;
  2884. const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel';
  2885. if (!isTouchEvent) {
  2886. if (data.touchId !== null) return; // return from pointer if we use touch
  2887. if (e.pointerId !== data.pointerId) return;
  2888. targetTouch = e;
  2889. } else {
  2890. targetTouch = [...e.changedTouches].filter(t => t.identifier === data.touchId)[0];
  2891. if (!targetTouch || targetTouch.identifier !== data.touchId) return;
  2892. }
  2893. if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) {
  2894. const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView);
  2895. if (!proceed) {
  2896. return;
  2897. }
  2898. }
  2899. data.pointerId = null;
  2900. data.touchId = null;
  2901. const {
  2902. params,
  2903. touches,
  2904. rtlTranslate: rtl,
  2905. slidesGrid,
  2906. enabled
  2907. } = swiper;
  2908. if (!enabled) return;
  2909. if (!params.simulateTouch && e.pointerType === 'mouse') return;
  2910. if (data.allowTouchCallbacks) {
  2911. swiper.emit('touchEnd', e);
  2912. }
  2913. data.allowTouchCallbacks = false;
  2914. if (!data.isTouched) {
  2915. if (data.isMoved && params.grabCursor) {
  2916. swiper.setGrabCursor(false);
  2917. }
  2918. data.isMoved = false;
  2919. data.startMoving = false;
  2920. return;
  2921. }
  2922. // Return Grab Cursor
  2923. if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
  2924. swiper.setGrabCursor(false);
  2925. }
  2926. // Time diff
  2927. const touchEndTime = now();
  2928. const timeDiff = touchEndTime - data.touchStartTime;
  2929. // Tap, doubleTap, Click
  2930. if (swiper.allowClick) {
  2931. const pathTree = e.path || e.composedPath && e.composedPath();
  2932. swiper.updateClickedSlide(pathTree && pathTree[0] || e.target, pathTree);
  2933. swiper.emit('tap click', e);
  2934. if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
  2935. swiper.emit('doubleTap doubleClick', e);
  2936. }
  2937. }
  2938. data.lastClickTime = now();
  2939. nextTick(() => {
  2940. if (!swiper.destroyed) swiper.allowClick = true;
  2941. });
  2942. if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 && !data.loopSwapReset || data.currentTranslate === data.startTranslate && !data.loopSwapReset) {
  2943. data.isTouched = false;
  2944. data.isMoved = false;
  2945. data.startMoving = false;
  2946. return;
  2947. }
  2948. data.isTouched = false;
  2949. data.isMoved = false;
  2950. data.startMoving = false;
  2951. let currentPos;
  2952. if (params.followFinger) {
  2953. currentPos = rtl ? swiper.translate : -swiper.translate;
  2954. } else {
  2955. currentPos = -data.currentTranslate;
  2956. }
  2957. if (params.cssMode) {
  2958. return;
  2959. }
  2960. if (params.freeMode && params.freeMode.enabled) {
  2961. swiper.freeMode.onTouchEnd({
  2962. currentPos
  2963. });
  2964. return;
  2965. }
  2966. // Find current slide
  2967. const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop;
  2968. let stopIndex = 0;
  2969. let groupSize = swiper.slidesSizesGrid[0];
  2970. for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
  2971. const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
  2972. if (typeof slidesGrid[i + increment] !== 'undefined') {
  2973. if (swipeToLast || currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
  2974. stopIndex = i;
  2975. groupSize = slidesGrid[i + increment] - slidesGrid[i];
  2976. }
  2977. } else if (swipeToLast || currentPos >= slidesGrid[i]) {
  2978. stopIndex = i;
  2979. groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
  2980. }
  2981. }
  2982. let rewindFirstIndex = null;
  2983. let rewindLastIndex = null;
  2984. if (params.rewind) {
  2985. if (swiper.isBeginning) {
  2986. rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
  2987. } else if (swiper.isEnd) {
  2988. rewindFirstIndex = 0;
  2989. }
  2990. }
  2991. // Find current slide size
  2992. const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
  2993. const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
  2994. if (timeDiff > params.longSwipesMs) {
  2995. // Long touches
  2996. if (!params.longSwipes) {
  2997. swiper.slideTo(swiper.activeIndex);
  2998. return;
  2999. }
  3000. if (swiper.swipeDirection === 'next') {
  3001. if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);
  3002. }
  3003. if (swiper.swipeDirection === 'prev') {
  3004. if (ratio > 1 - params.longSwipesRatio) {
  3005. swiper.slideTo(stopIndex + increment);
  3006. } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {
  3007. swiper.slideTo(rewindLastIndex);
  3008. } else {
  3009. swiper.slideTo(stopIndex);
  3010. }
  3011. }
  3012. } else {
  3013. // Short swipes
  3014. if (!params.shortSwipes) {
  3015. swiper.slideTo(swiper.activeIndex);
  3016. return;
  3017. }
  3018. const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
  3019. if (!isNavButtonTarget) {
  3020. if (swiper.swipeDirection === 'next') {
  3021. swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);
  3022. }
  3023. if (swiper.swipeDirection === 'prev') {
  3024. swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);
  3025. }
  3026. } else if (e.target === swiper.navigation.nextEl) {
  3027. swiper.slideTo(stopIndex + increment);
  3028. } else {
  3029. swiper.slideTo(stopIndex);
  3030. }
  3031. }
  3032. }
  3033. function onResize() {
  3034. const swiper = this;
  3035. const {
  3036. params,
  3037. el
  3038. } = swiper;
  3039. if (el && el.offsetWidth === 0) return;
  3040. // Breakpoints
  3041. if (params.breakpoints) {
  3042. swiper.setBreakpoint();
  3043. }
  3044. // Save locks
  3045. const {
  3046. allowSlideNext,
  3047. allowSlidePrev,
  3048. snapGrid
  3049. } = swiper;
  3050. const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
  3051. // Disable locks on resize
  3052. swiper.allowSlideNext = true;
  3053. swiper.allowSlidePrev = true;
  3054. swiper.updateSize();
  3055. swiper.updateSlides();
  3056. swiper.updateSlidesClasses();
  3057. const isVirtualLoop = isVirtual && params.loop;
  3058. if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
  3059. swiper.slideTo(swiper.slides.length - 1, 0, false, true);
  3060. } else {
  3061. if (swiper.params.loop && !isVirtual) {
  3062. swiper.slideToLoop(swiper.realIndex, 0, false, true);
  3063. } else {
  3064. swiper.slideTo(swiper.activeIndex, 0, false, true);
  3065. }
  3066. }
  3067. if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
  3068. clearTimeout(swiper.autoplay.resizeTimeout);
  3069. swiper.autoplay.resizeTimeout = setTimeout(() => {
  3070. if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
  3071. swiper.autoplay.resume();
  3072. }
  3073. }, 500);
  3074. }
  3075. // Return locks after resize
  3076. swiper.allowSlidePrev = allowSlidePrev;
  3077. swiper.allowSlideNext = allowSlideNext;
  3078. if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
  3079. swiper.checkOverflow();
  3080. }
  3081. }
  3082. function onClick(e) {
  3083. const swiper = this;
  3084. if (!swiper.enabled) return;
  3085. if (!swiper.allowClick) {
  3086. if (swiper.params.preventClicks) e.preventDefault();
  3087. if (swiper.params.preventClicksPropagation && swiper.animating) {
  3088. e.stopPropagation();
  3089. e.stopImmediatePropagation();
  3090. }
  3091. }
  3092. }
  3093. function onScroll() {
  3094. const swiper = this;
  3095. const {
  3096. wrapperEl,
  3097. rtlTranslate,
  3098. enabled
  3099. } = swiper;
  3100. if (!enabled) return;
  3101. swiper.previousTranslate = swiper.translate;
  3102. if (swiper.isHorizontal()) {
  3103. swiper.translate = -wrapperEl.scrollLeft;
  3104. } else {
  3105. swiper.translate = -wrapperEl.scrollTop;
  3106. }
  3107. // eslint-disable-next-line
  3108. if (swiper.translate === 0) swiper.translate = 0;
  3109. swiper.updateActiveIndex();
  3110. swiper.updateSlidesClasses();
  3111. let newProgress;
  3112. const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
  3113. if (translatesDiff === 0) {
  3114. newProgress = 0;
  3115. } else {
  3116. newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
  3117. }
  3118. if (newProgress !== swiper.progress) {
  3119. swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
  3120. }
  3121. swiper.emit('setTranslate', swiper.translate, false);
  3122. }
  3123. function onLoad(e) {
  3124. const swiper = this;
  3125. processLazyPreloader(swiper, e.target);
  3126. if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
  3127. return;
  3128. }
  3129. swiper.update();
  3130. }
  3131. function onDocumentTouchStart() {
  3132. const swiper = this;
  3133. if (swiper.documentTouchHandlerProceeded) return;
  3134. swiper.documentTouchHandlerProceeded = true;
  3135. if (swiper.params.touchReleaseOnEdges) {
  3136. swiper.el.style.touchAction = 'auto';
  3137. }
  3138. }
  3139. const events = (swiper, method) => {
  3140. const document = getDocument();
  3141. const {
  3142. params,
  3143. el,
  3144. wrapperEl,
  3145. device
  3146. } = swiper;
  3147. const capture = !!params.nested;
  3148. const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
  3149. const swiperMethod = method;
  3150. if (!el || typeof el === 'string') return;
  3151. // Touch Events
  3152. document[domMethod]('touchstart', swiper.onDocumentTouchStart, {
  3153. passive: false,
  3154. capture
  3155. });
  3156. el[domMethod]('touchstart', swiper.onTouchStart, {
  3157. passive: false
  3158. });
  3159. el[domMethod]('pointerdown', swiper.onTouchStart, {
  3160. passive: false
  3161. });
  3162. document[domMethod]('touchmove', swiper.onTouchMove, {
  3163. passive: false,
  3164. capture
  3165. });
  3166. document[domMethod]('pointermove', swiper.onTouchMove, {
  3167. passive: false,
  3168. capture
  3169. });
  3170. document[domMethod]('touchend', swiper.onTouchEnd, {
  3171. passive: true
  3172. });
  3173. document[domMethod]('pointerup', swiper.onTouchEnd, {
  3174. passive: true
  3175. });
  3176. document[domMethod]('pointercancel', swiper.onTouchEnd, {
  3177. passive: true
  3178. });
  3179. document[domMethod]('touchcancel', swiper.onTouchEnd, {
  3180. passive: true
  3181. });
  3182. document[domMethod]('pointerout', swiper.onTouchEnd, {
  3183. passive: true
  3184. });
  3185. document[domMethod]('pointerleave', swiper.onTouchEnd, {
  3186. passive: true
  3187. });
  3188. document[domMethod]('contextmenu', swiper.onTouchEnd, {
  3189. passive: true
  3190. });
  3191. // Prevent Links Clicks
  3192. if (params.preventClicks || params.preventClicksPropagation) {
  3193. el[domMethod]('click', swiper.onClick, true);
  3194. }
  3195. if (params.cssMode) {
  3196. wrapperEl[domMethod]('scroll', swiper.onScroll);
  3197. }
  3198. // Resize handler
  3199. if (params.updateOnWindowResize) {
  3200. swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);
  3201. } else {
  3202. swiper[swiperMethod]('observerUpdate', onResize, true);
  3203. }
  3204. // Images loader
  3205. el[domMethod]('load', swiper.onLoad, {
  3206. capture: true
  3207. });
  3208. };
  3209. function attachEvents() {
  3210. const swiper = this;
  3211. const {
  3212. params
  3213. } = swiper;
  3214. swiper.onTouchStart = onTouchStart.bind(swiper);
  3215. swiper.onTouchMove = onTouchMove.bind(swiper);
  3216. swiper.onTouchEnd = onTouchEnd.bind(swiper);
  3217. swiper.onDocumentTouchStart = onDocumentTouchStart.bind(swiper);
  3218. if (params.cssMode) {
  3219. swiper.onScroll = onScroll.bind(swiper);
  3220. }
  3221. swiper.onClick = onClick.bind(swiper);
  3222. swiper.onLoad = onLoad.bind(swiper);
  3223. events(swiper, 'on');
  3224. }
  3225. function detachEvents() {
  3226. const swiper = this;
  3227. events(swiper, 'off');
  3228. }
  3229. var events$1 = {
  3230. attachEvents,
  3231. detachEvents
  3232. };
  3233. const isGridEnabled = (swiper, params) => {
  3234. return swiper.grid && params.grid && params.grid.rows > 1;
  3235. };
  3236. function setBreakpoint() {
  3237. const swiper = this;
  3238. const {
  3239. realIndex,
  3240. initialized,
  3241. params,
  3242. el
  3243. } = swiper;
  3244. const breakpoints = params.breakpoints;
  3245. if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return;
  3246. // Get breakpoint for window width and update parameters
  3247. const breakpoint = swiper.getBreakpoint(breakpoints, swiper.params.breakpointsBase, swiper.el);
  3248. if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
  3249. const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
  3250. const breakpointParams = breakpointOnlyParams || swiper.originalParams;
  3251. const wasMultiRow = isGridEnabled(swiper, params);
  3252. const isMultiRow = isGridEnabled(swiper, breakpointParams);
  3253. const wasGrabCursor = swiper.params.grabCursor;
  3254. const isGrabCursor = breakpointParams.grabCursor;
  3255. const wasEnabled = params.enabled;
  3256. if (wasMultiRow && !isMultiRow) {
  3257. el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
  3258. swiper.emitContainerClasses();
  3259. } else if (!wasMultiRow && isMultiRow) {
  3260. el.classList.add(`${params.containerModifierClass}grid`);
  3261. if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
  3262. el.classList.add(`${params.containerModifierClass}grid-column`);
  3263. }
  3264. swiper.emitContainerClasses();
  3265. }
  3266. if (wasGrabCursor && !isGrabCursor) {
  3267. swiper.unsetGrabCursor();
  3268. } else if (!wasGrabCursor && isGrabCursor) {
  3269. swiper.setGrabCursor();
  3270. }
  3271. // Toggle navigation, pagination, scrollbar
  3272. ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
  3273. if (typeof breakpointParams[prop] === 'undefined') return;
  3274. const wasModuleEnabled = params[prop] && params[prop].enabled;
  3275. const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
  3276. if (wasModuleEnabled && !isModuleEnabled) {
  3277. swiper[prop].disable();
  3278. }
  3279. if (!wasModuleEnabled && isModuleEnabled) {
  3280. swiper[prop].enable();
  3281. }
  3282. });
  3283. const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
  3284. const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
  3285. const wasLoop = params.loop;
  3286. if (directionChanged && initialized) {
  3287. swiper.changeDirection();
  3288. }
  3289. extend(swiper.params, breakpointParams);
  3290. const isEnabled = swiper.params.enabled;
  3291. const hasLoop = swiper.params.loop;
  3292. Object.assign(swiper, {
  3293. allowTouchMove: swiper.params.allowTouchMove,
  3294. allowSlideNext: swiper.params.allowSlideNext,
  3295. allowSlidePrev: swiper.params.allowSlidePrev
  3296. });
  3297. if (wasEnabled && !isEnabled) {
  3298. swiper.disable();
  3299. } else if (!wasEnabled && isEnabled) {
  3300. swiper.enable();
  3301. }
  3302. swiper.currentBreakpoint = breakpoint;
  3303. swiper.emit('_beforeBreakpoint', breakpointParams);
  3304. if (initialized) {
  3305. if (needsReLoop) {
  3306. swiper.loopDestroy();
  3307. swiper.loopCreate(realIndex);
  3308. swiper.updateSlides();
  3309. } else if (!wasLoop && hasLoop) {
  3310. swiper.loopCreate(realIndex);
  3311. swiper.updateSlides();
  3312. } else if (wasLoop && !hasLoop) {
  3313. swiper.loopDestroy();
  3314. }
  3315. }
  3316. swiper.emit('breakpoint', breakpointParams);
  3317. }
  3318. function getBreakpoint(breakpoints, base, containerEl) {
  3319. if (base === void 0) {
  3320. base = 'window';
  3321. }
  3322. if (!breakpoints || base === 'container' && !containerEl) return undefined;
  3323. let breakpoint = false;
  3324. const window = getWindow();
  3325. const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
  3326. const points = Object.keys(breakpoints).map(point => {
  3327. if (typeof point === 'string' && point.indexOf('@') === 0) {
  3328. const minRatio = parseFloat(point.substr(1));
  3329. const value = currentHeight * minRatio;
  3330. return {
  3331. value,
  3332. point
  3333. };
  3334. }
  3335. return {
  3336. value: point,
  3337. point
  3338. };
  3339. });
  3340. points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
  3341. for (let i = 0; i < points.length; i += 1) {
  3342. const {
  3343. point,
  3344. value
  3345. } = points[i];
  3346. if (base === 'window') {
  3347. if (window.matchMedia(`(min-width: ${value}px)`).matches) {
  3348. breakpoint = point;
  3349. }
  3350. } else if (value <= containerEl.clientWidth) {
  3351. breakpoint = point;
  3352. }
  3353. }
  3354. return breakpoint || 'max';
  3355. }
  3356. var breakpoints = {
  3357. setBreakpoint,
  3358. getBreakpoint
  3359. };
  3360. function prepareClasses(entries, prefix) {
  3361. const resultClasses = [];
  3362. entries.forEach(item => {
  3363. if (typeof item === 'object') {
  3364. Object.keys(item).forEach(classNames => {
  3365. if (item[classNames]) {
  3366. resultClasses.push(prefix + classNames);
  3367. }
  3368. });
  3369. } else if (typeof item === 'string') {
  3370. resultClasses.push(prefix + item);
  3371. }
  3372. });
  3373. return resultClasses;
  3374. }
  3375. function addClasses() {
  3376. const swiper = this;
  3377. const {
  3378. classNames,
  3379. params,
  3380. rtl,
  3381. el,
  3382. device
  3383. } = swiper;
  3384. // prettier-ignore
  3385. const suffixes = prepareClasses(['initialized', params.direction, {
  3386. 'free-mode': swiper.params.freeMode && params.freeMode.enabled
  3387. }, {
  3388. 'autoheight': params.autoHeight
  3389. }, {
  3390. 'rtl': rtl
  3391. }, {
  3392. 'grid': params.grid && params.grid.rows > 1
  3393. }, {
  3394. 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
  3395. }, {
  3396. 'android': device.android
  3397. }, {
  3398. 'ios': device.ios
  3399. }, {
  3400. 'css-mode': params.cssMode
  3401. }, {
  3402. 'centered': params.cssMode && params.centeredSlides
  3403. }, {
  3404. 'watch-progress': params.watchSlidesProgress
  3405. }], params.containerModifierClass);
  3406. classNames.push(...suffixes);
  3407. el.classList.add(...classNames);
  3408. swiper.emitContainerClasses();
  3409. }
  3410. function removeClasses() {
  3411. const swiper = this;
  3412. const {
  3413. el,
  3414. classNames
  3415. } = swiper;
  3416. if (!el || typeof el === 'string') return;
  3417. el.classList.remove(...classNames);
  3418. swiper.emitContainerClasses();
  3419. }
  3420. var classes = {
  3421. addClasses,
  3422. removeClasses
  3423. };
  3424. function checkOverflow() {
  3425. const swiper = this;
  3426. const {
  3427. isLocked: wasLocked,
  3428. params
  3429. } = swiper;
  3430. const {
  3431. slidesOffsetBefore
  3432. } = params;
  3433. if (slidesOffsetBefore) {
  3434. const lastSlideIndex = swiper.slides.length - 1;
  3435. const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;
  3436. swiper.isLocked = swiper.size > lastSlideRightEdge;
  3437. } else {
  3438. swiper.isLocked = swiper.snapGrid.length === 1;
  3439. }
  3440. if (params.allowSlideNext === true) {
  3441. swiper.allowSlideNext = !swiper.isLocked;
  3442. }
  3443. if (params.allowSlidePrev === true) {
  3444. swiper.allowSlidePrev = !swiper.isLocked;
  3445. }
  3446. if (wasLocked && wasLocked !== swiper.isLocked) {
  3447. swiper.isEnd = false;
  3448. }
  3449. if (wasLocked !== swiper.isLocked) {
  3450. swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
  3451. }
  3452. }
  3453. var checkOverflow$1 = {
  3454. checkOverflow
  3455. };
  3456. var defaults = {
  3457. init: true,
  3458. direction: 'horizontal',
  3459. oneWayMovement: false,
  3460. swiperElementNodeName: 'SWIPER-CONTAINER',
  3461. touchEventsTarget: 'wrapper',
  3462. initialSlide: 0,
  3463. speed: 300,
  3464. cssMode: false,
  3465. updateOnWindowResize: true,
  3466. resizeObserver: true,
  3467. nested: false,
  3468. createElements: false,
  3469. eventsPrefix: 'swiper',
  3470. enabled: true,
  3471. focusableElements: 'input, select, option, textarea, button, video, label',
  3472. // Overrides
  3473. width: null,
  3474. height: null,
  3475. //
  3476. preventInteractionOnTransition: false,
  3477. // ssr
  3478. userAgent: null,
  3479. url: null,
  3480. // To support iOS's swipe-to-go-back gesture (when being used in-app).
  3481. edgeSwipeDetection: false,
  3482. edgeSwipeThreshold: 20,
  3483. // Autoheight
  3484. autoHeight: false,
  3485. // Set wrapper width
  3486. setWrapperSize: false,
  3487. // Virtual Translate
  3488. virtualTranslate: false,
  3489. // Effects
  3490. effect: 'slide',
  3491. // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
  3492. // Breakpoints
  3493. breakpoints: undefined,
  3494. breakpointsBase: 'window',
  3495. // Slides grid
  3496. spaceBetween: 0,
  3497. slidesPerView: 1,
  3498. slidesPerGroup: 1,
  3499. slidesPerGroupSkip: 0,
  3500. slidesPerGroupAuto: false,
  3501. centeredSlides: false,
  3502. centeredSlidesBounds: false,
  3503. slidesOffsetBefore: 0,
  3504. // in px
  3505. slidesOffsetAfter: 0,
  3506. // in px
  3507. normalizeSlideIndex: true,
  3508. centerInsufficientSlides: false,
  3509. // Disable swiper and hide navigation when container not overflow
  3510. watchOverflow: true,
  3511. // Round length
  3512. roundLengths: false,
  3513. // Touches
  3514. touchRatio: 1,
  3515. touchAngle: 45,
  3516. simulateTouch: true,
  3517. shortSwipes: true,
  3518. longSwipes: true,
  3519. longSwipesRatio: 0.5,
  3520. longSwipesMs: 300,
  3521. followFinger: true,
  3522. allowTouchMove: true,
  3523. threshold: 5,
  3524. touchMoveStopPropagation: false,
  3525. touchStartPreventDefault: true,
  3526. touchStartForcePreventDefault: false,
  3527. touchReleaseOnEdges: false,
  3528. // Unique Navigation Elements
  3529. uniqueNavElements: true,
  3530. // Resistance
  3531. resistance: true,
  3532. resistanceRatio: 0.85,
  3533. // Progress
  3534. watchSlidesProgress: false,
  3535. // Cursor
  3536. grabCursor: false,
  3537. // Clicks
  3538. preventClicks: true,
  3539. preventClicksPropagation: true,
  3540. slideToClickedSlide: false,
  3541. // loop
  3542. loop: false,
  3543. loopAddBlankSlides: true,
  3544. loopAdditionalSlides: 0,
  3545. loopPreventsSliding: true,
  3546. // rewind
  3547. rewind: false,
  3548. // Swiping/no swiping
  3549. allowSlidePrev: true,
  3550. allowSlideNext: true,
  3551. swipeHandler: null,
  3552. // '.swipe-handler',
  3553. noSwiping: true,
  3554. noSwipingClass: 'swiper-no-swiping',
  3555. noSwipingSelector: null,
  3556. // Passive Listeners
  3557. passiveListeners: true,
  3558. maxBackfaceHiddenSlides: 10,
  3559. // NS
  3560. containerModifierClass: 'swiper-',
  3561. // NEW
  3562. slideClass: 'swiper-slide',
  3563. slideBlankClass: 'swiper-slide-blank',
  3564. slideActiveClass: 'swiper-slide-active',
  3565. slideVisibleClass: 'swiper-slide-visible',
  3566. slideFullyVisibleClass: 'swiper-slide-fully-visible',
  3567. slideNextClass: 'swiper-slide-next',
  3568. slidePrevClass: 'swiper-slide-prev',
  3569. wrapperClass: 'swiper-wrapper',
  3570. lazyPreloaderClass: 'swiper-lazy-preloader',
  3571. lazyPreloadPrevNext: 0,
  3572. // Callbacks
  3573. runCallbacksOnInit: true,
  3574. // Internals
  3575. _emitClasses: false
  3576. };
  3577. function moduleExtendParams(params, allModulesParams) {
  3578. return function extendParams(obj) {
  3579. if (obj === void 0) {
  3580. obj = {};
  3581. }
  3582. const moduleParamName = Object.keys(obj)[0];
  3583. const moduleParams = obj[moduleParamName];
  3584. if (typeof moduleParams !== 'object' || moduleParams === null) {
  3585. extend(allModulesParams, obj);
  3586. return;
  3587. }
  3588. if (params[moduleParamName] === true) {
  3589. params[moduleParamName] = {
  3590. enabled: true
  3591. };
  3592. }
  3593. if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) {
  3594. params[moduleParamName].auto = true;
  3595. }
  3596. if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
  3597. params[moduleParamName].auto = true;
  3598. }
  3599. if (!(moduleParamName in params && 'enabled' in moduleParams)) {
  3600. extend(allModulesParams, obj);
  3601. return;
  3602. }
  3603. if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
  3604. params[moduleParamName].enabled = true;
  3605. }
  3606. if (!params[moduleParamName]) params[moduleParamName] = {
  3607. enabled: false
  3608. };
  3609. extend(allModulesParams, obj);
  3610. };
  3611. }
  3612. /* eslint no-param-reassign: "off" */
  3613. const prototypes = {
  3614. eventsEmitter,
  3615. update,
  3616. translate,
  3617. transition,
  3618. slide,
  3619. loop,
  3620. grabCursor,
  3621. events: events$1,
  3622. breakpoints,
  3623. checkOverflow: checkOverflow$1,
  3624. classes
  3625. };
  3626. const extendedDefaults = {};
  3627. class Swiper {
  3628. constructor() {
  3629. let el;
  3630. let params;
  3631. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  3632. args[_key] = arguments[_key];
  3633. }
  3634. if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
  3635. params = args[0];
  3636. } else {
  3637. [el, params] = args;
  3638. }
  3639. if (!params) params = {};
  3640. params = extend({}, params);
  3641. if (el && !params.el) params.el = el;
  3642. const document = getDocument();
  3643. if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) {
  3644. const swipers = [];
  3645. document.querySelectorAll(params.el).forEach(containerEl => {
  3646. const newParams = extend({}, params, {
  3647. el: containerEl
  3648. });
  3649. swipers.push(new Swiper(newParams));
  3650. });
  3651. // eslint-disable-next-line no-constructor-return
  3652. return swipers;
  3653. }
  3654. // Swiper Instance
  3655. const swiper = this;
  3656. swiper.__swiper__ = true;
  3657. swiper.support = getSupport();
  3658. swiper.device = getDevice({
  3659. userAgent: params.userAgent
  3660. });
  3661. swiper.browser = getBrowser();
  3662. swiper.eventsListeners = {};
  3663. swiper.eventsAnyListeners = [];
  3664. swiper.modules = [...swiper.__modules__];
  3665. if (params.modules && Array.isArray(params.modules)) {
  3666. swiper.modules.push(...params.modules);
  3667. }
  3668. const allModulesParams = {};
  3669. swiper.modules.forEach(mod => {
  3670. mod({
  3671. params,
  3672. swiper,
  3673. extendParams: moduleExtendParams(params, allModulesParams),
  3674. on: swiper.on.bind(swiper),
  3675. once: swiper.once.bind(swiper),
  3676. off: swiper.off.bind(swiper),
  3677. emit: swiper.emit.bind(swiper)
  3678. });
  3679. });
  3680. // Extend defaults with modules params
  3681. const swiperParams = extend({}, defaults, allModulesParams);
  3682. // Extend defaults with passed params
  3683. swiper.params = extend({}, swiperParams, extendedDefaults, params);
  3684. swiper.originalParams = extend({}, swiper.params);
  3685. swiper.passedParams = extend({}, params);
  3686. // add event listeners
  3687. if (swiper.params && swiper.params.on) {
  3688. Object.keys(swiper.params.on).forEach(eventName => {
  3689. swiper.on(eventName, swiper.params.on[eventName]);
  3690. });
  3691. }
  3692. if (swiper.params && swiper.params.onAny) {
  3693. swiper.onAny(swiper.params.onAny);
  3694. }
  3695. // Extend Swiper
  3696. Object.assign(swiper, {
  3697. enabled: swiper.params.enabled,
  3698. el,
  3699. // Classes
  3700. classNames: [],
  3701. // Slides
  3702. slides: [],
  3703. slidesGrid: [],
  3704. snapGrid: [],
  3705. slidesSizesGrid: [],
  3706. // isDirection
  3707. isHorizontal() {
  3708. return swiper.params.direction === 'horizontal';
  3709. },
  3710. isVertical() {
  3711. return swiper.params.direction === 'vertical';
  3712. },
  3713. // Indexes
  3714. activeIndex: 0,
  3715. realIndex: 0,
  3716. //
  3717. isBeginning: true,
  3718. isEnd: false,
  3719. // Props
  3720. translate: 0,
  3721. previousTranslate: 0,
  3722. progress: 0,
  3723. velocity: 0,
  3724. animating: false,
  3725. cssOverflowAdjustment() {
  3726. // Returns 0 unless `translate` is > 2**23
  3727. // Should be subtracted from css values to prevent overflow
  3728. return Math.trunc(this.translate / 2 ** 23) * 2 ** 23;
  3729. },
  3730. // Locks
  3731. allowSlideNext: swiper.params.allowSlideNext,
  3732. allowSlidePrev: swiper.params.allowSlidePrev,
  3733. // Touch Events
  3734. touchEventsData: {
  3735. isTouched: undefined,
  3736. isMoved: undefined,
  3737. allowTouchCallbacks: undefined,
  3738. touchStartTime: undefined,
  3739. isScrolling: undefined,
  3740. currentTranslate: undefined,
  3741. startTranslate: undefined,
  3742. allowThresholdMove: undefined,
  3743. // Form elements to match
  3744. focusableElements: swiper.params.focusableElements,
  3745. // Last click time
  3746. lastClickTime: 0,
  3747. clickTimeout: undefined,
  3748. // Velocities
  3749. velocities: [],
  3750. allowMomentumBounce: undefined,
  3751. startMoving: undefined,
  3752. pointerId: null,
  3753. touchId: null
  3754. },
  3755. // Clicks
  3756. allowClick: true,
  3757. // Touches
  3758. allowTouchMove: swiper.params.allowTouchMove,
  3759. touches: {
  3760. startX: 0,
  3761. startY: 0,
  3762. currentX: 0,
  3763. currentY: 0,
  3764. diff: 0
  3765. },
  3766. // Images
  3767. imagesToLoad: [],
  3768. imagesLoaded: 0
  3769. });
  3770. swiper.emit('_swiper');
  3771. // Init
  3772. if (swiper.params.init) {
  3773. swiper.init();
  3774. }
  3775. // Return app instance
  3776. // eslint-disable-next-line no-constructor-return
  3777. return swiper;
  3778. }
  3779. getDirectionLabel(property) {
  3780. if (this.isHorizontal()) {
  3781. return property;
  3782. }
  3783. // prettier-ignore
  3784. return {
  3785. 'width': 'height',
  3786. 'margin-top': 'margin-left',
  3787. 'margin-bottom ': 'margin-right',
  3788. 'margin-left': 'margin-top',
  3789. 'margin-right': 'margin-bottom',
  3790. 'padding-left': 'padding-top',
  3791. 'padding-right': 'padding-bottom',
  3792. 'marginRight': 'marginBottom'
  3793. }[property];
  3794. }
  3795. getSlideIndex(slideEl) {
  3796. const {
  3797. slidesEl,
  3798. params
  3799. } = this;
  3800. const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
  3801. const firstSlideIndex = elementIndex(slides[0]);
  3802. return elementIndex(slideEl) - firstSlideIndex;
  3803. }
  3804. getSlideIndexByData(index) {
  3805. return this.getSlideIndex(this.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index)[0]);
  3806. }
  3807. recalcSlides() {
  3808. const swiper = this;
  3809. const {
  3810. slidesEl,
  3811. params
  3812. } = swiper;
  3813. swiper.slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
  3814. }
  3815. enable() {
  3816. const swiper = this;
  3817. if (swiper.enabled) return;
  3818. swiper.enabled = true;
  3819. if (swiper.params.grabCursor) {
  3820. swiper.setGrabCursor();
  3821. }
  3822. swiper.emit('enable');
  3823. }
  3824. disable() {
  3825. const swiper = this;
  3826. if (!swiper.enabled) return;
  3827. swiper.enabled = false;
  3828. if (swiper.params.grabCursor) {
  3829. swiper.unsetGrabCursor();
  3830. }
  3831. swiper.emit('disable');
  3832. }
  3833. setProgress(progress, speed) {
  3834. const swiper = this;
  3835. progress = Math.min(Math.max(progress, 0), 1);
  3836. const min = swiper.minTranslate();
  3837. const max = swiper.maxTranslate();
  3838. const current = (max - min) * progress + min;
  3839. swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
  3840. swiper.updateActiveIndex();
  3841. swiper.updateSlidesClasses();
  3842. }
  3843. emitContainerClasses() {
  3844. const swiper = this;
  3845. if (!swiper.params._emitClasses || !swiper.el) return;
  3846. const cls = swiper.el.className.split(' ').filter(className => {
  3847. return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
  3848. });
  3849. swiper.emit('_containerClasses', cls.join(' '));
  3850. }
  3851. getSlideClasses(slideEl) {
  3852. const swiper = this;
  3853. if (swiper.destroyed) return '';
  3854. return slideEl.className.split(' ').filter(className => {
  3855. return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
  3856. }).join(' ');
  3857. }
  3858. emitSlidesClasses() {
  3859. const swiper = this;
  3860. if (!swiper.params._emitClasses || !swiper.el) return;
  3861. const updates = [];
  3862. swiper.slides.forEach(slideEl => {
  3863. const classNames = swiper.getSlideClasses(slideEl);
  3864. updates.push({
  3865. slideEl,
  3866. classNames
  3867. });
  3868. swiper.emit('_slideClass', slideEl, classNames);
  3869. });
  3870. swiper.emit('_slideClasses', updates);
  3871. }
  3872. slidesPerViewDynamic(view, exact) {
  3873. if (view === void 0) {
  3874. view = 'current';
  3875. }
  3876. if (exact === void 0) {
  3877. exact = false;
  3878. }
  3879. const swiper = this;
  3880. const {
  3881. params,
  3882. slides,
  3883. slidesGrid,
  3884. slidesSizesGrid,
  3885. size: swiperSize,
  3886. activeIndex
  3887. } = swiper;
  3888. let spv = 1;
  3889. if (typeof params.slidesPerView === 'number') return params.slidesPerView;
  3890. if (params.centeredSlides) {
  3891. let slideSize = slides[activeIndex] ? Math.ceil(slides[activeIndex].swiperSlideSize) : 0;
  3892. let breakLoop;
  3893. for (let i = activeIndex + 1; i < slides.length; i += 1) {
  3894. if (slides[i] && !breakLoop) {
  3895. slideSize += Math.ceil(slides[i].swiperSlideSize);
  3896. spv += 1;
  3897. if (slideSize > swiperSize) breakLoop = true;
  3898. }
  3899. }
  3900. for (let i = activeIndex - 1; i >= 0; i -= 1) {
  3901. if (slides[i] && !breakLoop) {
  3902. slideSize += slides[i].swiperSlideSize;
  3903. spv += 1;
  3904. if (slideSize > swiperSize) breakLoop = true;
  3905. }
  3906. }
  3907. } else {
  3908. // eslint-disable-next-line
  3909. if (view === 'current') {
  3910. for (let i = activeIndex + 1; i < slides.length; i += 1) {
  3911. const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
  3912. if (slideInView) {
  3913. spv += 1;
  3914. }
  3915. }
  3916. } else {
  3917. // previous
  3918. for (let i = activeIndex - 1; i >= 0; i -= 1) {
  3919. const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
  3920. if (slideInView) {
  3921. spv += 1;
  3922. }
  3923. }
  3924. }
  3925. }
  3926. return spv;
  3927. }
  3928. update() {
  3929. const swiper = this;
  3930. if (!swiper || swiper.destroyed) return;
  3931. const {
  3932. snapGrid,
  3933. params
  3934. } = swiper;
  3935. // Breakpoints
  3936. if (params.breakpoints) {
  3937. swiper.setBreakpoint();
  3938. }
  3939. [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
  3940. if (imageEl.complete) {
  3941. processLazyPreloader(swiper, imageEl);
  3942. }
  3943. });
  3944. swiper.updateSize();
  3945. swiper.updateSlides();
  3946. swiper.updateProgress();
  3947. swiper.updateSlidesClasses();
  3948. function setTranslate() {
  3949. const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
  3950. const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
  3951. swiper.setTranslate(newTranslate);
  3952. swiper.updateActiveIndex();
  3953. swiper.updateSlidesClasses();
  3954. }
  3955. let translated;
  3956. if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
  3957. setTranslate();
  3958. if (params.autoHeight) {
  3959. swiper.updateAutoHeight();
  3960. }
  3961. } else {
  3962. if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
  3963. const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
  3964. translated = swiper.slideTo(slides.length - 1, 0, false, true);
  3965. } else {
  3966. translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
  3967. }
  3968. if (!translated) {
  3969. setTranslate();
  3970. }
  3971. }
  3972. if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
  3973. swiper.checkOverflow();
  3974. }
  3975. swiper.emit('update');
  3976. }
  3977. changeDirection(newDirection, needUpdate) {
  3978. if (needUpdate === void 0) {
  3979. needUpdate = true;
  3980. }
  3981. const swiper = this;
  3982. const currentDirection = swiper.params.direction;
  3983. if (!newDirection) {
  3984. // eslint-disable-next-line
  3985. newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
  3986. }
  3987. if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
  3988. return swiper;
  3989. }
  3990. swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`);
  3991. swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`);
  3992. swiper.emitContainerClasses();
  3993. swiper.params.direction = newDirection;
  3994. swiper.slides.forEach(slideEl => {
  3995. if (newDirection === 'vertical') {
  3996. slideEl.style.width = '';
  3997. } else {
  3998. slideEl.style.height = '';
  3999. }
  4000. });
  4001. swiper.emit('changeDirection');
  4002. if (needUpdate) swiper.update();
  4003. return swiper;
  4004. }
  4005. changeLanguageDirection(direction) {
  4006. const swiper = this;
  4007. if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return;
  4008. swiper.rtl = direction === 'rtl';
  4009. swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;
  4010. if (swiper.rtl) {
  4011. swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`);
  4012. swiper.el.dir = 'rtl';
  4013. } else {
  4014. swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`);
  4015. swiper.el.dir = 'ltr';
  4016. }
  4017. swiper.update();
  4018. }
  4019. mount(element) {
  4020. const swiper = this;
  4021. if (swiper.mounted) return true;
  4022. // Find el
  4023. let el = element || swiper.params.el;
  4024. if (typeof el === 'string') {
  4025. el = document.querySelector(el);
  4026. }
  4027. if (!el) {
  4028. return false;
  4029. }
  4030. el.swiper = swiper;
  4031. if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) {
  4032. swiper.isElement = true;
  4033. }
  4034. const getWrapperSelector = () => {
  4035. return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
  4036. };
  4037. const getWrapper = () => {
  4038. if (el && el.shadowRoot && el.shadowRoot.querySelector) {
  4039. const res = el.shadowRoot.querySelector(getWrapperSelector());
  4040. // Children needs to return slot items
  4041. return res;
  4042. }
  4043. return elementChildren(el, getWrapperSelector())[0];
  4044. };
  4045. // Find Wrapper
  4046. let wrapperEl = getWrapper();
  4047. if (!wrapperEl && swiper.params.createElements) {
  4048. wrapperEl = createElement('div', swiper.params.wrapperClass);
  4049. el.append(wrapperEl);
  4050. elementChildren(el, `.${swiper.params.slideClass}`).forEach(slideEl => {
  4051. wrapperEl.append(slideEl);
  4052. });
  4053. }
  4054. Object.assign(swiper, {
  4055. el,
  4056. wrapperEl,
  4057. slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
  4058. hostEl: swiper.isElement ? el.parentNode.host : el,
  4059. mounted: true,
  4060. // RTL
  4061. rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
  4062. rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
  4063. wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
  4064. });
  4065. return true;
  4066. }
  4067. init(el) {
  4068. const swiper = this;
  4069. if (swiper.initialized) return swiper;
  4070. const mounted = swiper.mount(el);
  4071. if (mounted === false) return swiper;
  4072. swiper.emit('beforeInit');
  4073. // Set breakpoint
  4074. if (swiper.params.breakpoints) {
  4075. swiper.setBreakpoint();
  4076. }
  4077. // Add Classes
  4078. swiper.addClasses();
  4079. // Update size
  4080. swiper.updateSize();
  4081. // Update slides
  4082. swiper.updateSlides();
  4083. if (swiper.params.watchOverflow) {
  4084. swiper.checkOverflow();
  4085. }
  4086. // Set Grab Cursor
  4087. if (swiper.params.grabCursor && swiper.enabled) {
  4088. swiper.setGrabCursor();
  4089. }
  4090. // Slide To Initial Slide
  4091. if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
  4092. swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
  4093. } else {
  4094. swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
  4095. }
  4096. // Create loop
  4097. if (swiper.params.loop) {
  4098. swiper.loopCreate();
  4099. }
  4100. // Attach events
  4101. swiper.attachEvents();
  4102. const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')];
  4103. if (swiper.isElement) {
  4104. lazyElements.push(...swiper.hostEl.querySelectorAll('[loading="lazy"]'));
  4105. }
  4106. lazyElements.forEach(imageEl => {
  4107. if (imageEl.complete) {
  4108. processLazyPreloader(swiper, imageEl);
  4109. } else {
  4110. imageEl.addEventListener('load', e => {
  4111. processLazyPreloader(swiper, e.target);
  4112. });
  4113. }
  4114. });
  4115. preload(swiper);
  4116. // Init Flag
  4117. swiper.initialized = true;
  4118. preload(swiper);
  4119. // Emit
  4120. swiper.emit('init');
  4121. swiper.emit('afterInit');
  4122. return swiper;
  4123. }
  4124. destroy(deleteInstance, cleanStyles) {
  4125. if (deleteInstance === void 0) {
  4126. deleteInstance = true;
  4127. }
  4128. if (cleanStyles === void 0) {
  4129. cleanStyles = true;
  4130. }
  4131. const swiper = this;
  4132. const {
  4133. params,
  4134. el,
  4135. wrapperEl,
  4136. slides
  4137. } = swiper;
  4138. if (typeof swiper.params === 'undefined' || swiper.destroyed) {
  4139. return null;
  4140. }
  4141. swiper.emit('beforeDestroy');
  4142. // Init Flag
  4143. swiper.initialized = false;
  4144. // Detach events
  4145. swiper.detachEvents();
  4146. // Destroy loop
  4147. if (params.loop) {
  4148. swiper.loopDestroy();
  4149. }
  4150. // Cleanup styles
  4151. if (cleanStyles) {
  4152. swiper.removeClasses();
  4153. if (el && typeof el !== 'string') {
  4154. el.removeAttribute('style');
  4155. }
  4156. if (wrapperEl) {
  4157. wrapperEl.removeAttribute('style');
  4158. }
  4159. if (slides && slides.length) {
  4160. slides.forEach(slideEl => {
  4161. slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
  4162. slideEl.removeAttribute('style');
  4163. slideEl.removeAttribute('data-swiper-slide-index');
  4164. });
  4165. }
  4166. }
  4167. swiper.emit('destroy');
  4168. // Detach emitter events
  4169. Object.keys(swiper.eventsListeners).forEach(eventName => {
  4170. swiper.off(eventName);
  4171. });
  4172. if (deleteInstance !== false) {
  4173. if (swiper.el && typeof swiper.el !== 'string') {
  4174. swiper.el.swiper = null;
  4175. }
  4176. deleteProps(swiper);
  4177. }
  4178. swiper.destroyed = true;
  4179. return null;
  4180. }
  4181. static extendDefaults(newDefaults) {
  4182. extend(extendedDefaults, newDefaults);
  4183. }
  4184. static get extendedDefaults() {
  4185. return extendedDefaults;
  4186. }
  4187. static get defaults() {
  4188. return defaults;
  4189. }
  4190. static installModule(mod) {
  4191. if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
  4192. const modules = Swiper.prototype.__modules__;
  4193. if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
  4194. modules.push(mod);
  4195. }
  4196. }
  4197. static use(module) {
  4198. if (Array.isArray(module)) {
  4199. module.forEach(m => Swiper.installModule(m));
  4200. return Swiper;
  4201. }
  4202. Swiper.installModule(module);
  4203. return Swiper;
  4204. }
  4205. }
  4206. Object.keys(prototypes).forEach(prototypeGroup => {
  4207. Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
  4208. Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
  4209. });
  4210. });
  4211. Swiper.use([Resize, Observer]);
  4212. return Swiper;
  4213. })();