{ "version": 3, "sources": ["../../../node_modules/@rails/actioncable/src/adapters.js", "../../../node_modules/@rails/actioncable/src/logger.js", "../../../node_modules/@rails/actioncable/src/connection_monitor.js", "../../../node_modules/@rails/actioncable/src/internal.js", "../../../node_modules/@rails/actioncable/src/connection.js", "../../../node_modules/@rails/actioncable/src/subscription.js", "../../../node_modules/@rails/actioncable/src/subscription_guarantor.js", "../../../node_modules/@rails/actioncable/src/subscriptions.js", "../../../node_modules/@rails/actioncable/src/consumer.js", "../../../node_modules/@rails/actioncable/src/index.js", "../../../node_modules/cropperjs/dist/cropper.js", "../../../node_modules/@simonwep/pickr/dist/webpack:/webpack/universalModuleDefinition", "../../../node_modules/@simonwep/pickr/dist/webpack:/webpack/bootstrap", "../../../node_modules/@simonwep/pickr/dist/webpack:/webpack/runtime/define property getters", "../../../node_modules/@simonwep/pickr/dist/webpack:/webpack/runtime/hasOwnProperty shorthand", "../../../node_modules/@simonwep/pickr/dist/webpack:/webpack/runtime/make namespace object", "../../../node_modules/@simonwep/pickr/dist/webpack:/src/js/utils/utils.js", "../../../node_modules/@simonwep/pickr/dist/webpack:/src/js/utils/color.js", "../../../node_modules/@simonwep/pickr/dist/webpack:/src/js/utils/hsvacolor.js", "../../../node_modules/@simonwep/pickr/dist/webpack:/src/js/libs/moveable.js", "../../../node_modules/@simonwep/pickr/dist/webpack:/src/js/libs/selectable.js", "../../../node_modules/@simonwep/pickr/dist/webpack:/src/js/template.js", "../../../node_modules/@simonwep/pickr/dist/webpack:/node_modules/.pnpm/nanopop@2.4.2/node_modules/nanopop/dist/nanopop.mjs", "../../../node_modules/@simonwep/pickr/dist/webpack:/src/js/pickr.js", "../../../node_modules/color-name/index.js", "../../../node_modules/color-convert/conversions.js", "../../../node_modules/color-convert/route.js", "../../../node_modules/color-convert/index.js", "../../../node_modules/flatpickr/dist/themes/airbnb.css", "../../../node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/snakeize.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable_stream_source_element.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/fetch_requests.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/index.js", "../../../node_modules/@hotwired/stimulus/dist/stimulus.js", "../../javascript/controllers/application.js", "../../javascript/controllers/announcements_controller.js", "../../javascript/controllers/carousel_controller.js", "../../javascript/controllers/classrooms_roles_controller.js", "../../javascript/controllers/column_settings_controller.js", "../../../node_modules/sortablejs/modular/sortable.esm.js", "../../javascript/plugins/src/metadata.js", "../../javascript/controllers/column_sortables_controller.js", "../../javascript/controllers/contact_forms_controller.js", "../../javascript/controllers/dialogs_controller.js", "../../javascript/controllers/drag_drop_controller.js", "../../javascript/controllers/drop_attachments_controller.js", "../../javascript/controllers/flatpickr_controller.js", "../../javascript/controllers/image_croppers_controller.js", "../../javascript/controllers/message_controller.js", "../../javascript/controllers/move_rows_controller.js", "../../javascript/controllers/navbar_controller.js", "../../javascript/controllers/navigable_sub_pages_controller.js", "../../javascript/controllers/new_rows_controller.js", "../../javascript/controllers/newsletter_article_sortables_controller.js", "../../javascript/controllers/newsletters_controller.js", "../../javascript/controllers/notifications_controller.js", "../../javascript/controllers/page_sortables_controller.js", "../../javascript/controllers/pickr_controller.js", "../../../node_modules/@stimulus-components/popover/dist/stimulus-popover.mjs", "../../javascript/controllers/popover_controller.js", "../../../node_modules/lodash-es/_freeGlobal.js", "../../../node_modules/lodash-es/_root.js", "../../../node_modules/lodash-es/_Symbol.js", "../../../node_modules/lodash-es/_getRawTag.js", "../../../node_modules/lodash-es/_objectToString.js", "../../../node_modules/lodash-es/_baseGetTag.js", "../../../node_modules/lodash-es/isObjectLike.js", "../../../node_modules/lodash-es/isSymbol.js", "../../../node_modules/lodash-es/_arrayMap.js", "../../../node_modules/lodash-es/isArray.js", "../../../node_modules/lodash-es/_baseToString.js", "../../../node_modules/lodash-es/_trimmedEndIndex.js", "../../../node_modules/lodash-es/_baseTrim.js", "../../../node_modules/lodash-es/isObject.js", "../../../node_modules/lodash-es/toNumber.js", "../../../node_modules/lodash-es/identity.js", "../../../node_modules/lodash-es/isFunction.js", "../../../node_modules/lodash-es/_coreJsData.js", "../../../node_modules/lodash-es/_isMasked.js", "../../../node_modules/lodash-es/_toSource.js", "../../../node_modules/lodash-es/_baseIsNative.js", "../../../node_modules/lodash-es/_getValue.js", "../../../node_modules/lodash-es/_getNative.js", "../../../node_modules/lodash-es/_WeakMap.js", "../../../node_modules/lodash-es/_baseCreate.js", "../../../node_modules/lodash-es/_apply.js", "../../../node_modules/lodash-es/_copyArray.js", "../../../node_modules/lodash-es/_shortOut.js", "../../../node_modules/lodash-es/constant.js", "../../../node_modules/lodash-es/_defineProperty.js", "../../../node_modules/lodash-es/_baseSetToString.js", "../../../node_modules/lodash-es/_setToString.js", "../../../node_modules/lodash-es/_arrayEach.js", "../../../node_modules/lodash-es/_isIndex.js", "../../../node_modules/lodash-es/_baseAssignValue.js", "../../../node_modules/lodash-es/eq.js", "../../../node_modules/lodash-es/_assignValue.js", "../../../node_modules/lodash-es/_copyObject.js", "../../../node_modules/lodash-es/_overRest.js", "../../../node_modules/lodash-es/_baseRest.js", "../../../node_modules/lodash-es/isLength.js", "../../../node_modules/lodash-es/isArrayLike.js", "../../../node_modules/lodash-es/_isIterateeCall.js", "../../../node_modules/lodash-es/_createAssigner.js", "../../../node_modules/lodash-es/_isPrototype.js", "../../../node_modules/lodash-es/_baseTimes.js", "../../../node_modules/lodash-es/_baseIsArguments.js", "../../../node_modules/lodash-es/isArguments.js", "../../../node_modules/lodash-es/stubFalse.js", "../../../node_modules/lodash-es/isBuffer.js", "../../../node_modules/lodash-es/_baseIsTypedArray.js", "../../../node_modules/lodash-es/_baseUnary.js", "../../../node_modules/lodash-es/_nodeUtil.js", "../../../node_modules/lodash-es/isTypedArray.js", "../../../node_modules/lodash-es/_arrayLikeKeys.js", "../../../node_modules/lodash-es/_overArg.js", "../../../node_modules/lodash-es/_nativeKeys.js", "../../../node_modules/lodash-es/_baseKeys.js", "../../../node_modules/lodash-es/keys.js", "../../../node_modules/lodash-es/_nativeKeysIn.js", "../../../node_modules/lodash-es/_baseKeysIn.js", "../../../node_modules/lodash-es/keysIn.js", "../../../node_modules/lodash-es/assignIn.js", "../../../node_modules/lodash-es/_isKey.js", "../../../node_modules/lodash-es/_nativeCreate.js", "../../../node_modules/lodash-es/_hashClear.js", "../../../node_modules/lodash-es/_hashDelete.js", "../../../node_modules/lodash-es/_hashGet.js", "../../../node_modules/lodash-es/_hashHas.js", "../../../node_modules/lodash-es/_hashSet.js", "../../../node_modules/lodash-es/_Hash.js", "../../../node_modules/lodash-es/_listCacheClear.js", "../../../node_modules/lodash-es/_assocIndexOf.js", "../../../node_modules/lodash-es/_listCacheDelete.js", "../../../node_modules/lodash-es/_listCacheGet.js", "../../../node_modules/lodash-es/_listCacheHas.js", "../../../node_modules/lodash-es/_listCacheSet.js", "../../../node_modules/lodash-es/_ListCache.js", "../../../node_modules/lodash-es/_Map.js", "../../../node_modules/lodash-es/_mapCacheClear.js", "../../../node_modules/lodash-es/_isKeyable.js", "../../../node_modules/lodash-es/_getMapData.js", "../../../node_modules/lodash-es/_mapCacheDelete.js", "../../../node_modules/lodash-es/_mapCacheGet.js", "../../../node_modules/lodash-es/_mapCacheHas.js", "../../../node_modules/lodash-es/_mapCacheSet.js", "../../../node_modules/lodash-es/_MapCache.js", "../../../node_modules/lodash-es/memoize.js", "../../../node_modules/lodash-es/_memoizeCapped.js", "../../../node_modules/lodash-es/_stringToPath.js", "../../../node_modules/lodash-es/toString.js", "../../../node_modules/lodash-es/_castPath.js", "../../../node_modules/lodash-es/_toKey.js", "../../../node_modules/lodash-es/_baseGet.js", "../../../node_modules/lodash-es/get.js", "../../../node_modules/lodash-es/_arrayPush.js", "../../../node_modules/lodash-es/_getPrototype.js", "../../../node_modules/lodash-es/isPlainObject.js", "../../../node_modules/lodash-es/_baseSlice.js", "../../../node_modules/lodash-es/_castSlice.js", "../../../node_modules/lodash-es/_hasUnicode.js", "../../../node_modules/lodash-es/_asciiToArray.js", "../../../node_modules/lodash-es/_unicodeToArray.js", "../../../node_modules/lodash-es/_stringToArray.js", "../../../node_modules/lodash-es/_createCaseFirst.js", "../../../node_modules/lodash-es/upperFirst.js", "../../../node_modules/lodash-es/_stackClear.js", "../../../node_modules/lodash-es/_stackDelete.js", "../../../node_modules/lodash-es/_stackGet.js", "../../../node_modules/lodash-es/_stackHas.js", "../../../node_modules/lodash-es/_stackSet.js", "../../../node_modules/lodash-es/_Stack.js", "../../../node_modules/lodash-es/_baseAssign.js", "../../../node_modules/lodash-es/_baseAssignIn.js", "../../../node_modules/lodash-es/_cloneBuffer.js", "../../../node_modules/lodash-es/_arrayFilter.js", "../../../node_modules/lodash-es/stubArray.js", "../../../node_modules/lodash-es/_getSymbols.js", "../../../node_modules/lodash-es/_copySymbols.js", "../../../node_modules/lodash-es/_getSymbolsIn.js", "../../../node_modules/lodash-es/_copySymbolsIn.js", "../../../node_modules/lodash-es/_baseGetAllKeys.js", "../../../node_modules/lodash-es/_getAllKeys.js", "../../../node_modules/lodash-es/_getAllKeysIn.js", "../../../node_modules/lodash-es/_DataView.js", "../../../node_modules/lodash-es/_Promise.js", "../../../node_modules/lodash-es/_Set.js", "../../../node_modules/lodash-es/_getTag.js", "../../../node_modules/lodash-es/_initCloneArray.js", "../../../node_modules/lodash-es/_Uint8Array.js", "../../../node_modules/lodash-es/_cloneArrayBuffer.js", "../../../node_modules/lodash-es/_cloneDataView.js", "../../../node_modules/lodash-es/_cloneRegExp.js", "../../../node_modules/lodash-es/_cloneSymbol.js", "../../../node_modules/lodash-es/_cloneTypedArray.js", "../../../node_modules/lodash-es/_initCloneByTag.js", "../../../node_modules/lodash-es/_initCloneObject.js", "../../../node_modules/lodash-es/_baseIsMap.js", "../../../node_modules/lodash-es/isMap.js", "../../../node_modules/lodash-es/_baseIsSet.js", "../../../node_modules/lodash-es/isSet.js", "../../../node_modules/lodash-es/_baseClone.js", "../../../node_modules/lodash-es/clone.js", "../../../node_modules/lodash-es/cloneDeep.js", "../../../node_modules/lodash-es/cloneDeepWith.js", "../../../node_modules/lodash-es/_setCacheAdd.js", "../../../node_modules/lodash-es/_setCacheHas.js", "../../../node_modules/lodash-es/_SetCache.js", "../../../node_modules/lodash-es/_arraySome.js", "../../../node_modules/lodash-es/_cacheHas.js", "../../../node_modules/lodash-es/_equalArrays.js", "../../../node_modules/lodash-es/_mapToArray.js", "../../../node_modules/lodash-es/_setToArray.js", "../../../node_modules/lodash-es/_equalByTag.js", "../../../node_modules/lodash-es/_equalObjects.js", "../../../node_modules/lodash-es/_baseIsEqualDeep.js", "../../../node_modules/lodash-es/_baseIsEqual.js", "../../../node_modules/lodash-es/_baseIsMatch.js", "../../../node_modules/lodash-es/_isStrictComparable.js", "../../../node_modules/lodash-es/_getMatchData.js", "../../../node_modules/lodash-es/_matchesStrictComparable.js", "../../../node_modules/lodash-es/_baseMatches.js", "../../../node_modules/lodash-es/_baseHasIn.js", "../../../node_modules/lodash-es/_hasPath.js", "../../../node_modules/lodash-es/hasIn.js", "../../../node_modules/lodash-es/_baseMatchesProperty.js", "../../../node_modules/lodash-es/_baseProperty.js", "../../../node_modules/lodash-es/_basePropertyDeep.js", "../../../node_modules/lodash-es/property.js", "../../../node_modules/lodash-es/_baseIteratee.js", "../../../node_modules/lodash-es/_createBaseFor.js", "../../../node_modules/lodash-es/_baseFor.js", "../../../node_modules/lodash-es/_baseForOwn.js", "../../../node_modules/lodash-es/_createBaseEach.js", "../../../node_modules/lodash-es/_baseEach.js", "../../../node_modules/lodash-es/now.js", "../../../node_modules/lodash-es/debounce.js", "../../../node_modules/lodash-es/_assignMergeValue.js", "../../../node_modules/lodash-es/isArrayLikeObject.js", "../../../node_modules/lodash-es/_safeGet.js", "../../../node_modules/lodash-es/toPlainObject.js", "../../../node_modules/lodash-es/_baseMergeDeep.js", "../../../node_modules/lodash-es/_baseMerge.js", "../../../node_modules/lodash-es/last.js", "../../../node_modules/lodash-es/escapeRegExp.js", "../../../node_modules/lodash-es/_baseMap.js", "../../../node_modules/lodash-es/map.js", "../../../node_modules/lodash-es/isString.js", "../../../node_modules/lodash-es/_parent.js", "../../../node_modules/lodash-es/isElement.js", "../../../node_modules/lodash-es/isEqual.js", "../../../node_modules/lodash-es/isEqualWith.js", "../../../node_modules/lodash-es/mapValues.js", "../../../node_modules/lodash-es/merge.js", "../../../node_modules/lodash-es/_baseUnset.js", "../../../node_modules/lodash-es/_baseSet.js", "../../../node_modules/lodash-es/set.js", "../../../node_modules/lodash-es/throttle.js", "../../../node_modules/lodash-es/unset.js", "../../../node_modules/@ckeditor/ckeditor5-utils/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/global.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/env.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/fastdiff.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/diff.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/difftochanges.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/mix.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/spy.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/eventinfo.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/uid.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/priorities.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/inserttopriorityarray.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/version.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/emittermixin.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/elementreplacer.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/abortabledebounce.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/count.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/comparearrays.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/isiterable.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/createelement.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/config.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/isnode.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/iswindow.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/emittermixin.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/findclosestscrollableancestor.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getancestors.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getdatafromelement.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getborderwidths.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/istext.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/isrange.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getpositionedancestor.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/rect.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/resizeobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/setdatainelement.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/tounit.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/indexof.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/insertat.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/iscomment.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/isvalidattributename.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/isvisible.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/position.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/remove.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/scroll.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/keyboard.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/language.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/toarray.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/translation-service.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/locale.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/collection.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/first.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/focustracker.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/keystrokehandler.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/objecttomap.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/tomap.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/wait.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/retry.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/splicearray.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/delay.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/verifylicense.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/unicode.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/placeholder.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/typecheckable.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/node.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/text.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/textproxy.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/matcher.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/stylesmap.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/element.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/containerelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/editableelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/rooteditableelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/treewalker.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/position.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/range.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/selection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/documentselection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/bubblingeventinfo.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/bubblingemittermixin.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/document.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/attributeelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/emptyelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/uielement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/rawelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/documentfragment.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/downcastwriter.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/filler.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/renderer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/domconverter.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/observer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventdata.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/keyobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/fakeselectionobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mutationobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/focusobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/selectionobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/compositionobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/datatransfer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/inputobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/arrowkeysobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/tabobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/view.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/typecheckable.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/node.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/nodelist.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/text.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/textproxy.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/element.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/treewalker.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/position.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/range.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/mapper.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/modelconsumable.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/downcastdispatcher.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/selection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/liverange.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/documentselection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/conversionhelpers.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/downcasthelpers.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/autoparagraphing.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/upcasthelpers.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/selection-post-fixer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/controller/editingcontroller.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/viewconsumable.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/schema.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/upcastdispatcher.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/basichtmlwriter.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/controller/datacontroller.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/conversion.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/xmldataprocessor.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/operation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/moveoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/insertoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/splitoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/mergeoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/markeroperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/attributeoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/nooperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/renameoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/rootattributeoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/rootoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/operationfactory.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/transform.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/liveposition.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/batch.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/differ.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/history.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/rootelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/document.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/markercollection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/detachoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/documentfragment.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/writer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/deletecontent.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/getselectedcontent.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/insertcontent.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/insertobject.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/modifyselection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/model.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/clickobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/upcastwriter.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/background.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/border.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/margin.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/padding.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dev-utils/view.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dev-utils/model.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/watchdog.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/utils/getsubnodes.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/utils/areconnectedthroughproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/editorwatchdog.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/contextwatchdog.ts", "../../../node_modules/@ckeditor/ckeditor5-core/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-core/src/plugin.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/command.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/multicommand.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/plugincollection.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/context.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/contextplugin.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/commandcollection.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/accessibility.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/editor.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/utils/attachtoform.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/utils/dataapimixin.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/utils/elementapimixin.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/utils/securesourceelement.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/pendingactions.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/index.ts", "../../../node_modules/@ckeditor/ckeditor5-upload/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-upload/src/filereader.ts", "../../../node_modules/@ckeditor/ckeditor5-upload/src/filerepository.ts", "../../../node_modules/@ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter.ts", "../../../node_modules/@ckeditor/ckeditor5-upload/src/adapters/simpleuploadadapter.ts", "../../../node_modules/color-parse/index.mjs", "../../../node_modules/@ckeditor/ckeditor5-ui/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-ui/src/viewcollection.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/template.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/view.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/injectcsstransitiondisabler.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/csstransitiondisablermixin.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/submithandler.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/addkeyboardhandlingforgrid.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/icon/iconview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/buttonlabelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/formheader/formheaderview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/focuscycler.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/draggableviewmixin.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dialog/dialogactionsview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dialog/dialogcontentview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dialog/dialogview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dialog/dialog.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenulistitembuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/label/labelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/accessibilityhelp/accessibilityhelpcontentview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/accessibilityhelp/accessibilityhelp.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/bodycollection.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/switchbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/filedialogbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/collapsible/collapsibleview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorgrid/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorgrid/colortileview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorgrid/colorgridview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorpicker/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/labeledfield/labeledfieldview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/input/inputbase.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/input/inputview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/inputtext/inputtextview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/inputnumber/inputnumberview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/textarea/textareaview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/dropdownpanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/dropdownview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/button/dropdownbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarseparatorview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarlinebreakview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/preventdefault.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/normalizetoolbarconfig.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/list/listitemview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/list/listseparatorview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/list/listitemgroupview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/list/listview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/labeledfield/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorpicker/colorpickerview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorselector/documentcolorcollection.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorselector/colorgridsfragmentview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorselector/colorpickerfragmentview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorselector/colorselectorview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/componentfactory.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/tooltipmanager.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/poweredby.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/arialiveannouncer.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/editorui.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/editoruiview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/boxed/boxededitoruiview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editableui/editableuiview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/iframe/iframeview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/notification/notification.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/model.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/panel/sticky/stickypanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/text/searchtextqueryview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/searchinfoview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/searchresultsview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/text/searchtextview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/autocomplete/autocompleteview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/highlightedtext/highlightedtextview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/spinner/spinnerview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/balloon/balloontoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/block/blockbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/block/blocktoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenubuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenulistitemview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenupanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenuview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenulistview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenulistitemfiledialogbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarview.ts", "../../../node_modules/vanilla-colorful/src/lib/utils/math.ts", "../../../node_modules/vanilla-colorful/src/lib/utils/convert.ts", "../../../node_modules/vanilla-colorful/src/lib/utils/compare.ts", "../../../node_modules/vanilla-colorful/src/lib/utils/dom.ts", "../../../node_modules/vanilla-colorful/src/lib/components/slider.ts", "../../../node_modules/vanilla-colorful/src/lib/components/hue.ts", "../../../node_modules/vanilla-colorful/src/lib/components/saturation.ts", "../../../node_modules/vanilla-colorful/src/lib/styles/color-picker.ts", "../../../node_modules/vanilla-colorful/src/lib/styles/hue.ts", "../../../node_modules/vanilla-colorful/src/lib/styles/saturation.ts", "../../../node_modules/vanilla-colorful/src/lib/components/color-picker.ts", "../../../node_modules/vanilla-colorful/src/lib/entrypoints/hex.ts", "../../../node_modules/@ckeditor/ckeditor5-alignment/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-alignment/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-alignment/src/alignmentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-alignment/src/alignmentediting.ts", "../../../node_modules/@ckeditor/ckeditor5-alignment/src/alignmentui.ts", "../../../node_modules/@ckeditor/ckeditor5-alignment/src/alignment.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-typing/src/utils/changebuffer.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/inserttextcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/inserttextobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/input.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/deletecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/deleteobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/delete.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/typing.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/utils/getlasttextline.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/textwatcher.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/twostepcaretmovement.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/texttransformation.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/utils/findattributerange.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/utils/inlinehighlight.ts", "../../../node_modules/@ckeditor/ckeditor5-autoformat/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.ts", "../../../node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.ts", "../../../node_modules/@ckeditor/ckeditor5-autoformat/src/autoformat.ts", "../../../node_modules/@ckeditor/ckeditor5-autosave/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-autosave/src/autosave.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/code.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/underline.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-enter/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/entercommand.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/enterobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/enter.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/shiftentercommand.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/shiftenter.ts", "../../../node_modules/@ckeditor/ckeditor5-block-quote/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.ts", "../../../node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.ts", "../../../node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-widget/src/highlightstack.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgettypearound/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgettypearound/widgettypearound.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/verticalnavigation.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widget.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgettoolbarrepository.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgetresize/resizerstate.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgetresize/sizeview.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgetresize/resizer.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgetresize.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardmarkersutils.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/lineview.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/dragdroptarget.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/dragdropblocktoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.ts", "../../../node_modules/@ckeditor/ckeditor5-editor-inline/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-editor-inline/src/inlineeditorui.ts", "../../../node_modules/@ckeditor/ckeditor5-editor-inline/src/inlineeditoruiview.ts", "../../../node_modules/@ckeditor/ckeditor5-editor-inline/src/inlineeditor.ts", "../../../node_modules/@ckeditor/ckeditor5-select-all/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-select-all/src/selectallcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-select-all/src/selectallediting.ts", "../../../node_modules/@ckeditor/ckeditor5-select-all/src/selectallui.ts", "../../../node_modules/@ckeditor/ckeditor5-select-all/src/selectall.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-undo/src/basecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/undocommand.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/redocommand.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/undoediting.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/undoui.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/undo.ts", "../../../node_modules/@ckeditor/ckeditor5-essentials/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-essentials/src/essentials.ts", "../../../node_modules/@ckeditor/ckeditor5-font/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontfamily/fontfamilycommand.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontfamily/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontfamily/fontfamilyediting.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontfamily/fontfamilyui.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontfamily.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontsize/fontsizecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontsize/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontsize/fontsizeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontsize/fontsizeui.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontsize.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontcolor/fontcolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontcolor/fontcolorediting.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/ui/colorui.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontcolor/fontcolorui.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontcolor.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontbackgroundcolor/fontbackgroundcolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontbackgroundcolor/fontbackgroundcolorediting.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontbackgroundcolor/fontbackgroundcolorui.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/fontbackgroundcolor.ts", "../../../node_modules/@ckeditor/ckeditor5-font/src/font.ts", "../../../node_modules/@ckeditor/ckeditor5-paragraph/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-paragraph/src/paragraphcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-paragraph/src/insertparagraphcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-paragraph/src/paragraph.ts", "../../../node_modules/@ckeditor/ckeditor5-paragraph/src/paragraphbuttonui.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-heading/src/headingcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/headingediting.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/headingui.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/heading.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/headingbuttonsui.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/title.ts", "../../../node_modules/@ckeditor/ckeditor5-highlight/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-highlight/src/highlightcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-highlight/src/highlightediting.ts", "../../../node_modules/@ckeditor/ckeditor5-highlight/src/highlightui.ts", "../../../node_modules/@ckeditor/ckeditor5-highlight/src/highlight.ts", "../../../node_modules/@ckeditor/ckeditor5-horizontal-line/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-horizontal-line/src/horizontallinecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-horizontal-line/src/horizontallineediting.ts", "../../../node_modules/@ckeditor/ckeditor5-horizontal-line/src/horizontallineui.ts", "../../../node_modules/@ckeditor/ckeditor5-horizontal-line/src/horizontalline.ts", "../../../node_modules/@ckeditor/ckeditor5-image/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageutils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/autoimage.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/ui/textalternativeformview.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/ui/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageloadobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/insertimagecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/replaceimagesourcecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagesizeattributes.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imagetypecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageplaceholder.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageblockediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert/ui/imageinsertformview.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert/imageinsertui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageblock.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageinlineediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinline.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionutils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption/toggleimagecaptioncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadprogress.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/uploadimagecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert/ui/imageinserturlview.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert/imageinsertviaurlui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsertviaurl.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/resizeimagecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/imageresizeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/imageresizebuttons.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/imageresizehandles.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/utils/tryparsedimensionwithunit.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/utils/getselectedimageeditornodes.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/utils/getselectedimagewidthinunits.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/ui/imagecustomresizeformview.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/utils/getselectedimagepossibleresizerange.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/imagecustomresizeui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestyleediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestyleui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/pictureediting.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentediting.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentui.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indent.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentblockcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentcommandbehavior/indentusingoffset.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentcommandbehavior/indentusingclasses.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentblock.ts", "../../../node_modules/@ckeditor/ckeditor5-link/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-link/src/utils/automaticdecorators.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/unlinkcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/utils/manualdecorator.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkediting.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/ui/linkformview.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/ui/linkactionsview.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkui.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/autolink.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/link.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkimageediting.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkimageui.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkimage.ts", "../../../node_modules/@ckeditor/ckeditor5-list/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils/listwalker.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils/model.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listindentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listmergecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listsplitcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listutils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils/view.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils/postfixers.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listui.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/liststartcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/utils/style.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/liststylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/listreversedcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/listpropertiesutils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/listpropertiesediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/ui/listpropertiesview.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/listpropertiesui.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist/checktodolistcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist/todocheckboxchangeobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist/todolistediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist/todolistui.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacylistcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacyindentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacyutils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacylistutils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacyconverters.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacylistediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties/legacyliststylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties/legacylistreversedcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties/legacyliststartcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties/legacylistpropertiesediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacytodolist/legacychecktodolistcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacytodolist/legacytodolistconverters.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacytodolist/legacytodolistediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacytodolist.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/adjacentlistssupport.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/documentlist.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/documentlistproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/tododocumentlist.ts", "../../../node_modules/marked/lib/marked.esm.js", "../../../node_modules/turndown/lib/turndown.browser.es.js", "../../../node_modules/turndown-plugin-gfm/lib/turndown-plugin-gfm.es.js", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/markdown2html/markdown2html.ts", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/html2markdown/html2markdown.ts", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/gfmdataprocessor.ts", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/markdown.ts", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/pastefrommarkdownexperimental.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembedcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaregistry.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembedediting.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/automediaembed.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/ui/mediaformview.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembedui.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembed.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembedtoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-mention/src/mentioncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/mentionediting.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/ui/mentionsview.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/ui/domwrapperview.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/ui/mentionlistitemview.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/mentionui.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/mention.ts", "../../../node_modules/@ckeditor/ckeditor5-page-break/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-page-break/src/pagebreakcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-page-break/src/pagebreakediting.ts", "../../../node_modules/@ckeditor/ckeditor5-page-break/src/pagebreakui.ts", "../../../node_modules/@ckeditor/ckeditor5-page-break/src/pagebreak.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/list.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/image.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removemsattributes.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/normalizers/mswordnormalizer.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removeboldwrapper.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/br.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/normalizers/googledocsnormalizer.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removexmlns.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removegooglesheetstag.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removeinvalidtablewidth.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removestyleblock.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/normalizers/googlesheetsnormalizer.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/space.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/parse.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice.ts", "../../../node_modules/@ckeditor/ckeditor5-remove-format/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-remove-format/src/removeformatui.ts", "../../../node_modules/@ckeditor/ckeditor5-remove-format/src/removeformatcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-remove-format/src/removeformatediting.ts", "../../../node_modules/@ckeditor/ckeditor5-remove-format/src/removeformat.ts", "../../../node_modules/@ckeditor/ckeditor5-table/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/tableproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/common.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/upcasttable.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablewalker.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/downcast.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/inserttablecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/insertrowcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/insertcolumncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/splitcellcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/structure.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/mergecellcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/removerowcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/removecolumncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/setheaderrowcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/setheadercolumncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/constants.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableutils.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/mergecellscommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/selectrowcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/selectcolumncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-layout-post-fixer.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-cell-paragraph-post-fixer.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-headings-refresh-handler.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-cell-refresh-handler.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/ui/inserttableview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableui.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableselection.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableclipboard.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablekeyboard.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablemouse/mouseeventsobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablemouse.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/table.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/plaintableoutput.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/ui/widget.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tabletoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/ui/colorinputview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/ui/table-properties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/ui/formrowview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/ui/tablecellpropertiesview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/ui/contextualballoon.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/table-properties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/tablecellpropertiesui.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellpropertycommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellwidth/commands/tablecellwidthcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellwidth/tablecellwidthediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellpaddingcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellheightcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellverticalalignmentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellborderstylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellbordercolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellborderwidthcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/tablecellpropertiesediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablepropertycommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablebackgroundcolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablebordercolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tableborderstylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tableborderwidthcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablewidthcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tableheightcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablealignmentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/tablepropertiesediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/ui/tablepropertiesview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/tablepropertiesui.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-caption-post-fixer.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption/toggletablecaptioncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption/tablecaptionediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption/tablecaptionui.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/tablewidthscommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/tablecolumnresizeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize.ts", "../../javascript/controllers/rich_text_editors_controller.js", "../../javascript/controllers/row_settings_controller.js", "../../javascript/controllers/row_sortables_controller.js", "../../javascript/controllers/search_form_controller.js", "../../javascript/controllers/slide_overs_controller.js", "../../javascript/controllers/small_screen_admin_navbar_controller.js", "../../javascript/controllers/sub_pages_expandable_controller.js", "../../javascript/controllers/website_navbar_small_controller.js", "../../javascript/controllers/index.js", "../../../node_modules/flatpickr/dist/esm/types/options.js", "../../../node_modules/flatpickr/dist/esm/l10n/default.js", "../../../node_modules/flatpickr/dist/esm/utils/index.js", "../../../node_modules/flatpickr/dist/esm/utils/dom.js", "../../../node_modules/flatpickr/dist/esm/utils/formatting.js", "../../../node_modules/flatpickr/dist/esm/utils/dates.js", "../../../node_modules/flatpickr/dist/esm/utils/polyfills.js", "../../../node_modules/flatpickr/dist/esm/index.js", "../../javascript/application.js"], "sourcesContent": ["export default {\n logger: typeof console !== \"undefined\" ? console : undefined,\n WebSocket: typeof WebSocket !== \"undefined\" ? WebSocket : undefined,\n}\n", "import adapters from \"./adapters\"\n\n// The logger is disabled by default. You can enable it with:\n//\n// ActionCable.logger.enabled = true\n//\n// Example:\n//\n// import * as ActionCable from '@rails/actioncable'\n//\n// ActionCable.logger.enabled = true\n// ActionCable.logger.log('Connection Established.')\n//\n\nexport default {\n log(...messages) {\n if (this.enabled) {\n messages.push(Date.now())\n adapters.logger.log(\"[ActionCable]\", ...messages)\n }\n },\n}\n", "import logger from \"./logger\"\n\n// Responsible for ensuring the cable connection is in good health by validating the heartbeat pings sent from the server, and attempting\n// revival reconnections if things go astray. Internal class, not intended for direct user manipulation.\n\nconst now = () => new Date().getTime()\n\nconst secondsSince = time => (now() - time) / 1000\n\nclass ConnectionMonitor {\n constructor(connection) {\n this.visibilityDidChange = this.visibilityDidChange.bind(this)\n this.connection = connection\n this.reconnectAttempts = 0\n }\n\n start() {\n if (!this.isRunning()) {\n this.startedAt = now()\n delete this.stoppedAt\n this.startPolling()\n addEventListener(\"visibilitychange\", this.visibilityDidChange)\n logger.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`)\n }\n }\n\n stop() {\n if (this.isRunning()) {\n this.stoppedAt = now()\n this.stopPolling()\n removeEventListener(\"visibilitychange\", this.visibilityDidChange)\n logger.log(\"ConnectionMonitor stopped\")\n }\n }\n\n isRunning() {\n return this.startedAt && !this.stoppedAt\n }\n\n recordMessage() {\n this.pingedAt = now()\n }\n\n recordConnect() {\n this.reconnectAttempts = 0\n delete this.disconnectedAt\n logger.log(\"ConnectionMonitor recorded connect\")\n }\n\n recordDisconnect() {\n this.disconnectedAt = now()\n logger.log(\"ConnectionMonitor recorded disconnect\")\n }\n\n // Private\n\n startPolling() {\n this.stopPolling()\n this.poll()\n }\n\n stopPolling() {\n clearTimeout(this.pollTimeout)\n }\n\n poll() {\n this.pollTimeout = setTimeout(() => {\n this.reconnectIfStale()\n this.poll()\n }\n , this.getPollInterval())\n }\n\n getPollInterval() {\n const { staleThreshold, reconnectionBackoffRate } = this.constructor\n const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10))\n const jitterMax = this.reconnectAttempts === 0 ? 1.0 : reconnectionBackoffRate\n const jitter = jitterMax * Math.random()\n return staleThreshold * 1000 * backoff * (1 + jitter)\n }\n\n reconnectIfStale() {\n if (this.connectionIsStale()) {\n logger.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`)\n this.reconnectAttempts++\n if (this.disconnectedRecently()) {\n logger.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`)\n } else {\n logger.log(\"ConnectionMonitor reopening\")\n this.connection.reopen()\n }\n }\n }\n\n get refreshedAt() {\n return this.pingedAt ? this.pingedAt : this.startedAt\n }\n\n connectionIsStale() {\n return secondsSince(this.refreshedAt) > this.constructor.staleThreshold\n }\n\n disconnectedRecently() {\n return this.disconnectedAt && (secondsSince(this.disconnectedAt) < this.constructor.staleThreshold)\n }\n\n visibilityDidChange() {\n if (document.visibilityState === \"visible\") {\n setTimeout(() => {\n if (this.connectionIsStale() || !this.connection.isOpen()) {\n logger.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`)\n this.connection.reopen()\n }\n }\n , 200)\n }\n }\n\n}\n\nConnectionMonitor.staleThreshold = 6 // Server::Connections::BEAT_INTERVAL * 2 (missed two pings)\nConnectionMonitor.reconnectionBackoffRate = 0.15\n\nexport default ConnectionMonitor\n", "export default {\n \"message_types\": {\n \"welcome\": \"welcome\",\n \"disconnect\": \"disconnect\",\n \"ping\": \"ping\",\n \"confirmation\": \"confirm_subscription\",\n \"rejection\": \"reject_subscription\"\n },\n \"disconnect_reasons\": {\n \"unauthorized\": \"unauthorized\",\n \"invalid_request\": \"invalid_request\",\n \"server_restart\": \"server_restart\",\n \"remote\": \"remote\"\n },\n \"default_mount_path\": \"/cable\",\n \"protocols\": [\n \"actioncable-v1-json\",\n \"actioncable-unsupported\"\n ]\n}\n", "import adapters from \"./adapters\"\nimport ConnectionMonitor from \"./connection_monitor\"\nimport INTERNAL from \"./internal\"\nimport logger from \"./logger\"\n\n// Encapsulate the cable connection held by the consumer. This is an internal class not intended for direct user manipulation.\n\nconst {message_types, protocols} = INTERNAL\nconst supportedProtocols = protocols.slice(0, protocols.length - 1)\n\nconst indexOf = [].indexOf\n\nclass Connection {\n constructor(consumer) {\n this.open = this.open.bind(this)\n this.consumer = consumer\n this.subscriptions = this.consumer.subscriptions\n this.monitor = new ConnectionMonitor(this)\n this.disconnected = true\n }\n\n send(data) {\n if (this.isOpen()) {\n this.webSocket.send(JSON.stringify(data))\n return true\n } else {\n return false\n }\n }\n\n open() {\n if (this.isActive()) {\n logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`)\n return false\n } else {\n const socketProtocols = [...protocols, ...this.consumer.subprotocols || []]\n logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`)\n if (this.webSocket) { this.uninstallEventHandlers() }\n this.webSocket = new adapters.WebSocket(this.consumer.url, socketProtocols)\n this.installEventHandlers()\n this.monitor.start()\n return true\n }\n }\n\n close({allowReconnect} = {allowReconnect: true}) {\n if (!allowReconnect) { this.monitor.stop() }\n // Avoid closing websockets in a \"connecting\" state due to Safari 15.1+ bug. See: https://github.com/rails/rails/issues/43835#issuecomment-1002288478\n if (this.isOpen()) {\n return this.webSocket.close()\n }\n }\n\n reopen() {\n logger.log(`Reopening WebSocket, current state is ${this.getState()}`)\n if (this.isActive()) {\n try {\n return this.close()\n } catch (error) {\n logger.log(\"Failed to reopen WebSocket\", error)\n }\n finally {\n logger.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`)\n setTimeout(this.open, this.constructor.reopenDelay)\n }\n } else {\n return this.open()\n }\n }\n\n getProtocol() {\n if (this.webSocket) {\n return this.webSocket.protocol\n }\n }\n\n isOpen() {\n return this.isState(\"open\")\n }\n\n isActive() {\n return this.isState(\"open\", \"connecting\")\n }\n\n triedToReconnect() {\n return this.monitor.reconnectAttempts > 0\n }\n\n // Private\n\n isProtocolSupported() {\n return indexOf.call(supportedProtocols, this.getProtocol()) >= 0\n }\n\n isState(...states) {\n return indexOf.call(states, this.getState()) >= 0\n }\n\n getState() {\n if (this.webSocket) {\n for (let state in adapters.WebSocket) {\n if (adapters.WebSocket[state] === this.webSocket.readyState) {\n return state.toLowerCase()\n }\n }\n }\n return null\n }\n\n installEventHandlers() {\n for (let eventName in this.events) {\n const handler = this.events[eventName].bind(this)\n this.webSocket[`on${eventName}`] = handler\n }\n }\n\n uninstallEventHandlers() {\n for (let eventName in this.events) {\n this.webSocket[`on${eventName}`] = function() {}\n }\n }\n\n}\n\nConnection.reopenDelay = 500\n\nConnection.prototype.events = {\n message(event) {\n if (!this.isProtocolSupported()) { return }\n const {identifier, message, reason, reconnect, type} = JSON.parse(event.data)\n this.monitor.recordMessage()\n switch (type) {\n case message_types.welcome:\n if (this.triedToReconnect()) {\n this.reconnectAttempted = true\n }\n this.monitor.recordConnect()\n return this.subscriptions.reload()\n case message_types.disconnect:\n logger.log(`Disconnecting. Reason: ${reason}`)\n return this.close({allowReconnect: reconnect})\n case message_types.ping:\n return null\n case message_types.confirmation:\n this.subscriptions.confirmSubscription(identifier)\n if (this.reconnectAttempted) {\n this.reconnectAttempted = false\n return this.subscriptions.notify(identifier, \"connected\", {reconnected: true})\n } else {\n return this.subscriptions.notify(identifier, \"connected\", {reconnected: false})\n }\n case message_types.rejection:\n return this.subscriptions.reject(identifier)\n default:\n return this.subscriptions.notify(identifier, \"received\", message)\n }\n },\n\n open() {\n logger.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`)\n this.disconnected = false\n if (!this.isProtocolSupported()) {\n logger.log(\"Protocol is unsupported. Stopping monitor and disconnecting.\")\n return this.close({allowReconnect: false})\n }\n },\n\n close(event) {\n logger.log(\"WebSocket onclose event\")\n if (this.disconnected) { return }\n this.disconnected = true\n this.monitor.recordDisconnect()\n return this.subscriptions.notifyAll(\"disconnected\", {willAttemptReconnect: this.monitor.isRunning()})\n },\n\n error() {\n logger.log(\"WebSocket onerror event\")\n }\n}\n\nexport default Connection\n", "// A new subscription is created through the ActionCable.Subscriptions instance available on the consumer.\n// It provides a number of callbacks and a method for calling remote procedure calls on the corresponding\n// Channel instance on the server side.\n//\n// An example demonstrates the basic functionality:\n//\n// App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\", {\n// connected() {\n// // Called once the subscription has been successfully completed\n// },\n//\n// disconnected({ willAttemptReconnect: boolean }) {\n// // Called when the client has disconnected with the server.\n// // The object will have an `willAttemptReconnect` property which\n// // says whether the client has the intention of attempting\n// // to reconnect.\n// },\n//\n// appear() {\n// this.perform('appear', {appearing_on: this.appearingOn()})\n// },\n//\n// away() {\n// this.perform('away')\n// },\n//\n// appearingOn() {\n// $('main').data('appearing-on')\n// }\n// })\n//\n// The methods #appear and #away forward their intent to the remote AppearanceChannel instance on the server\n// by calling the `perform` method with the first parameter being the action (which maps to AppearanceChannel#appear/away).\n// The second parameter is a hash that'll get JSON encoded and made available on the server in the data parameter.\n//\n// This is how the server component would look:\n//\n// class AppearanceChannel < ApplicationActionCable::Channel\n// def subscribed\n// current_user.appear\n// end\n//\n// def unsubscribed\n// current_user.disappear\n// end\n//\n// def appear(data)\n// current_user.appear on: data['appearing_on']\n// end\n//\n// def away\n// current_user.away\n// end\n// end\n//\n// The \"AppearanceChannel\" name is automatically mapped between the client-side subscription creation and the server-side Ruby class name.\n// The AppearanceChannel#appear/away public methods are exposed automatically to client-side invocation through the perform method.\n\nconst extend = function(object, properties) {\n if (properties != null) {\n for (let key in properties) {\n const value = properties[key]\n object[key] = value\n }\n }\n return object\n}\n\nexport default class Subscription {\n constructor(consumer, params = {}, mixin) {\n this.consumer = consumer\n this.identifier = JSON.stringify(params)\n extend(this, mixin)\n }\n\n // Perform a channel action with the optional data passed as an attribute\n perform(action, data = {}) {\n data.action = action\n return this.send(data)\n }\n\n send(data) {\n return this.consumer.send({command: \"message\", identifier: this.identifier, data: JSON.stringify(data)})\n }\n\n unsubscribe() {\n return this.consumer.subscriptions.remove(this)\n }\n}\n", "import logger from \"./logger\"\n\n// Responsible for ensuring channel subscribe command is confirmed, retrying until confirmation is received.\n// Internal class, not intended for direct user manipulation.\n\nclass SubscriptionGuarantor {\n constructor(subscriptions) {\n this.subscriptions = subscriptions\n this.pendingSubscriptions = []\n }\n\n guarantee(subscription) {\n if(this.pendingSubscriptions.indexOf(subscription) == -1){ \n logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`)\n this.pendingSubscriptions.push(subscription) \n }\n else {\n logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`)\n }\n this.startGuaranteeing()\n }\n\n forget(subscription) {\n logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`)\n this.pendingSubscriptions = (this.pendingSubscriptions.filter((s) => s !== subscription))\n }\n\n startGuaranteeing() {\n this.stopGuaranteeing()\n this.retrySubscribing()\n }\n \n stopGuaranteeing() {\n clearTimeout(this.retryTimeout)\n }\n\n retrySubscribing() {\n this.retryTimeout = setTimeout(() => {\n if (this.subscriptions && typeof(this.subscriptions.subscribe) === \"function\") {\n this.pendingSubscriptions.map((subscription) => {\n logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`)\n this.subscriptions.subscribe(subscription)\n })\n }\n }\n , 500)\n }\n}\n\nexport default SubscriptionGuarantor", "import Subscription from \"./subscription\"\nimport SubscriptionGuarantor from \"./subscription_guarantor\"\nimport logger from \"./logger\"\n\n// Collection class for creating (and internally managing) channel subscriptions.\n// The only method intended to be triggered by the user is ActionCable.Subscriptions#create,\n// and it should be called through the consumer like so:\n//\n// App = {}\n// App.cable = ActionCable.createConsumer(\"ws://example.com/accounts/1\")\n// App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\")\n//\n// For more details on how you'd configure an actual channel subscription, see ActionCable.Subscription.\n\nexport default class Subscriptions {\n constructor(consumer) {\n this.consumer = consumer\n this.guarantor = new SubscriptionGuarantor(this)\n this.subscriptions = []\n }\n\n create(channelName, mixin) {\n const channel = channelName\n const params = typeof channel === \"object\" ? channel : {channel}\n const subscription = new Subscription(this.consumer, params, mixin)\n return this.add(subscription)\n }\n\n // Private\n\n add(subscription) {\n this.subscriptions.push(subscription)\n this.consumer.ensureActiveConnection()\n this.notify(subscription, \"initialized\")\n this.subscribe(subscription)\n return subscription\n }\n\n remove(subscription) {\n this.forget(subscription)\n if (!this.findAll(subscription.identifier).length) {\n this.sendCommand(subscription, \"unsubscribe\")\n }\n return subscription\n }\n\n reject(identifier) {\n return this.findAll(identifier).map((subscription) => {\n this.forget(subscription)\n this.notify(subscription, \"rejected\")\n return subscription\n })\n }\n\n forget(subscription) {\n this.guarantor.forget(subscription)\n this.subscriptions = (this.subscriptions.filter((s) => s !== subscription))\n return subscription\n }\n\n findAll(identifier) {\n return this.subscriptions.filter((s) => s.identifier === identifier)\n }\n\n reload() {\n return this.subscriptions.map((subscription) =>\n this.subscribe(subscription))\n }\n\n notifyAll(callbackName, ...args) {\n return this.subscriptions.map((subscription) =>\n this.notify(subscription, callbackName, ...args))\n }\n\n notify(subscription, callbackName, ...args) {\n let subscriptions\n if (typeof subscription === \"string\") {\n subscriptions = this.findAll(subscription)\n } else {\n subscriptions = [subscription]\n }\n\n return subscriptions.map((subscription) =>\n (typeof subscription[callbackName] === \"function\" ? subscription[callbackName](...args) : undefined))\n }\n\n subscribe(subscription) {\n if (this.sendCommand(subscription, \"subscribe\")) {\n this.guarantor.guarantee(subscription)\n }\n }\n\n confirmSubscription(identifier) {\n logger.log(`Subscription confirmed ${identifier}`)\n this.findAll(identifier).map((subscription) =>\n this.guarantor.forget(subscription))\n }\n\n sendCommand(subscription, command) {\n const {identifier} = subscription\n return this.consumer.send({command, identifier})\n }\n}\n", "import Connection from \"./connection\"\nimport Subscriptions from \"./subscriptions\"\n\n// The ActionCable.Consumer establishes the connection to a server-side Ruby Connection object. Once established,\n// the ActionCable.ConnectionMonitor will ensure that its properly maintained through heartbeats and checking for stale updates.\n// The Consumer instance is also the gateway to establishing subscriptions to desired channels through the #createSubscription\n// method.\n//\n// The following example shows how this can be set up:\n//\n// App = {}\n// App.cable = ActionCable.createConsumer(\"ws://example.com/accounts/1\")\n// App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\")\n//\n// For more details on how you'd configure an actual channel subscription, see ActionCable.Subscription.\n//\n// When a consumer is created, it automatically connects with the server.\n//\n// To disconnect from the server, call\n//\n// App.cable.disconnect()\n//\n// and to restart the connection:\n//\n// App.cable.connect()\n//\n// Any channel subscriptions which existed prior to disconnecting will\n// automatically resubscribe.\n\nexport default class Consumer {\n constructor(url) {\n this._url = url\n this.subscriptions = new Subscriptions(this)\n this.connection = new Connection(this)\n this.subprotocols = []\n }\n\n get url() {\n return createWebSocketURL(this._url)\n }\n\n send(data) {\n return this.connection.send(data)\n }\n\n connect() {\n return this.connection.open()\n }\n\n disconnect() {\n return this.connection.close({allowReconnect: false})\n }\n\n ensureActiveConnection() {\n if (!this.connection.isActive()) {\n return this.connection.open()\n }\n }\n\n addSubProtocol(subprotocol) {\n this.subprotocols = [...this.subprotocols, subprotocol]\n }\n}\n\nexport function createWebSocketURL(url) {\n if (typeof url === \"function\") {\n url = url()\n }\n\n if (url && !/^wss?:/i.test(url)) {\n const a = document.createElement(\"a\")\n a.href = url\n // Fix populating Location properties in IE. Otherwise, protocol will be blank.\n a.href = a.href\n a.protocol = a.protocol.replace(\"http\", \"ws\")\n return a.href\n } else {\n return url\n }\n}\n", "import Connection from \"./connection\"\nimport ConnectionMonitor from \"./connection_monitor\"\nimport Consumer, { createWebSocketURL } from \"./consumer\"\nimport INTERNAL from \"./internal\"\nimport Subscription from \"./subscription\"\nimport Subscriptions from \"./subscriptions\"\nimport SubscriptionGuarantor from \"./subscription_guarantor\"\nimport adapters from \"./adapters\"\nimport logger from \"./logger\"\n\nexport {\n Connection,\n ConnectionMonitor,\n Consumer,\n INTERNAL,\n Subscription,\n Subscriptions,\n SubscriptionGuarantor,\n adapters,\n createWebSocketURL,\n logger,\n}\n\nexport function createConsumer(url = getConfig(\"url\") || INTERNAL.default_mount_path) {\n return new Consumer(url)\n}\n\nexport function getConfig(name) {\n const element = document.head.querySelector(`meta[name='action-cable-${name}']`)\n if (element) {\n return element.getAttribute(\"content\")\n }\n}\n", "/*!\n * Cropper.js v1.6.2\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2024-04-21T07:43:05.335Z\n */\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Cropper = factory());\n})(this, (function () { 'use strict';\n\n function ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n }\n function _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n }\n function _toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n }\n function _toPropertyKey(t) {\n var i = _toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : i + \"\";\n }\n function _typeof(o) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) {\n return typeof o;\n } : function (o) {\n return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o;\n }, _typeof(o);\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, _toPropertyKey(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 key = _toPropertyKey(key);\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\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\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\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\u00B0\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\u00B0\n case 5:\n rotate = 90;\n scaleY = -1;\n break;\n\n // Rotate right 90\u00B0\n case 6:\n rotate = 90;\n break;\n\n // Flip horizontal and rotate right 90\u00B0\n case 7:\n rotate = 90;\n scaleX = -1;\n break;\n\n // Rotate left 90\u00B0\n case 8:\n rotate = -90;\n break;\n }\n return {\n rotate: rotate,\n scaleX: scaleX,\n scaleY: scaleY\n };\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\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\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\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\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\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(options.rounded),\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\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 element.');\n }\n this.element = element;\n this.options = assign({}, DEFAULTS, isPlainObject(options) && options);\n this.cropped = false;\n this.disabled = false;\n this.pointers = {};\n this.ready = false;\n this.reloading = false;\n this.replaced = false;\n this.sized = false;\n this.sizing = false;\n this.init();\n }\n return _createClass(Cropper, [{\n key: \"init\",\n value: function init() {\n var element = this.element;\n var tagName = element.tagName.toLowerCase();\n var url;\n if (element[NAMESPACE]) {\n return;\n }\n element[NAMESPACE] = this;\n if (tagName === 'img') {\n this.isImg = true;\n\n // e.g.: \"img/picture.jpg\"\n url = element.getAttribute('src') || '';\n this.originalUrl = url;\n\n // Stop when it's a blank image\n if (!url) {\n return;\n }\n\n // e.g.: \"https://example.com/img/picture.jpg\"\n url = element.src;\n } else if (tagName === 'canvas' && window.HTMLCanvasElement) {\n url = element.toDataURL();\n }\n this.load(url);\n }\n }, {\n key: \"load\",\n value: function load(url) {\n var _this = this;\n if (!url) {\n return;\n }\n this.url = url;\n this.imageData = {};\n var element = this.element,\n options = this.options;\n if (!options.rotatable && !options.scalable) {\n options.checkOrientation = false;\n }\n\n // Only IE10+ supports Typed Arrays\n if (!options.checkOrientation || !window.ArrayBuffer) {\n this.clone();\n return;\n }\n\n // Detect the mime type of the image directly if it is a Data URL\n if (REGEXP_DATA_URL.test(url)) {\n // Read ArrayBuffer from Data URL of JPEG images directly for better performance\n if (REGEXP_DATA_URL_JPEG.test(url)) {\n this.read(dataURLToArrayBuffer(url));\n } else {\n // Only a JPEG image may contains Exif Orientation information,\n // the rest types of Data URLs are not necessary to check orientation at all.\n this.clone();\n }\n return;\n }\n\n // 1. Detect the mime type of the image by a XMLHttpRequest.\n // 2. Load the image as ArrayBuffer for reading orientation if its a JPEG image.\n var xhr = new XMLHttpRequest();\n var clone = this.clone.bind(this);\n this.reloading = true;\n this.xhr = xhr;\n\n // 1. Cross origin requests are only supported for protocol schemes:\n // http, https, data, chrome, chrome-extension.\n // 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy\n // in some browsers as IE11 and Safari.\n xhr.onabort = clone;\n xhr.onerror = clone;\n xhr.ontimeout = clone;\n xhr.onprogress = function () {\n // Abort the request directly if it not a JPEG image for better performance\n if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {\n xhr.abort();\n }\n };\n xhr.onload = function () {\n _this.read(xhr.response);\n };\n xhr.onloadend = function () {\n _this.reloading = false;\n _this.xhr = null;\n };\n\n // Bust cache when there is a \"crossOrigin\" property to avoid browser cache error\n if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {\n url = addTimestamp(url);\n }\n\n // The third parameter is required for avoiding side-effect (#682)\n xhr.open('GET', url, true);\n xhr.responseType = 'arraybuffer';\n xhr.withCredentials = element.crossOrigin === 'use-credentials';\n xhr.send();\n }\n }, {\n key: \"read\",\n value: function read(arrayBuffer) {\n var options = this.options,\n imageData = this.imageData;\n\n // Reset the orientation value to its default value 1\n // as some iOS browsers will render image with its orientation\n var orientation = resetAndGetOrientation(arrayBuffer);\n var rotate = 0;\n var scaleX = 1;\n var scaleY = 1;\n if (orientation > 1) {\n // Generate a new URL which has the default orientation value\n this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);\n var _parseOrientation = parseOrientation(orientation);\n rotate = _parseOrientation.rotate;\n scaleX = _parseOrientation.scaleX;\n scaleY = _parseOrientation.scaleY;\n }\n if (options.rotatable) {\n imageData.rotate = rotate;\n }\n if (options.scalable) {\n imageData.scaleX = scaleX;\n imageData.scaleY = scaleY;\n }\n this.clone();\n }\n }, {\n key: \"clone\",\n value: function clone() {\n var element = this.element,\n url = this.url;\n var crossOrigin = element.crossOrigin;\n var crossOriginUrl = url;\n if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {\n if (!crossOrigin) {\n crossOrigin = 'anonymous';\n }\n\n // Bust cache when there is not a \"crossOrigin\" property (#519)\n crossOriginUrl = addTimestamp(url);\n }\n this.crossOrigin = crossOrigin;\n this.crossOriginUrl = crossOriginUrl;\n var image = document.createElement('img');\n if (crossOrigin) {\n image.crossOrigin = crossOrigin;\n }\n image.src = crossOriginUrl || url;\n image.alt = element.alt || 'The image to crop';\n this.image = image;\n image.onload = this.start.bind(this);\n image.onerror = this.stop.bind(this);\n addClass(image, CLASS_HIDE);\n element.parentNode.insertBefore(image, element.nextSibling);\n }\n }, {\n key: \"start\",\n value: function start() {\n var _this2 = this;\n var image = this.image;\n image.onload = null;\n image.onerror = null;\n this.sizing = true;\n\n // Match all browsers that use WebKit as the layout engine in iOS devices,\n // such as Safari for iOS, Chrome for iOS, and in-app browsers.\n var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);\n var done = function done(naturalWidth, naturalHeight) {\n assign(_this2.imageData, {\n naturalWidth: naturalWidth,\n naturalHeight: naturalHeight,\n aspectRatio: naturalWidth / naturalHeight\n });\n _this2.initialImageData = assign({}, _this2.imageData);\n _this2.sizing = false;\n _this2.sized = true;\n _this2.build();\n };\n\n // Most modern browsers (excepts iOS WebKit)\n if (image.naturalWidth && !isIOSWebKit) {\n done(image.naturalWidth, image.naturalHeight);\n return;\n }\n var sizingImage = document.createElement('img');\n var body = document.body || document.documentElement;\n this.sizingImage = sizingImage;\n sizingImage.onload = function () {\n done(sizingImage.width, sizingImage.height);\n if (!isIOSWebKit) {\n body.removeChild(sizingImage);\n }\n };\n sizingImage.src = image.src;\n\n // iOS WebKit will convert the image automatically\n // with its orientation once append it into DOM (#279)\n if (!isIOSWebKit) {\n sizingImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';\n body.appendChild(sizingImage);\n }\n }\n }, {\n key: \"stop\",\n value: function stop() {\n var image = this.image;\n image.onload = null;\n image.onerror = null;\n image.parentNode.removeChild(image);\n this.image = null;\n }\n }, {\n key: \"build\",\n value: function build() {\n if (!this.sized || this.ready) {\n return;\n }\n var element = this.element,\n options = this.options,\n image = this.image;\n\n // Create cropper elements\n var container = element.parentNode;\n var template = document.createElement('div');\n template.innerHTML = TEMPLATE;\n var cropper = template.querySelector(\".\".concat(NAMESPACE, \"-container\"));\n var canvas = cropper.querySelector(\".\".concat(NAMESPACE, \"-canvas\"));\n var dragBox = cropper.querySelector(\".\".concat(NAMESPACE, \"-drag-box\"));\n var cropBox = cropper.querySelector(\".\".concat(NAMESPACE, \"-crop-box\"));\n var face = cropBox.querySelector(\".\".concat(NAMESPACE, \"-face\"));\n this.container = container;\n this.cropper = cropper;\n this.canvas = canvas;\n this.dragBox = dragBox;\n this.cropBox = cropBox;\n this.viewBox = cropper.querySelector(\".\".concat(NAMESPACE, \"-view-box\"));\n this.face = face;\n canvas.appendChild(image);\n\n // Hide the original image\n addClass(element, CLASS_HIDDEN);\n\n // Inserts the cropper after to the current image\n container.insertBefore(cropper, element.nextSibling);\n\n // Show the hidden image\n removeClass(image, CLASS_HIDE);\n this.initPreview();\n this.bind();\n options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;\n options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;\n options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;\n addClass(cropBox, CLASS_HIDDEN);\n if (!options.guides) {\n addClass(cropBox.getElementsByClassName(\"\".concat(NAMESPACE, \"-dashed\")), CLASS_HIDDEN);\n }\n if (!options.center) {\n addClass(cropBox.getElementsByClassName(\"\".concat(NAMESPACE, \"-center\")), CLASS_HIDDEN);\n }\n if (options.background) {\n addClass(cropper, \"\".concat(NAMESPACE, \"-bg\"));\n }\n if (!options.highlight) {\n addClass(face, CLASS_INVISIBLE);\n }\n if (options.cropBoxMovable) {\n addClass(face, CLASS_MOVE);\n setData(face, DATA_ACTION, ACTION_ALL);\n }\n if (!options.cropBoxResizable) {\n addClass(cropBox.getElementsByClassName(\"\".concat(NAMESPACE, \"-line\")), CLASS_HIDDEN);\n addClass(cropBox.getElementsByClassName(\"\".concat(NAMESPACE, \"-point\")), CLASS_HIDDEN);\n }\n this.render();\n this.ready = true;\n this.setDragMode(options.dragMode);\n if (options.autoCrop) {\n this.crop();\n }\n this.setData(options.data);\n if (isFunction(options.ready)) {\n addListener(element, EVENT_READY, options.ready, {\n once: true\n });\n }\n dispatchEvent(element, EVENT_READY);\n }\n }, {\n key: \"unbuild\",\n value: function unbuild() {\n if (!this.ready) {\n return;\n }\n this.ready = false;\n this.unbind();\n this.resetPreview();\n var parentNode = this.cropper.parentNode;\n if (parentNode) {\n parentNode.removeChild(this.cropper);\n }\n removeClass(this.element, CLASS_HIDDEN);\n }\n }, {\n key: \"uncreate\",\n value: function uncreate() {\n if (this.ready) {\n this.unbuild();\n this.ready = false;\n this.cropped = false;\n } else if (this.sizing) {\n this.sizingImage.onload = null;\n this.sizing = false;\n this.sized = false;\n } else if (this.reloading) {\n this.xhr.onabort = null;\n this.xhr.abort();\n } else if (this.image) {\n this.stop();\n }\n }\n\n /**\n * Get the no conflict cropper class.\n * @returns {Cropper} The cropper class.\n */\n }], [{\n key: \"noConflict\",\n value: function noConflict() {\n window.Cropper = AnotherCropper;\n return Cropper;\n }\n\n /**\n * Change the default options.\n * @param {Object} options - The new default options.\n */\n }, {\n key: \"setDefaults\",\n value: function setDefaults(options) {\n assign(DEFAULTS, isPlainObject(options) && options);\n }\n }]);\n }();\n assign(Cropper.prototype, render, preview, events, handlers, change, methods);\n\n return Cropper;\n\n}));\n", "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Pickr\"] = factory();\n\telse\n\t\troot[\"Pickr\"] = factory();\n})(self, () => {\nreturn ", "// The require scope\nvar __webpack_require__ = {};\n\n", "// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};", "__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))", "// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};", "/* eslint-disable prefer-rest-params */\nfunction eventListener(method, elements, events, fn, options = {}) {\n\n // Normalize array\n if (elements instanceof HTMLCollection || elements instanceof NodeList) {\n elements = Array.from(elements);\n } else if (!Array.isArray(elements)) {\n elements = [elements];\n }\n\n if (!Array.isArray(events)) {\n events = [events];\n }\n\n for (const el of elements) {\n for (const ev of events) {\n el[method](ev, fn, {capture: false, ...options});\n }\n }\n\n return Array.prototype.slice.call(arguments, 1);\n}\n\n/**\n * Add event(s) to element(s).\n * @param elements DOM-Elements\n * @param events Event names\n * @param fn Callback\n * @param options Optional options\n * @return Array passed arguments\n */\nexport const on = eventListener.bind(null, 'addEventListener');\n\n/**\n * Remove event(s) from element(s).\n * @param elements DOM-Elements\n * @param events Event names\n * @param fn Callback\n * @param options Optional options\n * @return Array passed arguments\n */\nexport const off = eventListener.bind(null, 'removeEventListener');\n\n/**\n * Creates an DOM-Element out of a string (Single element).\n * @param html HTML representing a single element\n * @returns {Element | null} The element.\n */\nexport function createElementFromString(html) {\n const div = document.createElement('div');\n div.innerHTML = html.trim();\n return div.firstElementChild;\n}\n\n/**\n * Creates a new html element, every element which has\n * a ':ref' attribute will be saved in a object (which will be returned)\n * where the value of ':ref' is the object-key and the value the HTMLElement.\n *\n * It's possible to create a hierarchy if you add a ':obj' attribute. Every\n * sibling will be added to the object which will get the name from the 'data-con' attribute.\n *\n * If you want to create an Array out of multiple elements, you can use the ':arr' attribute,\n * the value defines the key and all elements, which has the same parent and the same 'data-arr' attribute,\n * would be added to it.\n *\n * @param str - The HTML String.\n */\n\nexport function createFromTemplate(str) {\n\n // Removes an attribute from a HTMLElement and returns the value.\n const removeAttribute = (el, name) => {\n const value = el.getAttribute(name);\n el.removeAttribute(name);\n return value;\n };\n\n // Recursive function to resolve template\n const resolve = (element, base = {}) => {\n\n // Check key and container attribute\n const con = removeAttribute(element, ':obj');\n const key = removeAttribute(element, ':ref');\n const subtree = con ? (base[con] = {}) : base;\n\n // Check and save element\n key && (base[key] = element);\n for (const child of Array.from(element.children)) {\n const arr = removeAttribute(child, ':arr');\n const sub = resolve(child, arr ? {} : subtree);\n\n if (arr) {\n\n // Check if there is already an array and add element\n (subtree[arr] || (subtree[arr] = []))\n .push(Object.keys(sub).length ? sub : child);\n }\n }\n\n return base;\n };\n\n return resolve(createElementFromString(str));\n}\n\n/**\n * Polyfill for safari & firefox for the eventPath event property.\n * @param evt The event object.\n * @return [String] event path.\n */\nexport function eventPath(evt) {\n let path = evt.path || (evt.composedPath && evt.composedPath());\n if (path) {\n return path;\n }\n\n let el = evt.target.parentElement;\n path = [evt.target, el];\n while (el = el.parentElement) {\n path.push(el);\n }\n\n path.push(document, window);\n return path;\n}\n\n/**\n * Resolves a HTMLElement by query.\n * @param val\n * @returns {null|Document|Element}\n */\nexport function resolveElement(val) {\n if (val instanceof Element) {\n return val;\n } else if (typeof val === 'string') {\n return val.split(/>>/g).reduce((pv, cv, ci, a) => {\n pv = pv.querySelector(cv);\n return ci < a.length - 1 ? pv.shadowRoot : pv;\n }, document);\n }\n\n return null;\n}\n\n/**\n * Creates the ability to change numbers in an input field with the scroll-wheel.\n * @param el\n * @param mapper\n */\nexport function adjustableInputNumbers(el, mapper = v => v) {\n\n function handleScroll(e) {\n const inc = ([0.001, 0.01, 0.1])[Number(e.shiftKey || e.ctrlKey * 2)] * (e.deltaY < 0 ? 1 : -1);\n\n let index = 0;\n let off = el.selectionStart;\n el.value = el.value.replace(/[\\d.]+/g, (v, i) => {\n\n // Check if number is in cursor range and increase it\n if (i <= off && i + v.length >= off) {\n off = i;\n return mapper(Number(v), inc, index);\n }\n\n index++;\n return v;\n });\n\n el.focus();\n el.setSelectionRange(off, off);\n\n // Prevent default and trigger input event\n e.preventDefault();\n el.dispatchEvent(new Event('input'));\n }\n\n // Bind events\n on(el, 'focus', () => on(window, 'wheel', handleScroll, {passive: false}));\n on(el, 'blur', () => off(window, 'wheel', handleScroll));\n}\n", "// Shorthands\nconst {min, max, floor, round} = Math;\n\n/**\n * Tries to convert a color name to rgb/a hex representation\n * @param name\n * @returns {string | CanvasGradient | CanvasPattern}\n */\nfunction standardizeColor(name) {\n\n // Since invalid color's will be parsed as black, filter them out\n if (name.toLowerCase() === 'black') {\n return '#000';\n }\n\n const ctx = document.createElement('canvas').getContext('2d');\n ctx.fillStyle = name;\n return ctx.fillStyle === '#000' ? null : ctx.fillStyle;\n}\n\n/**\n * Convert HSV spectrum to RGB.\n * @param h Hue\n * @param s Saturation\n * @param v Value\n * @returns {number[]} Array with rgb values.\n */\nexport function hsvToRgb(h, s, v) {\n h = (h / 360) * 6;\n s /= 100;\n v /= 100;\n\n const i = floor(h);\n\n const f = h - i;\n const p = v * (1 - s);\n const q = v * (1 - f * s);\n const t = v * (1 - (1 - f) * s);\n\n const mod = i % 6;\n const r = [v, q, p, p, t, v][mod];\n const g = [t, v, v, q, p, p][mod];\n const b = [p, p, t, v, v, q][mod];\n\n return [\n r * 255,\n g * 255,\n b * 255\n ];\n}\n\n/**\n * Convert HSV spectrum to Hex.\n * @param h Hue\n * @param s Saturation\n * @param v Value\n * @returns {string[]} Hex values\n */\nexport function hsvToHex(h, s, v) {\n return hsvToRgb(h, s, v).map(v =>\n round(v).toString(16).padStart(2, '0')\n );\n}\n\n/**\n * Convert HSV spectrum to CMYK.\n * @param h Hue\n * @param s Saturation\n * @param v Value\n * @returns {number[]} CMYK values\n */\nexport function hsvToCmyk(h, s, v) {\n const rgb = hsvToRgb(h, s, v);\n const r = rgb[0] / 255;\n const g = rgb[1] / 255;\n const b = rgb[2] / 255;\n\n const k = min(1 - r, 1 - g, 1 - b);\n const c = k === 1 ? 0 : (1 - r - k) / (1 - k);\n const m = k === 1 ? 0 : (1 - g - k) / (1 - k);\n const y = k === 1 ? 0 : (1 - b - k) / (1 - k);\n\n return [\n c * 100,\n m * 100,\n y * 100,\n k * 100\n ];\n}\n\n/**\n * Convert HSV spectrum to HSL.\n * @param h Hue\n * @param s Saturation\n * @param v Value\n * @returns {number[]} HSL values\n */\nexport function hsvToHsl(h, s, v) {\n s /= 100;\n v /= 100;\n\n const l = (2 - s) * v / 2;\n\n if (l !== 0) {\n if (l === 1) {\n s = 0;\n } else if (l < 0.5) {\n s = s * v / (l * 2);\n } else {\n s = s * v / (2 - l * 2);\n }\n }\n\n return [\n h,\n s * 100,\n l * 100\n ];\n}\n\n/**\n * Convert RGB to HSV.\n * @param r Red\n * @param g Green\n * @param b Blue\n * @return {number[]} HSV values.\n */\nfunction rgbToHsv(r, g, b) {\n r /= 255;\n g /= 255;\n b /= 255;\n\n const minVal = min(r, g, b);\n const maxVal = max(r, g, b);\n const delta = maxVal - minVal;\n\n let h, s;\n const v = maxVal;\n if (delta === 0) {\n h = s = 0;\n } else {\n s = delta / maxVal;\n const dr = (((maxVal - r) / 6) + (delta / 2)) / delta;\n const dg = (((maxVal - g) / 6) + (delta / 2)) / delta;\n const db = (((maxVal - b) / 6) + (delta / 2)) / delta;\n\n if (r === maxVal) {\n h = db - dg;\n } else if (g === maxVal) {\n h = (1 / 3) + dr - db;\n } else if (b === maxVal) {\n h = (2 / 3) + dg - dr;\n }\n\n if (h < 0) {\n h += 1;\n } else if (h > 1) {\n h -= 1;\n }\n }\n\n return [\n h * 360,\n s * 100,\n v * 100\n ];\n}\n\n/**\n * Convert CMYK to HSV.\n * @param c Cyan\n * @param m Magenta\n * @param y Yellow\n * @param k Key (Black)\n * @return {number[]} HSV values.\n */\nfunction cmykToHsv(c, m, y, k) {\n c /= 100;\n m /= 100;\n y /= 100;\n k /= 100;\n\n const r = (1 - min(1, c * (1 - k) + k)) * 255;\n const g = (1 - min(1, m * (1 - k) + k)) * 255;\n const b = (1 - min(1, y * (1 - k) + k)) * 255;\n\n return [...rgbToHsv(r, g, b)];\n}\n\n/**\n * Convert HSL to HSV.\n * @param h Hue\n * @param s Saturation\n * @param l Lightness\n * @return {number[]} HSV values.\n */\nfunction hslToHsv(h, s, l) {\n s /= 100;\n l /= 100;\n s *= l < 0.5 ? l : 1 - l;\n\n const ns = (2 * s / (l + s)) * 100;\n const v = (l + s) * 100;\n return [h, isNaN(ns) ? 0 : ns, v];\n}\n\n/**\n * Convert HEX to HSV.\n * @param hex Hexadecimal string of rgb colors, can have length 3 or 6.\n * @return {number[]} HSV values.\n */\nfunction hexToHsv(hex) {\n return rgbToHsv(...hex.match(/.{2}/g).map(v => parseInt(v, 16)));\n}\n\n/**\n * Try's to parse a string which represents a color to a HSV array.\n * Current supported types are cmyk, rgba, hsla and hexadecimal.\n * @param str\n * @return {*}\n */\nexport function parseToHSVA(str) {\n\n // Check if string is a color-name\n str = str.match(/^[a-zA-Z]+$/) ? standardizeColor(str) : str;\n\n // Regular expressions to match different types of color represention\n const regex = {\n cmyk: /^cmyk\\D+([\\d.]+)\\D+([\\d.]+)\\D+([\\d.]+)\\D+([\\d.]+)/i,\n rgba: /^rgba?\\D+([\\d.]+)(%?)\\D+([\\d.]+)(%?)\\D+([\\d.]+)(%?)\\D*?(([\\d.]+)(%?)|$)/i,\n hsla: /^hsla?\\D+([\\d.]+)\\D+([\\d.]+)\\D+([\\d.]+)\\D*?(([\\d.]+)(%?)|$)/i,\n hsva: /^hsva?\\D+([\\d.]+)\\D+([\\d.]+)\\D+([\\d.]+)\\D*?(([\\d.]+)(%?)|$)/i,\n hexa: /^#?(([\\dA-Fa-f]{3,4})|([\\dA-Fa-f]{6})|([\\dA-Fa-f]{8}))$/i\n };\n\n /**\n * Takes an Array of any type, convert strings which represents\n * a number to a number an anything else to undefined.\n * @param array\n * @return {*}\n */\n const numarize = array => array.map(v => /^(|\\d+)\\.\\d+|\\d+$/.test(v) ? Number(v) : undefined);\n\n let match;\n invalid: for (const type in regex) {\n\n // Check if current scheme passed\n if (!(match = regex[type].exec(str))) {\n continue;\n }\n\n // Try to convert\n switch (type) {\n case 'cmyk': {\n const [, c, m, y, k] = numarize(match);\n\n if (c > 100 || m > 100 || y > 100 || k > 100) {\n break invalid;\n }\n\n return {values: cmykToHsv(c, m, y, k), type};\n }\n case 'rgba': {\n let [, r, , g, , b, , , a] = numarize(match);\n\n r = match[2] === '%' ? (r / 100) * 255 : r;\n g = match[4] === '%' ? (g / 100) * 255 : g;\n b = match[6] === '%' ? (b / 100) * 255 : b;\n a = match[9] === '%' ? (a / 100) : a;\n\n if (r > 255 || g > 255 || b > 255 || a < 0 || a > 1) {\n break invalid;\n }\n\n return {values: [...rgbToHsv(r, g, b), a], a, type};\n }\n case 'hexa': {\n let [, hex] = match;\n\n if (hex.length === 4 || hex.length === 3) {\n hex = hex.split('').map(v => v + v).join('');\n }\n\n const raw = hex.substring(0, 6);\n let a = hex.substring(6);\n\n // Convert 0 - 255 to 0 - 1 for opacity\n a = a ? (parseInt(a, 16) / 255) : undefined;\n\n return {values: [...hexToHsv(raw), a], a, type};\n }\n case 'hsla': {\n let [, h, s, l, , a] = numarize(match);\n a = match[6] === '%' ? (a / 100) : a;\n\n if (h > 360 || s > 100 || l > 100 || a < 0 || a > 1) {\n break invalid;\n }\n\n return {values: [...hslToHsv(h, s, l), a], a, type};\n }\n case 'hsva': {\n let [, h, s, v, , a] = numarize(match);\n a = match[6] === '%' ? (a / 100) : a;\n\n if (h > 360 || s > 100 || v > 100 || a < 0 || a > 1) {\n break invalid;\n }\n\n return {values: [h, s, v, a], a, type};\n }\n }\n }\n\n return {values: null, type: null};\n}\n", "import {hsvToCmyk, hsvToHex, hsvToHsl, hsvToRgb} from './color';\n\n/**\n * Simple class which holds the properties\n * of the color represention model hsla (hue saturation lightness alpha)\n */\nexport function HSVaColor(h = 0, s = 0, v = 0, a = 1) {\n const mapper = (original, next) => (precision = -1) => {\n return next(~precision ? original.map(v => Number(v.toFixed(precision))) : original);\n };\n\n const that = {\n h, s, v, a,\n\n toHSVA() {\n const hsva = [that.h, that.s, that.v, that.a];\n hsva.toString = mapper(hsva, arr => `hsva(${arr[0]}, ${arr[1]}%, ${arr[2]}%, ${that.a})`);\n return hsva;\n },\n\n toHSLA() {\n const hsla = [...hsvToHsl(that.h, that.s, that.v), that.a];\n hsla.toString = mapper(hsla, arr => `hsla(${arr[0]}, ${arr[1]}%, ${arr[2]}%, ${that.a})`);\n return hsla;\n },\n\n toRGBA() {\n const rgba = [...hsvToRgb(that.h, that.s, that.v), that.a];\n rgba.toString = mapper(rgba, arr => `rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, ${that.a})`);\n return rgba;\n },\n\n toCMYK() {\n const cmyk = hsvToCmyk(that.h, that.s, that.v);\n cmyk.toString = mapper(cmyk, arr => `cmyk(${arr[0]}%, ${arr[1]}%, ${arr[2]}%, ${arr[3]}%)`);\n return cmyk;\n },\n\n toHEXA() {\n const hex = hsvToHex(that.h, that.s, that.v);\n\n // Check if alpha channel make sense, convert it to 255 number space, convert\n // To hex and pad it with zeros if needet.\n const alpha = that.a >= 1 ? '' : Number((that.a * 255).toFixed(0))\n .toString(16)\n .toUpperCase().padStart(2, '0');\n\n alpha && hex.push(alpha);\n hex.toString = () => `#${hex.join('').toUpperCase()}`;\n return hex;\n },\n\n clone: () => HSVaColor(that.h, that.s, that.v, that.a)\n };\n\n return that;\n}\n", "import * as _ from '../utils/utils';\n\nconst clamp = v => Math.max(Math.min(v, 1), 0);\nexport default function Moveable(opt) {\n\n const that = {\n\n // Assign default values\n options: Object.assign({\n lock: null,\n onchange: () => 0,\n onstop: () => 0\n }, opt),\n\n _keyboard(e) {\n const {options} = that;\n const {type, key} = e;\n\n // Check to see if the Movable is focused and then move it based on arrow key inputs\n // For improved accessibility\n if (document.activeElement === options.wrapper) {\n const {lock} = that.options;\n const up = key === 'ArrowUp';\n const right = key === 'ArrowRight';\n const down = key === 'ArrowDown';\n const left = key === 'ArrowLeft';\n\n if (type === 'keydown' && (up || right || down || left)) {\n let xm = 0;\n let ym = 0;\n\n if (lock === 'v') {\n xm = (up || right) ? 1 : -1;\n } else if (lock === 'h') {\n xm = (up || right) ? -1 : 1;\n } else {\n ym = up ? -1 : (down ? 1 : 0);\n xm = left ? -1 : (right ? 1 : 0);\n }\n\n that.update(\n clamp(that.cache.x + (0.01 * xm)),\n clamp(that.cache.y + (0.01 * ym))\n );\n e.preventDefault();\n } else if (key.startsWith('Arrow')) {\n that.options.onstop();\n e.preventDefault();\n }\n }\n },\n\n _tapstart(evt) {\n _.on(document, ['mouseup', 'touchend', 'touchcancel'], that._tapstop);\n _.on(document, ['mousemove', 'touchmove'], that._tapmove);\n\n if (evt.cancelable) {\n evt.preventDefault();\n }\n\n // Trigger\n that._tapmove(evt);\n },\n\n _tapmove(evt) {\n const {options, cache} = that;\n const {lock, element, wrapper} = options;\n const b = wrapper.getBoundingClientRect();\n\n let x = 0, y = 0;\n if (evt) {\n const touch = evt && evt.touches && evt.touches[0];\n x = evt ? (touch || evt).clientX : 0;\n y = evt ? (touch || evt).clientY : 0;\n\n // Reset to bounds\n if (x < b.left) {\n x = b.left;\n } else if (x > b.left + b.width) {\n x = b.left + b.width;\n }\n if (y < b.top) {\n y = b.top;\n } else if (y > b.top + b.height) {\n y = b.top + b.height;\n }\n\n // Normalize\n x -= b.left;\n y -= b.top;\n } else if (cache) {\n x = cache.x * b.width;\n y = cache.y * b.height;\n }\n\n if (lock !== 'h') {\n element.style.left = `calc(${x / b.width * 100}% - ${element.offsetWidth / 2}px)`;\n }\n\n if (lock !== 'v') {\n element.style.top = `calc(${y / b.height * 100}% - ${element.offsetHeight / 2}px)`;\n }\n\n that.cache = {x: x / b.width, y: y / b.height};\n const cx = clamp(x / b.width);\n const cy = clamp(y / b.height);\n\n switch (lock) {\n case 'v':\n return options.onchange(cx);\n case 'h':\n return options.onchange(cy);\n default:\n return options.onchange(cx, cy);\n }\n },\n\n _tapstop() {\n that.options.onstop();\n _.off(document, ['mouseup', 'touchend', 'touchcancel'], that._tapstop);\n _.off(document, ['mousemove', 'touchmove'], that._tapmove);\n },\n\n trigger() {\n that._tapmove();\n },\n\n update(x = 0, y = 0) {\n const {left, top, width, height} = that.options.wrapper.getBoundingClientRect();\n\n if (that.options.lock === 'h') {\n y = x;\n }\n\n that._tapmove({\n clientX: left + width * x,\n clientY: top + height * y\n });\n },\n\n destroy() {\n const {options, _tapstart, _keyboard} = that;\n _.off(document, ['keydown', 'keyup'], _keyboard);\n _.off([options.wrapper, options.element], 'mousedown', _tapstart);\n _.off([options.wrapper, options.element], 'touchstart', _tapstart, {\n passive: false\n });\n }\n };\n\n // Initilize\n const {options, _tapstart, _keyboard} = that;\n _.on([options.wrapper, options.element], 'mousedown', _tapstart);\n _.on([options.wrapper, options.element], 'touchstart', _tapstart, {\n passive: false\n });\n\n _.on(document, ['keydown', 'keyup'], _keyboard);\n\n return that;\n}\n", "import * as _ from '../utils/utils';\n\nexport default function Selectable(opt = {}) {\n opt = Object.assign({\n onchange: () => 0,\n className: '',\n elements: []\n }, opt);\n\n const onTap = _.on(opt.elements, 'click', evt => {\n opt.elements.forEach(e =>\n e.classList[evt.target === e ? 'add' : 'remove'](opt.className)\n );\n\n opt.onchange(evt);\n\n // Fix for https://github.com/Simonwep/pickr/issues/243\n evt.stopPropagation();\n });\n\n return {\n destroy: () => _.off(...onTap)\n };\n}\n", "import * as _ from './utils/utils';\n\nexport default instance => {\n\n const {\n components,\n useAsButton,\n inline,\n appClass,\n theme,\n lockOpacity\n } = instance.options;\n\n // Utils\n const hidden = con => con ? '' : 'style=\"display:none\" hidden';\n const t = str => instance._t(str);\n\n const root = _.createFromTemplate(`\n
\n\n ${useAsButton ? '' : ''}\n\n
\n
\n
\n \n
\n
\n\n
\n
\n
\n
\n\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n\n
\n\n
\n \n\n \n \n \n \n \n\n \n \n \n
\n
\n
\n `);\n\n const int = root.interaction;\n\n // Select option which is not hidden\n int.options.find(o => !o.hidden && !o.classList.add('active'));\n\n // Append method to find currently active option\n int.type = () => int.options.find(e => e.classList.contains('active'));\n return root;\n};\n", "/*! NanoPop 2.4.2 MIT | https://github.com/Simonwep/nanopop */\nconst N = \"2.4.2\", I = {\n variantFlipOrder: { start: \"sme\", middle: \"mse\", end: \"ems\" },\n positionFlipOrder: { top: \"tbrl\", right: \"rltb\", bottom: \"btrl\", left: \"lrbt\" },\n position: \"bottom\",\n margin: 8,\n padding: 0\n}, J = (n, i, m) => {\n const {\n container: r,\n arrow: a,\n margin: e,\n padding: l,\n position: V,\n variantFlipOrder: C,\n positionFlipOrder: M\n } = {\n container: document.documentElement.getBoundingClientRect(),\n ...I,\n ...m\n }, { left: F, top: K } = i.style;\n i.style.left = \"0\", i.style.top = \"0\";\n const t = n.getBoundingClientRect(), o = i.getBoundingClientRect(), P = {\n t: t.top - o.height - e,\n b: t.bottom + e,\n r: t.right + e,\n l: t.left - o.width - e\n }, R = {\n vs: t.left,\n vm: t.left + t.width / 2 - o.width / 2,\n ve: t.left + t.width - o.width,\n hs: t.top,\n hm: t.bottom - t.height / 2 - o.height / 2,\n he: t.bottom - o.height\n }, [$, E = \"middle\"] = V.split(\"-\"), L = M[$], j = C[E], { top: y, left: x, bottom: B, right: O } = r;\n for (const c of L) {\n const s = c === \"t\" || c === \"b\";\n let p = P[c];\n const [d, g] = s ? [\"top\", \"left\"] : [\"left\", \"top\"], [u, v] = s ? [o.height, o.width] : [o.width, o.height], [z, T] = s ? [B, O] : [O, B], [H, k] = s ? [y, x] : [x, y];\n if (!(p < H || p + u + l > z))\n for (const b of j) {\n let f = R[(s ? \"v\" : \"h\") + b];\n if (!(f < k || f + v + l > T)) {\n if (f -= o[g], p -= o[d], i.style[g] = `${f}px`, i.style[d] = `${p}px`, a) {\n const w = s ? t.width / 2 : t.height / 2, h = v / 2, S = w > h, q = {\n s: S ? h : w,\n m: h,\n e: S ? h : v - w\n }, A = {\n t: u,\n b: 0,\n r: 0,\n l: u\n }, D = f + q[b], G = p + A[c];\n a.style[g] = `${D}px`, a.style[d] = `${G}px`;\n }\n return c + b;\n }\n }\n }\n return i.style.left = F, i.style.top = K, null;\n}, Q = (n, i, m) => {\n const r = typeof n == \"object\" && !(n instanceof HTMLElement) ? n : { reference: n, popper: i, ...m };\n return {\n /**\n * Repositions the current popper.\n * @param options Optional options which get merged with the current ones.\n */\n update(a = r) {\n const { reference: e, popper: l } = Object.assign(r, a);\n if (!l || !e)\n throw new Error(\"Popper- or reference-element missing.\");\n return J(e, l, r);\n }\n };\n};\nexport {\n Q as createPopper,\n I as defaults,\n J as reposition,\n N as version\n};\n//# sourceMappingURL=nanopop.mjs.map\n", "import * as _ from './utils/utils';\nimport {parseToHSVA} from './utils/color';\nimport {HSVaColor} from './utils/hsvacolor';\nimport Moveable from './libs/moveable';\nimport Selectable from './libs/selectable';\nimport buildPickr from './template';\nimport {createPopper} from 'nanopop';\n\nexport default class Pickr {\n\n // Expose pickr utils\n static utils = _;\n\n // Assign version and export\n static version = VERSION;\n\n // Default strings\n static I18N_DEFAULTS = {\n\n // Strings visible in the UI\n 'ui:dialog': 'color picker dialog',\n 'btn:toggle': 'toggle color picker dialog',\n 'btn:swatch': 'color swatch',\n 'btn:last-color': 'use previous color',\n 'btn:save': 'Save',\n 'btn:cancel': 'Cancel',\n 'btn:clear': 'Clear',\n\n // Strings used for aria-labels\n 'aria:btn:save': 'save and close',\n 'aria:btn:cancel': 'cancel and close',\n 'aria:btn:clear': 'clear and close',\n 'aria:input': 'color input field',\n 'aria:palette': 'color selection area',\n 'aria:hue': 'hue selection slider',\n 'aria:opacity': 'selection slider'\n };\n\n // Default options\n static DEFAULT_OPTIONS = {\n appClass: null,\n theme: 'classic',\n useAsButton: false,\n padding: 8,\n disabled: false,\n comparison: true,\n closeOnScroll: false,\n outputPrecision: 0,\n lockOpacity: false,\n autoReposition: true,\n container: 'body',\n\n components: {\n interaction: {}\n },\n\n i18n: {},\n swatches: null,\n inline: false,\n sliders: null,\n\n default: '#42445a',\n defaultRepresentation: null,\n position: 'bottom-middle',\n adjustableNumbers: true,\n showAlways: false,\n\n closeWithKey: 'Escape'\n };\n\n // Will be used to prevent specific actions during initilization\n _initializingActive = true;\n\n // If the current color value should be recalculated\n _recalc = true;\n\n // Positioning engine and DOM-Tree\n _nanopop = null;\n _root = null;\n\n // Current and last color for comparison\n _color = HSVaColor();\n _lastColor = HSVaColor();\n _swatchColors = [];\n\n // Animation frame used for setup.\n // Will be cancelled in case of destruction.\n _setupAnimationFrame = null;\n\n // Evenlistener name: [callbacks]\n _eventListener = {\n init: [],\n save: [],\n hide: [],\n show: [],\n clear: [],\n change: [],\n changestop: [],\n cancel: [],\n swatchselect: []\n };\n\n constructor(opt) {\n\n // Assign default values\n this.options = opt = Object.assign({...Pickr.DEFAULT_OPTIONS}, opt);\n\n const {swatches, components, theme, sliders, lockOpacity, padding} = opt;\n\n if (['nano', 'monolith'].includes(theme) && !sliders) {\n opt.sliders = 'h';\n }\n\n // Check interaction section\n if (!components.interaction) {\n components.interaction = {};\n }\n\n // Overwrite palette if preview, opacity or hue are true\n const {preview, opacity, hue, palette} = components;\n components.opacity = (!lockOpacity && opacity);\n components.palette = palette || preview || opacity || hue;\n\n // Initialize picker\n this._preBuild();\n this._buildComponents();\n this._bindEvents();\n this._finalBuild();\n\n // Append pre-defined swatch colors\n if (swatches && swatches.length) {\n swatches.forEach(color => this.addSwatch(color));\n }\n\n // Initialize positioning engine\n const {button, app} = this._root;\n this._nanopop = createPopper(button, app, {\n margin: padding\n });\n\n // Initialize accessibility\n button.setAttribute('role', 'button');\n button.setAttribute('aria-label', this._t('btn:toggle'));\n\n // Initilization is finish, pickr is visible and ready for usage\n const that = this;\n this._setupAnimationFrame = requestAnimationFrame((function cb() {\n\n // TODO: Performance issue due to high call-rate?\n if (!app.offsetWidth) {\n return requestAnimationFrame(cb);\n }\n\n // Apply default color\n that.setColor(opt.default);\n that._rePositioningPicker();\n\n // Initialize color representation\n if (opt.defaultRepresentation) {\n that._representation = opt.defaultRepresentation;\n that.setColorRepresentation(that._representation);\n }\n\n // Show pickr if locked\n if (opt.showAlways) {\n that.show();\n }\n\n // Initialization is done - pickr is usable, fire init event\n that._initializingActive = false;\n that._emit('init');\n }));\n }\n\n // Create instance via method\n static create = options => new Pickr(options);\n\n // Does only the absolutly basic thing to initialize the components\n _preBuild() {\n const {options} = this;\n\n // Resolve elements\n for (const type of ['el', 'container']) {\n options[type] = _.resolveElement(options[type]);\n }\n\n // Create element and append it to body to\n // Prevent initialization errors\n this._root = buildPickr(this);\n\n // Check if a custom button is used\n if (options.useAsButton) {\n this._root.button = options.el; // Replace button with customized button\n }\n\n options.container.appendChild(this._root.root);\n }\n\n _finalBuild() {\n const opt = this.options;\n const root = this._root;\n\n // Remove from body\n opt.container.removeChild(root.root);\n\n if (opt.inline) {\n const parent = opt.el.parentElement;\n\n if (opt.el.nextSibling) {\n parent.insertBefore(root.app, opt.el.nextSibling);\n } else {\n parent.appendChild(root.app);\n }\n } else {\n opt.container.appendChild(root.app);\n }\n\n // Don't replace the the element if a custom button is used\n if (!opt.useAsButton) {\n\n // Replace element with actual color-picker\n opt.el.parentNode.replaceChild(root.root, opt.el);\n } else if (opt.inline) {\n opt.el.remove();\n }\n\n // Check if it should be immediatly disabled\n if (opt.disabled) {\n this.disable();\n }\n\n // Check if color comparison is disabled, if yes - remove transitions so everything keeps smoothly\n if (!opt.comparison) {\n root.button.style.transition = 'none';\n\n if (!opt.useAsButton) {\n root.preview.lastColor.style.transition = 'none';\n }\n }\n\n this.hide();\n }\n\n _buildComponents() {\n\n // Instance reference\n const inst = this;\n const cs = this.options.components;\n const sliders = (inst.options.sliders || 'v').repeat(2);\n const [so, sh] = sliders.match(/^[vh]+$/g) ? sliders : [];\n\n // Re-assign if null\n const getColor = () =>\n this._color || (this._color = this._lastColor.clone());\n\n const components = {\n\n palette: Moveable({\n element: inst._root.palette.picker,\n wrapper: inst._root.palette.palette,\n\n onstop: () => inst._emit('changestop', 'slider', inst),\n onchange(x, y) {\n if (!cs.palette) {\n return;\n }\n\n const color = getColor();\n const {_root, options} = inst;\n const {lastColor, currentColor} = _root.preview;\n\n // Update the input field only if the user is currently not typing\n if (inst._recalc) {\n\n // Calculate saturation based on the position\n color.s = x * 100;\n\n // Calculate the value\n color.v = 100 - y * 100;\n\n // Prevent falling under zero\n color.v < 0 ? color.v = 0 : 0;\n inst._updateOutput('slider');\n }\n\n // Set picker and gradient color\n const cssRGBaString = color.toRGBA().toString(0);\n this.element.style.background = cssRGBaString;\n this.wrapper.style.background = `\n linear-gradient(to top, rgba(0, 0, 0, ${color.a}), transparent),\n linear-gradient(to left, hsla(${color.h}, 100%, 50%, ${color.a}), rgba(255, 255, 255, ${color.a}))\n `;\n\n // Check if color is locked\n if (!options.comparison) {\n _root.button.style.setProperty('--pcr-color', cssRGBaString);\n\n // If the user changes the color, remove the cleared icon\n _root.button.classList.remove('clear');\n } else if (!options.useAsButton && !inst._lastColor) {\n\n // Apply color to both the last and current color since the current state is cleared\n lastColor.style.setProperty('--pcr-color', cssRGBaString);\n }\n\n // Check if there's a swatch which color matches the current one\n const hexa = color.toHEXA().toString();\n for (const {el, color} of inst._swatchColors) {\n el.classList[hexa === color.toHEXA().toString() ? 'add' : 'remove']('pcr-active');\n }\n\n // Change current color\n currentColor.style.setProperty('--pcr-color', cssRGBaString);\n }\n }),\n\n hue: Moveable({\n lock: sh === 'v' ? 'h' : 'v',\n element: inst._root.hue.picker,\n wrapper: inst._root.hue.slider,\n\n onstop: () => inst._emit('changestop', 'slider', inst),\n onchange(v) {\n if (!cs.hue || !cs.palette) {\n return;\n }\n\n const color = getColor();\n\n // Calculate hue\n if (inst._recalc) {\n color.h = v * 360;\n }\n\n // Update color\n this.element.style.backgroundColor = `hsl(${color.h}, 100%, 50%)`;\n components.palette.trigger();\n }\n }),\n\n opacity: Moveable({\n lock: so === 'v' ? 'h' : 'v',\n element: inst._root.opacity.picker,\n wrapper: inst._root.opacity.slider,\n\n onstop: () => inst._emit('changestop', 'slider', inst),\n onchange(v) {\n if (!cs.opacity || !cs.palette) {\n return;\n }\n\n const color = getColor();\n\n // Calculate opacity\n if (inst._recalc) {\n color.a = Math.round(v * 1e2) / 100;\n }\n\n // Update color\n this.element.style.background = `rgba(0, 0, 0, ${color.a})`;\n components.palette.trigger();\n }\n }),\n\n selectable: Selectable({\n elements: inst._root.interaction.options,\n className: 'active',\n\n onchange(e) {\n inst._representation = e.target.getAttribute('data-type').toUpperCase();\n inst._recalc && inst._updateOutput('swatch');\n }\n })\n };\n\n this._components = components;\n }\n\n _bindEvents() {\n const {_root, options} = this;\n\n const eventBindings = [\n\n // Clear color\n _.on(_root.interaction.clear, 'click', () => this._clearColor()),\n\n // Select last color on click\n _.on([\n _root.interaction.cancel,\n _root.preview.lastColor\n ], 'click', () => {\n this.setHSVA(...(this._lastColor || this._color).toHSVA(), true);\n this._emit('cancel');\n }),\n\n // Save color\n _.on(_root.interaction.save, 'click', () => {\n !this.applyColor() && !options.showAlways && this.hide();\n }),\n\n // User input\n _.on(_root.interaction.result, ['keyup', 'input'], e => {\n\n // Fire listener if initialization is finish and changed color was valid\n if (this.setColor(e.target.value, true) && !this._initializingActive) {\n this._emit('change', this._color, 'input', this);\n this._emit('changestop', 'input', this);\n }\n\n e.stopImmediatePropagation();\n }),\n\n // Detect user input and disable auto-recalculation\n _.on(_root.interaction.result, ['focus', 'blur'], e => {\n this._recalc = e.type === 'blur';\n this._recalc && this._updateOutput(null);\n }),\n\n // Cancel input detection on color change\n _.on([\n _root.palette.palette,\n _root.palette.picker,\n _root.hue.slider,\n _root.hue.picker,\n _root.opacity.slider,\n _root.opacity.picker\n ], ['mousedown', 'touchstart'], () => this._recalc = true, {passive: true})\n ];\n\n // Provide hiding / showing abilities only if showAlways is false\n if (!options.showAlways) {\n const ck = options.closeWithKey;\n\n eventBindings.push(\n\n // Save and hide / show picker\n _.on(_root.button, 'click', () => this.isOpen() ? this.hide() : this.show()),\n\n // Close with escape key\n _.on(document, 'keyup', e => this.isOpen() && (e.key === ck || e.code === ck) && this.hide()),\n\n // Cancel selecting if the user taps behind the color picker\n _.on(document, ['touchstart', 'mousedown'], e => {\n if (this.isOpen() && !_.eventPath(e).some(el => el === _root.app || el === _root.button)) {\n this.hide();\n }\n }, {capture: true})\n );\n }\n\n // Make input adjustable if enabled\n if (options.adjustableNumbers) {\n const ranges = {\n rgba: [255, 255, 255, 1],\n hsva: [360, 100, 100, 1],\n hsla: [360, 100, 100, 1],\n cmyk: [100, 100, 100, 100]\n };\n\n _.adjustableInputNumbers(_root.interaction.result, (o, step, index) => {\n const range = ranges[this.getColorRepresentation().toLowerCase()];\n\n if (range) {\n const max = range[index];\n\n // Calculate next reasonable number\n const nv = o + (max >= 100 ? step * 1000 : step);\n\n // Apply range of zero up to max, fix floating-point issues\n return nv <= 0 ? 0 : Number((nv < max ? nv : max).toPrecision(3));\n }\n\n return o;\n });\n }\n\n if (options.autoReposition && !options.inline) {\n let timeout = null;\n const that = this;\n\n // Re-calc position on window resize, scroll and wheel\n eventBindings.push(\n _.on(window, ['scroll', 'resize'], () => {\n if (that.isOpen()) {\n\n if (options.closeOnScroll) {\n that.hide();\n }\n\n if (timeout === null) {\n timeout = setTimeout(() => timeout = null, 100);\n\n // Update position on every frame\n requestAnimationFrame(function rs() {\n that._rePositioningPicker();\n (timeout !== null) && requestAnimationFrame(rs);\n });\n } else {\n clearTimeout(timeout);\n timeout = setTimeout(() => timeout = null, 100);\n }\n }\n }, {capture: true})\n );\n }\n\n // Save bindings\n this._eventBindings = eventBindings;\n }\n\n _rePositioningPicker() {\n const {options} = this;\n\n // No repositioning needed if inline\n if (!options.inline) {\n const success = this._nanopop.update({\n container: document.body.getBoundingClientRect(),\n position: options.position\n });\n\n if (!success) {\n const el = this._root.app;\n const eb = el.getBoundingClientRect();\n el.style.top = `${(window.innerHeight - eb.height) / 2}px`;\n el.style.left = `${(window.innerWidth - eb.width) / 2}px`;\n }\n }\n }\n\n _updateOutput(eventSource) {\n const {_root, _color, options} = this;\n\n // Check if component is present\n if (_root.interaction.type()) {\n\n // Construct function name and call if present\n const method = `to${_root.interaction.type().getAttribute('data-type')}`;\n _root.interaction.result.value = typeof _color[method] === 'function' ?\n _color[method]().toString(options.outputPrecision) : '';\n }\n\n // Fire listener if initialization is finish\n if (!this._initializingActive && this._recalc) {\n this._emit('change', _color, eventSource, this);\n }\n }\n\n _clearColor(silent = false) {\n const {_root, options} = this;\n\n // Change only the button color if it isn't customized\n if (!options.useAsButton) {\n _root.button.style.setProperty('--pcr-color', 'rgba(0, 0, 0, 0.15)');\n }\n\n _root.button.classList.add('clear');\n\n if (!options.showAlways) {\n this.hide();\n }\n\n this._lastColor = null;\n if (!this._initializingActive && !silent) {\n\n // Fire listener\n this._emit('save', null);\n this._emit('clear');\n }\n }\n\n _parseLocalColor(str) {\n const {values, type, a} = parseToHSVA(str);\n const {lockOpacity} = this.options;\n const alphaMakesAChange = a !== undefined && a !== 1;\n\n // If no opacity is applied, add undefined at the very end which gets\n // Set to 1 in setHSVA\n if (values && values.length === 3) {\n values[3] = undefined;\n }\n\n return {\n values: (!values || (lockOpacity && alphaMakesAChange)) ? null : values,\n type\n };\n }\n\n _t(key) {\n return this.options.i18n[key] || Pickr.I18N_DEFAULTS[key];\n }\n\n _emit(event, ...args) {\n this._eventListener[event].forEach(cb => cb(...args, this));\n }\n\n on(event, cb) {\n this._eventListener[event].push(cb);\n return this;\n }\n\n off(event, cb) {\n const callBacks = (this._eventListener[event] || []);\n const index = callBacks.indexOf(cb);\n\n if (~index) {\n callBacks.splice(index, 1);\n }\n\n return this;\n }\n\n /**\n * Appends a color to the swatch palette\n * @param color\n * @returns {boolean}\n */\n addSwatch(color) {\n const {values} = this._parseLocalColor(color);\n\n if (values) {\n const {_swatchColors, _root} = this;\n const color = HSVaColor(...values);\n\n // Create new swatch HTMLElement\n const el = _.createElementFromString(\n `