').parent(), e.$slideTrack.css(\"opacity\", 0), !0 !== e.options.centerMode && !0 !== e.options.swipeToSlide || (e.options.slidesToScroll = 1), i(\"img[data-lazy]\", e.$slider).not(\"[src]\").addClass(\"slick-loading\"), e.setupInfinite(), e.buildArrows(), e.buildDots(), e.updateDots(), e.setSlideClasses(\"number\" == typeof e.currentSlide ? e.currentSlide : 0), !0 === e.options.draggable && e.$list.addClass(\"draggable\");\n }, e.prototype.buildRows = function () {\n var i,\n e,\n t,\n o,\n s,\n n,\n r,\n l = this;\n if (o = document.createDocumentFragment(), n = l.$slider.children(), l.options.rows > 1) {\n for (r = l.options.slidesPerRow * l.options.rows, s = Math.ceil(n.length / r), i = 0; i < s; i++) {\n var d = document.createElement(\"div\");\n for (e = 0; e < l.options.rows; e++) {\n var a = document.createElement(\"div\");\n for (t = 0; t < l.options.slidesPerRow; t++) {\n var c = i * r + (e * l.options.slidesPerRow + t);\n n.get(c) && a.appendChild(n.get(c));\n }\n d.appendChild(a);\n }\n o.appendChild(d);\n }\n l.$slider.empty().append(o), l.$slider.children().children().children().css({\n width: 100 / l.options.slidesPerRow + \"%\",\n display: \"inline-block\"\n });\n }\n }, e.prototype.checkResponsive = function (e, t) {\n var o,\n s,\n n,\n r = this,\n l = !1,\n d = r.$slider.width(),\n a = window.innerWidth || i(window).width();\n if (\"window\" === r.respondTo ? n = a : \"slider\" === r.respondTo ? n = d : \"min\" === r.respondTo && (n = Math.min(a, d)), r.options.responsive && r.options.responsive.length && null !== r.options.responsive) {\n s = null;\n for (o in r.breakpoints) r.breakpoints.hasOwnProperty(o) && (!1 === r.originalSettings.mobileFirst ? n < r.breakpoints[o] && (s = r.breakpoints[o]) : n > r.breakpoints[o] && (s = r.breakpoints[o]));\n null !== s ? null !== r.activeBreakpoint ? (s !== r.activeBreakpoint || t) && (r.activeBreakpoint = s, \"unslick\" === r.breakpointSettings[s] ? r.unslick(s) : (r.options = i.extend({}, r.originalSettings, r.breakpointSettings[s]), !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e)), l = s) : (r.activeBreakpoint = s, \"unslick\" === r.breakpointSettings[s] ? r.unslick(s) : (r.options = i.extend({}, r.originalSettings, r.breakpointSettings[s]), !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e)), l = s) : null !== r.activeBreakpoint && (r.activeBreakpoint = null, r.options = r.originalSettings, !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e), l = s), e || !1 === l || r.$slider.trigger(\"breakpoint\", [r, l]);\n }\n }, e.prototype.changeSlide = function (e, t) {\n var o,\n s,\n n,\n r = this,\n l = i(e.currentTarget);\n switch (l.is(\"a\") && e.preventDefault(), l.is(\"li\") || (l = l.closest(\"li\")), n = r.slideCount % r.options.slidesToScroll != 0, o = n ? 0 : (r.slideCount - r.currentSlide) % r.options.slidesToScroll, e.data.message) {\n case \"previous\":\n s = 0 === o ? r.options.slidesToScroll : r.options.slidesToShow - o, r.slideCount > r.options.slidesToShow && r.slideHandler(r.currentSlide - s, !1, t);\n break;\n case \"next\":\n s = 0 === o ? r.options.slidesToScroll : o, r.slideCount > r.options.slidesToShow && r.slideHandler(r.currentSlide + s, !1, t);\n break;\n case \"index\":\n var d = 0 === e.data.index ? 0 : e.data.index || l.index() * r.options.slidesToScroll;\n r.slideHandler(r.checkNavigable(d), !1, t), l.children().trigger(\"focus\");\n break;\n default:\n return;\n }\n }, e.prototype.checkNavigable = function (i) {\n var e, t;\n if (e = this.getNavigableIndexes(), t = 0, i > e[e.length - 1]) i = e[e.length - 1];else for (var o in e) {\n if (i < e[o]) {\n i = t;\n break;\n }\n t = e[o];\n }\n return i;\n }, e.prototype.cleanUpEvents = function () {\n var e = this;\n e.options.dots && null !== e.$dots && (i(\"li\", e.$dots).off(\"click.slick\", e.changeSlide).off(\"mouseenter.slick\", i.proxy(e.interrupt, e, !0)).off(\"mouseleave.slick\", i.proxy(e.interrupt, e, !1)), !0 === e.options.accessibility && e.$dots.off(\"keydown.slick\", e.keyHandler)), e.$slider.off(\"focus.slick blur.slick\"), !0 === e.options.arrows && e.slideCount > e.options.slidesToShow && (e.$prevArrow && e.$prevArrow.off(\"click.slick\", e.changeSlide), e.$nextArrow && e.$nextArrow.off(\"click.slick\", e.changeSlide), !0 === e.options.accessibility && (e.$prevArrow && e.$prevArrow.off(\"keydown.slick\", e.keyHandler), e.$nextArrow && e.$nextArrow.off(\"keydown.slick\", e.keyHandler))), e.$list.off(\"touchstart.slick mousedown.slick\", e.swipeHandler), e.$list.off(\"touchmove.slick mousemove.slick\", e.swipeHandler), e.$list.off(\"touchend.slick mouseup.slick\", e.swipeHandler), e.$list.off(\"touchcancel.slick mouseleave.slick\", e.swipeHandler), e.$list.off(\"click.slick\", e.clickHandler), i(document).off(e.visibilityChange, e.visibility), e.cleanUpSlideEvents(), !0 === e.options.accessibility && e.$list.off(\"keydown.slick\", e.keyHandler), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().off(\"click.slick\", e.selectHandler), i(window).off(\"orientationchange.slick.slick-\" + e.instanceUid, e.orientationChange), i(window).off(\"resize.slick.slick-\" + e.instanceUid, e.resize), i(\"[draggable!=true]\", e.$slideTrack).off(\"dragstart\", e.preventDefault), i(window).off(\"load.slick.slick-\" + e.instanceUid, e.setPosition);\n }, e.prototype.cleanUpSlideEvents = function () {\n var e = this;\n e.$list.off(\"mouseenter.slick\", i.proxy(e.interrupt, e, !0)), e.$list.off(\"mouseleave.slick\", i.proxy(e.interrupt, e, !1));\n }, e.prototype.cleanUpRows = function () {\n var i,\n e = this;\n e.options.rows > 1 && ((i = e.$slides.children().children()).removeAttr(\"style\"), e.$slider.empty().append(i));\n }, e.prototype.clickHandler = function (i) {\n !1 === this.shouldClick && (i.stopImmediatePropagation(), i.stopPropagation(), i.preventDefault());\n }, e.prototype.destroy = function (e) {\n var t = this;\n t.autoPlayClear(), t.touchObject = {}, t.cleanUpEvents(), i(\".slick-cloned\", t.$slider).detach(), t.$dots && t.$dots.remove(), t.$prevArrow && t.$prevArrow.length && (t.$prevArrow.removeClass(\"slick-disabled slick-arrow slick-hidden\").removeAttr(\"aria-hidden aria-disabled tabindex\").css(\"display\", \"\"), t.htmlExpr.test(t.options.prevArrow) && t.$prevArrow.remove()), t.$nextArrow && t.$nextArrow.length && (t.$nextArrow.removeClass(\"slick-disabled slick-arrow slick-hidden\").removeAttr(\"aria-hidden aria-disabled tabindex\").css(\"display\", \"\"), t.htmlExpr.test(t.options.nextArrow) && t.$nextArrow.remove()), t.$slides && (t.$slides.removeClass(\"slick-slide slick-active slick-center slick-visible slick-current\").removeAttr(\"aria-hidden\").removeAttr(\"data-slick-index\").each(function () {\n i(this).attr(\"style\", i(this).data(\"originalStyling\"));\n }), t.$slideTrack.children(this.options.slide).detach(), t.$slideTrack.detach(), t.$list.detach(), t.$slider.append(t.$slides)), t.cleanUpRows(), t.$slider.removeClass(\"slick-slider\"), t.$slider.removeClass(\"slick-initialized\"), t.$slider.removeClass(\"slick-dotted\"), t.unslicked = !0, e || t.$slider.trigger(\"destroy\", [t]);\n }, e.prototype.disableTransition = function (i) {\n var e = this,\n t = {};\n t[e.transitionType] = \"\", !1 === e.options.fade ? e.$slideTrack.css(t) : e.$slides.eq(i).css(t);\n }, e.prototype.fadeSlide = function (i, e) {\n var t = this;\n !1 === t.cssTransitions ? (t.$slides.eq(i).css({\n zIndex: t.options.zIndex\n }), t.$slides.eq(i).animate({\n opacity: 1\n }, t.options.speed, t.options.easing, e)) : (t.applyTransition(i), t.$slides.eq(i).css({\n opacity: 1,\n zIndex: t.options.zIndex\n }), e && setTimeout(function () {\n t.disableTransition(i), e.call();\n }, t.options.speed));\n }, e.prototype.fadeSlideOut = function (i) {\n var e = this;\n !1 === e.cssTransitions ? e.$slides.eq(i).animate({\n opacity: 0,\n zIndex: e.options.zIndex - 2\n }, e.options.speed, e.options.easing) : (e.applyTransition(i), e.$slides.eq(i).css({\n opacity: 0,\n zIndex: e.options.zIndex - 2\n }));\n }, e.prototype.filterSlides = e.prototype.slickFilter = function (i) {\n var e = this;\n null !== i && (e.$slidesCache = e.$slides, e.unload(), e.$slideTrack.children(this.options.slide).detach(), e.$slidesCache.filter(i).appendTo(e.$slideTrack), e.reinit());\n }, e.prototype.focusHandler = function () {\n var e = this;\n e.$slider.off(\"focus.slick blur.slick\").on(\"focus.slick blur.slick\", \"*\", function (t) {\n t.stopImmediatePropagation();\n var o = i(this);\n setTimeout(function () {\n e.options.pauseOnFocus && (e.focussed = o.is(\":focus\"), e.autoPlay());\n }, 0);\n });\n }, e.prototype.getCurrent = e.prototype.slickCurrentSlide = function () {\n return this.currentSlide;\n }, e.prototype.getDotCount = function () {\n var i = this,\n e = 0,\n t = 0,\n o = 0;\n if (!0 === i.options.infinite) {\n if (i.slideCount <= i.options.slidesToShow) ++o;else for (; e < i.slideCount;) ++o, e = t + i.options.slidesToScroll, t += i.options.slidesToScroll <= i.options.slidesToShow ? i.options.slidesToScroll : i.options.slidesToShow;\n } else if (!0 === i.options.centerMode) o = i.slideCount;else if (i.options.asNavFor) for (; e < i.slideCount;) ++o, e = t + i.options.slidesToScroll, t += i.options.slidesToScroll <= i.options.slidesToShow ? i.options.slidesToScroll : i.options.slidesToShow;else o = 1 + Math.ceil((i.slideCount - i.options.slidesToShow) / i.options.slidesToScroll);\n return o - 1;\n }, e.prototype.getLeft = function (i) {\n var e,\n t,\n o,\n s,\n n = this,\n r = 0;\n return n.slideOffset = 0, t = n.$slides.first().outerHeight(!0), !0 === n.options.infinite ? (n.slideCount > n.options.slidesToShow && (n.slideOffset = n.slideWidth * n.options.slidesToShow * -1, s = -1, !0 === n.options.vertical && !0 === n.options.centerMode && (2 === n.options.slidesToShow ? s = -1.5 : 1 === n.options.slidesToShow && (s = -2)), r = t * n.options.slidesToShow * s), n.slideCount % n.options.slidesToScroll != 0 && i + n.options.slidesToScroll > n.slideCount && n.slideCount > n.options.slidesToShow && (i > n.slideCount ? (n.slideOffset = (n.options.slidesToShow - (i - n.slideCount)) * n.slideWidth * -1, r = (n.options.slidesToShow - (i - n.slideCount)) * t * -1) : (n.slideOffset = n.slideCount % n.options.slidesToScroll * n.slideWidth * -1, r = n.slideCount % n.options.slidesToScroll * t * -1))) : i + n.options.slidesToShow > n.slideCount && (n.slideOffset = (i + n.options.slidesToShow - n.slideCount) * n.slideWidth, r = (i + n.options.slidesToShow - n.slideCount) * t), n.slideCount <= n.options.slidesToShow && (n.slideOffset = 0, r = 0), !0 === n.options.centerMode && n.slideCount <= n.options.slidesToShow ? n.slideOffset = n.slideWidth * Math.floor(n.options.slidesToShow) / 2 - n.slideWidth * n.slideCount / 2 : !0 === n.options.centerMode && !0 === n.options.infinite ? n.slideOffset += n.slideWidth * Math.floor(n.options.slidesToShow / 2) - n.slideWidth : !0 === n.options.centerMode && (n.slideOffset = 0, n.slideOffset += n.slideWidth * Math.floor(n.options.slidesToShow / 2)), e = !1 === n.options.vertical ? i * n.slideWidth * -1 + n.slideOffset : i * t * -1 + r, !0 === n.options.variableWidth && (o = n.slideCount <= n.options.slidesToShow || !1 === n.options.infinite ? n.$slideTrack.children(\".slick-slide\").eq(i) : n.$slideTrack.children(\".slick-slide\").eq(i + n.options.slidesToShow), e = !0 === n.options.rtl ? o[0] ? -1 * (n.$slideTrack.width() - o[0].offsetLeft - o.width()) : 0 : o[0] ? -1 * o[0].offsetLeft : 0, !0 === n.options.centerMode && (o = n.slideCount <= n.options.slidesToShow || !1 === n.options.infinite ? n.$slideTrack.children(\".slick-slide\").eq(i) : n.$slideTrack.children(\".slick-slide\").eq(i + n.options.slidesToShow + 1), e = !0 === n.options.rtl ? o[0] ? -1 * (n.$slideTrack.width() - o[0].offsetLeft - o.width()) : 0 : o[0] ? -1 * o[0].offsetLeft : 0, e += (n.$list.width() - o.outerWidth()) / 2)), e;\n }, e.prototype.getOption = e.prototype.slickGetOption = function (i) {\n return this.options[i];\n }, e.prototype.getNavigableIndexes = function () {\n var i,\n e = this,\n t = 0,\n o = 0,\n s = [];\n for (!1 === e.options.infinite ? i = e.slideCount : (t = -1 * e.options.slidesToScroll, o = -1 * e.options.slidesToScroll, i = 2 * e.slideCount); t < i;) s.push(t), t = o + e.options.slidesToScroll, o += e.options.slidesToScroll <= e.options.slidesToShow ? e.options.slidesToScroll : e.options.slidesToShow;\n return s;\n }, e.prototype.getSlick = function () {\n return this;\n }, e.prototype.getSlideCount = function () {\n var e,\n t,\n o = this;\n return t = !0 === o.options.centerMode ? o.slideWidth * Math.floor(o.options.slidesToShow / 2) : 0, !0 === o.options.swipeToSlide ? (o.$slideTrack.find(\".slick-slide\").each(function (s, n) {\n if (n.offsetLeft - t + i(n).outerWidth() / 2 > -1 * o.swipeLeft) return e = n, !1;\n }), Math.abs(i(e).attr(\"data-slick-index\") - o.currentSlide) || 1) : o.options.slidesToScroll;\n }, e.prototype.goTo = e.prototype.slickGoTo = function (i, e) {\n this.changeSlide({\n data: {\n message: \"index\",\n index: parseInt(i)\n }\n }, e);\n }, e.prototype.init = function (e) {\n var t = this;\n i(t.$slider).hasClass(\"slick-initialized\") || (i(t.$slider).addClass(\"slick-initialized\"), t.buildRows(), t.buildOut(), t.setProps(), t.startLoad(), t.loadSlider(), t.initializeEvents(), t.updateArrows(), t.updateDots(), t.checkResponsive(!0), t.focusHandler()), e && t.$slider.trigger(\"init\", [t]), !0 === t.options.accessibility && t.initADA(), t.options.autoplay && (t.paused = !1, t.autoPlay());\n }, e.prototype.initADA = function () {\n var e = this,\n t = Math.ceil(e.slideCount / e.options.slidesToShow),\n o = e.getNavigableIndexes().filter(function (i) {\n return i >= 0 && i < e.slideCount;\n });\n e.$slides.add(e.$slideTrack.find(\".slick-cloned\")).attr({\n \"aria-hidden\": \"true\",\n tabindex: \"-1\"\n }).find(\"a, input, button, select\").attr({\n tabindex: \"-1\"\n }), null !== e.$dots && (e.$slides.not(e.$slideTrack.find(\".slick-cloned\")).each(function (t) {\n var s = o.indexOf(t);\n i(this).attr({\n role: \"tabpanel\",\n id: \"slick-slide\" + e.instanceUid + t,\n tabindex: -1\n }), -1 !== s && i(this).attr({\n \"aria-describedby\": \"slick-slide-control\" + e.instanceUid + s\n });\n }), e.$dots.attr(\"role\", \"tablist\").find(\"li\").each(function (s) {\n var n = o[s];\n i(this).attr({\n role: \"presentation\"\n }), i(this).find(\"button\").first().attr({\n role: \"tab\",\n id: \"slick-slide-control\" + e.instanceUid + s,\n \"aria-controls\": \"slick-slide\" + e.instanceUid + n,\n \"aria-label\": s + 1 + \" of \" + t,\n \"aria-selected\": null,\n tabindex: \"-1\"\n });\n }).eq(e.currentSlide).find(\"button\").attr({\n \"aria-selected\": \"true\",\n tabindex: \"0\"\n }).end());\n for (var s = e.currentSlide, n = s + e.options.slidesToShow; s < n; s++) e.$slides.eq(s).attr(\"tabindex\", 0);\n e.activateADA();\n }, e.prototype.initArrowEvents = function () {\n var i = this;\n !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.off(\"click.slick\").on(\"click.slick\", {\n message: \"previous\"\n }, i.changeSlide), i.$nextArrow.off(\"click.slick\").on(\"click.slick\", {\n message: \"next\"\n }, i.changeSlide), !0 === i.options.accessibility && (i.$prevArrow.on(\"keydown.slick\", i.keyHandler), i.$nextArrow.on(\"keydown.slick\", i.keyHandler)));\n }, e.prototype.initDotEvents = function () {\n var e = this;\n !0 === e.options.dots && (i(\"li\", e.$dots).on(\"click.slick\", {\n message: \"index\"\n }, e.changeSlide), !0 === e.options.accessibility && e.$dots.on(\"keydown.slick\", e.keyHandler)), !0 === e.options.dots && !0 === e.options.pauseOnDotsHover && i(\"li\", e.$dots).on(\"mouseenter.slick\", i.proxy(e.interrupt, e, !0)).on(\"mouseleave.slick\", i.proxy(e.interrupt, e, !1));\n }, e.prototype.initSlideEvents = function () {\n var e = this;\n e.options.pauseOnHover && (e.$list.on(\"mouseenter.slick\", i.proxy(e.interrupt, e, !0)), e.$list.on(\"mouseleave.slick\", i.proxy(e.interrupt, e, !1)));\n }, e.prototype.initializeEvents = function () {\n var e = this;\n e.initArrowEvents(), e.initDotEvents(), e.initSlideEvents(), e.$list.on(\"touchstart.slick mousedown.slick\", {\n action: \"start\"\n }, e.swipeHandler), e.$list.on(\"touchmove.slick mousemove.slick\", {\n action: \"move\"\n }, e.swipeHandler), e.$list.on(\"touchend.slick mouseup.slick\", {\n action: \"end\"\n }, e.swipeHandler), e.$list.on(\"touchcancel.slick mouseleave.slick\", {\n action: \"end\"\n }, e.swipeHandler), e.$list.on(\"click.slick\", e.clickHandler), i(document).on(e.visibilityChange, i.proxy(e.visibility, e)), !0 === e.options.accessibility && e.$list.on(\"keydown.slick\", e.keyHandler), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().on(\"click.slick\", e.selectHandler), i(window).on(\"orientationchange.slick.slick-\" + e.instanceUid, i.proxy(e.orientationChange, e)), i(window).on(\"resize.slick.slick-\" + e.instanceUid, i.proxy(e.resize, e)), i(\"[draggable!=true]\", e.$slideTrack).on(\"dragstart\", e.preventDefault), i(window).on(\"load.slick.slick-\" + e.instanceUid, e.setPosition), i(e.setPosition);\n }, e.prototype.initUI = function () {\n var i = this;\n !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.show(), i.$nextArrow.show()), !0 === i.options.dots && i.slideCount > i.options.slidesToShow && i.$dots.show();\n }, e.prototype.keyHandler = function (i) {\n var e = this;\n i.target.tagName.match(\"TEXTAREA|INPUT|SELECT\") || (37 === i.keyCode && !0 === e.options.accessibility ? e.changeSlide({\n data: {\n message: !0 === e.options.rtl ? \"next\" : \"previous\"\n }\n }) : 39 === i.keyCode && !0 === e.options.accessibility && e.changeSlide({\n data: {\n message: !0 === e.options.rtl ? \"previous\" : \"next\"\n }\n }));\n }, e.prototype.lazyLoad = function () {\n function e(e) {\n i(\"img[data-lazy]\", e).each(function () {\n var e = i(this),\n t = i(this).attr(\"data-lazy\"),\n o = i(this).attr(\"data-srcset\"),\n s = i(this).attr(\"data-sizes\") || n.$slider.attr(\"data-sizes\"),\n r = document.createElement(\"img\");\n r.onload = function () {\n e.animate({\n opacity: 0\n }, 100, function () {\n o && (e.attr(\"srcset\", o), s && e.attr(\"sizes\", s)), e.attr(\"src\", t).animate({\n opacity: 1\n }, 200, function () {\n e.removeAttr(\"data-lazy data-srcset data-sizes\").removeClass(\"slick-loading\");\n }), n.$slider.trigger(\"lazyLoaded\", [n, e, t]);\n });\n }, r.onerror = function () {\n e.removeAttr(\"data-lazy\").removeClass(\"slick-loading\").addClass(\"slick-lazyload-error\"), n.$slider.trigger(\"lazyLoadError\", [n, e, t]);\n }, r.src = t;\n });\n }\n var t,\n o,\n s,\n n = this;\n if (!0 === n.options.centerMode ? !0 === n.options.infinite ? s = (o = n.currentSlide + (n.options.slidesToShow / 2 + 1)) + n.options.slidesToShow + 2 : (o = Math.max(0, n.currentSlide - (n.options.slidesToShow / 2 + 1)), s = n.options.slidesToShow / 2 + 1 + 2 + n.currentSlide) : (o = n.options.infinite ? n.options.slidesToShow + n.currentSlide : n.currentSlide, s = Math.ceil(o + n.options.slidesToShow), !0 === n.options.fade && (o > 0 && o--, s <= n.slideCount && s++)), t = n.$slider.find(\".slick-slide\").slice(o, s), \"anticipated\" === n.options.lazyLoad) for (var r = o - 1, l = s, d = n.$slider.find(\".slick-slide\"), a = 0; a < n.options.slidesToScroll; a++) r < 0 && (r = n.slideCount - 1), t = (t = t.add(d.eq(r))).add(d.eq(l)), r--, l++;\n e(t), n.slideCount <= n.options.slidesToShow ? e(n.$slider.find(\".slick-slide\")) : n.currentSlide >= n.slideCount - n.options.slidesToShow ? e(n.$slider.find(\".slick-cloned\").slice(0, n.options.slidesToShow)) : 0 === n.currentSlide && e(n.$slider.find(\".slick-cloned\").slice(-1 * n.options.slidesToShow));\n }, e.prototype.loadSlider = function () {\n var i = this;\n i.setPosition(), i.$slideTrack.css({\n opacity: 1\n }), i.$slider.removeClass(\"slick-loading\"), i.initUI(), \"progressive\" === i.options.lazyLoad && i.progressiveLazyLoad();\n }, e.prototype.next = e.prototype.slickNext = function () {\n this.changeSlide({\n data: {\n message: \"next\"\n }\n });\n }, e.prototype.orientationChange = function () {\n var i = this;\n i.checkResponsive(), i.setPosition();\n }, e.prototype.pause = e.prototype.slickPause = function () {\n var i = this;\n i.autoPlayClear(), i.paused = !0;\n }, e.prototype.play = e.prototype.slickPlay = function () {\n var i = this;\n i.autoPlay(), i.options.autoplay = !0, i.paused = !1, i.focussed = !1, i.interrupted = !1;\n }, e.prototype.postSlide = function (e) {\n var t = this;\n t.unslicked || (t.$slider.trigger(\"afterChange\", [t, e]), t.animating = !1, t.slideCount > t.options.slidesToShow && t.setPosition(), t.swipeLeft = null, t.options.autoplay && t.autoPlay(), !0 === t.options.accessibility && (t.initADA(), t.options.focusOnChange && i(t.$slides.get(t.currentSlide)).attr(\"tabindex\", 0).focus()));\n }, e.prototype.prev = e.prototype.slickPrev = function () {\n this.changeSlide({\n data: {\n message: \"previous\"\n }\n });\n }, e.prototype.preventDefault = function (i) {\n i.preventDefault();\n }, e.prototype.progressiveLazyLoad = function (e) {\n e = e || 1;\n var t,\n o,\n s,\n n,\n r,\n l = this,\n d = i(\"img[data-lazy]\", l.$slider);\n d.length ? (t = d.first(), o = t.attr(\"data-lazy\"), s = t.attr(\"data-srcset\"), n = t.attr(\"data-sizes\") || l.$slider.attr(\"data-sizes\"), (r = document.createElement(\"img\")).onload = function () {\n s && (t.attr(\"srcset\", s), n && t.attr(\"sizes\", n)), t.attr(\"src\", o).removeAttr(\"data-lazy data-srcset data-sizes\").removeClass(\"slick-loading\"), !0 === l.options.adaptiveHeight && l.setPosition(), l.$slider.trigger(\"lazyLoaded\", [l, t, o]), l.progressiveLazyLoad();\n }, r.onerror = function () {\n e < 3 ? setTimeout(function () {\n l.progressiveLazyLoad(e + 1);\n }, 500) : (t.removeAttr(\"data-lazy\").removeClass(\"slick-loading\").addClass(\"slick-lazyload-error\"), l.$slider.trigger(\"lazyLoadError\", [l, t, o]), l.progressiveLazyLoad());\n }, r.src = o) : l.$slider.trigger(\"allImagesLoaded\", [l]);\n }, e.prototype.refresh = function (e) {\n var t,\n o,\n s = this;\n o = s.slideCount - s.options.slidesToShow, !s.options.infinite && s.currentSlide > o && (s.currentSlide = o), s.slideCount <= s.options.slidesToShow && (s.currentSlide = 0), t = s.currentSlide, s.destroy(!0), i.extend(s, s.initials, {\n currentSlide: t\n }), s.init(), e || s.changeSlide({\n data: {\n message: \"index\",\n index: t\n }\n }, !1);\n }, e.prototype.registerBreakpoints = function () {\n var e,\n t,\n o,\n s = this,\n n = s.options.responsive || null;\n if (\"array\" === i.type(n) && n.length) {\n s.respondTo = s.options.respondTo || \"window\";\n for (e in n) if (o = s.breakpoints.length - 1, n.hasOwnProperty(e)) {\n for (t = n[e].breakpoint; o >= 0;) s.breakpoints[o] && s.breakpoints[o] === t && s.breakpoints.splice(o, 1), o--;\n s.breakpoints.push(t), s.breakpointSettings[t] = n[e].settings;\n }\n s.breakpoints.sort(function (i, e) {\n return s.options.mobileFirst ? i - e : e - i;\n });\n }\n }, e.prototype.reinit = function () {\n var e = this;\n e.$slides = e.$slideTrack.children(e.options.slide).addClass(\"slick-slide\"), e.slideCount = e.$slides.length, e.currentSlide >= e.slideCount && 0 !== e.currentSlide && (e.currentSlide = e.currentSlide - e.options.slidesToScroll), e.slideCount <= e.options.slidesToShow && (e.currentSlide = 0), e.registerBreakpoints(), e.setProps(), e.setupInfinite(), e.buildArrows(), e.updateArrows(), e.initArrowEvents(), e.buildDots(), e.updateDots(), e.initDotEvents(), e.cleanUpSlideEvents(), e.initSlideEvents(), e.checkResponsive(!1, !0), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().on(\"click.slick\", e.selectHandler), e.setSlideClasses(\"number\" == typeof e.currentSlide ? e.currentSlide : 0), e.setPosition(), e.focusHandler(), e.paused = !e.options.autoplay, e.autoPlay(), e.$slider.trigger(\"reInit\", [e]);\n }, e.prototype.resize = function () {\n var e = this;\n i(window).width() !== e.windowWidth && (clearTimeout(e.windowDelay), e.windowDelay = window.setTimeout(function () {\n e.windowWidth = i(window).width(), e.checkResponsive(), e.unslicked || e.setPosition();\n }, 50));\n }, e.prototype.removeSlide = e.prototype.slickRemove = function (i, e, t) {\n var o = this;\n if (i = \"boolean\" == typeof i ? !0 === (e = i) ? 0 : o.slideCount - 1 : !0 === e ? --i : i, o.slideCount < 1 || i < 0 || i > o.slideCount - 1) return !1;\n o.unload(), !0 === t ? o.$slideTrack.children().remove() : o.$slideTrack.children(this.options.slide).eq(i).remove(), o.$slides = o.$slideTrack.children(this.options.slide), o.$slideTrack.children(this.options.slide).detach(), o.$slideTrack.append(o.$slides), o.$slidesCache = o.$slides, o.reinit();\n }, e.prototype.setCSS = function (i) {\n var e,\n t,\n o = this,\n s = {};\n !0 === o.options.rtl && (i = -i), e = \"left\" == o.positionProp ? Math.ceil(i) + \"px\" : \"0px\", t = \"top\" == o.positionProp ? Math.ceil(i) + \"px\" : \"0px\", s[o.positionProp] = i, !1 === o.transformsEnabled ? o.$slideTrack.css(s) : (s = {}, !1 === o.cssTransitions ? (s[o.animType] = \"translate(\" + e + \", \" + t + \")\", o.$slideTrack.css(s)) : (s[o.animType] = \"translate3d(\" + e + \", \" + t + \", 0px)\", o.$slideTrack.css(s)));\n }, e.prototype.setDimensions = function () {\n var i = this;\n !1 === i.options.vertical ? !0 === i.options.centerMode && i.$list.css({\n padding: \"0px \" + i.options.centerPadding\n }) : (i.$list.height(i.$slides.first().outerHeight(!0) * i.options.slidesToShow), !0 === i.options.centerMode && i.$list.css({\n padding: i.options.centerPadding + \" 0px\"\n })), i.listWidth = i.$list.width(), i.listHeight = i.$list.height(), !1 === i.options.vertical && !1 === i.options.variableWidth ? (i.slideWidth = Math.ceil(i.listWidth / i.options.slidesToShow), i.$slideTrack.width(Math.ceil(i.slideWidth * i.$slideTrack.children(\".slick-slide\").length))) : !0 === i.options.variableWidth ? i.$slideTrack.width(5e3 * i.slideCount) : (i.slideWidth = Math.ceil(i.listWidth), i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0) * i.$slideTrack.children(\".slick-slide\").length)));\n var e = i.$slides.first().outerWidth(!0) - i.$slides.first().width();\n !1 === i.options.variableWidth && i.$slideTrack.children(\".slick-slide\").width(i.slideWidth - e);\n }, e.prototype.setFade = function () {\n var e,\n t = this;\n t.$slides.each(function (o, s) {\n e = t.slideWidth * o * -1, !0 === t.options.rtl ? i(s).css({\n position: \"relative\",\n right: e,\n top: 0,\n zIndex: t.options.zIndex - 2,\n opacity: 0\n }) : i(s).css({\n position: \"relative\",\n left: e,\n top: 0,\n zIndex: t.options.zIndex - 2,\n opacity: 0\n });\n }), t.$slides.eq(t.currentSlide).css({\n zIndex: t.options.zIndex - 1,\n opacity: 1\n });\n }, e.prototype.setHeight = function () {\n var i = this;\n if (1 === i.options.slidesToShow && !0 === i.options.adaptiveHeight && !1 === i.options.vertical) {\n var e = i.$slides.eq(i.currentSlide).outerHeight(!0);\n i.$list.css(\"height\", e);\n }\n }, e.prototype.setOption = e.prototype.slickSetOption = function () {\n var e,\n t,\n o,\n s,\n n,\n r = this,\n l = !1;\n if (\"object\" === i.type(arguments[0]) ? (o = arguments[0], l = arguments[1], n = \"multiple\") : \"string\" === i.type(arguments[0]) && (o = arguments[0], s = arguments[1], l = arguments[2], \"responsive\" === arguments[0] && \"array\" === i.type(arguments[1]) ? n = \"responsive\" : void 0 !== arguments[1] && (n = \"single\")), \"single\" === n) r.options[o] = s;else if (\"multiple\" === n) i.each(o, function (i, e) {\n r.options[i] = e;\n });else if (\"responsive\" === n) for (t in s) if (\"array\" !== i.type(r.options.responsive)) r.options.responsive = [s[t]];else {\n for (e = r.options.responsive.length - 1; e >= 0;) r.options.responsive[e].breakpoint === s[t].breakpoint && r.options.responsive.splice(e, 1), e--;\n r.options.responsive.push(s[t]);\n }\n l && (r.unload(), r.reinit());\n }, e.prototype.setPosition = function () {\n var i = this;\n i.setDimensions(), i.setHeight(), !1 === i.options.fade ? i.setCSS(i.getLeft(i.currentSlide)) : i.setFade(), i.$slider.trigger(\"setPosition\", [i]);\n }, e.prototype.setProps = function () {\n var i = this,\n e = document.body.style;\n i.positionProp = !0 === i.options.vertical ? \"top\" : \"left\", \"top\" === i.positionProp ? i.$slider.addClass(\"slick-vertical\") : i.$slider.removeClass(\"slick-vertical\"), void 0 === e.WebkitTransition && void 0 === e.MozTransition && void 0 === e.msTransition || !0 === i.options.useCSS && (i.cssTransitions = !0), i.options.fade && (\"number\" == typeof i.options.zIndex ? i.options.zIndex < 3 && (i.options.zIndex = 3) : i.options.zIndex = i.defaults.zIndex), void 0 !== e.OTransform && (i.animType = \"OTransform\", i.transformType = \"-o-transform\", i.transitionType = \"OTransition\", void 0 === e.perspectiveProperty && void 0 === e.webkitPerspective && (i.animType = !1)), void 0 !== e.MozTransform && (i.animType = \"MozTransform\", i.transformType = \"-moz-transform\", i.transitionType = \"MozTransition\", void 0 === e.perspectiveProperty && void 0 === e.MozPerspective && (i.animType = !1)), void 0 !== e.webkitTransform && (i.animType = \"webkitTransform\", i.transformType = \"-webkit-transform\", i.transitionType = \"webkitTransition\", void 0 === e.perspectiveProperty && void 0 === e.webkitPerspective && (i.animType = !1)), void 0 !== e.msTransform && (i.animType = \"msTransform\", i.transformType = \"-ms-transform\", i.transitionType = \"msTransition\", void 0 === e.msTransform && (i.animType = !1)), void 0 !== e.transform && !1 !== i.animType && (i.animType = \"transform\", i.transformType = \"transform\", i.transitionType = \"transition\"), i.transformsEnabled = i.options.useTransform && null !== i.animType && !1 !== i.animType;\n }, e.prototype.setSlideClasses = function (i) {\n var e,\n t,\n o,\n s,\n n = this;\n if (t = n.$slider.find(\".slick-slide\").removeClass(\"slick-active slick-center slick-current\").attr(\"aria-hidden\", \"true\"), n.$slides.eq(i).addClass(\"slick-current\"), !0 === n.options.centerMode) {\n var r = n.options.slidesToShow % 2 == 0 ? 1 : 0;\n e = Math.floor(n.options.slidesToShow / 2), !0 === n.options.infinite && (i >= e && i <= n.slideCount - 1 - e ? n.$slides.slice(i - e + r, i + e + 1).addClass(\"slick-active\").attr(\"aria-hidden\", \"false\") : (o = n.options.slidesToShow + i, t.slice(o - e + 1 + r, o + e + 2).addClass(\"slick-active\").attr(\"aria-hidden\", \"false\")), 0 === i ? t.eq(t.length - 1 - n.options.slidesToShow).addClass(\"slick-center\") : i === n.slideCount - 1 && t.eq(n.options.slidesToShow).addClass(\"slick-center\")), n.$slides.eq(i).addClass(\"slick-center\");\n } else i >= 0 && i <= n.slideCount - n.options.slidesToShow ? n.$slides.slice(i, i + n.options.slidesToShow).addClass(\"slick-active\").attr(\"aria-hidden\", \"false\") : t.length <= n.options.slidesToShow ? t.addClass(\"slick-active\").attr(\"aria-hidden\", \"false\") : (s = n.slideCount % n.options.slidesToShow, o = !0 === n.options.infinite ? n.options.slidesToShow + i : i, n.options.slidesToShow == n.options.slidesToScroll && n.slideCount - i < n.options.slidesToShow ? t.slice(o - (n.options.slidesToShow - s), o + s).addClass(\"slick-active\").attr(\"aria-hidden\", \"false\") : t.slice(o, o + n.options.slidesToShow).addClass(\"slick-active\").attr(\"aria-hidden\", \"false\"));\n \"ondemand\" !== n.options.lazyLoad && \"anticipated\" !== n.options.lazyLoad || n.lazyLoad();\n }, e.prototype.setupInfinite = function () {\n var e,\n t,\n o,\n s = this;\n if (!0 === s.options.fade && (s.options.centerMode = !1), !0 === s.options.infinite && !1 === s.options.fade && (t = null, s.slideCount > s.options.slidesToShow)) {\n for (o = !0 === s.options.centerMode ? s.options.slidesToShow + 1 : s.options.slidesToShow, e = s.slideCount; e > s.slideCount - o; e -= 1) t = e - 1, i(s.$slides[t]).clone(!0).attr(\"id\", \"\").attr(\"data-slick-index\", t - s.slideCount).prependTo(s.$slideTrack).addClass(\"slick-cloned\");\n for (e = 0; e < o + s.slideCount; e += 1) t = e, i(s.$slides[t]).clone(!0).attr(\"id\", \"\").attr(\"data-slick-index\", t + s.slideCount).appendTo(s.$slideTrack).addClass(\"slick-cloned\");\n s.$slideTrack.find(\".slick-cloned\").find(\"[id]\").each(function () {\n i(this).attr(\"id\", \"\");\n });\n }\n }, e.prototype.interrupt = function (i) {\n var e = this;\n i || e.autoPlay(), e.interrupted = i;\n }, e.prototype.selectHandler = function (e) {\n var t = this,\n o = i(e.target).is(\".slick-slide\") ? i(e.target) : i(e.target).parents(\".slick-slide\"),\n s = parseInt(o.attr(\"data-slick-index\"));\n s || (s = 0), t.slideCount <= t.options.slidesToShow ? t.slideHandler(s, !1, !0) : t.slideHandler(s);\n }, e.prototype.slideHandler = function (i, e, t) {\n var o,\n s,\n n,\n r,\n l,\n d = null,\n a = this;\n if (e = e || !1, !(!0 === a.animating && !0 === a.options.waitForAnimate || !0 === a.options.fade && a.currentSlide === i)) if (!1 === e && a.asNavFor(i), o = i, d = a.getLeft(o), r = a.getLeft(a.currentSlide), a.currentLeft = null === a.swipeLeft ? r : a.swipeLeft, !1 === a.options.infinite && !1 === a.options.centerMode && (i < 0 || i > a.getDotCount() * a.options.slidesToScroll)) !1 === a.options.fade && (o = a.currentSlide, !0 !== t ? a.animateSlide(r, function () {\n a.postSlide(o);\n }) : a.postSlide(o));else if (!1 === a.options.infinite && !0 === a.options.centerMode && (i < 0 || i > a.slideCount - a.options.slidesToScroll)) !1 === a.options.fade && (o = a.currentSlide, !0 !== t ? a.animateSlide(r, function () {\n a.postSlide(o);\n }) : a.postSlide(o));else {\n if (a.options.autoplay && clearInterval(a.autoPlayTimer), s = o < 0 ? a.slideCount % a.options.slidesToScroll != 0 ? a.slideCount - a.slideCount % a.options.slidesToScroll : a.slideCount + o : o >= a.slideCount ? a.slideCount % a.options.slidesToScroll != 0 ? 0 : o - a.slideCount : o, a.animating = !0, a.$slider.trigger(\"beforeChange\", [a, a.currentSlide, s]), n = a.currentSlide, a.currentSlide = s, a.setSlideClasses(a.currentSlide), a.options.asNavFor && (l = (l = a.getNavTarget()).slick(\"getSlick\")).slideCount <= l.options.slidesToShow && l.setSlideClasses(a.currentSlide), a.updateDots(), a.updateArrows(), !0 === a.options.fade) return !0 !== t ? (a.fadeSlideOut(n), a.fadeSlide(s, function () {\n a.postSlide(s);\n })) : a.postSlide(s), void a.animateHeight();\n !0 !== t ? a.animateSlide(d, function () {\n a.postSlide(s);\n }) : a.postSlide(s);\n }\n }, e.prototype.startLoad = function () {\n var i = this;\n !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.hide(), i.$nextArrow.hide()), !0 === i.options.dots && i.slideCount > i.options.slidesToShow && i.$dots.hide(), i.$slider.addClass(\"slick-loading\");\n }, e.prototype.swipeDirection = function () {\n var i,\n e,\n t,\n o,\n s = this;\n return i = s.touchObject.startX - s.touchObject.curX, e = s.touchObject.startY - s.touchObject.curY, t = Math.atan2(e, i), (o = Math.round(180 * t / Math.PI)) < 0 && (o = 360 - Math.abs(o)), o <= 45 && o >= 0 ? !1 === s.options.rtl ? \"left\" : \"right\" : o <= 360 && o >= 315 ? !1 === s.options.rtl ? \"left\" : \"right\" : o >= 135 && o <= 225 ? !1 === s.options.rtl ? \"right\" : \"left\" : !0 === s.options.verticalSwiping ? o >= 35 && o <= 135 ? \"down\" : \"up\" : \"vertical\";\n }, e.prototype.swipeEnd = function (i) {\n var e,\n t,\n o = this;\n if (o.dragging = !1, o.swiping = !1, o.scrolling) return o.scrolling = !1, !1;\n if (o.interrupted = !1, o.shouldClick = !(o.touchObject.swipeLength > 10), void 0 === o.touchObject.curX) return !1;\n if (!0 === o.touchObject.edgeHit && o.$slider.trigger(\"edge\", [o, o.swipeDirection()]), o.touchObject.swipeLength >= o.touchObject.minSwipe) {\n switch (t = o.swipeDirection()) {\n case \"left\":\n case \"down\":\n e = o.options.swipeToSlide ? o.checkNavigable(o.currentSlide + o.getSlideCount()) : o.currentSlide + o.getSlideCount(), o.currentDirection = 0;\n break;\n case \"right\":\n case \"up\":\n e = o.options.swipeToSlide ? o.checkNavigable(o.currentSlide - o.getSlideCount()) : o.currentSlide - o.getSlideCount(), o.currentDirection = 1;\n }\n \"vertical\" != t && (o.slideHandler(e), o.touchObject = {}, o.$slider.trigger(\"swipe\", [o, t]));\n } else o.touchObject.startX !== o.touchObject.curX && (o.slideHandler(o.currentSlide), o.touchObject = {});\n }, e.prototype.swipeHandler = function (i) {\n var e = this;\n if (!(!1 === e.options.swipe || \"ontouchend\" in document && !1 === e.options.swipe || !1 === e.options.draggable && -1 !== i.type.indexOf(\"mouse\"))) switch (e.touchObject.fingerCount = i.originalEvent && void 0 !== i.originalEvent.touches ? i.originalEvent.touches.length : 1, e.touchObject.minSwipe = e.listWidth / e.options.touchThreshold, !0 === e.options.verticalSwiping && (e.touchObject.minSwipe = e.listHeight / e.options.touchThreshold), i.data.action) {\n case \"start\":\n e.swipeStart(i);\n break;\n case \"move\":\n e.swipeMove(i);\n break;\n case \"end\":\n e.swipeEnd(i);\n }\n }, e.prototype.swipeMove = function (i) {\n var e,\n t,\n o,\n s,\n n,\n r,\n l = this;\n return n = void 0 !== i.originalEvent ? i.originalEvent.touches : null, !(!l.dragging || l.scrolling || n && 1 !== n.length) && (e = l.getLeft(l.currentSlide), l.touchObject.curX = void 0 !== n ? n[0].pageX : i.clientX, l.touchObject.curY = void 0 !== n ? n[0].pageY : i.clientY, l.touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(l.touchObject.curX - l.touchObject.startX, 2))), r = Math.round(Math.sqrt(Math.pow(l.touchObject.curY - l.touchObject.startY, 2))), !l.options.verticalSwiping && !l.swiping && r > 4 ? (l.scrolling = !0, !1) : (!0 === l.options.verticalSwiping && (l.touchObject.swipeLength = r), t = l.swipeDirection(), void 0 !== i.originalEvent && l.touchObject.swipeLength > 4 && (l.swiping = !0, i.preventDefault()), s = (!1 === l.options.rtl ? 1 : -1) * (l.touchObject.curX > l.touchObject.startX ? 1 : -1), !0 === l.options.verticalSwiping && (s = l.touchObject.curY > l.touchObject.startY ? 1 : -1), o = l.touchObject.swipeLength, l.touchObject.edgeHit = !1, !1 === l.options.infinite && (0 === l.currentSlide && \"right\" === t || l.currentSlide >= l.getDotCount() && \"left\" === t) && (o = l.touchObject.swipeLength * l.options.edgeFriction, l.touchObject.edgeHit = !0), !1 === l.options.vertical ? l.swipeLeft = e + o * s : l.swipeLeft = e + o * (l.$list.height() / l.listWidth) * s, !0 === l.options.verticalSwiping && (l.swipeLeft = e + o * s), !0 !== l.options.fade && !1 !== l.options.touchMove && (!0 === l.animating ? (l.swipeLeft = null, !1) : void l.setCSS(l.swipeLeft))));\n }, e.prototype.swipeStart = function (i) {\n var e,\n t = this;\n if (t.interrupted = !0, 1 !== t.touchObject.fingerCount || t.slideCount <= t.options.slidesToShow) return t.touchObject = {}, !1;\n void 0 !== i.originalEvent && void 0 !== i.originalEvent.touches && (e = i.originalEvent.touches[0]), t.touchObject.startX = t.touchObject.curX = void 0 !== e ? e.pageX : i.clientX, t.touchObject.startY = t.touchObject.curY = void 0 !== e ? e.pageY : i.clientY, t.dragging = !0;\n }, e.prototype.unfilterSlides = e.prototype.slickUnfilter = function () {\n var i = this;\n null !== i.$slidesCache && (i.unload(), i.$slideTrack.children(this.options.slide).detach(), i.$slidesCache.appendTo(i.$slideTrack), i.reinit());\n }, e.prototype.unload = function () {\n var e = this;\n i(\".slick-cloned\", e.$slider).remove(), e.$dots && e.$dots.remove(), e.$prevArrow && e.htmlExpr.test(e.options.prevArrow) && e.$prevArrow.remove(), e.$nextArrow && e.htmlExpr.test(e.options.nextArrow) && e.$nextArrow.remove(), e.$slides.removeClass(\"slick-slide slick-active slick-visible slick-current\").attr(\"aria-hidden\", \"true\").css(\"width\", \"\");\n }, e.prototype.unslick = function (i) {\n var e = this;\n e.$slider.trigger(\"unslick\", [e, i]), e.destroy();\n }, e.prototype.updateArrows = function () {\n var i = this;\n Math.floor(i.options.slidesToShow / 2), !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && !i.options.infinite && (i.$prevArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\", \"false\"), i.$nextArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\", \"false\"), 0 === i.currentSlide ? (i.$prevArrow.addClass(\"slick-disabled\").attr(\"aria-disabled\", \"true\"), i.$nextArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\", \"false\")) : i.currentSlide >= i.slideCount - i.options.slidesToShow && !1 === i.options.centerMode ? (i.$nextArrow.addClass(\"slick-disabled\").attr(\"aria-disabled\", \"true\"), i.$prevArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\", \"false\")) : i.currentSlide >= i.slideCount - 1 && !0 === i.options.centerMode && (i.$nextArrow.addClass(\"slick-disabled\").attr(\"aria-disabled\", \"true\"), i.$prevArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\", \"false\")));\n }, e.prototype.updateDots = function () {\n var i = this;\n null !== i.$dots && (i.$dots.find(\"li\").removeClass(\"slick-active\").end(), i.$dots.find(\"li\").eq(Math.floor(i.currentSlide / i.options.slidesToScroll)).addClass(\"slick-active\"));\n }, e.prototype.visibility = function () {\n var i = this;\n i.options.autoplay && (document[i.hidden] ? i.interrupted = !0 : i.interrupted = !1);\n }, i.fn.slick = function () {\n var i,\n t,\n o = this,\n s = arguments[0],\n n = Array.prototype.slice.call(arguments, 1),\n r = o.length;\n for (i = 0; i < r; i++) if (\"object\" == typeof s || void 0 === s ? o[i].slick = new e(o[i], s) : t = o[i].slick[s].apply(o[i].slick, n), void 0 !== t) return t;\n return o;\n };\n});","/*!\n * jQuery UI Sortable 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Sortable\n//>>group: Interactions\n//>>description: Enables items in a list to be sorted using the mouse.\n//>>docs: http://api.jqueryui.com/sortable/\n//>>demos: http://jqueryui.com/sortable/\n//>>css.structure: ../../themes/base/sortable.css\n\n(function (factory) {\n \"use strict\";\n\n if (typeof define === \"function\" && define.amd) {\n // AMD. Register as an anonymous module.\n define([\"jquery\", \"./mouse\", \"../data\", \"../ie\", \"../scroll-parent\", \"../version\", \"../widget\"], factory);\n } else {\n // Browser globals\n factory(jQuery);\n }\n})(function ($) {\n \"use strict\";\n\n return $.widget(\"ui.sortable\", $.ui.mouse, {\n version: \"1.13.2\",\n widgetEventPrefix: \"sort\",\n ready: false,\n options: {\n appendTo: \"parent\",\n axis: false,\n connectWith: false,\n containment: false,\n cursor: \"auto\",\n cursorAt: false,\n dropOnEmpty: true,\n forcePlaceholderSize: false,\n forceHelperSize: false,\n grid: false,\n handle: false,\n helper: \"original\",\n items: \"> *\",\n opacity: false,\n placeholder: false,\n revert: false,\n scroll: true,\n scrollSensitivity: 20,\n scrollSpeed: 20,\n scope: \"default\",\n tolerance: \"intersect\",\n zIndex: 1000,\n // Callbacks\n activate: null,\n beforeStop: null,\n change: null,\n deactivate: null,\n out: null,\n over: null,\n receive: null,\n remove: null,\n sort: null,\n start: null,\n stop: null,\n update: null\n },\n _isOverAxis: function (x, reference, size) {\n return x >= reference && x < reference + size;\n },\n _isFloating: function (item) {\n return /left|right/.test(item.css(\"float\")) || /inline|table-cell/.test(item.css(\"display\"));\n },\n _create: function () {\n this.containerCache = {};\n this._addClass(\"ui-sortable\");\n\n //Get the items\n this.refresh();\n\n //Let's determine the parent's offset\n this.offset = this.element.offset();\n\n //Initialize mouse events for interaction\n this._mouseInit();\n this._setHandleClassName();\n\n //We're ready to go\n this.ready = true;\n },\n _setOption: function (key, value) {\n this._super(key, value);\n if (key === \"handle\") {\n this._setHandleClassName();\n }\n },\n _setHandleClassName: function () {\n var that = this;\n this._removeClass(this.element.find(\".ui-sortable-handle\"), \"ui-sortable-handle\");\n $.each(this.items, function () {\n that._addClass(this.instance.options.handle ? this.item.find(this.instance.options.handle) : this.item, \"ui-sortable-handle\");\n });\n },\n _destroy: function () {\n this._mouseDestroy();\n for (var i = this.items.length - 1; i >= 0; i--) {\n this.items[i].item.removeData(this.widgetName + \"-item\");\n }\n return this;\n },\n _mouseCapture: function (event, overrideHandle) {\n var currentItem = null,\n validHandle = false,\n that = this;\n if (this.reverting) {\n return false;\n }\n if (this.options.disabled || this.options.type === \"static\") {\n return false;\n }\n\n //We have to refresh the items data once first\n this._refreshItems(event);\n\n //Find out if the clicked node (or one of its parents) is a actual item in this.items\n $(event.target).parents().each(function () {\n if ($.data(this, that.widgetName + \"-item\") === that) {\n currentItem = $(this);\n return false;\n }\n });\n if ($.data(event.target, that.widgetName + \"-item\") === that) {\n currentItem = $(event.target);\n }\n if (!currentItem) {\n return false;\n }\n if (this.options.handle && !overrideHandle) {\n $(this.options.handle, currentItem).find(\"*\").addBack().each(function () {\n if (this === event.target) {\n validHandle = true;\n }\n });\n if (!validHandle) {\n return false;\n }\n }\n this.currentItem = currentItem;\n this._removeCurrentsFromItems();\n return true;\n },\n _mouseStart: function (event, overrideHandle, noActivation) {\n var i,\n body,\n o = this.options;\n this.currentContainer = this;\n\n //We only need to call refreshPositions, because the refreshItems call has been moved to\n // mouseCapture\n this.refreshPositions();\n\n //Prepare the dragged items parent\n this.appendTo = $(o.appendTo !== \"parent\" ? o.appendTo : this.currentItem.parent());\n\n //Create and append the visible helper\n this.helper = this._createHelper(event);\n\n //Cache the helper size\n this._cacheHelperProportions();\n\n /*\n * - Position generation -\n * This block generates everything position related - it's the core of draggables.\n */\n\n //Cache the margins of the original element\n this._cacheMargins();\n\n //The element's absolute position on the page minus margins\n this.offset = this.currentItem.offset();\n this.offset = {\n top: this.offset.top - this.margins.top,\n left: this.offset.left - this.margins.left\n };\n $.extend(this.offset, {\n click: {\n //Where the click happened, relative to the element\n left: event.pageX - this.offset.left,\n top: event.pageY - this.offset.top\n },\n // This is a relative to absolute position minus the actual position calculation -\n // only used for relative positioned helper\n relative: this._getRelativeOffset()\n });\n\n // After we get the helper offset, but before we get the parent offset we can\n // change the helper's position to absolute\n // TODO: Still need to figure out a way to make relative sorting possible\n this.helper.css(\"position\", \"absolute\");\n this.cssPosition = this.helper.css(\"position\");\n\n //Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n if (o.cursorAt) {\n this._adjustOffsetFromHelper(o.cursorAt);\n }\n\n //Cache the former DOM position\n this.domPosition = {\n prev: this.currentItem.prev()[0],\n parent: this.currentItem.parent()[0]\n };\n\n // If the helper is not the original, hide the original so it's not playing any role during\n // the drag, won't cause anything bad this way\n if (this.helper[0] !== this.currentItem[0]) {\n this.currentItem.hide();\n }\n\n //Create the placeholder\n this._createPlaceholder();\n\n //Get the next scrolling parent\n this.scrollParent = this.placeholder.scrollParent();\n $.extend(this.offset, {\n parent: this._getParentOffset()\n });\n\n //Set a containment if given in the options\n if (o.containment) {\n this._setContainment();\n }\n if (o.cursor && o.cursor !== \"auto\") {\n // cursor option\n body = this.document.find(\"body\");\n\n // Support: IE\n this.storedCursor = body.css(\"cursor\");\n body.css(\"cursor\", o.cursor);\n this.storedStylesheet = $(\"\").appendTo(body);\n }\n\n // We need to make sure to grab the zIndex before setting the\n // opacity, because setting the opacity to anything lower than 1\n // causes the zIndex to change from \"auto\" to 0.\n if (o.zIndex) {\n // zIndex option\n if (this.helper.css(\"zIndex\")) {\n this._storedZIndex = this.helper.css(\"zIndex\");\n }\n this.helper.css(\"zIndex\", o.zIndex);\n }\n if (o.opacity) {\n // opacity option\n if (this.helper.css(\"opacity\")) {\n this._storedOpacity = this.helper.css(\"opacity\");\n }\n this.helper.css(\"opacity\", o.opacity);\n }\n\n //Prepare scrolling\n if (this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== \"HTML\") {\n this.overflowOffset = this.scrollParent.offset();\n }\n\n //Call callbacks\n this._trigger(\"start\", event, this._uiHash());\n\n //Recache the helper size\n if (!this._preserveHelperProportions) {\n this._cacheHelperProportions();\n }\n\n //Post \"activate\" events to possible containers\n if (!noActivation) {\n for (i = this.containers.length - 1; i >= 0; i--) {\n this.containers[i]._trigger(\"activate\", event, this._uiHash(this));\n }\n }\n\n //Prepare possible droppables\n if ($.ui.ddmanager) {\n $.ui.ddmanager.current = this;\n }\n if ($.ui.ddmanager && !o.dropBehaviour) {\n $.ui.ddmanager.prepareOffsets(this, event);\n }\n this.dragging = true;\n this._addClass(this.helper, \"ui-sortable-helper\");\n\n //Move the helper, if needed\n if (!this.helper.parent().is(this.appendTo)) {\n this.helper.detach().appendTo(this.appendTo);\n\n //Update position\n this.offset.parent = this._getParentOffset();\n }\n\n //Generate the original position\n this.position = this.originalPosition = this._generatePosition(event);\n this.originalPageX = event.pageX;\n this.originalPageY = event.pageY;\n this.lastPositionAbs = this.positionAbs = this._convertPositionTo(\"absolute\");\n this._mouseDrag(event);\n return true;\n },\n _scroll: function (event) {\n var o = this.options,\n scrolled = false;\n if (this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== \"HTML\") {\n if (this.overflowOffset.top + this.scrollParent[0].offsetHeight - event.pageY < o.scrollSensitivity) {\n this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;\n } else if (event.pageY - this.overflowOffset.top < o.scrollSensitivity) {\n this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;\n }\n if (this.overflowOffset.left + this.scrollParent[0].offsetWidth - event.pageX < o.scrollSensitivity) {\n this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;\n } else if (event.pageX - this.overflowOffset.left < o.scrollSensitivity) {\n this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;\n }\n } else {\n if (event.pageY - this.document.scrollTop() < o.scrollSensitivity) {\n scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);\n } else if (this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {\n scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);\n }\n if (event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {\n scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);\n } else if (this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {\n scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);\n }\n }\n return scrolled;\n },\n _mouseDrag: function (event) {\n var i,\n item,\n itemElement,\n intersection,\n o = this.options;\n\n //Compute the helpers position\n this.position = this._generatePosition(event);\n this.positionAbs = this._convertPositionTo(\"absolute\");\n\n //Set the helper position\n if (!this.options.axis || this.options.axis !== \"y\") {\n this.helper[0].style.left = this.position.left + \"px\";\n }\n if (!this.options.axis || this.options.axis !== \"x\") {\n this.helper[0].style.top = this.position.top + \"px\";\n }\n\n //Do scrolling\n if (o.scroll) {\n if (this._scroll(event) !== false) {\n //Update item positions used in position checks\n this._refreshItemPositions(true);\n if ($.ui.ddmanager && !o.dropBehaviour) {\n $.ui.ddmanager.prepareOffsets(this, event);\n }\n }\n }\n this.dragDirection = {\n vertical: this._getDragVerticalDirection(),\n horizontal: this._getDragHorizontalDirection()\n };\n\n //Rearrange\n for (i = this.items.length - 1; i >= 0; i--) {\n //Cache variables and intersection, continue if no intersection\n item = this.items[i];\n itemElement = item.item[0];\n intersection = this._intersectsWithPointer(item);\n if (!intersection) {\n continue;\n }\n\n // Only put the placeholder inside the current Container, skip all\n // items from other containers. This works because when moving\n // an item from one container to another the\n // currentContainer is switched before the placeholder is moved.\n //\n // Without this, moving items in \"sub-sortables\" can cause\n // the placeholder to jitter between the outer and inner container.\n if (item.instance !== this.currentContainer) {\n continue;\n }\n\n // Cannot intersect with itself\n // no useless actions that have been done before\n // no action if the item moved is the parent of the item checked\n if (itemElement !== this.currentItem[0] && this.placeholder[intersection === 1 ? \"next\" : \"prev\"]()[0] !== itemElement && !$.contains(this.placeholder[0], itemElement) && (this.options.type === \"semi-dynamic\" ? !$.contains(this.element[0], itemElement) : true)) {\n this.direction = intersection === 1 ? \"down\" : \"up\";\n if (this.options.tolerance === \"pointer\" || this._intersectsWithSides(item)) {\n this._rearrange(event, item);\n } else {\n break;\n }\n this._trigger(\"change\", event, this._uiHash());\n break;\n }\n }\n\n //Post events to containers\n this._contactContainers(event);\n\n //Interconnect with droppables\n if ($.ui.ddmanager) {\n $.ui.ddmanager.drag(this, event);\n }\n\n //Call callbacks\n this._trigger(\"sort\", event, this._uiHash());\n this.lastPositionAbs = this.positionAbs;\n return false;\n },\n _mouseStop: function (event, noPropagation) {\n if (!event) {\n return;\n }\n\n //If we are using droppables, inform the manager about the drop\n if ($.ui.ddmanager && !this.options.dropBehaviour) {\n $.ui.ddmanager.drop(this, event);\n }\n if (this.options.revert) {\n var that = this,\n cur = this.placeholder.offset(),\n axis = this.options.axis,\n animation = {};\n if (!axis || axis === \"x\") {\n animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);\n }\n if (!axis || axis === \"y\") {\n animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);\n }\n this.reverting = true;\n $(this.helper).animate(animation, parseInt(this.options.revert, 10) || 500, function () {\n that._clear(event);\n });\n } else {\n this._clear(event, noPropagation);\n }\n return false;\n },\n cancel: function () {\n if (this.dragging) {\n this._mouseUp(new $.Event(\"mouseup\", {\n target: null\n }));\n if (this.options.helper === \"original\") {\n this.currentItem.css(this._storedCSS);\n this._removeClass(this.currentItem, \"ui-sortable-helper\");\n } else {\n this.currentItem.show();\n }\n\n //Post deactivating events to containers\n for (var i = this.containers.length - 1; i >= 0; i--) {\n this.containers[i]._trigger(\"deactivate\", null, this._uiHash(this));\n if (this.containers[i].containerCache.over) {\n this.containers[i]._trigger(\"out\", null, this._uiHash(this));\n this.containers[i].containerCache.over = 0;\n }\n }\n }\n if (this.placeholder) {\n //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,\n // it unbinds ALL events from the original node!\n if (this.placeholder[0].parentNode) {\n this.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n }\n if (this.options.helper !== \"original\" && this.helper && this.helper[0].parentNode) {\n this.helper.remove();\n }\n $.extend(this, {\n helper: null,\n dragging: false,\n reverting: false,\n _noFinalSort: null\n });\n if (this.domPosition.prev) {\n $(this.domPosition.prev).after(this.currentItem);\n } else {\n $(this.domPosition.parent).prepend(this.currentItem);\n }\n }\n return this;\n },\n serialize: function (o) {\n var items = this._getItemsAsjQuery(o && o.connected),\n str = [];\n o = o || {};\n $(items).each(function () {\n var res = ($(o.item || this).attr(o.attribute || \"id\") || \"\").match(o.expression || /(.+)[\\-=_](.+)/);\n if (res) {\n str.push((o.key || res[1] + \"[]\") + \"=\" + (o.key && o.expression ? res[1] : res[2]));\n }\n });\n if (!str.length && o.key) {\n str.push(o.key + \"=\");\n }\n return str.join(\"&\");\n },\n toArray: function (o) {\n var items = this._getItemsAsjQuery(o && o.connected),\n ret = [];\n o = o || {};\n items.each(function () {\n ret.push($(o.item || this).attr(o.attribute || \"id\") || \"\");\n });\n return ret;\n },\n /* Be careful with the following core functions */\n _intersectsWith: function (item) {\n var x1 = this.positionAbs.left,\n x2 = x1 + this.helperProportions.width,\n y1 = this.positionAbs.top,\n y2 = y1 + this.helperProportions.height,\n l = item.left,\n r = l + item.width,\n t = item.top,\n b = t + item.height,\n dyClick = this.offset.click.top,\n dxClick = this.offset.click.left,\n isOverElementHeight = this.options.axis === \"x\" || y1 + dyClick > t && y1 + dyClick < b,\n isOverElementWidth = this.options.axis === \"y\" || x1 + dxClick > l && x1 + dxClick < r,\n isOverElement = isOverElementHeight && isOverElementWidth;\n if (this.options.tolerance === \"pointer\" || this.options.forcePointerForContainers || this.options.tolerance !== \"pointer\" && this.helperProportions[this.floating ? \"width\" : \"height\"] > item[this.floating ? \"width\" : \"height\"]) {\n return isOverElement;\n } else {\n return l < x1 + this.helperProportions.width / 2 &&\n // Right Half\n x2 - this.helperProportions.width / 2 < r &&\n // Left Half\n t < y1 + this.helperProportions.height / 2 &&\n // Bottom Half\n y2 - this.helperProportions.height / 2 < b; // Top Half\n }\n },\n\n _intersectsWithPointer: function (item) {\n var verticalDirection,\n horizontalDirection,\n isOverElementHeight = this.options.axis === \"x\" || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),\n isOverElementWidth = this.options.axis === \"y\" || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),\n isOverElement = isOverElementHeight && isOverElementWidth;\n if (!isOverElement) {\n return false;\n }\n verticalDirection = this.dragDirection.vertical;\n horizontalDirection = this.dragDirection.horizontal;\n return this.floating ? horizontalDirection === \"right\" || verticalDirection === \"down\" ? 2 : 1 : verticalDirection && (verticalDirection === \"down\" ? 2 : 1);\n },\n _intersectsWithSides: function (item) {\n var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + item.height / 2, item.height),\n isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + item.width / 2, item.width),\n verticalDirection = this.dragDirection.vertical,\n horizontalDirection = this.dragDirection.horizontal;\n if (this.floating && horizontalDirection) {\n return horizontalDirection === \"right\" && isOverRightHalf || horizontalDirection === \"left\" && !isOverRightHalf;\n } else {\n return verticalDirection && (verticalDirection === \"down\" && isOverBottomHalf || verticalDirection === \"up\" && !isOverBottomHalf);\n }\n },\n _getDragVerticalDirection: function () {\n var delta = this.positionAbs.top - this.lastPositionAbs.top;\n return delta !== 0 && (delta > 0 ? \"down\" : \"up\");\n },\n _getDragHorizontalDirection: function () {\n var delta = this.positionAbs.left - this.lastPositionAbs.left;\n return delta !== 0 && (delta > 0 ? \"right\" : \"left\");\n },\n refresh: function (event) {\n this._refreshItems(event);\n this._setHandleClassName();\n this.refreshPositions();\n return this;\n },\n _connectWith: function () {\n var options = this.options;\n return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;\n },\n _getItemsAsjQuery: function (connected) {\n var i,\n j,\n cur,\n inst,\n items = [],\n queries = [],\n connectWith = this._connectWith();\n if (connectWith && connected) {\n for (i = connectWith.length - 1; i >= 0; i--) {\n cur = $(connectWith[i], this.document[0]);\n for (j = cur.length - 1; j >= 0; j--) {\n inst = $.data(cur[j], this.widgetFullName);\n if (inst && inst !== this && !inst.options.disabled) {\n queries.push([typeof inst.options.items === \"function\" ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), inst]);\n }\n }\n }\n }\n queries.push([typeof this.options.items === \"function\" ? this.options.items.call(this.element, null, {\n options: this.options,\n item: this.currentItem\n }) : $(this.options.items, this.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), this]);\n function addItems() {\n items.push(this);\n }\n for (i = queries.length - 1; i >= 0; i--) {\n queries[i][0].each(addItems);\n }\n return $(items);\n },\n _removeCurrentsFromItems: function () {\n var list = this.currentItem.find(\":data(\" + this.widgetName + \"-item)\");\n this.items = $.grep(this.items, function (item) {\n for (var j = 0; j < list.length; j++) {\n if (list[j] === item.item[0]) {\n return false;\n }\n }\n return true;\n });\n },\n _refreshItems: function (event) {\n this.items = [];\n this.containers = [this];\n var i,\n j,\n cur,\n inst,\n targetData,\n _queries,\n item,\n queriesLength,\n items = this.items,\n queries = [[typeof this.options.items === \"function\" ? this.options.items.call(this.element[0], event, {\n item: this.currentItem\n }) : $(this.options.items, this.element), this]],\n connectWith = this._connectWith();\n\n //Shouldn't be run the first time through due to massive slow-down\n if (connectWith && this.ready) {\n for (i = connectWith.length - 1; i >= 0; i--) {\n cur = $(connectWith[i], this.document[0]);\n for (j = cur.length - 1; j >= 0; j--) {\n inst = $.data(cur[j], this.widgetFullName);\n if (inst && inst !== this && !inst.options.disabled) {\n queries.push([typeof inst.options.items === \"function\" ? inst.options.items.call(inst.element[0], event, {\n item: this.currentItem\n }) : $(inst.options.items, inst.element), inst]);\n this.containers.push(inst);\n }\n }\n }\n }\n for (i = queries.length - 1; i >= 0; i--) {\n targetData = queries[i][1];\n _queries = queries[i][0];\n for (j = 0, queriesLength = _queries.length; j < queriesLength; j++) {\n item = $(_queries[j]);\n\n // Data for target checking (mouse manager)\n item.data(this.widgetName + \"-item\", targetData);\n items.push({\n item: item,\n instance: targetData,\n width: 0,\n height: 0,\n left: 0,\n top: 0\n });\n }\n }\n },\n _refreshItemPositions: function (fast) {\n var i, item, t, p;\n for (i = this.items.length - 1; i >= 0; i--) {\n item = this.items[i];\n\n //We ignore calculating positions of all connected containers when we're not over them\n if (this.currentContainer && item.instance !== this.currentContainer && item.item[0] !== this.currentItem[0]) {\n continue;\n }\n t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;\n if (!fast) {\n item.width = t.outerWidth();\n item.height = t.outerHeight();\n }\n p = t.offset();\n item.left = p.left;\n item.top = p.top;\n }\n },\n refreshPositions: function (fast) {\n // Determine whether items are being displayed horizontally\n this.floating = this.items.length ? this.options.axis === \"x\" || this._isFloating(this.items[0].item) : false;\n\n // This has to be redone because due to the item being moved out/into the offsetParent,\n // the offsetParent's position will change\n if (this.offsetParent && this.helper) {\n this.offset.parent = this._getParentOffset();\n }\n this._refreshItemPositions(fast);\n var i, p;\n if (this.options.custom && this.options.custom.refreshContainers) {\n this.options.custom.refreshContainers.call(this);\n } else {\n for (i = this.containers.length - 1; i >= 0; i--) {\n p = this.containers[i].element.offset();\n this.containers[i].containerCache.left = p.left;\n this.containers[i].containerCache.top = p.top;\n this.containers[i].containerCache.width = this.containers[i].element.outerWidth();\n this.containers[i].containerCache.height = this.containers[i].element.outerHeight();\n }\n }\n return this;\n },\n _createPlaceholder: function (that) {\n that = that || this;\n var className,\n nodeName,\n o = that.options;\n if (!o.placeholder || o.placeholder.constructor === String) {\n className = o.placeholder;\n nodeName = that.currentItem[0].nodeName.toLowerCase();\n o.placeholder = {\n element: function () {\n var element = $(\"<\" + nodeName + \">\", that.document[0]);\n that._addClass(element, \"ui-sortable-placeholder\", className || that.currentItem[0].className)._removeClass(element, \"ui-sortable-helper\");\n if (nodeName === \"tbody\") {\n that._createTrPlaceholder(that.currentItem.find(\"tr\").eq(0), $(\"
\", that.document[0]).appendTo(element));\n } else if (nodeName === \"tr\") {\n that._createTrPlaceholder(that.currentItem, element);\n } else if (nodeName === \"img\") {\n element.attr(\"src\", that.currentItem.attr(\"src\"));\n }\n if (!className) {\n element.css(\"visibility\", \"hidden\");\n }\n return element;\n },\n update: function (container, p) {\n // 1. If a className is set as 'placeholder option, we don't force sizes -\n // the class is responsible for that\n // 2. The option 'forcePlaceholderSize can be enabled to force it even if a\n // class name is specified\n if (className && !o.forcePlaceholderSize) {\n return;\n }\n\n // If the element doesn't have a actual height or width by itself (without\n // styles coming from a stylesheet), it receives the inline height and width\n // from the dragged item. Or, if it's a tbody or tr, it's going to have a height\n // anyway since we're populating them with s above, but they're unlikely to\n // be the correct height on their own if the row heights are dynamic, so we'll\n // always assign the height of the dragged item given forcePlaceholderSize\n // is true.\n if (!p.height() || o.forcePlaceholderSize && (nodeName === \"tbody\" || nodeName === \"tr\")) {\n p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css(\"paddingTop\") || 0, 10) - parseInt(that.currentItem.css(\"paddingBottom\") || 0, 10));\n }\n if (!p.width()) {\n p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css(\"paddingLeft\") || 0, 10) - parseInt(that.currentItem.css(\"paddingRight\") || 0, 10));\n }\n }\n };\n }\n\n //Create the placeholder\n that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));\n\n //Append it after the actual current item\n that.currentItem.after(that.placeholder);\n\n //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)\n o.placeholder.update(that, that.placeholder);\n },\n _createTrPlaceholder: function (sourceTr, targetTr) {\n var that = this;\n sourceTr.children().each(function () {\n $(\" | | \", that.document[0]).attr(\"colspan\", $(this).attr(\"colspan\") || 1).appendTo(targetTr);\n });\n },\n _contactContainers: function (event) {\n var i,\n j,\n dist,\n itemWithLeastDistance,\n posProperty,\n sizeProperty,\n cur,\n nearBottom,\n floating,\n axis,\n innermostContainer = null,\n innermostIndex = null;\n\n // Get innermost container that intersects with item\n for (i = this.containers.length - 1; i >= 0; i--) {\n // Never consider a container that's located within the item itself\n if ($.contains(this.currentItem[0], this.containers[i].element[0])) {\n continue;\n }\n if (this._intersectsWith(this.containers[i].containerCache)) {\n // If we've already found a container and it's more \"inner\" than this, then continue\n if (innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {\n continue;\n }\n innermostContainer = this.containers[i];\n innermostIndex = i;\n } else {\n // container doesn't intersect. trigger \"out\" event if necessary\n if (this.containers[i].containerCache.over) {\n this.containers[i]._trigger(\"out\", event, this._uiHash(this));\n this.containers[i].containerCache.over = 0;\n }\n }\n }\n\n // If no intersecting containers found, return\n if (!innermostContainer) {\n return;\n }\n\n // Move the item into the container if it's not there already\n if (this.containers.length === 1) {\n if (!this.containers[innermostIndex].containerCache.over) {\n this.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n this.containers[innermostIndex].containerCache.over = 1;\n }\n } else {\n // When entering a new container, we will find the item with the least distance and\n // append our item near it\n dist = 10000;\n itemWithLeastDistance = null;\n floating = innermostContainer.floating || this._isFloating(this.currentItem);\n posProperty = floating ? \"left\" : \"top\";\n sizeProperty = floating ? \"width\" : \"height\";\n axis = floating ? \"pageX\" : \"pageY\";\n for (j = this.items.length - 1; j >= 0; j--) {\n if (!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {\n continue;\n }\n if (this.items[j].item[0] === this.currentItem[0]) {\n continue;\n }\n cur = this.items[j].item.offset()[posProperty];\n nearBottom = false;\n if (event[axis] - cur > this.items[j][sizeProperty] / 2) {\n nearBottom = true;\n }\n if (Math.abs(event[axis] - cur) < dist) {\n dist = Math.abs(event[axis] - cur);\n itemWithLeastDistance = this.items[j];\n this.direction = nearBottom ? \"up\" : \"down\";\n }\n }\n\n //Check if dropOnEmpty is enabled\n if (!itemWithLeastDistance && !this.options.dropOnEmpty) {\n return;\n }\n if (this.currentContainer === this.containers[innermostIndex]) {\n if (!this.currentContainer.containerCache.over) {\n this.containers[innermostIndex]._trigger(\"over\", event, this._uiHash());\n this.currentContainer.containerCache.over = 1;\n }\n return;\n }\n if (itemWithLeastDistance) {\n this._rearrange(event, itemWithLeastDistance, null, true);\n } else {\n this._rearrange(event, null, this.containers[innermostIndex].element, true);\n }\n this._trigger(\"change\", event, this._uiHash());\n this.containers[innermostIndex]._trigger(\"change\", event, this._uiHash(this));\n this.currentContainer = this.containers[innermostIndex];\n\n //Update the placeholder\n this.options.placeholder.update(this.currentContainer, this.placeholder);\n\n //Update scrollParent\n this.scrollParent = this.placeholder.scrollParent();\n\n //Update overflowOffset\n if (this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== \"HTML\") {\n this.overflowOffset = this.scrollParent.offset();\n }\n this.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n this.containers[innermostIndex].containerCache.over = 1;\n }\n },\n _createHelper: function (event) {\n var o = this.options,\n helper = typeof o.helper === \"function\" ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : o.helper === \"clone\" ? this.currentItem.clone() : this.currentItem;\n\n //Add the helper to the DOM if that didn't happen already\n if (!helper.parents(\"body\").length) {\n this.appendTo[0].appendChild(helper[0]);\n }\n if (helper[0] === this.currentItem[0]) {\n this._storedCSS = {\n width: this.currentItem[0].style.width,\n height: this.currentItem[0].style.height,\n position: this.currentItem.css(\"position\"),\n top: this.currentItem.css(\"top\"),\n left: this.currentItem.css(\"left\")\n };\n }\n if (!helper[0].style.width || o.forceHelperSize) {\n helper.width(this.currentItem.width());\n }\n if (!helper[0].style.height || o.forceHelperSize) {\n helper.height(this.currentItem.height());\n }\n return helper;\n },\n _adjustOffsetFromHelper: function (obj) {\n if (typeof obj === \"string\") {\n obj = obj.split(\" \");\n }\n if (Array.isArray(obj)) {\n obj = {\n left: +obj[0],\n top: +obj[1] || 0\n };\n }\n if (\"left\" in obj) {\n this.offset.click.left = obj.left + this.margins.left;\n }\n if (\"right\" in obj) {\n this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n }\n if (\"top\" in obj) {\n this.offset.click.top = obj.top + this.margins.top;\n }\n if (\"bottom\" in obj) {\n this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n }\n },\n _getParentOffset: function () {\n //Get the offsetParent and cache its position\n this.offsetParent = this.helper.offsetParent();\n var po = this.offsetParent.offset();\n\n // This is a special case where we need to modify a offset calculated on start, since the\n // following happened:\n // 1. The position of the helper is absolute, so it's position is calculated based on the\n // next positioned parent\n // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't\n // the document, which means that the scroll is included in the initial calculation of the\n // offset of the parent, and never recalculated upon drag\n if (this.cssPosition === \"absolute\" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {\n po.left += this.scrollParent.scrollLeft();\n po.top += this.scrollParent.scrollTop();\n }\n\n // This needs to be actually done for all browsers, since pageX/pageY includes this\n // information with an ugly IE fix\n if (this.offsetParent[0] === this.document[0].body || this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === \"html\" && $.ui.ie) {\n po = {\n top: 0,\n left: 0\n };\n }\n return {\n top: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"), 10) || 0),\n left: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"), 10) || 0)\n };\n },\n _getRelativeOffset: function () {\n if (this.cssPosition === \"relative\") {\n var p = this.currentItem.position();\n return {\n top: p.top - (parseInt(this.helper.css(\"top\"), 10) || 0) + this.scrollParent.scrollTop(),\n left: p.left - (parseInt(this.helper.css(\"left\"), 10) || 0) + this.scrollParent.scrollLeft()\n };\n } else {\n return {\n top: 0,\n left: 0\n };\n }\n },\n _cacheMargins: function () {\n this.margins = {\n left: parseInt(this.currentItem.css(\"marginLeft\"), 10) || 0,\n top: parseInt(this.currentItem.css(\"marginTop\"), 10) || 0\n };\n },\n _cacheHelperProportions: function () {\n this.helperProportions = {\n width: this.helper.outerWidth(),\n height: this.helper.outerHeight()\n };\n },\n _setContainment: function () {\n var ce,\n co,\n over,\n o = this.options;\n if (o.containment === \"parent\") {\n o.containment = this.helper[0].parentNode;\n }\n if (o.containment === \"document\" || o.containment === \"window\") {\n this.containment = [0 - this.offset.relative.left - this.offset.parent.left, 0 - this.offset.relative.top - this.offset.parent.top, o.containment === \"document\" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left, (o.containment === \"document\" ? this.document.height() || document.body.parentNode.scrollHeight : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top];\n }\n if (!/^(document|window|parent)$/.test(o.containment)) {\n ce = $(o.containment)[0];\n co = $(o.containment).offset();\n over = $(ce).css(\"overflow\") !== \"hidden\";\n this.containment = [co.left + (parseInt($(ce).css(\"borderLeftWidth\"), 10) || 0) + (parseInt($(ce).css(\"paddingLeft\"), 10) || 0) - this.margins.left, co.top + (parseInt($(ce).css(\"borderTopWidth\"), 10) || 0) + (parseInt($(ce).css(\"paddingTop\"), 10) || 0) - this.margins.top, co.left + (over ? Math.max(ce.scrollWidth, ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css(\"borderLeftWidth\"), 10) || 0) - (parseInt($(ce).css(\"paddingRight\"), 10) || 0) - this.helperProportions.width - this.margins.left, co.top + (over ? Math.max(ce.scrollHeight, ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css(\"borderTopWidth\"), 10) || 0) - (parseInt($(ce).css(\"paddingBottom\"), 10) || 0) - this.helperProportions.height - this.margins.top];\n }\n },\n _convertPositionTo: function (d, pos) {\n if (!pos) {\n pos = this.position;\n }\n var mod = d === \"absolute\" ? 1 : -1,\n scroll = this.cssPosition === \"absolute\" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,\n scrollIsRootNode = /(html|body)/i.test(scroll[0].tagName);\n return {\n top:\n // The absolute mouse position\n pos.top +\n // Only for relative positioned nodes: Relative offset from element to offset parent\n this.offset.relative.top * mod +\n // The offsetParent's offset without borders (offset + border)\n this.offset.parent.top * mod - (this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : scrollIsRootNode ? 0 : scroll.scrollTop()) * mod,\n left:\n // The absolute mouse position\n pos.left +\n // Only for relative positioned nodes: Relative offset from element to offset parent\n this.offset.relative.left * mod +\n // The offsetParent's offset without borders (offset + border)\n this.offset.parent.left * mod - (this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft()) * mod\n };\n },\n _generatePosition: function (event) {\n var top,\n left,\n o = this.options,\n pageX = event.pageX,\n pageY = event.pageY,\n scroll = this.cssPosition === \"absolute\" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,\n scrollIsRootNode = /(html|body)/i.test(scroll[0].tagName);\n\n // This is another very weird special case that only happens for relative elements:\n // 1. If the css position is relative\n // 2. and the scroll parent is the document or similar to the offset parent\n // we have to refresh the relative offset during the scroll so there are no jumps\n if (this.cssPosition === \"relative\" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {\n this.offset.relative = this._getRelativeOffset();\n }\n\n /*\n * - Position constraining -\n * Constrain the position to a mix of grid, containment.\n */\n\n if (this.originalPosition) {\n //If we are not dragging yet, we won't check for options\n\n if (this.containment) {\n if (event.pageX - this.offset.click.left < this.containment[0]) {\n pageX = this.containment[0] + this.offset.click.left;\n }\n if (event.pageY - this.offset.click.top < this.containment[1]) {\n pageY = this.containment[1] + this.offset.click.top;\n }\n if (event.pageX - this.offset.click.left > this.containment[2]) {\n pageX = this.containment[2] + this.offset.click.left;\n }\n if (event.pageY - this.offset.click.top > this.containment[3]) {\n pageY = this.containment[3] + this.offset.click.top;\n }\n }\n if (o.grid) {\n top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];\n pageY = this.containment ? top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3] ? top : top - this.offset.click.top >= this.containment[1] ? top - o.grid[1] : top + o.grid[1] : top;\n left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];\n pageX = this.containment ? left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2] ? left : left - this.offset.click.left >= this.containment[0] ? left - o.grid[0] : left + o.grid[0] : left;\n }\n }\n return {\n top:\n // The absolute mouse position\n pageY -\n // Click offset (relative to the element)\n this.offset.click.top -\n // Only for relative positioned nodes: Relative offset from element to offset parent\n this.offset.relative.top -\n // The offsetParent's offset without borders (offset + border)\n this.offset.parent.top + (this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : scrollIsRootNode ? 0 : scroll.scrollTop()),\n left:\n // The absolute mouse position\n pageX -\n // Click offset (relative to the element)\n this.offset.click.left -\n // Only for relative positioned nodes: Relative offset from element to offset parent\n this.offset.relative.left -\n // The offsetParent's offset without borders (offset + border)\n this.offset.parent.left + (this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft())\n };\n },\n _rearrange: function (event, i, a, hardRefresh) {\n if (a) {\n a[0].appendChild(this.placeholder[0]);\n } else {\n i.item[0].parentNode.insertBefore(this.placeholder[0], this.direction === \"down\" ? i.item[0] : i.item[0].nextSibling);\n }\n\n //Various things done here to improve the performance:\n // 1. we create a setTimeout, that calls refreshPositions\n // 2. on the instance, we have a counter variable, that get's higher after every append\n // 3. on the local scope, we copy the counter variable, and check in the timeout,\n // if it's still the same\n // 4. this lets only the last addition to the timeout stack through\n this.counter = this.counter ? ++this.counter : 1;\n var counter = this.counter;\n this._delay(function () {\n if (counter === this.counter) {\n //Precompute after each DOM insertion, NOT on mousemove\n this.refreshPositions(!hardRefresh);\n }\n });\n },\n _clear: function (event, noPropagation) {\n this.reverting = false;\n\n // We delay all events that have to be triggered to after the point where the placeholder\n // has been removed and everything else normalized again\n var i,\n delayedTriggers = [];\n\n // We first have to update the dom position of the actual currentItem\n // Note: don't do it if the current item is already removed (by a user), or it gets\n // reappended (see #4088)\n if (!this._noFinalSort && this.currentItem.parent().length) {\n this.placeholder.before(this.currentItem);\n }\n this._noFinalSort = null;\n if (this.helper[0] === this.currentItem[0]) {\n for (i in this._storedCSS) {\n if (this._storedCSS[i] === \"auto\" || this._storedCSS[i] === \"static\") {\n this._storedCSS[i] = \"\";\n }\n }\n this.currentItem.css(this._storedCSS);\n this._removeClass(this.currentItem, \"ui-sortable-helper\");\n } else {\n this.currentItem.show();\n }\n if (this.fromOutside && !noPropagation) {\n delayedTriggers.push(function (event) {\n this._trigger(\"receive\", event, this._uiHash(this.fromOutside));\n });\n }\n if ((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(\".ui-sortable-helper\")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {\n // Trigger update callback if the DOM position has changed\n delayedTriggers.push(function (event) {\n this._trigger(\"update\", event, this._uiHash());\n });\n }\n\n // Check if the items Container has Changed and trigger appropriate\n // events.\n if (this !== this.currentContainer) {\n if (!noPropagation) {\n delayedTriggers.push(function (event) {\n this._trigger(\"remove\", event, this._uiHash());\n });\n delayedTriggers.push(function (c) {\n return function (event) {\n c._trigger(\"receive\", event, this._uiHash(this));\n };\n }.call(this, this.currentContainer));\n delayedTriggers.push(function (c) {\n return function (event) {\n c._trigger(\"update\", event, this._uiHash(this));\n };\n }.call(this, this.currentContainer));\n }\n }\n\n //Post events to containers\n function delayEvent(type, instance, container) {\n return function (event) {\n container._trigger(type, event, instance._uiHash(instance));\n };\n }\n for (i = this.containers.length - 1; i >= 0; i--) {\n if (!noPropagation) {\n delayedTriggers.push(delayEvent(\"deactivate\", this, this.containers[i]));\n }\n if (this.containers[i].containerCache.over) {\n delayedTriggers.push(delayEvent(\"out\", this, this.containers[i]));\n this.containers[i].containerCache.over = 0;\n }\n }\n\n //Do what was originally in plugins\n if (this.storedCursor) {\n this.document.find(\"body\").css(\"cursor\", this.storedCursor);\n this.storedStylesheet.remove();\n }\n if (this._storedOpacity) {\n this.helper.css(\"opacity\", this._storedOpacity);\n }\n if (this._storedZIndex) {\n this.helper.css(\"zIndex\", this._storedZIndex === \"auto\" ? \"\" : this._storedZIndex);\n }\n this.dragging = false;\n if (!noPropagation) {\n this._trigger(\"beforeStop\", event, this._uiHash());\n }\n\n //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,\n // it unbinds ALL events from the original node!\n this.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n if (!this.cancelHelperRemoval) {\n if (this.helper[0] !== this.currentItem[0]) {\n this.helper.remove();\n }\n this.helper = null;\n }\n if (!noPropagation) {\n for (i = 0; i < delayedTriggers.length; i++) {\n // Trigger all delayed events\n delayedTriggers[i].call(this, event);\n }\n this._trigger(\"stop\", event, this._uiHash());\n }\n this.fromOutside = false;\n return !this.cancelHelperRemoval;\n },\n _trigger: function () {\n if ($.Widget.prototype._trigger.apply(this, arguments) === false) {\n this.cancel();\n }\n },\n _uiHash: function (_inst) {\n var inst = _inst || this;\n return {\n helper: inst.helper,\n placeholder: inst.placeholder || $([]),\n position: inst.position,\n originalPosition: inst.originalPosition,\n offset: inst.positionAbs,\n item: inst.currentItem,\n sender: _inst ? _inst.element : null\n };\n }\n });\n});","/*!\n * jQuery UI Mouse 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Mouse\n//>>group: Widgets\n//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.\n//>>docs: http://api.jqueryui.com/mouse/\n\n(function (factory) {\n \"use strict\";\n\n if (typeof define === \"function\" && define.amd) {\n // AMD. Register as an anonymous module.\n define([\"jquery\", \"../ie\", \"../version\", \"../widget\"], factory);\n } else {\n // Browser globals\n factory(jQuery);\n }\n})(function ($) {\n \"use strict\";\n\n var mouseHandled = false;\n $(document).on(\"mouseup\", function () {\n mouseHandled = false;\n });\n return $.widget(\"ui.mouse\", {\n version: \"1.13.2\",\n options: {\n cancel: \"input, textarea, button, select, option\",\n distance: 1,\n delay: 0\n },\n _mouseInit: function () {\n var that = this;\n this.element.on(\"mousedown.\" + this.widgetName, function (event) {\n return that._mouseDown(event);\n }).on(\"click.\" + this.widgetName, function (event) {\n if (true === $.data(event.target, that.widgetName + \".preventClickEvent\")) {\n $.removeData(event.target, that.widgetName + \".preventClickEvent\");\n event.stopImmediatePropagation();\n return false;\n }\n });\n this.started = false;\n },\n // TODO: make sure destroying one instance of mouse doesn't mess with\n // other instances of mouse\n _mouseDestroy: function () {\n this.element.off(\".\" + this.widgetName);\n if (this._mouseMoveDelegate) {\n this.document.off(\"mousemove.\" + this.widgetName, this._mouseMoveDelegate).off(\"mouseup.\" + this.widgetName, this._mouseUpDelegate);\n }\n },\n _mouseDown: function (event) {\n // don't let more than one widget handle mouseStart\n if (mouseHandled) {\n return;\n }\n this._mouseMoved = false;\n\n // We may have missed mouseup (out of window)\n if (this._mouseStarted) {\n this._mouseUp(event);\n }\n this._mouseDownEvent = event;\n var that = this,\n btnIsLeft = event.which === 1,\n // event.target.nodeName works around a bug in IE 8 with\n // disabled inputs (#7620)\n elIsCancel = typeof this.options.cancel === \"string\" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false;\n if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {\n return true;\n }\n this.mouseDelayMet = !this.options.delay;\n if (!this.mouseDelayMet) {\n this._mouseDelayTimer = setTimeout(function () {\n that.mouseDelayMet = true;\n }, this.options.delay);\n }\n if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {\n this._mouseStarted = this._mouseStart(event) !== false;\n if (!this._mouseStarted) {\n event.preventDefault();\n return true;\n }\n }\n\n // Click event may never have fired (Gecko & Opera)\n if (true === $.data(event.target, this.widgetName + \".preventClickEvent\")) {\n $.removeData(event.target, this.widgetName + \".preventClickEvent\");\n }\n\n // These delegates are required to keep context\n this._mouseMoveDelegate = function (event) {\n return that._mouseMove(event);\n };\n this._mouseUpDelegate = function (event) {\n return that._mouseUp(event);\n };\n this.document.on(\"mousemove.\" + this.widgetName, this._mouseMoveDelegate).on(\"mouseup.\" + this.widgetName, this._mouseUpDelegate);\n event.preventDefault();\n mouseHandled = true;\n return true;\n },\n _mouseMove: function (event) {\n // Only check for mouseups outside the document if you've moved inside the document\n // at least once. This prevents the firing of mouseup in the case of IE<9, which will\n // fire a mousemove event if content is placed under the cursor. See #7778\n // Support: IE <9\n if (this._mouseMoved) {\n // IE mouseup check - mouseup happened when mouse was out of window\n if ($.ui.ie && (!document.documentMode || document.documentMode < 9) && !event.button) {\n return this._mouseUp(event);\n\n // Iframe mouseup check - mouseup occurred in another document\n } else if (!event.which) {\n // Support: Safari <=8 - 9\n // Safari sets which to 0 if you press any of the following keys\n // during a drag (#14461)\n if (event.originalEvent.altKey || event.originalEvent.ctrlKey || event.originalEvent.metaKey || event.originalEvent.shiftKey) {\n this.ignoreMissingWhich = true;\n } else if (!this.ignoreMissingWhich) {\n return this._mouseUp(event);\n }\n }\n }\n if (event.which || event.button) {\n this._mouseMoved = true;\n }\n if (this._mouseStarted) {\n this._mouseDrag(event);\n return event.preventDefault();\n }\n if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {\n this._mouseStarted = this._mouseStart(this._mouseDownEvent, event) !== false;\n if (this._mouseStarted) {\n this._mouseDrag(event);\n } else {\n this._mouseUp(event);\n }\n }\n return !this._mouseStarted;\n },\n _mouseUp: function (event) {\n this.document.off(\"mousemove.\" + this.widgetName, this._mouseMoveDelegate).off(\"mouseup.\" + this.widgetName, this._mouseUpDelegate);\n if (this._mouseStarted) {\n this._mouseStarted = false;\n if (event.target === this._mouseDownEvent.target) {\n $.data(event.target, this.widgetName + \".preventClickEvent\", true);\n }\n this._mouseStop(event);\n }\n if (this._mouseDelayTimer) {\n clearTimeout(this._mouseDelayTimer);\n delete this._mouseDelayTimer;\n }\n this.ignoreMissingWhich = false;\n mouseHandled = false;\n event.preventDefault();\n },\n _mouseDistanceMet: function (event) {\n return Math.max(Math.abs(this._mouseDownEvent.pageX - event.pageX), Math.abs(this._mouseDownEvent.pageY - event.pageY)) >= this.options.distance;\n },\n _mouseDelayMet: function /* event */\n () {\n return this.mouseDelayMet;\n },\n // These are placeholder methods, to be overriden by extending plugin\n _mouseStart: function /* event */ () {},\n _mouseDrag: function /* event */ () {},\n _mouseStop: function /* event */ () {},\n _mouseCapture: function /* event */\n () {\n return true;\n }\n });\n});","/*!\n * jQuery UI :data 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: :data Selector\n//>>group: Core\n//>>description: Selects elements which have data stored under the specified key.\n//>>docs: http://api.jqueryui.com/data-selector/\n\n(function (factory) {\n \"use strict\";\n\n if (typeof define === \"function\" && define.amd) {\n // AMD. Register as an anonymous module.\n define([\"jquery\", \"./version\"], factory);\n } else {\n // Browser globals\n factory(jQuery);\n }\n})(function ($) {\n \"use strict\";\n\n return $.extend($.expr.pseudos, {\n data: $.expr.createPseudo ? $.expr.createPseudo(function (dataName) {\n return function (elem) {\n return !!$.data(elem, dataName);\n };\n }) :\n // Support: jQuery <1.8\n function (elem, i, match) {\n return !!$.data(elem, match[3]);\n }\n });\n});","/*!\n * jQuery UI Scroll Parent 1.13.2\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: scrollParent\n//>>group: Core\n//>>description: Get the closest ancestor element that is scrollable.\n//>>docs: http://api.jqueryui.com/scrollParent/\n\n(function (factory) {\n \"use strict\";\n\n if (typeof define === \"function\" && define.amd) {\n // AMD. Register as an anonymous module.\n define([\"jquery\", \"./version\"], factory);\n } else {\n // Browser globals\n factory(jQuery);\n }\n})(function ($) {\n \"use strict\";\n\n return $.fn.scrollParent = function (includeHidden) {\n var position = this.css(\"position\"),\n excludeStaticParent = position === \"absolute\",\n overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,\n scrollParent = this.parents().filter(function () {\n var parent = $(this);\n if (excludeStaticParent && parent.css(\"position\") === \"static\") {\n return false;\n }\n return overflowRegex.test(parent.css(\"overflow\") + parent.css(\"overflow-y\") + parent.css(\"overflow-x\"));\n }).eq(0);\n return position === \"fixed\" || !scrollParent.length ? $(this[0].ownerDocument || document) : scrollParent;\n };\n});","/*!\n * jQuery Cropper v1.0.1\n * https://fengyuanchen.github.io/jquery-cropper\n *\n * Copyright 2018-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2019-10-19T08:48:33.062Z\n */\n!function (e, r) {\n \"object\" == typeof exports && \"undefined\" != typeof module ? r(require(\"jquery\"), require(\"cropperjs\")) : \"function\" == typeof define && define.amd ? define([\"jquery\", \"cropperjs\"], r) : r((e = e || self).jQuery, e.Cropper);\n}(this, function (c, s) {\n \"use strict\";\n\n if (c = c && c.hasOwnProperty(\"default\") ? c.default : c, s = s && s.hasOwnProperty(\"default\") ? s.default : s, c && c.fn && s) {\n var e = c.fn.cropper,\n d = \"cropper\";\n c.fn.cropper = function (p) {\n for (var e = arguments.length, a = new Array(1 < e ? e - 1 : 0), r = 1; r < e; r++) a[r - 1] = arguments[r];\n var u;\n return this.each(function (e, r) {\n var t = c(r),\n n = \"destroy\" === p,\n o = t.data(d);\n if (!o) {\n if (n) return;\n var f = c.extend({}, t.data(), c.isPlainObject(p) && p);\n o = new s(r, f), t.data(d, o);\n }\n if (\"string\" == typeof p) {\n var i = o[p];\n c.isFunction(i) && ((u = i.apply(o, a)) === o && (u = void 0), n && t.removeData(d));\n }\n }), void 0 !== u ? u : this;\n }, c.fn.cropper.Constructor = s, c.fn.cropper.setDefaults = s.setDefaults, c.fn.cropper.noConflict = function () {\n return c.fn.cropper = e, this;\n };\n }\n});","/*!\n * Cropper.js v1.5.13\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2022-11-20T05:30:46.114Z\n */\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Cropper = factory());\n})(this, function () {\n 'use strict';\n\n function ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n enumerableOnly && (symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n })), keys.push.apply(keys, symbols);\n }\n return keys;\n }\n function _objectSpread2(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = null != arguments[i] ? arguments[i] : {};\n i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {\n _defineProperty(target, key, source[key]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n return target;\n }\n function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n }\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n }\n function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n }\n function _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n }\n function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n }\n function _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n }\n function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n }\n function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n }\n function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n }\n var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';\n var WINDOW = IS_BROWSER ? window : {};\n var IS_TOUCH_DEVICE = IS_BROWSER && WINDOW.document.documentElement ? 'ontouchstart' in WINDOW.document.documentElement : false;\n var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;\n var NAMESPACE = 'cropper';\n\n // Actions\n var ACTION_ALL = 'all';\n var ACTION_CROP = 'crop';\n var ACTION_MOVE = 'move';\n var ACTION_ZOOM = 'zoom';\n var ACTION_EAST = 'e';\n var ACTION_WEST = 'w';\n var ACTION_SOUTH = 's';\n var ACTION_NORTH = 'n';\n var ACTION_NORTH_EAST = 'ne';\n var ACTION_NORTH_WEST = 'nw';\n var ACTION_SOUTH_EAST = 'se';\n var ACTION_SOUTH_WEST = 'sw';\n\n // Classes\n var CLASS_CROP = \"\".concat(NAMESPACE, \"-crop\");\n var CLASS_DISABLED = \"\".concat(NAMESPACE, \"-disabled\");\n var CLASS_HIDDEN = \"\".concat(NAMESPACE, \"-hidden\");\n var CLASS_HIDE = \"\".concat(NAMESPACE, \"-hide\");\n var CLASS_INVISIBLE = \"\".concat(NAMESPACE, \"-invisible\");\n var CLASS_MODAL = \"\".concat(NAMESPACE, \"-modal\");\n var CLASS_MOVE = \"\".concat(NAMESPACE, \"-move\");\n\n // Data keys\n var DATA_ACTION = \"\".concat(NAMESPACE, \"Action\");\n var DATA_PREVIEW = \"\".concat(NAMESPACE, \"Preview\");\n\n // Drag modes\n var DRAG_MODE_CROP = 'crop';\n var DRAG_MODE_MOVE = 'move';\n var DRAG_MODE_NONE = 'none';\n\n // Events\n var EVENT_CROP = 'crop';\n var EVENT_CROP_END = 'cropend';\n var EVENT_CROP_MOVE = 'cropmove';\n var EVENT_CROP_START = 'cropstart';\n var EVENT_DBLCLICK = 'dblclick';\n var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';\n var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';\n var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';\n var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;\n var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;\n var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;\n var EVENT_READY = 'ready';\n var EVENT_RESIZE = 'resize';\n var EVENT_WHEEL = 'wheel';\n var EVENT_ZOOM = 'zoom';\n\n // Mime types\n var MIME_TYPE_JPEG = 'image/jpeg';\n\n // RegExps\n var REGEXP_ACTIONS = /^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/;\n var REGEXP_DATA_URL = /^data:/;\n var REGEXP_DATA_URL_JPEG = /^data:image\\/jpeg;base64,/;\n var REGEXP_TAG_NAME = /^img|canvas$/i;\n\n // Misc\n // Inspired by the default width and height of a canvas element.\n var MIN_CONTAINER_WIDTH = 200;\n var MIN_CONTAINER_HEIGHT = 100;\n var DEFAULTS = {\n // Define the view mode of the cropper\n viewMode: 0,\n // 0, 1, 2, 3\n\n // Define the dragging mode of the cropper\n dragMode: DRAG_MODE_CROP,\n // 'crop', 'move' or 'none'\n\n // Define the initial aspect ratio of the crop box\n initialAspectRatio: NaN,\n // Define the aspect ratio of the crop box\n aspectRatio: NaN,\n // An object with the previous cropping result data\n data: null,\n // A selector for adding extra containers to preview\n preview: '',\n // Re-render the cropper when resize the window\n responsive: true,\n // Restore the cropped area after resize the window\n restore: true,\n // Check if the current image is a cross-origin image\n checkCrossOrigin: true,\n // Check the current image's Exif Orientation information\n checkOrientation: true,\n // Show the black modal\n modal: true,\n // Show the dashed lines for guiding\n guides: true,\n // Show the center indicator for guiding\n center: true,\n // Show the white modal to highlight the crop box\n highlight: true,\n // Show the grid background\n background: true,\n // Enable to crop the image automatically when initialize\n autoCrop: true,\n // Define the percentage of automatic cropping area when initializes\n autoCropArea: 0.8,\n // Enable to move the image\n movable: true,\n // Enable to rotate the image\n rotatable: true,\n // Enable to scale the image\n scalable: true,\n // Enable to zoom the image\n zoomable: true,\n // Enable to zoom the image by dragging touch\n zoomOnTouch: true,\n // Enable to zoom the image by wheeling mouse\n zoomOnWheel: true,\n // Define zoom ratio when zoom the image by wheeling mouse\n wheelZoomRatio: 0.1,\n // Enable to move the crop box\n cropBoxMovable: true,\n // Enable to resize the crop box\n cropBoxResizable: true,\n // Toggle drag mode between \"crop\" and \"move\" when click twice on the cropper\n toggleDragModeOnDblclick: true,\n // Size limitation\n minCanvasWidth: 0,\n minCanvasHeight: 0,\n minCropBoxWidth: 0,\n minCropBoxHeight: 0,\n minContainerWidth: MIN_CONTAINER_WIDTH,\n minContainerHeight: MIN_CONTAINER_HEIGHT,\n // Shortcuts of events\n ready: null,\n cropstart: null,\n cropmove: null,\n cropend: null,\n crop: null,\n zoom: null\n };\n var TEMPLATE = '' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
' + '
';\n\n /**\n * Check if the given value is not a number.\n */\n var isNaN = Number.isNaN || WINDOW.isNaN;\n\n /**\n * Check if the given value is a number.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a number, else `false`.\n */\n function isNumber(value) {\n return typeof value === 'number' && !isNaN(value);\n }\n\n /**\n * Check if the given value is a positive number.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.\n */\n var isPositiveNumber = function isPositiveNumber(value) {\n return value > 0 && value < Infinity;\n };\n\n /**\n * Check if the given value is undefined.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is undefined, else `false`.\n */\n function isUndefined(value) {\n return typeof value === 'undefined';\n }\n\n /**\n * Check if the given value is an object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is an object, else `false`.\n */\n function isObject(value) {\n return _typeof(value) === 'object' && value !== null;\n }\n var hasOwnProperty = Object.prototype.hasOwnProperty;\n\n /**\n * Check if the given value is a plain object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.\n */\n function isPlainObject(value) {\n if (!isObject(value)) {\n return false;\n }\n try {\n var _constructor = value.constructor;\n var prototype = _constructor.prototype;\n return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Check if the given value is a function.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a function, else `false`.\n */\n function isFunction(value) {\n return typeof value === 'function';\n }\n var slice = Array.prototype.slice;\n\n /**\n * Convert array-like or iterable object to an array.\n * @param {*} value - The value to convert.\n * @returns {Array} Returns a new array.\n */\n function toArray(value) {\n return Array.from ? Array.from(value) : slice.call(value);\n }\n\n /**\n * Iterate the given data.\n * @param {*} data - The data to iterate.\n * @param {Function} callback - The process function for each element.\n * @returns {*} The original data.\n */\n function forEach(data, callback) {\n if (data && isFunction(callback)) {\n if (Array.isArray(data) || isNumber(data.length) /* array-like */) {\n toArray(data).forEach(function (value, key) {\n callback.call(data, value, key, data);\n });\n } else if (isObject(data)) {\n Object.keys(data).forEach(function (key) {\n callback.call(data, data[key], key, data);\n });\n }\n }\n return data;\n }\n\n /**\n * Extend the given object.\n * @param {*} target - The target object to extend.\n * @param {*} args - The rest objects for merging to the target object.\n * @returns {Object} The extended object.\n */\n var assign = Object.assign || function assign(target) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n if (isObject(target) && args.length > 0) {\n args.forEach(function (arg) {\n if (isObject(arg)) {\n Object.keys(arg).forEach(function (key) {\n target[key] = arg[key];\n });\n }\n });\n }\n return target;\n };\n var REGEXP_DECIMALS = /\\.\\d*(?:0|9){12}\\d*$/;\n\n /**\n * Normalize decimal number.\n * Check out {@link https://0.30000000000000004.com/}\n * @param {number} value - The value to normalize.\n * @param {number} [times=100000000000] - The times for normalizing.\n * @returns {number} Returns the normalized number.\n */\n function normalizeDecimalNumber(value) {\n var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;\n return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;\n }\n var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;\n\n /**\n * Apply styles to the given element.\n * @param {Element} element - The target element.\n * @param {Object} styles - The styles for applying.\n */\n function setStyle(element, styles) {\n var style = element.style;\n forEach(styles, function (value, property) {\n if (REGEXP_SUFFIX.test(property) && isNumber(value)) {\n value = \"\".concat(value, \"px\");\n }\n style[property] = value;\n });\n }\n\n /**\n * Check if the given element has a special class.\n * @param {Element} element - The element to check.\n * @param {string} value - The class to search.\n * @returns {boolean} Returns `true` if the special class was found.\n */\n function hasClass(element, value) {\n return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;\n }\n\n /**\n * Add classes to the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be added.\n */\n function addClass(element, value) {\n if (!value) {\n return;\n }\n if (isNumber(element.length)) {\n forEach(element, function (elem) {\n addClass(elem, value);\n });\n return;\n }\n if (element.classList) {\n element.classList.add(value);\n return;\n }\n var className = element.className.trim();\n if (!className) {\n element.className = value;\n } else if (className.indexOf(value) < 0) {\n element.className = \"\".concat(className, \" \").concat(value);\n }\n }\n\n /**\n * Remove classes from the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be removed.\n */\n function removeClass(element, value) {\n if (!value) {\n return;\n }\n if (isNumber(element.length)) {\n forEach(element, function (elem) {\n removeClass(elem, value);\n });\n return;\n }\n if (element.classList) {\n element.classList.remove(value);\n return;\n }\n if (element.className.indexOf(value) >= 0) {\n element.className = element.className.replace(value, '');\n }\n }\n\n /**\n * Add or remove classes from the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be toggled.\n * @param {boolean} added - Add only.\n */\n function toggleClass(element, value, added) {\n if (!value) {\n return;\n }\n if (isNumber(element.length)) {\n forEach(element, function (elem) {\n toggleClass(elem, value, added);\n });\n return;\n }\n\n // IE10-11 doesn't support the second parameter of `classList.toggle`\n if (added) {\n addClass(element, value);\n } else {\n removeClass(element, value);\n }\n }\n var REGEXP_CAMEL_CASE = /([a-z\\d])([A-Z])/g;\n\n /**\n * Transform the given string from camelCase to kebab-case\n * @param {string} value - The value to transform.\n * @returns {string} The transformed value.\n */\n function toParamCase(value) {\n return value.replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();\n }\n\n /**\n * Get data from the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to get.\n * @returns {string} The data value.\n */\n function getData(element, name) {\n if (isObject(element[name])) {\n return element[name];\n }\n if (element.dataset) {\n return element.dataset[name];\n }\n return element.getAttribute(\"data-\".concat(toParamCase(name)));\n }\n\n /**\n * Set data to the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to set.\n * @param {string} data - The data value.\n */\n function setData(element, name, data) {\n if (isObject(data)) {\n element[name] = data;\n } else if (element.dataset) {\n element.dataset[name] = data;\n } else {\n element.setAttribute(\"data-\".concat(toParamCase(name)), data);\n }\n }\n\n /**\n * Remove data from the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to remove.\n */\n function removeData(element, name) {\n if (isObject(element[name])) {\n try {\n delete element[name];\n } catch (error) {\n element[name] = undefined;\n }\n } else if (element.dataset) {\n // #128 Safari not allows to delete dataset property\n try {\n delete element.dataset[name];\n } catch (error) {\n element.dataset[name] = undefined;\n }\n } else {\n element.removeAttribute(\"data-\".concat(toParamCase(name)));\n }\n }\n var REGEXP_SPACES = /\\s\\s*/;\n var onceSupported = function () {\n var supported = false;\n if (IS_BROWSER) {\n var once = false;\n var listener = function listener() {};\n var options = Object.defineProperty({}, 'once', {\n get: function get() {\n supported = true;\n return once;\n },\n /**\n * This setter can fix a `TypeError` in strict mode\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}\n * @param {boolean} value - The value to set\n */\n set: function set(value) {\n once = value;\n }\n });\n WINDOW.addEventListener('test', listener, options);\n WINDOW.removeEventListener('test', listener, options);\n }\n return supported;\n }();\n\n /**\n * Remove event listener from the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Function} listener - The event listener.\n * @param {Object} options - The event options.\n */\n function removeListener(element, type, listener) {\n var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n var handler = listener;\n type.trim().split(REGEXP_SPACES).forEach(function (event) {\n if (!onceSupported) {\n var listeners = element.listeners;\n if (listeners && listeners[event] && listeners[event][listener]) {\n handler = listeners[event][listener];\n delete listeners[event][listener];\n if (Object.keys(listeners[event]).length === 0) {\n delete listeners[event];\n }\n if (Object.keys(listeners).length === 0) {\n delete element.listeners;\n }\n }\n }\n element.removeEventListener(event, handler, options);\n });\n }\n\n /**\n * Add event listener to the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Function} listener - The event listener.\n * @param {Object} options - The event options.\n */\n function addListener(element, type, listener) {\n var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n var _handler = listener;\n type.trim().split(REGEXP_SPACES).forEach(function (event) {\n if (options.once && !onceSupported) {\n var _element$listeners = element.listeners,\n listeners = _element$listeners === void 0 ? {} : _element$listeners;\n _handler = function handler() {\n delete listeners[event][listener];\n element.removeEventListener(event, _handler, options);\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n listener.apply(element, args);\n };\n if (!listeners[event]) {\n listeners[event] = {};\n }\n if (listeners[event][listener]) {\n element.removeEventListener(event, listeners[event][listener], options);\n }\n listeners[event][listener] = _handler;\n element.listeners = listeners;\n }\n element.addEventListener(event, _handler, options);\n });\n }\n\n /**\n * Dispatch event on the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Object} data - The additional event data.\n * @returns {boolean} Indicate if the event is default prevented or not.\n */\n function dispatchEvent(element, type, data) {\n var event;\n\n // Event and CustomEvent on IE9-11 are global objects, not constructors\n if (isFunction(Event) && isFunction(CustomEvent)) {\n event = new CustomEvent(type, {\n detail: data,\n bubbles: true,\n cancelable: true\n });\n } else {\n event = document.createEvent('CustomEvent');\n event.initCustomEvent(type, true, true, data);\n }\n return element.dispatchEvent(event);\n }\n\n /**\n * Get the offset base on the document.\n * @param {Element} element - The target element.\n * @returns {Object} The offset data.\n */\n function getOffset(element) {\n var box = element.getBoundingClientRect();\n return {\n left: box.left + (window.pageXOffset - document.documentElement.clientLeft),\n top: box.top + (window.pageYOffset - document.documentElement.clientTop)\n };\n }\n var location = WINDOW.location;\n var REGEXP_ORIGINS = /^(\\w+:)\\/\\/([^:/?#]*):?(\\d*)/i;\n\n /**\n * Check if the given URL is a cross origin URL.\n * @param {string} url - The target URL.\n * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.\n */\n function isCrossOriginURL(url) {\n var parts = url.match(REGEXP_ORIGINS);\n return parts !== null && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);\n }\n\n /**\n * Add timestamp to the given URL.\n * @param {string} url - The target URL.\n * @returns {string} The result URL.\n */\n function addTimestamp(url) {\n var timestamp = \"timestamp=\".concat(new Date().getTime());\n return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;\n }\n\n /**\n * Get transforms base on the given object.\n * @param {Object} obj - The target object.\n * @returns {string} A string contains transform values.\n */\n function getTransforms(_ref) {\n var rotate = _ref.rotate,\n scaleX = _ref.scaleX,\n scaleY = _ref.scaleY,\n translateX = _ref.translateX,\n translateY = _ref.translateY;\n var values = [];\n if (isNumber(translateX) && translateX !== 0) {\n values.push(\"translateX(\".concat(translateX, \"px)\"));\n }\n if (isNumber(translateY) && translateY !== 0) {\n values.push(\"translateY(\".concat(translateY, \"px)\"));\n }\n\n // Rotate should come first before scale to match orientation transform\n if (isNumber(rotate) && rotate !== 0) {\n values.push(\"rotate(\".concat(rotate, \"deg)\"));\n }\n if (isNumber(scaleX) && scaleX !== 1) {\n values.push(\"scaleX(\".concat(scaleX, \")\"));\n }\n if (isNumber(scaleY) && scaleY !== 1) {\n values.push(\"scaleY(\".concat(scaleY, \")\"));\n }\n var transform = values.length ? values.join(' ') : 'none';\n return {\n WebkitTransform: transform,\n msTransform: transform,\n transform: transform\n };\n }\n\n /**\n * Get the max ratio of a group of pointers.\n * @param {string} pointers - The target pointers.\n * @returns {number} The result ratio.\n */\n function getMaxZoomRatio(pointers) {\n var pointers2 = _objectSpread2({}, pointers);\n var maxRatio = 0;\n forEach(pointers, function (pointer, pointerId) {\n delete pointers2[pointerId];\n forEach(pointers2, function (pointer2) {\n var x1 = Math.abs(pointer.startX - pointer2.startX);\n var y1 = Math.abs(pointer.startY - pointer2.startY);\n var x2 = Math.abs(pointer.endX - pointer2.endX);\n var y2 = Math.abs(pointer.endY - pointer2.endY);\n var z1 = Math.sqrt(x1 * x1 + y1 * y1);\n var z2 = Math.sqrt(x2 * x2 + y2 * y2);\n var ratio = (z2 - z1) / z1;\n if (Math.abs(ratio) > Math.abs(maxRatio)) {\n maxRatio = ratio;\n }\n });\n });\n return maxRatio;\n }\n\n /**\n * Get a pointer from an event object.\n * @param {Object} event - The target event object.\n * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.\n * @returns {Object} The result pointer contains start and/or end point coordinates.\n */\n function getPointer(_ref2, endOnly) {\n var pageX = _ref2.pageX,\n pageY = _ref2.pageY;\n var end = {\n endX: pageX,\n endY: pageY\n };\n return endOnly ? end : _objectSpread2({\n startX: pageX,\n startY: pageY\n }, end);\n }\n\n /**\n * Get the center point coordinate of a group of pointers.\n * @param {Object} pointers - The target pointers.\n * @returns {Object} The center point coordinate.\n */\n function getPointersCenter(pointers) {\n var pageX = 0;\n var pageY = 0;\n var count = 0;\n forEach(pointers, function (_ref3) {\n var startX = _ref3.startX,\n startY = _ref3.startY;\n pageX += startX;\n pageY += startY;\n count += 1;\n });\n pageX /= count;\n pageY /= count;\n return {\n pageX: pageX,\n pageY: pageY\n };\n }\n\n /**\n * Get the max sizes in a rectangle under the given aspect ratio.\n * @param {Object} data - The original sizes.\n * @param {string} [type='contain'] - The adjust type.\n * @returns {Object} The result sizes.\n */\n function getAdjustedSizes(_ref4) {\n var aspectRatio = _ref4.aspectRatio,\n height = _ref4.height,\n width = _ref4.width;\n var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain';\n var isValidWidth = isPositiveNumber(width);\n var isValidHeight = isPositiveNumber(height);\n if (isValidWidth && isValidHeight) {\n var adjustedWidth = height * aspectRatio;\n if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {\n height = width / aspectRatio;\n } else {\n width = height * aspectRatio;\n }\n } else if (isValidWidth) {\n height = width / aspectRatio;\n } else if (isValidHeight) {\n width = height * aspectRatio;\n }\n return {\n width: width,\n height: height\n };\n }\n\n /**\n * Get the new sizes of a rectangle after rotated.\n * @param {Object} data - The original sizes.\n * @returns {Object} The result sizes.\n */\n function getRotatedSizes(_ref5) {\n var width = _ref5.width,\n height = _ref5.height,\n degree = _ref5.degree;\n degree = Math.abs(degree) % 180;\n if (degree === 90) {\n return {\n width: height,\n height: width\n };\n }\n var arc = degree % 90 * Math.PI / 180;\n var sinArc = Math.sin(arc);\n var cosArc = Math.cos(arc);\n var newWidth = width * cosArc + height * sinArc;\n var newHeight = width * sinArc + height * cosArc;\n return degree > 90 ? {\n width: newHeight,\n height: newWidth\n } : {\n width: newWidth,\n height: newHeight\n };\n }\n\n /**\n * Get a canvas which drew the given image.\n * @param {HTMLImageElement} image - The image for drawing.\n * @param {Object} imageData - The image data.\n * @param {Object} canvasData - The canvas data.\n * @param {Object} options - The options.\n * @returns {HTMLCanvasElement} The result canvas.\n */\n function getSourceCanvas(image, _ref6, _ref7, _ref8) {\n var imageAspectRatio = _ref6.aspectRatio,\n imageNaturalWidth = _ref6.naturalWidth,\n imageNaturalHeight = _ref6.naturalHeight,\n _ref6$rotate = _ref6.rotate,\n rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,\n _ref6$scaleX = _ref6.scaleX,\n scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,\n _ref6$scaleY = _ref6.scaleY,\n scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;\n var aspectRatio = _ref7.aspectRatio,\n naturalWidth = _ref7.naturalWidth,\n naturalHeight = _ref7.naturalHeight;\n var _ref8$fillColor = _ref8.fillColor,\n fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,\n _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,\n imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,\n _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,\n imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,\n _ref8$maxWidth = _ref8.maxWidth,\n maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,\n _ref8$maxHeight = _ref8.maxHeight,\n maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,\n _ref8$minWidth = _ref8.minWidth,\n minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,\n _ref8$minHeight = _ref8.minHeight,\n minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;\n var canvas = document.createElement('canvas');\n var context = canvas.getContext('2d');\n var maxSizes = getAdjustedSizes({\n aspectRatio: aspectRatio,\n width: maxWidth,\n height: maxHeight\n });\n var minSizes = getAdjustedSizes({\n aspectRatio: aspectRatio,\n width: minWidth,\n height: minHeight\n }, 'cover');\n var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));\n var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight));\n\n // Note: should always use image's natural sizes for drawing as\n // imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90\n var destMaxSizes = getAdjustedSizes({\n aspectRatio: imageAspectRatio,\n width: maxWidth,\n height: maxHeight\n });\n var destMinSizes = getAdjustedSizes({\n aspectRatio: imageAspectRatio,\n width: minWidth,\n height: minHeight\n }, 'cover');\n var destWidth = Math.min(destMaxSizes.width, Math.max(destMinSizes.width, imageNaturalWidth));\n var destHeight = Math.min(destMaxSizes.height, Math.max(destMinSizes.height, imageNaturalHeight));\n var params = [-destWidth / 2, -destHeight / 2, destWidth, destHeight];\n canvas.width = normalizeDecimalNumber(width);\n canvas.height = normalizeDecimalNumber(height);\n context.fillStyle = fillColor;\n context.fillRect(0, 0, width, height);\n context.save();\n context.translate(width / 2, height / 2);\n context.rotate(rotate * Math.PI / 180);\n context.scale(scaleX, scaleY);\n context.imageSmoothingEnabled = imageSmoothingEnabled;\n context.imageSmoothingQuality = imageSmoothingQuality;\n context.drawImage.apply(context, [image].concat(_toConsumableArray(params.map(function (param) {\n return Math.floor(normalizeDecimalNumber(param));\n }))));\n context.restore();\n return canvas;\n }\n var fromCharCode = String.fromCharCode;\n\n /**\n * Get string from char code in data view.\n * @param {DataView} dataView - The data view for read.\n * @param {number} start - The start index.\n * @param {number} length - The read length.\n * @returns {string} The read result.\n */\n function getStringFromCharCode(dataView, start, length) {\n var str = '';\n length += start;\n for (var i = start; i < length; i += 1) {\n str += fromCharCode(dataView.getUint8(i));\n }\n return str;\n }\n var REGEXP_DATA_URL_HEAD = /^data:.*,/;\n\n /**\n * Transform Data URL to array buffer.\n * @param {string} dataURL - The Data URL to transform.\n * @returns {ArrayBuffer} The result array buffer.\n */\n function dataURLToArrayBuffer(dataURL) {\n var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');\n var binary = atob(base64);\n var arrayBuffer = new ArrayBuffer(binary.length);\n var uint8 = new Uint8Array(arrayBuffer);\n forEach(uint8, function (value, i) {\n uint8[i] = binary.charCodeAt(i);\n });\n return arrayBuffer;\n }\n\n /**\n * Transform array buffer to Data URL.\n * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.\n * @param {string} mimeType - The mime type of the Data URL.\n * @returns {string} The result Data URL.\n */\n function arrayBufferToDataURL(arrayBuffer, mimeType) {\n var chunks = [];\n\n // Chunk Typed Array for better performance (#435)\n var chunkSize = 8192;\n var uint8 = new Uint8Array(arrayBuffer);\n while (uint8.length > 0) {\n // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9\n // eslint-disable-next-line prefer-spread\n chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));\n uint8 = uint8.subarray(chunkSize);\n }\n return \"data:\".concat(mimeType, \";base64,\").concat(btoa(chunks.join('')));\n }\n\n /**\n * Get orientation value from given array buffer.\n * @param {ArrayBuffer} arrayBuffer - The array buffer to read.\n * @returns {number} The read orientation value.\n */\n function resetAndGetOrientation(arrayBuffer) {\n var dataView = new DataView(arrayBuffer);\n var orientation;\n\n // Ignores range error when the image does not have correct Exif information\n try {\n var littleEndian;\n var app1Start;\n var ifdStart;\n\n // Only handle JPEG image (start by 0xFFD8)\n if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {\n var length = dataView.byteLength;\n var offset = 2;\n while (offset + 1 < length) {\n if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {\n app1Start = offset;\n break;\n }\n offset += 1;\n }\n }\n if (app1Start) {\n var exifIDCode = app1Start + 4;\n var tiffOffset = app1Start + 10;\n if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {\n var endianness = dataView.getUint16(tiffOffset);\n littleEndian = endianness === 0x4949;\n if (littleEndian || endianness === 0x4D4D /* bigEndian */) {\n if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {\n var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);\n if (firstIFDOffset >= 0x00000008) {\n ifdStart = tiffOffset + firstIFDOffset;\n }\n }\n }\n }\n }\n if (ifdStart) {\n var _length = dataView.getUint16(ifdStart, littleEndian);\n var _offset;\n var i;\n for (i = 0; i < _length; i += 1) {\n _offset = ifdStart + i * 12 + 2;\n if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) {\n // 8 is the offset of the current tag's value\n _offset += 8;\n\n // Get the original orientation value\n orientation = dataView.getUint16(_offset, littleEndian);\n\n // Override the orientation with its default value\n dataView.setUint16(_offset, 1, littleEndian);\n break;\n }\n }\n }\n } catch (error) {\n orientation = 1;\n }\n return orientation;\n }\n\n /**\n * Parse Exif Orientation value.\n * @param {number} orientation - The orientation to parse.\n * @returns {Object} The parsed result.\n */\n function parseOrientation(orientation) {\n var rotate = 0;\n var scaleX = 1;\n var scaleY = 1;\n switch (orientation) {\n // Flip horizontal\n case 2:\n scaleX = -1;\n break;\n\n // Rotate left 180°\n case 3:\n rotate = -180;\n break;\n\n // Flip vertical\n case 4:\n scaleY = -1;\n break;\n\n // Flip vertical and rotate right 90°\n case 5:\n rotate = 90;\n scaleY = -1;\n break;\n\n // Rotate right 90°\n case 6:\n rotate = 90;\n break;\n\n // Flip horizontal and rotate right 90°\n case 7:\n rotate = 90;\n scaleX = -1;\n break;\n\n // Rotate left 90°\n case 8:\n rotate = -90;\n break;\n }\n return {\n rotate: rotate,\n scaleX: scaleX,\n scaleY: scaleY\n };\n }\n var render = {\n render: function render() {\n this.initContainer();\n this.initCanvas();\n this.initCropBox();\n this.renderCanvas();\n if (this.cropped) {\n this.renderCropBox();\n }\n },\n initContainer: function initContainer() {\n var element = this.element,\n options = this.options,\n container = this.container,\n cropper = this.cropper;\n var minWidth = Number(options.minContainerWidth);\n var minHeight = Number(options.minContainerHeight);\n addClass(cropper, CLASS_HIDDEN);\n removeClass(element, CLASS_HIDDEN);\n var containerData = {\n width: Math.max(container.offsetWidth, minWidth >= 0 ? minWidth : MIN_CONTAINER_WIDTH),\n height: Math.max(container.offsetHeight, minHeight >= 0 ? minHeight : MIN_CONTAINER_HEIGHT)\n };\n this.containerData = containerData;\n setStyle(cropper, {\n width: containerData.width,\n height: containerData.height\n });\n addClass(element, CLASS_HIDDEN);\n removeClass(cropper, CLASS_HIDDEN);\n },\n // Canvas (image wrapper)\n initCanvas: function initCanvas() {\n var containerData = this.containerData,\n imageData = this.imageData;\n var viewMode = this.options.viewMode;\n var rotated = Math.abs(imageData.rotate) % 180 === 90;\n var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;\n var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;\n var aspectRatio = naturalWidth / naturalHeight;\n var canvasWidth = containerData.width;\n var canvasHeight = containerData.height;\n if (containerData.height * aspectRatio > containerData.width) {\n if (viewMode === 3) {\n canvasWidth = containerData.height * aspectRatio;\n } else {\n canvasHeight = containerData.width / aspectRatio;\n }\n } else if (viewMode === 3) {\n canvasHeight = containerData.width / aspectRatio;\n } else {\n canvasWidth = containerData.height * aspectRatio;\n }\n var canvasData = {\n aspectRatio: aspectRatio,\n naturalWidth: naturalWidth,\n naturalHeight: naturalHeight,\n width: canvasWidth,\n height: canvasHeight\n };\n this.canvasData = canvasData;\n this.limited = viewMode === 1 || viewMode === 2;\n this.limitCanvas(true, true);\n canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);\n canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);\n canvasData.left = (containerData.width - canvasData.width) / 2;\n canvasData.top = (containerData.height - canvasData.height) / 2;\n canvasData.oldLeft = canvasData.left;\n canvasData.oldTop = canvasData.top;\n this.initialCanvasData = assign({}, canvasData);\n },\n limitCanvas: function limitCanvas(sizeLimited, positionLimited) {\n var options = this.options,\n containerData = this.containerData,\n canvasData = this.canvasData,\n cropBoxData = this.cropBoxData;\n var viewMode = options.viewMode;\n var aspectRatio = canvasData.aspectRatio;\n var cropped = this.cropped && cropBoxData;\n if (sizeLimited) {\n var minCanvasWidth = Number(options.minCanvasWidth) || 0;\n var minCanvasHeight = Number(options.minCanvasHeight) || 0;\n if (viewMode > 1) {\n minCanvasWidth = Math.max(minCanvasWidth, containerData.width);\n minCanvasHeight = Math.max(minCanvasHeight, containerData.height);\n if (viewMode === 3) {\n if (minCanvasHeight * aspectRatio > minCanvasWidth) {\n minCanvasWidth = minCanvasHeight * aspectRatio;\n } else {\n minCanvasHeight = minCanvasWidth / aspectRatio;\n }\n }\n } else if (viewMode > 0) {\n if (minCanvasWidth) {\n minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);\n } else if (minCanvasHeight) {\n minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);\n } else if (cropped) {\n minCanvasWidth = cropBoxData.width;\n minCanvasHeight = cropBoxData.height;\n if (minCanvasHeight * aspectRatio > minCanvasWidth) {\n minCanvasWidth = minCanvasHeight * aspectRatio;\n } else {\n minCanvasHeight = minCanvasWidth / aspectRatio;\n }\n }\n }\n var _getAdjustedSizes = getAdjustedSizes({\n aspectRatio: aspectRatio,\n width: minCanvasWidth,\n height: minCanvasHeight\n });\n minCanvasWidth = _getAdjustedSizes.width;\n minCanvasHeight = _getAdjustedSizes.height;\n canvasData.minWidth = minCanvasWidth;\n canvasData.minHeight = minCanvasHeight;\n canvasData.maxWidth = Infinity;\n canvasData.maxHeight = Infinity;\n }\n if (positionLimited) {\n if (viewMode > (cropped ? 0 : 1)) {\n var newCanvasLeft = containerData.width - canvasData.width;\n var newCanvasTop = containerData.height - canvasData.height;\n canvasData.minLeft = Math.min(0, newCanvasLeft);\n canvasData.minTop = Math.min(0, newCanvasTop);\n canvasData.maxLeft = Math.max(0, newCanvasLeft);\n canvasData.maxTop = Math.max(0, newCanvasTop);\n if (cropped && this.limited) {\n canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));\n canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));\n canvasData.maxLeft = cropBoxData.left;\n canvasData.maxTop = cropBoxData.top;\n if (viewMode === 2) {\n if (canvasData.width >= containerData.width) {\n canvasData.minLeft = Math.min(0, newCanvasLeft);\n canvasData.maxLeft = Math.max(0, newCanvasLeft);\n }\n if (canvasData.height >= containerData.height) {\n canvasData.minTop = Math.min(0, newCanvasTop);\n canvasData.maxTop = Math.max(0, newCanvasTop);\n }\n }\n }\n } else {\n canvasData.minLeft = -canvasData.width;\n canvasData.minTop = -canvasData.height;\n canvasData.maxLeft = containerData.width;\n canvasData.maxTop = containerData.height;\n }\n }\n },\n renderCanvas: function renderCanvas(changed, transformed) {\n var canvasData = this.canvasData,\n imageData = this.imageData;\n if (transformed) {\n var _getRotatedSizes = getRotatedSizes({\n width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),\n height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),\n degree: imageData.rotate || 0\n }),\n naturalWidth = _getRotatedSizes.width,\n naturalHeight = _getRotatedSizes.height;\n var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);\n var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);\n canvasData.left -= (width - canvasData.width) / 2;\n canvasData.top -= (height - canvasData.height) / 2;\n canvasData.width = width;\n canvasData.height = height;\n canvasData.aspectRatio = naturalWidth / naturalHeight;\n canvasData.naturalWidth = naturalWidth;\n canvasData.naturalHeight = naturalHeight;\n this.limitCanvas(true, false);\n }\n if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {\n canvasData.left = canvasData.oldLeft;\n }\n if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {\n canvasData.top = canvasData.oldTop;\n }\n canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);\n canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);\n this.limitCanvas(false, true);\n canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);\n canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);\n canvasData.oldLeft = canvasData.left;\n canvasData.oldTop = canvasData.top;\n setStyle(this.canvas, assign({\n width: canvasData.width,\n height: canvasData.height\n }, getTransforms({\n translateX: canvasData.left,\n translateY: canvasData.top\n })));\n this.renderImage(changed);\n if (this.cropped && this.limited) {\n this.limitCropBox(true, true);\n }\n },\n renderImage: function renderImage(changed) {\n var canvasData = this.canvasData,\n imageData = this.imageData;\n var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);\n var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);\n assign(imageData, {\n width: width,\n height: height,\n left: (canvasData.width - width) / 2,\n top: (canvasData.height - height) / 2\n });\n setStyle(this.image, assign({\n width: imageData.width,\n height: imageData.height\n }, getTransforms(assign({\n translateX: imageData.left,\n translateY: imageData.top\n }, imageData))));\n if (changed) {\n this.output();\n }\n },\n initCropBox: function initCropBox() {\n var options = this.options,\n canvasData = this.canvasData;\n var aspectRatio = options.aspectRatio || options.initialAspectRatio;\n var autoCropArea = Number(options.autoCropArea) || 0.8;\n var cropBoxData = {\n width: canvasData.width,\n height: canvasData.height\n };\n if (aspectRatio) {\n if (canvasData.height * aspectRatio > canvasData.width) {\n cropBoxData.height = cropBoxData.width / aspectRatio;\n } else {\n cropBoxData.width = cropBoxData.height * aspectRatio;\n }\n }\n this.cropBoxData = cropBoxData;\n this.limitCropBox(true, true);\n\n // Initialize auto crop area\n cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);\n cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);\n\n // The width/height of auto crop area must large than \"minWidth/Height\"\n cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);\n cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);\n cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;\n cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;\n cropBoxData.oldLeft = cropBoxData.left;\n cropBoxData.oldTop = cropBoxData.top;\n this.initialCropBoxData = assign({}, cropBoxData);\n },\n limitCropBox: function limitCropBox(sizeLimited, positionLimited) {\n var options = this.options,\n containerData = this.containerData,\n canvasData = this.canvasData,\n cropBoxData = this.cropBoxData,\n limited = this.limited;\n var aspectRatio = options.aspectRatio;\n if (sizeLimited) {\n var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;\n var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;\n var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;\n var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height;\n\n // The min/maxCropBoxWidth/Height must be less than container's width/height\n minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);\n minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);\n if (aspectRatio) {\n if (minCropBoxWidth && minCropBoxHeight) {\n if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {\n minCropBoxHeight = minCropBoxWidth / aspectRatio;\n } else {\n minCropBoxWidth = minCropBoxHeight * aspectRatio;\n }\n } else if (minCropBoxWidth) {\n minCropBoxHeight = minCropBoxWidth / aspectRatio;\n } else if (minCropBoxHeight) {\n minCropBoxWidth = minCropBoxHeight * aspectRatio;\n }\n if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {\n maxCropBoxHeight = maxCropBoxWidth / aspectRatio;\n } else {\n maxCropBoxWidth = maxCropBoxHeight * aspectRatio;\n }\n }\n\n // The minWidth/Height must be less than maxWidth/Height\n cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);\n cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);\n cropBoxData.maxWidth = maxCropBoxWidth;\n cropBoxData.maxHeight = maxCropBoxHeight;\n }\n if (positionLimited) {\n if (limited) {\n cropBoxData.minLeft = Math.max(0, canvasData.left);\n cropBoxData.minTop = Math.max(0, canvasData.top);\n cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;\n cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;\n } else {\n cropBoxData.minLeft = 0;\n cropBoxData.minTop = 0;\n cropBoxData.maxLeft = containerData.width - cropBoxData.width;\n cropBoxData.maxTop = containerData.height - cropBoxData.height;\n }\n }\n },\n renderCropBox: function renderCropBox() {\n var options = this.options,\n containerData = this.containerData,\n cropBoxData = this.cropBoxData;\n if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {\n cropBoxData.left = cropBoxData.oldLeft;\n }\n if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {\n cropBoxData.top = cropBoxData.oldTop;\n }\n cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);\n cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);\n this.limitCropBox(false, true);\n cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);\n cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);\n cropBoxData.oldLeft = cropBoxData.left;\n cropBoxData.oldTop = cropBoxData.top;\n if (options.movable && options.cropBoxMovable) {\n // Turn to move the canvas when the crop box is equal to the container\n setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);\n }\n setStyle(this.cropBox, assign({\n width: cropBoxData.width,\n height: cropBoxData.height\n }, getTransforms({\n translateX: cropBoxData.left,\n translateY: cropBoxData.top\n })));\n if (this.cropped && this.limited) {\n this.limitCanvas(true, true);\n }\n if (!this.disabled) {\n this.output();\n }\n },\n output: function output() {\n this.preview();\n dispatchEvent(this.element, EVENT_CROP, this.getData());\n }\n };\n var preview = {\n initPreview: function initPreview() {\n var element = this.element,\n crossOrigin = this.crossOrigin;\n var preview = this.options.preview;\n var url = crossOrigin ? this.crossOriginUrl : this.url;\n var alt = element.alt || 'The image to preview';\n var image = document.createElement('img');\n if (crossOrigin) {\n image.crossOrigin = crossOrigin;\n }\n image.src = url;\n image.alt = alt;\n this.viewBox.appendChild(image);\n this.viewBoxImage = image;\n if (!preview) {\n return;\n }\n var previews = preview;\n if (typeof preview === 'string') {\n previews = element.ownerDocument.querySelectorAll(preview);\n } else if (preview.querySelector) {\n previews = [preview];\n }\n this.previews = previews;\n forEach(previews, function (el) {\n var img = document.createElement('img');\n\n // Save the original size for recover\n setData(el, DATA_PREVIEW, {\n width: el.offsetWidth,\n height: el.offsetHeight,\n html: el.innerHTML\n });\n if (crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n img.src = url;\n img.alt = alt;\n\n /**\n * Override img element styles\n * Add `display:block` to avoid margin top issue\n * Add `height:auto` to override `height` attribute on IE8\n * (Occur only when margin-top <= -height)\n */\n img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;\"';\n el.innerHTML = '';\n el.appendChild(img);\n });\n },\n resetPreview: function resetPreview() {\n forEach(this.previews, function (element) {\n var data = getData(element, DATA_PREVIEW);\n setStyle(element, {\n width: data.width,\n height: data.height\n });\n element.innerHTML = data.html;\n removeData(element, DATA_PREVIEW);\n });\n },\n preview: function preview() {\n var imageData = this.imageData,\n canvasData = this.canvasData,\n cropBoxData = this.cropBoxData;\n var cropBoxWidth = cropBoxData.width,\n cropBoxHeight = cropBoxData.height;\n var width = imageData.width,\n height = imageData.height;\n var left = cropBoxData.left - canvasData.left - imageData.left;\n var top = cropBoxData.top - canvasData.top - imageData.top;\n if (!this.cropped || this.disabled) {\n return;\n }\n setStyle(this.viewBoxImage, assign({\n width: width,\n height: height\n }, getTransforms(assign({\n translateX: -left,\n translateY: -top\n }, imageData))));\n forEach(this.previews, function (element) {\n var data = getData(element, DATA_PREVIEW);\n var originalWidth = data.width;\n var originalHeight = data.height;\n var newWidth = originalWidth;\n var newHeight = originalHeight;\n var ratio = 1;\n if (cropBoxWidth) {\n ratio = originalWidth / cropBoxWidth;\n newHeight = cropBoxHeight * ratio;\n }\n if (cropBoxHeight && newHeight > originalHeight) {\n ratio = originalHeight / cropBoxHeight;\n newWidth = cropBoxWidth * ratio;\n newHeight = originalHeight;\n }\n setStyle(element, {\n width: newWidth,\n height: newHeight\n });\n setStyle(element.getElementsByTagName('img')[0], assign({\n width: width * ratio,\n height: height * ratio\n }, getTransforms(assign({\n translateX: -left * ratio,\n translateY: -top * ratio\n }, imageData))));\n });\n }\n };\n var events = {\n bind: function bind() {\n var element = this.element,\n options = this.options,\n cropper = this.cropper;\n if (isFunction(options.cropstart)) {\n addListener(element, EVENT_CROP_START, options.cropstart);\n }\n if (isFunction(options.cropmove)) {\n addListener(element, EVENT_CROP_MOVE, options.cropmove);\n }\n if (isFunction(options.cropend)) {\n addListener(element, EVENT_CROP_END, options.cropend);\n }\n if (isFunction(options.crop)) {\n addListener(element, EVENT_CROP, options.crop);\n }\n if (isFunction(options.zoom)) {\n addListener(element, EVENT_ZOOM, options.zoom);\n }\n addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));\n if (options.zoomable && options.zoomOnWheel) {\n addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {\n passive: false,\n capture: true\n });\n }\n if (options.toggleDragModeOnDblclick) {\n addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));\n }\n addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this));\n addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this));\n if (options.responsive) {\n addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));\n }\n },\n unbind: function unbind() {\n var element = this.element,\n options = this.options,\n cropper = this.cropper;\n if (isFunction(options.cropstart)) {\n removeListener(element, EVENT_CROP_START, options.cropstart);\n }\n if (isFunction(options.cropmove)) {\n removeListener(element, EVENT_CROP_MOVE, options.cropmove);\n }\n if (isFunction(options.cropend)) {\n removeListener(element, EVENT_CROP_END, options.cropend);\n }\n if (isFunction(options.crop)) {\n removeListener(element, EVENT_CROP, options.crop);\n }\n if (isFunction(options.zoom)) {\n removeListener(element, EVENT_ZOOM, options.zoom);\n }\n removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);\n if (options.zoomable && options.zoomOnWheel) {\n removeListener(cropper, EVENT_WHEEL, this.onWheel, {\n passive: false,\n capture: true\n });\n }\n if (options.toggleDragModeOnDblclick) {\n removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);\n }\n removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);\n removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);\n if (options.responsive) {\n removeListener(window, EVENT_RESIZE, this.onResize);\n }\n }\n };\n var handlers = {\n resize: function resize() {\n if (this.disabled) {\n return;\n }\n var options = this.options,\n container = this.container,\n containerData = this.containerData;\n var ratioX = container.offsetWidth / containerData.width;\n var ratioY = container.offsetHeight / containerData.height;\n var ratio = Math.abs(ratioX - 1) > Math.abs(ratioY - 1) ? ratioX : ratioY;\n\n // Resize when width changed or height changed\n if (ratio !== 1) {\n var canvasData;\n var cropBoxData;\n if (options.restore) {\n canvasData = this.getCanvasData();\n cropBoxData = this.getCropBoxData();\n }\n this.render();\n if (options.restore) {\n this.setCanvasData(forEach(canvasData, function (n, i) {\n canvasData[i] = n * ratio;\n }));\n this.setCropBoxData(forEach(cropBoxData, function (n, i) {\n cropBoxData[i] = n * ratio;\n }));\n }\n }\n },\n dblclick: function dblclick() {\n if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {\n return;\n }\n this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);\n },\n wheel: function wheel(event) {\n var _this = this;\n var ratio = Number(this.options.wheelZoomRatio) || 0.1;\n var delta = 1;\n if (this.disabled) {\n return;\n }\n event.preventDefault();\n\n // Limit wheel speed to prevent zoom too fast (#21)\n if (this.wheeling) {\n return;\n }\n this.wheeling = true;\n setTimeout(function () {\n _this.wheeling = false;\n }, 50);\n if (event.deltaY) {\n delta = event.deltaY > 0 ? 1 : -1;\n } else if (event.wheelDelta) {\n delta = -event.wheelDelta / 120;\n } else if (event.detail) {\n delta = event.detail > 0 ? 1 : -1;\n }\n this.zoom(-delta * ratio, event);\n },\n cropStart: function cropStart(event) {\n var buttons = event.buttons,\n button = event.button;\n if (this.disabled\n\n // Handle mouse event and pointer event and ignore touch event\n || (event.type === 'mousedown' || event.type === 'pointerdown' && event.pointerType === 'mouse') && (\n // No primary button (Usually the left button)\n isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0\n\n // Open context menu\n || event.ctrlKey)) {\n return;\n }\n var options = this.options,\n pointers = this.pointers;\n var action;\n if (event.changedTouches) {\n // Handle touch event\n forEach(event.changedTouches, function (touch) {\n pointers[touch.identifier] = getPointer(touch);\n });\n } else {\n // Handle mouse event and pointer event\n pointers[event.pointerId || 0] = getPointer(event);\n }\n if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {\n action = ACTION_ZOOM;\n } else {\n action = getData(event.target, DATA_ACTION);\n }\n if (!REGEXP_ACTIONS.test(action)) {\n return;\n }\n if (dispatchEvent(this.element, EVENT_CROP_START, {\n originalEvent: event,\n action: action\n }) === false) {\n return;\n }\n\n // This line is required for preventing page zooming in iOS browsers\n event.preventDefault();\n this.action = action;\n this.cropping = false;\n if (action === ACTION_CROP) {\n this.cropping = true;\n addClass(this.dragBox, CLASS_MODAL);\n }\n },\n cropMove: function cropMove(event) {\n var action = this.action;\n if (this.disabled || !action) {\n return;\n }\n var pointers = this.pointers;\n event.preventDefault();\n if (dispatchEvent(this.element, EVENT_CROP_MOVE, {\n originalEvent: event,\n action: action\n }) === false) {\n return;\n }\n if (event.changedTouches) {\n forEach(event.changedTouches, function (touch) {\n // The first parameter should not be undefined (#432)\n assign(pointers[touch.identifier] || {}, getPointer(touch, true));\n });\n } else {\n assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));\n }\n this.change(event);\n },\n cropEnd: function cropEnd(event) {\n if (this.disabled) {\n return;\n }\n var action = this.action,\n pointers = this.pointers;\n if (event.changedTouches) {\n forEach(event.changedTouches, function (touch) {\n delete pointers[touch.identifier];\n });\n } else {\n delete pointers[event.pointerId || 0];\n }\n if (!action) {\n return;\n }\n event.preventDefault();\n if (!Object.keys(pointers).length) {\n this.action = '';\n }\n if (this.cropping) {\n this.cropping = false;\n toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);\n }\n dispatchEvent(this.element, EVENT_CROP_END, {\n originalEvent: event,\n action: action\n });\n }\n };\n var change = {\n change: function change(event) {\n var options = this.options,\n canvasData = this.canvasData,\n containerData = this.containerData,\n cropBoxData = this.cropBoxData,\n pointers = this.pointers;\n var action = this.action;\n var aspectRatio = options.aspectRatio;\n var left = cropBoxData.left,\n top = cropBoxData.top,\n width = cropBoxData.width,\n height = cropBoxData.height;\n var right = left + width;\n var bottom = top + height;\n var minLeft = 0;\n var minTop = 0;\n var maxWidth = containerData.width;\n var maxHeight = containerData.height;\n var renderable = true;\n var offset;\n\n // Locking aspect ratio in \"free mode\" by holding shift key\n if (!aspectRatio && event.shiftKey) {\n aspectRatio = width && height ? width / height : 1;\n }\n if (this.limited) {\n minLeft = cropBoxData.minLeft;\n minTop = cropBoxData.minTop;\n maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);\n maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);\n }\n var pointer = pointers[Object.keys(pointers)[0]];\n var range = {\n x: pointer.endX - pointer.startX,\n y: pointer.endY - pointer.startY\n };\n var check = function check(side) {\n switch (side) {\n case ACTION_EAST:\n if (right + range.x > maxWidth) {\n range.x = maxWidth - right;\n }\n break;\n case ACTION_WEST:\n if (left + range.x < minLeft) {\n range.x = minLeft - left;\n }\n break;\n case ACTION_NORTH:\n if (top + range.y < minTop) {\n range.y = minTop - top;\n }\n break;\n case ACTION_SOUTH:\n if (bottom + range.y > maxHeight) {\n range.y = maxHeight - bottom;\n }\n break;\n }\n };\n switch (action) {\n // Move crop box\n case ACTION_ALL:\n left += range.x;\n top += range.y;\n break;\n\n // Resize crop box\n case ACTION_EAST:\n if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {\n renderable = false;\n break;\n }\n check(ACTION_EAST);\n width += range.x;\n if (width < 0) {\n action = ACTION_WEST;\n width = -width;\n left -= width;\n }\n if (aspectRatio) {\n height = width / aspectRatio;\n top += (cropBoxData.height - height) / 2;\n }\n break;\n case ACTION_NORTH:\n if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {\n renderable = false;\n break;\n }\n check(ACTION_NORTH);\n height -= range.y;\n top += range.y;\n if (height < 0) {\n action = ACTION_SOUTH;\n height = -height;\n top -= height;\n }\n if (aspectRatio) {\n width = height * aspectRatio;\n left += (cropBoxData.width - width) / 2;\n }\n break;\n case ACTION_WEST:\n if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {\n renderable = false;\n break;\n }\n check(ACTION_WEST);\n width -= range.x;\n left += range.x;\n if (width < 0) {\n action = ACTION_EAST;\n width = -width;\n left -= width;\n }\n if (aspectRatio) {\n height = width / aspectRatio;\n top += (cropBoxData.height - height) / 2;\n }\n break;\n case ACTION_SOUTH:\n if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {\n renderable = false;\n break;\n }\n check(ACTION_SOUTH);\n height += range.y;\n if (height < 0) {\n action = ACTION_NORTH;\n height = -height;\n top -= height;\n }\n if (aspectRatio) {\n width = height * aspectRatio;\n left += (cropBoxData.width - width) / 2;\n }\n break;\n case ACTION_NORTH_EAST:\n if (aspectRatio) {\n if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {\n renderable = false;\n break;\n }\n check(ACTION_NORTH);\n height -= range.y;\n top += range.y;\n width = height * aspectRatio;\n } else {\n check(ACTION_NORTH);\n check(ACTION_EAST);\n if (range.x >= 0) {\n if (right < maxWidth) {\n width += range.x;\n } else if (range.y <= 0 && top <= minTop) {\n renderable = false;\n }\n } else {\n width += range.x;\n }\n if (range.y <= 0) {\n if (top > minTop) {\n height -= range.y;\n top += range.y;\n }\n } else {\n height -= range.y;\n top += range.y;\n }\n }\n if (width < 0 && height < 0) {\n action = ACTION_SOUTH_WEST;\n height = -height;\n width = -width;\n top -= height;\n left -= width;\n } else if (width < 0) {\n action = ACTION_NORTH_WEST;\n width = -width;\n left -= width;\n } else if (height < 0) {\n action = ACTION_SOUTH_EAST;\n height = -height;\n top -= height;\n }\n break;\n case ACTION_NORTH_WEST:\n if (aspectRatio) {\n if (range.y <= 0 && (top <= minTop || left <= minLeft)) {\n renderable = false;\n break;\n }\n check(ACTION_NORTH);\n height -= range.y;\n top += range.y;\n width = height * aspectRatio;\n left += cropBoxData.width - width;\n } else {\n check(ACTION_NORTH);\n check(ACTION_WEST);\n if (range.x <= 0) {\n if (left > minLeft) {\n width -= range.x;\n left += range.x;\n } else if (range.y <= 0 && top <= minTop) {\n renderable = false;\n }\n } else {\n width -= range.x;\n left += range.x;\n }\n if (range.y <= 0) {\n if (top > minTop) {\n height -= range.y;\n top += range.y;\n }\n } else {\n height -= range.y;\n top += range.y;\n }\n }\n if (width < 0 && height < 0) {\n action = ACTION_SOUTH_EAST;\n height = -height;\n width = -width;\n top -= height;\n left -= width;\n } else if (width < 0) {\n action = ACTION_NORTH_EAST;\n width = -width;\n left -= width;\n } else if (height < 0) {\n action = ACTION_SOUTH_WEST;\n height = -height;\n top -= height;\n }\n break;\n case ACTION_SOUTH_WEST:\n if (aspectRatio) {\n if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {\n renderable = false;\n break;\n }\n check(ACTION_WEST);\n width -= range.x;\n left += range.x;\n height = width / aspectRatio;\n } else {\n check(ACTION_SOUTH);\n check(ACTION_WEST);\n if (range.x <= 0) {\n if (left > minLeft) {\n width -= range.x;\n left += range.x;\n } else if (range.y >= 0 && bottom >= maxHeight) {\n renderable = false;\n }\n } else {\n width -= range.x;\n left += range.x;\n }\n if (range.y >= 0) {\n if (bottom < maxHeight) {\n height += range.y;\n }\n } else {\n height += range.y;\n }\n }\n if (width < 0 && height < 0) {\n action = ACTION_NORTH_EAST;\n height = -height;\n width = -width;\n top -= height;\n left -= width;\n } else if (width < 0) {\n action = ACTION_SOUTH_EAST;\n width = -width;\n left -= width;\n } else if (height < 0) {\n action = ACTION_NORTH_WEST;\n height = -height;\n top -= height;\n }\n break;\n case ACTION_SOUTH_EAST:\n if (aspectRatio) {\n if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {\n renderable = false;\n break;\n }\n check(ACTION_EAST);\n width += range.x;\n height = width / aspectRatio;\n } else {\n check(ACTION_SOUTH);\n check(ACTION_EAST);\n if (range.x >= 0) {\n if (right < maxWidth) {\n width += range.x;\n } else if (range.y >= 0 && bottom >= maxHeight) {\n renderable = false;\n }\n } else {\n width += range.x;\n }\n if (range.y >= 0) {\n if (bottom < maxHeight) {\n height += range.y;\n }\n } else {\n height += range.y;\n }\n }\n if (width < 0 && height < 0) {\n action = ACTION_NORTH_WEST;\n height = -height;\n width = -width;\n top -= height;\n left -= width;\n } else if (width < 0) {\n action = ACTION_SOUTH_WEST;\n width = -width;\n left -= width;\n } else if (height < 0) {\n action = ACTION_NORTH_EAST;\n height = -height;\n top -= height;\n }\n break;\n\n // Move canvas\n case ACTION_MOVE:\n this.move(range.x, range.y);\n renderable = false;\n break;\n\n // Zoom canvas\n case ACTION_ZOOM:\n this.zoom(getMaxZoomRatio(pointers), event);\n renderable = false;\n break;\n\n // Create crop box\n case ACTION_CROP:\n if (!range.x || !range.y) {\n renderable = false;\n break;\n }\n offset = getOffset(this.cropper);\n left = pointer.startX - offset.left;\n top = pointer.startY - offset.top;\n width = cropBoxData.minWidth;\n height = cropBoxData.minHeight;\n if (range.x > 0) {\n action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;\n } else if (range.x < 0) {\n left -= width;\n action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;\n }\n if (range.y < 0) {\n top -= height;\n }\n\n // Show the crop box if is hidden\n if (!this.cropped) {\n removeClass(this.cropBox, CLASS_HIDDEN);\n this.cropped = true;\n if (this.limited) {\n this.limitCropBox(true, true);\n }\n }\n break;\n }\n if (renderable) {\n cropBoxData.width = width;\n cropBoxData.height = height;\n cropBoxData.left = left;\n cropBoxData.top = top;\n this.action = action;\n this.renderCropBox();\n }\n\n // Override\n forEach(pointers, function (p) {\n p.startX = p.endX;\n p.startY = p.endY;\n });\n }\n };\n var methods = {\n // Show the crop box manually\n crop: function crop() {\n if (this.ready && !this.cropped && !this.disabled) {\n this.cropped = true;\n this.limitCropBox(true, true);\n if (this.options.modal) {\n addClass(this.dragBox, CLASS_MODAL);\n }\n removeClass(this.cropBox, CLASS_HIDDEN);\n this.setCropBoxData(this.initialCropBoxData);\n }\n return this;\n },\n // Reset the image and crop box to their initial states\n reset: function reset() {\n if (this.ready && !this.disabled) {\n this.imageData = assign({}, this.initialImageData);\n this.canvasData = assign({}, this.initialCanvasData);\n this.cropBoxData = assign({}, this.initialCropBoxData);\n this.renderCanvas();\n if (this.cropped) {\n this.renderCropBox();\n }\n }\n return this;\n },\n // Clear the crop box\n clear: function clear() {\n if (this.cropped && !this.disabled) {\n assign(this.cropBoxData, {\n left: 0,\n top: 0,\n width: 0,\n height: 0\n });\n this.cropped = false;\n this.renderCropBox();\n this.limitCanvas(true, true);\n\n // Render canvas after crop box rendered\n this.renderCanvas();\n removeClass(this.dragBox, CLASS_MODAL);\n addClass(this.cropBox, CLASS_HIDDEN);\n }\n return this;\n },\n /**\n * Replace the image's src and rebuild the cropper\n * @param {string} url - The new URL.\n * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one.\n * @returns {Cropper} this\n */\n replace: function replace(url) {\n var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n if (!this.disabled && url) {\n if (this.isImg) {\n this.element.src = url;\n }\n if (hasSameSize) {\n this.url = url;\n this.image.src = url;\n if (this.ready) {\n this.viewBoxImage.src = url;\n forEach(this.previews, function (element) {\n element.getElementsByTagName('img')[0].src = url;\n });\n }\n } else {\n if (this.isImg) {\n this.replaced = true;\n }\n this.options.data = null;\n this.uncreate();\n this.load(url);\n }\n }\n return this;\n },\n // Enable (unfreeze) the cropper\n enable: function enable() {\n if (this.ready && this.disabled) {\n this.disabled = false;\n removeClass(this.cropper, CLASS_DISABLED);\n }\n return this;\n },\n // Disable (freeze) the cropper\n disable: function disable() {\n if (this.ready && !this.disabled) {\n this.disabled = true;\n addClass(this.cropper, CLASS_DISABLED);\n }\n return this;\n },\n /**\n * Destroy the cropper and remove the instance from the image\n * @returns {Cropper} this\n */\n destroy: function destroy() {\n var element = this.element;\n if (!element[NAMESPACE]) {\n return this;\n }\n element[NAMESPACE] = undefined;\n if (this.isImg && this.replaced) {\n element.src = this.originalUrl;\n }\n this.uncreate();\n return this;\n },\n /**\n * Move the canvas with relative offsets\n * @param {number} offsetX - The relative offset distance on the x-axis.\n * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis.\n * @returns {Cropper} this\n */\n move: function move(offsetX) {\n var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;\n var _this$canvasData = this.canvasData,\n left = _this$canvasData.left,\n top = _this$canvasData.top;\n return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));\n },\n /**\n * Move the canvas to an absolute point\n * @param {number} x - The x-axis coordinate.\n * @param {number} [y=x] - The y-axis coordinate.\n * @returns {Cropper} this\n */\n moveTo: function moveTo(x) {\n var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;\n var canvasData = this.canvasData;\n var changed = false;\n x = Number(x);\n y = Number(y);\n if (this.ready && !this.disabled && this.options.movable) {\n if (isNumber(x)) {\n canvasData.left = x;\n changed = true;\n }\n if (isNumber(y)) {\n canvasData.top = y;\n changed = true;\n }\n if (changed) {\n this.renderCanvas(true);\n }\n }\n return this;\n },\n /**\n * Zoom the canvas with a relative ratio\n * @param {number} ratio - The target ratio.\n * @param {Event} _originalEvent - The original event if any.\n * @returns {Cropper} this\n */\n zoom: function zoom(ratio, _originalEvent) {\n var canvasData = this.canvasData;\n ratio = Number(ratio);\n if (ratio < 0) {\n ratio = 1 / (1 - ratio);\n } else {\n ratio = 1 + ratio;\n }\n return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);\n },\n /**\n * Zoom the canvas to an absolute ratio\n * @param {number} ratio - The target ratio.\n * @param {Object} pivot - The zoom pivot point coordinate.\n * @param {Event} _originalEvent - The original event if any.\n * @returns {Cropper} this\n */\n zoomTo: function zoomTo(ratio, pivot, _originalEvent) {\n var options = this.options,\n canvasData = this.canvasData;\n var width = canvasData.width,\n height = canvasData.height,\n naturalWidth = canvasData.naturalWidth,\n naturalHeight = canvasData.naturalHeight;\n ratio = Number(ratio);\n if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {\n var newWidth = naturalWidth * ratio;\n var newHeight = naturalHeight * ratio;\n if (dispatchEvent(this.element, EVENT_ZOOM, {\n ratio: ratio,\n oldRatio: width / naturalWidth,\n originalEvent: _originalEvent\n }) === false) {\n return this;\n }\n if (_originalEvent) {\n var pointers = this.pointers;\n var offset = getOffset(this.cropper);\n var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {\n pageX: _originalEvent.pageX,\n pageY: _originalEvent.pageY\n };\n\n // Zoom from the triggering point of the event\n canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);\n canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);\n } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {\n canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);\n canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);\n } else {\n // Zoom from the center of the canvas\n canvasData.left -= (newWidth - width) / 2;\n canvasData.top -= (newHeight - height) / 2;\n }\n canvasData.width = newWidth;\n canvasData.height = newHeight;\n this.renderCanvas(true);\n }\n return this;\n },\n /**\n * Rotate the canvas with a relative degree\n * @param {number} degree - The rotate degree.\n * @returns {Cropper} this\n */\n rotate: function rotate(degree) {\n return this.rotateTo((this.imageData.rotate || 0) + Number(degree));\n },\n /**\n * Rotate the canvas to an absolute degree\n * @param {number} degree - The rotate degree.\n * @returns {Cropper} this\n */\n rotateTo: function rotateTo(degree) {\n degree = Number(degree);\n if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {\n this.imageData.rotate = degree % 360;\n this.renderCanvas(true, true);\n }\n return this;\n },\n /**\n * Scale the image on the x-axis.\n * @param {number} scaleX - The scale ratio on the x-axis.\n * @returns {Cropper} this\n */\n scaleX: function scaleX(_scaleX) {\n var scaleY = this.imageData.scaleY;\n return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);\n },\n /**\n * Scale the image on the y-axis.\n * @param {number} scaleY - The scale ratio on the y-axis.\n * @returns {Cropper} this\n */\n scaleY: function scaleY(_scaleY) {\n var scaleX = this.imageData.scaleX;\n return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);\n },\n /**\n * Scale the image\n * @param {number} scaleX - The scale ratio on the x-axis.\n * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.\n * @returns {Cropper} this\n */\n scale: function scale(scaleX) {\n var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;\n var imageData = this.imageData;\n var transformed = false;\n scaleX = Number(scaleX);\n scaleY = Number(scaleY);\n if (this.ready && !this.disabled && this.options.scalable) {\n if (isNumber(scaleX)) {\n imageData.scaleX = scaleX;\n transformed = true;\n }\n if (isNumber(scaleY)) {\n imageData.scaleY = scaleY;\n transformed = true;\n }\n if (transformed) {\n this.renderCanvas(true, true);\n }\n }\n return this;\n },\n /**\n * Get the cropped area position and size data (base on the original image)\n * @param {boolean} [rounded=false] - Indicate if round the data values or not.\n * @returns {Object} The result cropped data.\n */\n getData: function getData() {\n var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n var options = this.options,\n imageData = this.imageData,\n canvasData = this.canvasData,\n cropBoxData = this.cropBoxData;\n var data;\n if (this.ready && this.cropped) {\n data = {\n x: cropBoxData.left - canvasData.left,\n y: cropBoxData.top - canvasData.top,\n width: cropBoxData.width,\n height: cropBoxData.height\n };\n var ratio = imageData.width / imageData.naturalWidth;\n forEach(data, function (n, i) {\n data[i] = n / ratio;\n });\n if (rounded) {\n // In case rounding off leads to extra 1px in right or bottom border\n // we should round the top-left corner and the dimension (#343).\n var bottom = Math.round(data.y + data.height);\n var right = Math.round(data.x + data.width);\n data.x = Math.round(data.x);\n data.y = Math.round(data.y);\n data.width = right - data.x;\n data.height = bottom - data.y;\n }\n } else {\n data = {\n x: 0,\n y: 0,\n width: 0,\n height: 0\n };\n }\n if (options.rotatable) {\n data.rotate = imageData.rotate || 0;\n }\n if (options.scalable) {\n data.scaleX = imageData.scaleX || 1;\n data.scaleY = imageData.scaleY || 1;\n }\n return data;\n },\n /**\n * Set the cropped area position and size with new data\n * @param {Object} data - The new data.\n * @returns {Cropper} this\n */\n setData: function setData(data) {\n var options = this.options,\n imageData = this.imageData,\n canvasData = this.canvasData;\n var cropBoxData = {};\n if (this.ready && !this.disabled && isPlainObject(data)) {\n var transformed = false;\n if (options.rotatable) {\n if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {\n imageData.rotate = data.rotate;\n transformed = true;\n }\n }\n if (options.scalable) {\n if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {\n imageData.scaleX = data.scaleX;\n transformed = true;\n }\n if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {\n imageData.scaleY = data.scaleY;\n transformed = true;\n }\n }\n if (transformed) {\n this.renderCanvas(true, true);\n }\n var ratio = imageData.width / imageData.naturalWidth;\n if (isNumber(data.x)) {\n cropBoxData.left = data.x * ratio + canvasData.left;\n }\n if (isNumber(data.y)) {\n cropBoxData.top = data.y * ratio + canvasData.top;\n }\n if (isNumber(data.width)) {\n cropBoxData.width = data.width * ratio;\n }\n if (isNumber(data.height)) {\n cropBoxData.height = data.height * ratio;\n }\n this.setCropBoxData(cropBoxData);\n }\n return this;\n },\n /**\n * Get the container size data.\n * @returns {Object} The result container data.\n */\n getContainerData: function getContainerData() {\n return this.ready ? assign({}, this.containerData) : {};\n },\n /**\n * Get the image position and size data.\n * @returns {Object} The result image data.\n */\n getImageData: function getImageData() {\n return this.sized ? assign({}, this.imageData) : {};\n },\n /**\n * Get the canvas position and size data.\n * @returns {Object} The result canvas data.\n */\n getCanvasData: function getCanvasData() {\n var canvasData = this.canvasData;\n var data = {};\n if (this.ready) {\n forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {\n data[n] = canvasData[n];\n });\n }\n return data;\n },\n /**\n * Set the canvas position and size with new data.\n * @param {Object} data - The new canvas data.\n * @returns {Cropper} this\n */\n setCanvasData: function setCanvasData(data) {\n var canvasData = this.canvasData;\n var aspectRatio = canvasData.aspectRatio;\n if (this.ready && !this.disabled && isPlainObject(data)) {\n if (isNumber(data.left)) {\n canvasData.left = data.left;\n }\n if (isNumber(data.top)) {\n canvasData.top = data.top;\n }\n if (isNumber(data.width)) {\n canvasData.width = data.width;\n canvasData.height = data.width / aspectRatio;\n } else if (isNumber(data.height)) {\n canvasData.height = data.height;\n canvasData.width = data.height * aspectRatio;\n }\n this.renderCanvas(true);\n }\n return this;\n },\n /**\n * Get the crop box position and size data.\n * @returns {Object} The result crop box data.\n */\n getCropBoxData: function getCropBoxData() {\n var cropBoxData = this.cropBoxData;\n var data;\n if (this.ready && this.cropped) {\n data = {\n left: cropBoxData.left,\n top: cropBoxData.top,\n width: cropBoxData.width,\n height: cropBoxData.height\n };\n }\n return data || {};\n },\n /**\n * Set the crop box position and size with new data.\n * @param {Object} data - The new crop box data.\n * @returns {Cropper} this\n */\n setCropBoxData: function setCropBoxData(data) {\n var cropBoxData = this.cropBoxData;\n var aspectRatio = this.options.aspectRatio;\n var widthChanged;\n var heightChanged;\n if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {\n if (isNumber(data.left)) {\n cropBoxData.left = data.left;\n }\n if (isNumber(data.top)) {\n cropBoxData.top = data.top;\n }\n if (isNumber(data.width) && data.width !== cropBoxData.width) {\n widthChanged = true;\n cropBoxData.width = data.width;\n }\n if (isNumber(data.height) && data.height !== cropBoxData.height) {\n heightChanged = true;\n cropBoxData.height = data.height;\n }\n if (aspectRatio) {\n if (widthChanged) {\n cropBoxData.height = cropBoxData.width / aspectRatio;\n } else if (heightChanged) {\n cropBoxData.width = cropBoxData.height * aspectRatio;\n }\n }\n this.renderCropBox();\n }\n return this;\n },\n /**\n * Get a canvas drawn the cropped image.\n * @param {Object} [options={}] - The config options.\n * @returns {HTMLCanvasElement} - The result canvas.\n */\n getCroppedCanvas: function getCroppedCanvas() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (!this.ready || !window.HTMLCanvasElement) {\n return null;\n }\n var canvasData = this.canvasData;\n var source = getSourceCanvas(this.image, this.imageData, canvasData, options);\n\n // Returns the source canvas if it is not cropped.\n if (!this.cropped) {\n return source;\n }\n var _this$getData = this.getData(),\n initialX = _this$getData.x,\n initialY = _this$getData.y,\n initialWidth = _this$getData.width,\n initialHeight = _this$getData.height;\n var ratio = source.width / Math.floor(canvasData.naturalWidth);\n if (ratio !== 1) {\n initialX *= ratio;\n initialY *= ratio;\n initialWidth *= ratio;\n initialHeight *= ratio;\n }\n var aspectRatio = initialWidth / initialHeight;\n var maxSizes = getAdjustedSizes({\n aspectRatio: aspectRatio,\n width: options.maxWidth || Infinity,\n height: options.maxHeight || Infinity\n });\n var minSizes = getAdjustedSizes({\n aspectRatio: aspectRatio,\n width: options.minWidth || 0,\n height: options.minHeight || 0\n }, 'cover');\n var _getAdjustedSizes = getAdjustedSizes({\n aspectRatio: aspectRatio,\n width: options.width || (ratio !== 1 ? source.width : initialWidth),\n height: options.height || (ratio !== 1 ? source.height : initialHeight)\n }),\n width = _getAdjustedSizes.width,\n height = _getAdjustedSizes.height;\n width = Math.min(maxSizes.width, Math.max(minSizes.width, width));\n height = Math.min(maxSizes.height, Math.max(minSizes.height, height));\n var canvas = document.createElement('canvas');\n var context = canvas.getContext('2d');\n canvas.width = normalizeDecimalNumber(width);\n canvas.height = normalizeDecimalNumber(height);\n context.fillStyle = options.fillColor || 'transparent';\n context.fillRect(0, 0, width, height);\n var _options$imageSmoothi = options.imageSmoothingEnabled,\n imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,\n imageSmoothingQuality = options.imageSmoothingQuality;\n context.imageSmoothingEnabled = imageSmoothingEnabled;\n if (imageSmoothingQuality) {\n context.imageSmoothingQuality = imageSmoothingQuality;\n }\n\n // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage\n var sourceWidth = source.width;\n var sourceHeight = source.height;\n\n // Source canvas parameters\n var srcX = initialX;\n var srcY = initialY;\n var srcWidth;\n var srcHeight;\n\n // Destination canvas parameters\n var dstX;\n var dstY;\n var dstWidth;\n var dstHeight;\n if (srcX <= -initialWidth || srcX > sourceWidth) {\n srcX = 0;\n srcWidth = 0;\n dstX = 0;\n dstWidth = 0;\n } else if (srcX <= 0) {\n dstX = -srcX;\n srcX = 0;\n srcWidth = Math.min(sourceWidth, initialWidth + srcX);\n dstWidth = srcWidth;\n } else if (srcX <= sourceWidth) {\n dstX = 0;\n srcWidth = Math.min(initialWidth, sourceWidth - srcX);\n dstWidth = srcWidth;\n }\n if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {\n srcY = 0;\n srcHeight = 0;\n dstY = 0;\n dstHeight = 0;\n } else if (srcY <= 0) {\n dstY = -srcY;\n srcY = 0;\n srcHeight = Math.min(sourceHeight, initialHeight + srcY);\n dstHeight = srcHeight;\n } else if (srcY <= sourceHeight) {\n dstY = 0;\n srcHeight = Math.min(initialHeight, sourceHeight - srcY);\n dstHeight = srcHeight;\n }\n var params = [srcX, srcY, srcWidth, srcHeight];\n\n // Avoid \"IndexSizeError\"\n if (dstWidth > 0 && dstHeight > 0) {\n var scale = width / initialWidth;\n params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);\n }\n\n // All the numerical parameters should be integer for `drawImage`\n // https://github.com/fengyuanchen/cropper/issues/476\n context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {\n return Math.floor(normalizeDecimalNumber(param));\n }))));\n return canvas;\n },\n /**\n * Change the aspect ratio of the crop box.\n * @param {number} aspectRatio - The new aspect ratio.\n * @returns {Cropper} this\n */\n setAspectRatio: function setAspectRatio(aspectRatio) {\n var options = this.options;\n if (!this.disabled && !isUndefined(aspectRatio)) {\n // 0 -> NaN\n options.aspectRatio = Math.max(0, aspectRatio) || NaN;\n if (this.ready) {\n this.initCropBox();\n if (this.cropped) {\n this.renderCropBox();\n }\n }\n }\n return this;\n },\n /**\n * Change the drag mode.\n * @param {string} mode - The new drag mode.\n * @returns {Cropper} this\n */\n setDragMode: function setDragMode(mode) {\n var options = this.options,\n dragBox = this.dragBox,\n face = this.face;\n if (this.ready && !this.disabled) {\n var croppable = mode === DRAG_MODE_CROP;\n var movable = options.movable && mode === DRAG_MODE_MOVE;\n mode = croppable || movable ? mode : DRAG_MODE_NONE;\n options.dragMode = mode;\n setData(dragBox, DATA_ACTION, mode);\n toggleClass(dragBox, CLASS_CROP, croppable);\n toggleClass(dragBox, CLASS_MOVE, movable);\n if (!options.cropBoxMovable) {\n // Sync drag mode to crop box when it is not movable\n setData(face, DATA_ACTION, mode);\n toggleClass(face, CLASS_CROP, croppable);\n toggleClass(face, CLASS_MOVE, movable);\n }\n }\n return this;\n }\n };\n var AnotherCropper = WINDOW.Cropper;\n var Cropper = /*#__PURE__*/function () {\n /**\n * Create a new Cropper.\n * @param {Element} element - The target element for cropping.\n * @param {Object} [options={}] - The configuration options.\n */\n function Cropper(element) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n _classCallCheck(this, Cropper);\n if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {\n throw new Error('The first argument is required and must be an
or