swiper.js 149 KB

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