{"version":3,"file":"js/application-f89f01817c1066c1ac48.js","sources":["webpack:///webpack/bootstrap","webpack:///./app/javascript/channels sync _channel\\.js$","webpack:///./app/javascript/channels/index.js","webpack:///./app/javascript/game.js","webpack:///./app/javascript/hints.js","webpack:///./app/javascript/main.js","webpack:///./app/javascript/nav.js","webpack:///./app/javascript/packs/application.js","webpack:///./app/javascript/utils.js","webpack:///./node_modules/@rails/activestorage/app/assets/javascripts/activestorage.js","webpack:///./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js","webpack:///./node_modules/bootstrap/dist/js/bootstrap.js","webpack:///./node_modules/fraction.js/fraction.cjs","webpack:///./node_modules/gsap/CSSPlugin.js","webpack:///./node_modules/gsap/gsap-core.js","webpack:///./node_modules/gsap/index.js","webpack:///./node_modules/jquery-ui-dist/jquery-ui.js","webpack:///./node_modules/jquery/src/ajax.js","webpack:///./node_modules/jquery/src/ajax/jsonp.js","webpack:///./node_modules/jquery/src/ajax/load.js","webpack:///./node_modules/jquery/src/ajax/script.js","webpack:///./node_modules/jquery/src/ajax/var/location.js","webpack:///./node_modules/jquery/src/ajax/var/nonce.js","webpack:///./node_modules/jquery/src/ajax/var/rquery.js","webpack:///./node_modules/jquery/src/ajax/xhr.js","webpack:///./node_modules/jquery/src/attributes.js","webpack:///./node_modules/jquery/src/attributes/attr.js","webpack:///./node_modules/jquery/src/attributes/classes.js","webpack:///./node_modules/jquery/src/attributes/prop.js","webpack:///./node_modules/jquery/src/attributes/support.js","webpack:///./node_modules/jquery/src/attributes/val.js","webpack:///./node_modules/jquery/src/callbacks.js","webpack:///./node_modules/jquery/src/core.js","webpack:///./node_modules/jquery/src/core/DOMEval.js","webpack:///./node_modules/jquery/src/core/access.js","webpack:///./node_modules/jquery/src/core/camelCase.js","webpack:///./node_modules/jquery/src/core/init.js","webpack:///./node_modules/jquery/src/core/isAttached.js","webpack:///./node_modules/jquery/src/core/nodeName.js","webpack:///./node_modules/jquery/src/core/parseHTML.js","webpack:///./node_modules/jquery/src/core/parseXML.js","webpack:///./node_modules/jquery/src/core/ready.js","webpack:///./node_modules/jquery/src/core/readyException.js","webpack:///./node_modules/jquery/src/core/stripAndCollapse.js","webpack:///./node_modules/jquery/src/core/support.js","webpack:///./node_modules/jquery/src/core/toType.js","webpack:///./node_modules/jquery/src/core/var/rsingleTag.js","webpack:///./node_modules/jquery/src/css.js","webpack:///./node_modules/jquery/src/css/addGetHookIf.js","webpack:///./node_modules/jquery/src/css/adjustCSS.js","webpack:///./node_modules/jquery/src/css/curCSS.js","webpack:///./node_modules/jquery/src/css/finalPropName.js","webpack:///./node_modules/jquery/src/css/hiddenVisibleSelectors.js","webpack:///./node_modules/jquery/src/css/showHide.js","webpack:///./node_modules/jquery/src/css/support.js","webpack:///./node_modules/jquery/src/css/var/cssExpand.js","webpack:///./node_modules/jquery/src/css/var/getStyles.js","webpack:///./node_modules/jquery/src/css/var/isHiddenWithinTree.js","webpack:///./node_modules/jquery/src/css/var/rboxStyle.js","webpack:///./node_modules/jquery/src/css/var/rcustomProp.js","webpack:///./node_modules/jquery/src/css/var/rnumnonpx.js","webpack:///./node_modules/jquery/src/css/var/swap.js","webpack:///./node_modules/jquery/src/data.js","webpack:///./node_modules/jquery/src/data/Data.js","webpack:///./node_modules/jquery/src/data/var/acceptData.js","webpack:///./node_modules/jquery/src/data/var/dataPriv.js","webpack:///./node_modules/jquery/src/data/var/dataUser.js","webpack:///./node_modules/jquery/src/deferred.js","webpack:///./node_modules/jquery/src/deferred/exceptionHook.js","webpack:///./node_modules/jquery/src/deprecated.js","webpack:///./node_modules/jquery/src/deprecated/ajax-event-alias.js","webpack:///./node_modules/jquery/src/deprecated/event.js","webpack:///./node_modules/jquery/src/dimensions.js","webpack:///./node_modules/jquery/src/effects.js","webpack:///./node_modules/jquery/src/effects/Tween.js","webpack:///./node_modules/jquery/src/effects/animatedSelector.js","webpack:///./node_modules/jquery/src/event.js","webpack:///./node_modules/jquery/src/event/trigger.js","webpack:///./node_modules/jquery/src/exports/amd.js","webpack:///./node_modules/jquery/src/exports/global.js","webpack:///./node_modules/jquery/src/jquery.js","webpack:///./node_modules/jquery/src/manipulation.js","webpack:///./node_modules/jquery/src/manipulation/_evalUrl.js","webpack:///./node_modules/jquery/src/manipulation/buildFragment.js","webpack:///./node_modules/jquery/src/manipulation/getAll.js","webpack:///./node_modules/jquery/src/manipulation/setGlobalEval.js","webpack:///./node_modules/jquery/src/manipulation/support.js","webpack:///./node_modules/jquery/src/manipulation/var/rscriptType.js","webpack:///./node_modules/jquery/src/manipulation/var/rtagName.js","webpack:///./node_modules/jquery/src/manipulation/wrapMap.js","webpack:///./node_modules/jquery/src/offset.js","webpack:///./node_modules/jquery/src/queue.js","webpack:///./node_modules/jquery/src/queue/delay.js","webpack:///./node_modules/jquery/src/selector.js","webpack:///./node_modules/jquery/src/selector/contains.js","webpack:///./node_modules/jquery/src/selector/escapeSelector.js","webpack:///./node_modules/jquery/src/serialize.js","webpack:///./node_modules/jquery/src/traversing.js","webpack:///./node_modules/jquery/src/traversing/findFilter.js","webpack:///./node_modules/jquery/src/traversing/var/dir.js","webpack:///./node_modules/jquery/src/traversing/var/rneedsContext.js","webpack:///./node_modules/jquery/src/traversing/var/siblings.js","webpack:///./node_modules/jquery/src/var/ObjectFunctionString.js","webpack:///./node_modules/jquery/src/var/arr.js","webpack:///./node_modules/jquery/src/var/class2type.js","webpack:///./node_modules/jquery/src/var/document.js","webpack:///./node_modules/jquery/src/var/documentElement.js","webpack:///./node_modules/jquery/src/var/flat.js","webpack:///./node_modules/jquery/src/var/fnToString.js","webpack:///./node_modules/jquery/src/var/getProto.js","webpack:///./node_modules/jquery/src/var/hasOwn.js","webpack:///./node_modules/jquery/src/var/indexOf.js","webpack:///./node_modules/jquery/src/var/isFunction.js","webpack:///./node_modules/jquery/src/var/isWindow.js","webpack:///./node_modules/jquery/src/var/pnum.js","webpack:///./node_modules/jquery/src/var/pop.js","webpack:///./node_modules/jquery/src/var/push.js","webpack:///./node_modules/jquery/src/var/rcheckableType.js","webpack:///./node_modules/jquery/src/var/rcssNum.js","webpack:///./node_modules/jquery/src/var/rnothtmlwhite.js","webpack:///./node_modules/jquery/src/var/rtrimCSS.js","webpack:///./node_modules/jquery/src/var/slice.js","webpack:///./node_modules/jquery/src/var/sort.js","webpack:///./node_modules/jquery/src/var/splice.js","webpack:///./node_modules/jquery/src/var/support.js","webpack:///./node_modules/jquery/src/var/toString.js","webpack:///./node_modules/jquery/src/var/whitespace.js","webpack:///./node_modules/jquery/src/wrap.js","webpack:///./node_modules/js-cookie/src/js.cookie.js","webpack:///./node_modules/pluralize/pluralize.js","webpack:///./node_modules/popper.js/dist/esm/popper.js","webpack:///(webpack)/buildin/global.js"],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/packs/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./app/javascript/packs/application.js\");\n","function webpackEmptyContext(req) {\n\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\te.code = 'MODULE_NOT_FOUND';\n\tthrow e;\n}\nwebpackEmptyContext.keys = function() { return []; };\nwebpackEmptyContext.resolve = webpackEmptyContext;\nmodule.exports = webpackEmptyContext;\nwebpackEmptyContext.id = \"./app/javascript/channels sync recursive _channel\\\\.js$\";","// Load all the channels within this directory and all subdirectories.\n// Channel files must be named *_channel.js.\n\nconst channels = require.context('.', true, /_channel\\.js$/)\nchannels.keys().forEach(channels)\n","import { gsap } from \"gsap\";\nimport Cookies from 'js-cookie'\nimport { Utils } from './utils';\nimport { Nav } from \"./nav.js\";\nimport { Hints } from \"./hints.js\";\n\nexport let Game = {\n DOM: {\n playSection: () => $(\"section.play\"),\n\n newGameButton: () => $(\".new-btn\"),\n getHintButton: () => $(\".hint-btn\"),\n helpButton: () => $(\".help-btn\"),\n helpMessage: () => $(\".help-message\"),\n\n game: () => $(\".game\"),\n\n hintText: () => $(\".game .hint-text\"),\n hintTextCollapse: () => $(\".game .hint-text-collapse\"),\n\n playLevelInfoButton: () => $(\".play-level-setting .info\"),\n playLevelSettingButtons: () => $(\".play-level-setting button:not(.info)\"),\n playLevelSettingButton: (level) => $(`.play-level-setting button[data-level=${level}]`),\n playLevelEasyButton: () => $(\".play-level-setting #easy-level-setting\"),\n playLevelMediumButton: () => $(\".play-level-setting #medium-level-setting\"),\n playLevelHardButton: () => $(\".play-level-setting #hard-level-setting\"),\n playLevelMonstrousButton: () => $(\".play-level-setting #monstrous-level-setting\"),\n\n cardModeSettings: () => $(\".card-mode-setting\"),\n cardModeInfoButton: () => $(\".card-mode-setting .info\"),\n cardModeSettingButtons: () => $(\".card-mode-setting button:not(.info)\"),\n cardModeSettingButton: (mode) => $(`.card-mode-setting button[data-mode=${mode}]`),\n cardModeClassicButton: () => $(\".card-mode-setting #classic-mode-setting\"),\n cardModeFunOnesButton: () => $(\".card-mode-setting #fun-ones-mode-setting\"),\n\n cardDifficultySettings: () => $(\".card-difficulty-setting\"),\n cardDifficultyInfoButton: () => $(\".card-difficulty-setting .info\"),\n cardDifficultyStarsWrapper: () => $(\".card-difficulty-setting .star-icons\"),\n cardDifficultyStarButtons: () => $(\".card-difficulty-setting .star-icon\"),\n cardDifficultyStar1Button: () => $(\".card-difficulty-setting .star-icon-1\"),\n cardDifficultyStar2Button: () => $(\".card-difficulty-setting .star-icon-2\"),\n cardDifficultyStar3Button: () => $(\".card-difficulty-setting .star-icon-3\"),\n\n addButton: () => $(\".controls button.add\"),\n subtractButton: () => $(\".controls button.sub\"),\n multiplyButton: () => $(\".controls button.mul\"),\n divideButton: () => $(\".controls button.div\"),\n operationButtons: () => $(\".controls .op\"),\n selectedOperation: () => $(\".controls .op.selected\"),\n resetButton: () => $(\".controls button.reset\"),\n\n hexBg: () => $(\".game #hex_bg\"),\n cardDiffHitArea: () => $(\".game #card_diff_hit_area\"),\n playLevelHitArea: () => $(\".game #play_level_hit_area\"),\n modeLogoHitArea: () => $(\".game #mode_logo_hit_area\"),\n\n redSection: () => $(\".game #red_section\"),\n yellowSection: () => $(\".game #yellow_section\"),\n pinkSection: () => $(\".game #pink_section\"),\n tealSection: () => $(\".game #teal_section\"),\n blueSection: () => $(\".game #blue_section\"),\n\n cardSections: () => $(\".game .hex-section\"),\n cardSection: (color) => $(\".game .hex-section.\" + color),\n sectionForNumber: (number) => Game.DOM.cardSection(number.attr(\"data-color\")),\n\n redNumber: () => $(\".game #red_number\"),\n yellowNumber: () => $(\".game #yellow_number\"),\n pinkNumber: () => $(\".game #pink_number\"),\n tealNumber: () => $(\".game #teal_number\"),\n blueNumber: () => $(\".game #blue_number\"),\n\n number: (color) => $(\".game #\" + color + \"_number\"),\n numberForSection: (section) => Game.DOM.number(section.attr(\"data-color\")),\n sectionNumbers: () => $(\".game .section-number\"),\n selectedNumber: () => $(\".game .section-number.selected\"),\n unselectedUnusedNumbers: () => $(\".game .section-number:not(.selected):not(.used)\"),\n usedNumbers: () => $(\".game .section-number.used\"),\n unusedNumbers: () => $(\".game .section-number:not(.used)\"),\n\n playLevelLabels: () => $(\".game .play-level-label\"),\n playLevelLabelEasy: () => $(\".game #easy_label\"),\n playLevelLabelMedium: () => $(\".game #medium_label\"),\n playLevelLabelHard: () => $(\".game #hard_label\"),\n playLevelLabelMonstrous: () => $(\".game #monstrous_label\"),\n playLevelLabel: (level) => $(`.game .play-level-label.${level}`),\n\n oneStar: () => $(\".game #one_star\"),\n twoStar: () => $(\".game #two_star\"),\n threeStar: () => $(\".game #three_star\"),\n stars: (id) => {\n if(id) return $(\".game #\" + id)\n else return $(\".game .star\")\n },\n\n adsumudisAnswer: () => $(\".game #adsumudis_answer\"),\n answerCircle: () => $(\".game #circle\"),\n\n winMonster: () => $(\".game #win_monster\"),\n winMessage: () => $(\".win-message\"),\n signUpMessage: () => $(\".sign-up-message\"),\n\n modeLogos: () => $(\".game #logo-classic, .game #logo-fun_ones\"),\n modeLogo: (mode) => $(\".game #logo-\" + mode),\n\n ariaAlert: () => $(\"#aria-alert\")\n },\n\n PlayLevel: {\n EASY: \"easy\",\n MEDIUM: \"medium\",\n HARD: \"hard\",\n MONSTROUS: \"monstrous\"\n },\n\n CardDifficulty: {\n STAR1: \"one_star\",\n STAR2: \"two_star\",\n STAR3: \"three_star\"\n },\n\n Mode: {\n CLASSIC: \"classic\",\n FUN_ONES: \"fun_ones\"\n },\n\n PLAY_LEVEL: null,\n CARD_DIFFICULTY: null,\n MODE: null,\n\n cards: null,\n currentCard: null,\n interactionPaused: false,\n gameOver: false,\n showedUseMoreNumbersPopUp: false,\n keyedNumberTimeout: null,\n keyedNumber: null,\n\n FIRST_HINT_CLASS: \"first-hint\",\n NEXT_HINT_CLASS: \"next-hint\",\n SOLUTION_CLASS: \"solution\",\n RESET_HINTS_CLASS: \"reset-hints\",\n NEW_BTN_PULSE_CLASS: \"pulse\",\n\n SETTING_SELECTED_CLASS: \"selected\",\n SETTING_HOVER_CLASS: \"hover\",\n NUMBER_SELECTED_CLASS: \"selected\",\n NUMBER_UNDERLINE_CLASS: \"underline\",\n NUMBER_USED_CLASS: \"used\",\n NUMBER_LARGE_CLASS: \"large\",\n OPERATION_ACTIVE_CLASS: \"active\",\n OPERATION_SELECTED_CLASS: \"selected\",\n\n NUM_USED_NUMBERS_ATTR: \"num-used-numbers\",\n PLAY_LEVEL_DATA_ATTR: \"data-level\",\n CARD_MODE_DATA_ATTR: \"data-mode\",\n\n NUMBER_SELECTED_SCALE: 1.2,\n\n handleGame: () => {\n if(Game.DOM.playSection().length == 0) return;\n\n Game.currentCard = FIRST_CARD\n Game.cards = MORE_CARDS\n Hints.setCard(Game.currentCard)\n\n Game.PLAY_LEVEL = Game.PlayLevel.EASY\n Game.CARD_DIFFICULTY = Game.CardDifficulty.STAR1\n Game.MODE = Game.Mode.CLASSIC\n Game.DOM.modeLogos().hide()\n Game.DOM.modeLogo(Game.MODE).show()\n Hints.setPlayLevel(Game.PLAY_LEVEL)\n\n let touchEvent = Utils.isMobile() ? \"touchend\" : \"click\"\n let extendedTouchEvent = touchEvent + \" keydown\"\n\n Game.DOM.newGameButton().on(touchEvent, Game.newGameButtonClicked)\n Game.DOM.getHintButton().on(touchEvent, Game.getHintButtonClicked)\n Game.DOM.helpButton().on(touchEvent, Game.helpButtonClicked)\n\n if(HINT_MODE) {\n Game.DOM.helpButton().parent().hide()\n Game.DOM.getHintButton().parent().removeClass(\"text-center\")\n Game.DOM.getHintButton().parent().addClass(\"offset-4 text-right\")\n }\n\n Game.DOM.playLevelEasyButton().attr(Game.PLAY_LEVEL_DATA_ATTR, Game.PlayLevel.EASY)\n Game.DOM.playLevelMediumButton().attr(Game.PLAY_LEVEL_DATA_ATTR, Game.PlayLevel.MEDIUM)\n Game.DOM.playLevelHardButton().attr(Game.PLAY_LEVEL_DATA_ATTR, Game.PlayLevel.HARD)\n Game.DOM.playLevelMonstrousButton().attr(Game.PLAY_LEVEL_DATA_ATTR, Game.PlayLevel.MONSTROUS)\n Game.DOM.playLevelSettingButtons().on(touchEvent, Game.playLevelSettingButtonClicked)\n Game.DOM.playLevelInfoButton().on(touchEvent, Game.playLevelInfoButtonClicked)\n Game.setPlayLevelFromPref()\n\n if(HINT_MODE) {\n Game.DOM.cardDifficultySettings().hide()\n Game.DOM.cardModeSettings().hide()\n } else {\n Game.DOM.cardDifficultyInfoButton().on(touchEvent, Game.cardDifficultyInfoButtonClicked)\n\n Game.DOM.cardDifficultyStar1Button().on(touchEvent, Game.cardDifficultyStar1ButtonClicked)\n Game.DOM.cardDifficultyStar2Button().on(touchEvent, Game.cardDifficultyStar2ButtonClicked)\n Game.DOM.cardDifficultyStar3Button().on(touchEvent, Game.cardDifficultyStar3ButtonClicked)\n Game.setCardDifficultyFromPref()\n\n Game.DOM.cardDifficultyStar1Button().hover(Game.cardDifficultyStar1ButtonHovered)\n Game.DOM.cardDifficultyStar2Button().hover(Game.cardDifficultyStar2ButtonHovered)\n Game.DOM.cardDifficultyStar3Button().hover(Game.cardDifficultyStar3ButtonHovered)\n\n Game.DOM.cardModeClassicButton().attr(Game.CARD_MODE_DATA_ATTR, Game.Mode.CLASSIC)\n Game.DOM.cardModeFunOnesButton().attr(Game.CARD_MODE_DATA_ATTR, Game.Mode.FUN_ONES)\n Game.DOM.cardModeSettingButtons().on(touchEvent, Game.cardModeSettingButtonClicked)\n Game.DOM.cardModeInfoButton().on(touchEvent, Game.cardModeInfoButtonClicked)\n if(FORCE_FUN_ONES_MODE) {\n Game.setCardModePref(Game.Mode.FUN_ONES)\n }\n Game.setCardModeFromPref()\n }\n\n Game.DOM.addButton().on(touchEvent, Game.addButtonClicked)\n Game.DOM.subtractButton().on(touchEvent, Game.subtractButtonClicked)\n Game.DOM.multiplyButton().on(touchEvent, Game.multiplyButtonClicked)\n Game.DOM.divideButton().on(touchEvent, Game.divideButtonClicked)\n Game.DOM.resetButton().on(touchEvent, Game.resetButtonClicked)\n\n Game.DOM.cardSections().on(touchEvent, Game.sectionClicked)\n Game.DOM.sectionNumbers().on(extendedTouchEvent, Game.numberClicked)\n\n Game.DOM.playSection().on(touchEvent, Game.clickedAway)\n\n Game.DOM.adsumudisAnswer().on(touchEvent, Game.adsumudisAnswerClicked)\n Game.DOM.answerCircle().on(extendedTouchEvent, Game.adsumudisAnswerClicked)\n Game.DOM.cardDiffHitArea().on(touchEvent, Game.cardDifficultyHitAreaClicked)\n Game.DOM.stars().on(extendedTouchEvent, Game.cardDifficultyHitAreaClicked)\n Game.DOM.playLevelHitArea().on(touchEvent, Game.playLevelHitAreaClicked)\n Game.DOM.modeLogoHitArea().on(touchEvent, Game.modeLogoHitAreaClicked)\n Game.DOM.modeLogos().on(extendedTouchEvent, Game.modeLogoHitAreaClicked)\n\n Game.DOM.playLevelLabelEasy().addClass(Game.PlayLevel.EASY)\n Game.DOM.playLevelLabelMedium().addClass(Game.PlayLevel.MEDIUM)\n Game.DOM.playLevelLabelHard().addClass(Game.PlayLevel.HARD)\n Game.DOM.playLevelLabelMonstrous().addClass(Game.PlayLevel.MONSTROUS)\n Game.DOM.playLevelLabels().on(extendedTouchEvent, Game.playLevelHitAreaClicked)\n\n $(document).on(\"keypress keydown\", Game.gameControlKeyPressed)\n\n if(HINT_MODE) {\n Game.displayCurrentCard()\n Game.reset()\n } else {\n Game.newGameButtonClicked()\n }\n },\n\n shouldNotAllowKeydownEvent: (e) => {\n return e.type == \"keydown\" && !(e.keyCode == 32 || e.keyCode == 13)\n },\n\n blurElementForEvent: (event, el) => {\n if(!event || (event.type != \"keydown\" && (event.originalEvent && event.originalEvent.detail != 0))) el.blur()\n },\n\n displayCurrentCard: () => {\n Game.DOM.sectionNumbers().removeClass(Game.NUMBER_UNDERLINE_CLASS)\n\n Game.setNumber(Game.DOM.redNumber(), Game.currentCard.n1)\n Game.setNumber(Game.DOM.yellowNumber(), Game.currentCard.n2)\n Game.setNumber(Game.DOM.pinkNumber(), Game.currentCard.n3)\n Game.setNumber(Game.DOM.tealNumber(), Game.currentCard.n4)\n Game.setNumber(Game.DOM.blueNumber(), Game.currentCard.n5)\n Game.setNumber(Game.DOM.adsumudisAnswer(), Game.currentCard.target)\n\n Game.DOM.stars().hide()\n Game.DOM.stars(Game.currentCard.difficulty).show()\n Game.DOM.stars().attr(\"tabindex\", \"-1\")\n Game.DOM.stars(Game.currentCard.difficulty).removeAttr(\"tabindex\")\n },\n\n setNumber: (number, value) => {\n number.html(value)\n\n if(number.hasClass(Game.NUMBER_SELECTED_CLASS)) {\n number.attr(\"aria-label\", `${value} selected`)\n } else {\n number.attr(\"aria-label\", value)\n }\n\n if(Game.numberNeedsUnderline(value)) {\n number.addClass(Game.NUMBER_UNDERLINE_CLASS)\n } else {\n number.removeClass(Game.NUMBER_UNDERLINE_CLASS)\n }\n\n if(value > 99) {\n number.addClass(Game.NUMBER_LARGE_CLASS)\n if(number.hasClass(\"section-number\")) {\n number.attr(\"y\",\"63\")\n }\n } else {\n number.removeClass(Game.NUMBER_LARGE_CLASS)\n if(number.hasClass(\"section-number\")) {\n number.attr(\"y\",\"68\")\n }\n }\n },\n\n numberNeedsUnderline: (number) => {\n return [6, 9, 16, 18, 19, 61, 66, 68, 69, 81, 86, 89, 91, 96, 98, 99, 106, 108, 109, 116, 118, 119, 161, 166, 168, 169, 186, 188, 189, 191, 196, 198, 199, 601, 606, 608, 609, 611, 616, 618, 619, 661, 666, 668, 669, 681, 686, 688, 689, 691, 696, 698, 699, 901, 906, 908, 909, 911, 916, 918, 919, 961, 966, 968, 969, 981, 986, 988, 989, 991, 996, 998, 999].indexOf(number) != -1\n },\n\n newGameButtonClicked: (event = null) => {\n Game.blurElementForEvent(event, Game.DOM.newGameButton())\n if(Game.interactionPaused && !Game.gameOver) return;\n\n if(HINT_MODE) {\n window.location = \"/hints\"\n } else {\n Game.currentCard = Game.cards[Game.MODE][Game.CARD_DIFFICULTY].shift()\n Hints.setCard(Game.currentCard)\n if(Game.currentCard != null) {\n Game.reset()\n }\n Game.fetchCard()\n }\n },\n\n fetchCard: () => {\n var difficulty = Game.CARD_DIFFICULTY\n var mode = Game.MODE\n $.get(\"/fetch_card\", {difficulty: difficulty, version: mode}).done((data) => {\n Game.cards[mode][difficulty].push(data)\n })\n },\n\n getHintButtonClicked: (event) => {\n Game.blurElementForEvent(event, Game.DOM.getHintButton())\n if(Game.gameOver) return;\n\n var hint = Hints.nextHint()\n var title = Utils.capitalize(Game.PLAY_LEVEL) + \" Mode Hints\"\n\n if(Hints.isFirstHint()) {\n Game.DOM.getHintButton().removeClass(Game.FIRST_HINT_CLASS)\n Game.DOM.getHintButton().addClass(Game.NEXT_HINT_CLASS)\n } else if(Hints.isFinalHintNext()) {\n Game.DOM.getHintButton().removeClass(Game.NEXT_HINT_CLASS)\n Game.DOM.getHintButton().addClass(Game.SOLUTION_CLASS)\n } else if(Hints.isFinalHint() && hint != null) {\n Game.DOM.getHintButton().removeClass(Game.SOLUTION_CLASS)\n Game.DOM.getHintButton().addClass(Game.RESET_HINTS_CLASS)\n } else if(Hints.isFinalHint() && hint == null) {\n Game.resetHints()\n return\n }\n\n if(Hints.isFirstHint()) {\n Game.DOM.hintText().html(\"\" + title + \"\")\n }\n \n Game.DOM.hintText().html(Game.DOM.hintText().html() + \"
\" + hint)\n Game.DOM.hintTextCollapse().collapse(\"show\")\n },\n\n rememberPlayLevelHint: () => {\n return \"Remember that on \" + Game.PLAY_LEVEL + \" mode you need to use at least \" + Game.numCardsNeededForPlayLevel(Game.PLAY_LEVEL) + \" numbers to make Adsumudi's answer\"\n },\n\n isHintNumberSolutionHint: (num) => {\n var isSolutionHint = false\n if( ((Game.isEasyMode() || Game.isMediumMode()) && num == 3) ||\n ((Game.isHardMode() || Game.isMonstrousMode()) && num == 4)) {\n isSolutionHint = true;\n }\n return isSolutionHint\n },\n\n\n\n resetHints: () => {\n Hints.resetHints()\n Game.DOM.getHintButton().addClass(Game.FIRST_HINT_CLASS)\n Game.DOM.getHintButton().removeClass(Game.NEXT_HINT_CLASS)\n Game.DOM.getHintButton().removeClass(Game.SOLUTION_CLASS)\n Game.DOM.getHintButton().removeClass(Game.RESET_HINTS_CLASS)\n Game.DOM.hintTextCollapse().collapse(\"hide\")\n },\n\n resetOperationButtonsAria: () => {\n Game.DOM.addButton().attr(\"aria-label\",\"addition\")\n Game.DOM.subtractButton().attr(\"aria-label\",\"subtraction\")\n Game.DOM.multiplyButton().attr(\"aria-label\",\"multiplication\")\n Game.DOM.divideButton().attr(\"aria-label\",\"division\")\n },\n\n helpButtonClicked: (event) => {\n Game.blurElementForEvent(event, Game.DOM.helpButton())\n showModal(\"How To Play\", Game.DOM.helpMessage().html())\n },\n\n playLevelInfoButtonClicked: (event) => {\n showModal(\"Play Level\",\"When playing on easy, you can use any two or more of the five numbers around the outside of the card to make Adsumudi's answer in the middle. On medium, you have to use three or more. On hard, you have to use any four or more. And if you're playing on monstrously hard, you have to use all five numbers.\")\n Game.blurElementForEvent(event, Game.DOM.playLevelInfoButton())\n },\n\n cardDifficultyInfoButtonClicked: (event) => {\n showModal(\"Card Difficulty\",\"One, two, or three stars indicates a card's general difficulty level, where 1 star is the easiest and 3 stars is the hardest. Select the difficulty you would like to play with to get a new card of that difficulty.\")\n Game.blurElementForEvent(event, Game.DOM.cardDifficultyInfoButton())\n },\n\n currentCardNumStars: () => {\n if(Game.currentCard.difficulty == Game.CardDifficulty.STAR1) {\n return 1\n } else if(Game.currentCard.difficulty == Game.CardDifficulty.STAR2) {\n return 2\n } else if(Game.currentCard.difficulty == Game.CardDifficulty.STAR3) {\n return 3\n }\n },\n\n playLevelSettingButtonClicked: (event) => {\n var button = $(event.target)\n if(button.length == 0) return\n var level = button.attr(Game.PLAY_LEVEL_DATA_ATTR)\n var didChange = Game.PLAY_LEVEL != level\n\n Game.PLAY_LEVEL = level\n Hints.setPlayLevel(level)\n Game.DOM.playLevelSettingButtons().removeClass(Game.SETTING_SELECTED_CLASS)\n button.addClass(Game.SETTING_SELECTED_CLASS)\n Game.blurElementForEvent(event, button)\n Game.setPlayLevelPref(level)\n Game.resetHints()\n\n Game.DOM.playLevelLabels().hide()\n if(!Game.gameOver) {\n Game.DOM.playLevelLabel(level).show()\n Game.DOM.playLevelLabels().attr(\"tabindex\", \"-1\")\n Game.currentPlayLevelLabel().removeAttr(\"tabindex\")\n }\n\n if(didChange && event.type) {\n var levelDesc = \"can now use any two or more\"\n if(Game.isMediumMode()) levelDesc = \"now have to use three or more\"\n else if(Game.isHardMode()) levelDesc = \"now have to use four or more\"\n else if(Game.isMonstrousMode()) levelDesc = \"now have to use all five\"\n showModal(`${Utils.capitalize(level)} Mode Selected`, `You ${levelDesc} of the numbers around the outside to make Adsumudi's answer in the middle.`)\n }\n\n if(didChange && Game.DOM.usedNumbers().length > 0) {\n Game.reset()\n }\n },\n\n currentPlayLevelLabel: () => {\n if(Game.isEasyMode()) {\n return Game.DOM.playLevelLabelEasy()\n } else if(Game.isMediumMode()) {\n return Game.DOM.playLevelLabelMedium()\n } else if(Game.isHardMode()) {\n return Game.DOM.playLevelLabelHard()\n } else if(Game.isMonstrousMode()) {\n return Game.DOM.playLevelLabelMonstrous()\n }\n },\n\n playLevelPref: () => {\n return Cookies.get(\"play-level-pref\")\n },\n\n setPlayLevelPref: (level) => {\n Cookies.set(\"play-level-pref\", level)\n },\n\n setPlayLevelFromPref: () => {\n var pref = Game.playLevelPref()\n if(pref) {\n Game.playLevelSettingButtonClicked({target: Game.DOM.playLevelSettingButton(pref)})\n }\n },\n\n cardModeSettingButtonClicked: (event) => {\n var button = $(event.target)\n if(button.length == 0) return\n var mode = button.attr(Game.CARD_MODE_DATA_ATTR)\n var didChange = Game.MODE != mode\n\n Game.MODE = mode\n Game.DOM.cardModeSettingButtons().removeClass(Game.SETTING_SELECTED_CLASS)\n button.addClass(Game.SETTING_SELECTED_CLASS)\n Game.blurElementForEvent(event, button)\n Game.setCardModePref(mode)\n Game.resetHints()\n\n Game.DOM.modeLogos().hide()\n Game.DOM.modeLogo(mode).show()\n \n Game.DOM.playSection().removeClass(`theme-${Game.Mode.CLASSIC}`)\n Game.DOM.playSection().removeClass(`theme-${Game.Mode.FUN_ONES}`)\n Game.DOM.playSection().addClass(`theme-${mode}`)\n\n if(didChange && event.type) {\n var levelDesc = \"\"\n var title = \"\"\n if(Game.isClassicMode()) {\n showModal(`Classic Mode Selected`, `You selected \"Classic\" mode, which means you may need any one or all of + - × ÷ to solve cards and numbers range up to 30. This is the standard way of playing Adsumudi.`)\n } else if(Game.isFunOnesMode()) {\n showModal(`Fun Ones Mode Selected`, `You selected \"Fun Ones\" mode, which means only + and - are needed to solve cards and numbers only go up to 12. You can still use × and ÷ if you want, but you don't have to. This makes for a fun, fast-paced challenge.`)\n }\n\n Game.newGameButtonClicked()\n }\n },\n\n cardModeInfoButtonClicked: (event) => {\n showModal(\"Card Type\",\"\\\"Classic\\\" is the regular way of playing Adsumudi, where any one or all of + - × ÷ may be needed to solve cards and numbers range up to 30. \\\"Fun Ones\\\" means only + and - are needed and numbers only go up to 12, making for some fun, fast-paced mental math.\")\n Game.blurElementForEvent(event, Game.DOM.cardModeInfoButton())\n },\n\n cardModePref: () => {\n return Cookies.get(\"card-mode-pref\")\n },\n\n setCardModePref: (mode) => {\n Cookies.set(\"card-mode-pref\", mode)\n },\n\n setCardModeFromPref: () => {\n var pref = Game.cardModePref()\n if(pref) {\n Game.cardModeSettingButtonClicked({target: Game.DOM.cardModeSettingButton(pref)})\n }\n },\n\n isMode: (mode) => {\n return Game.MODE == mode\n },\n\n isClassicMode: () => {\n return Game.isMode(Game.Mode.CLASSIC)\n },\n\n isFunOnesMode: () => {\n return Game.isMode(Game.Mode.FUN_ONES)\n },\n\n numCardsNeededForPlayLevel: () => {\n return {\n [Game.PlayLevel.EASY]: 2,\n [Game.PlayLevel.MEDIUM]: 3,\n [Game.PlayLevel.HARD]: 4,\n [Game.PlayLevel.MONSTROUS]: 5\n }[Game.PLAY_LEVEL]\n },\n\n isPlayLevel: (playLevel) => {\n return Game.PLAY_LEVEL == playLevel\n },\n\n isEasyMode: () => {\n return Game.isPlayLevel(Game.PlayLevel.EASY)\n },\n\n isMediumMode: () => {\n return Game.isPlayLevel(Game.PlayLevel.MEDIUM)\n },\n\n isHardMode: () => {\n return Game.isPlayLevel(Game.PlayLevel.HARD)\n },\n\n isMonstrousMode: () => {\n return Game.isPlayLevel(Game.PlayLevel.MONSTROUS)\n },\n\n\n cardDifficultyStar1ButtonHovered: () => {\n Game.DOM.cardDifficultyStarButtons().removeClass(Game.SETTING_HOVER_CLASS)\n Game.DOM.cardDifficultyStar1Button().addClass(Game.SETTING_HOVER_CLASS)\n },\n\n cardDifficultyStar2ButtonHovered: () => {\n Game.DOM.cardDifficultyStarButtons().removeClass(Game.SETTING_HOVER_CLASS)\n Game.DOM.cardDifficultyStar1Button().addClass(Game.SETTING_HOVER_CLASS)\n Game.DOM.cardDifficultyStar2Button().addClass(Game.SETTING_HOVER_CLASS)\n },\n\n cardDifficultyStar3ButtonHovered: () => {\n Game.DOM.cardDifficultyStarButtons().addClass(Game.SETTING_HOVER_CLASS)\n },\n\n cardDifficultyStarsMouseOut: () => {\n Game.DOM.cardDifficultyStarButtons().removeClass(Game.SETTING_HOVER_CLASS)\n },\n\n cardDifficultyStar1ButtonClicked: (event) => {\n if(Game.interactionPaused && !Game.gameOver) return;\n var didChange = Game.CARD_DIFFICULTY != Game.CardDifficulty.STAR1\n Game.CARD_DIFFICULTY = Game.CardDifficulty.STAR1\n Game.DOM.cardDifficultyStarButtons().removeClass(Game.SETTING_SELECTED_CLASS)\n Game.DOM.cardDifficultyStar1Button().addClass(Game.SETTING_SELECTED_CLASS)\n Game.blurElementForEvent(event, Game.DOM.cardDifficultyStarButtons())\n Game.setCardDifficultyPref(Game.CARD_DIFFICULTY)\n if(didChange) Game.newGameButtonClicked()\n },\n\n cardDifficultyStar2ButtonClicked: (event) => {\n if(Game.interactionPaused && !Game.gameOver) return;\n var didChange = Game.CARD_DIFFICULTY != Game.CardDifficulty.STAR2\n Game.CARD_DIFFICULTY = Game.CardDifficulty.STAR2\n Game.DOM.cardDifficultyStarButtons().removeClass(Game.SETTING_SELECTED_CLASS)\n Game.DOM.cardDifficultyStar1Button().addClass(Game.SETTING_SELECTED_CLASS)\n Game.DOM.cardDifficultyStar2Button().addClass(Game.SETTING_SELECTED_CLASS)\n Game.blurElementForEvent(event, Game.DOM.cardDifficultyStarButtons())\n Game.setCardDifficultyPref(Game.CARD_DIFFICULTY)\n if(didChange) Game.newGameButtonClicked()\n },\n\n cardDifficultyStar3ButtonClicked: (event) => {\n if(Game.interactionPaused && !Game.gameOver) return;\n var didChange = Game.CARD_DIFFICULTY != Game.CardDifficulty.STAR3\n Game.CARD_DIFFICULTY = Game.CardDifficulty.STAR3\n Game.DOM.cardDifficultyStarButtons().removeClass(Game.SETTING_SELECTED_CLASS)\n Game.DOM.cardDifficultyStar1Button().addClass(Game.SETTING_SELECTED_CLASS)\n Game.DOM.cardDifficultyStar2Button().addClass(Game.SETTING_SELECTED_CLASS)\n Game.DOM.cardDifficultyStar3Button().addClass(Game.SETTING_SELECTED_CLASS)\n Game.blurElementForEvent(event, Game.DOM.cardDifficultyStarButtons())\n Game.setCardDifficultyPref(Game.CARD_DIFFICULTY)\n if(didChange) Game.newGameButtonClicked()\n },\n\n cardDifficultyPref: () => {\n return Cookies.get(\"card-difficulty-pref\")\n },\n\n setCardDifficultyPref: (diff) => {\n Cookies.set(\"card-difficulty-pref\", diff)\n },\n\n setCardDifficultyFromPref: () => {\n var pref = Game.cardDifficultyPref()\n if(pref == Game.CardDifficulty.STAR3) {\n Game.cardDifficultyStar3ButtonClicked()\n } else if(pref == Game.CardDifficulty.STAR2) {\n Game.cardDifficultyStar2ButtonClicked()\n } else if(pref == Game.CardDifficulty.STAR1) {\n Game.cardDifficultyStar1ButtonClicked()\n }\n },\n\n hasSelectedNumber: () => {\n var result = false\n $.each(Game.DOM.sectionNumbers(), (i, number) => {\n if(Game.isNumberSelected(number)) {\n result = true\n }\n })\n return result\n },\n\n isNumberSelected: (number) => {\n return $(number).hasClass(Game.NUMBER_SELECTED_CLASS)\n },\n\n hasSelectedOperation: () => {\n var result = false\n $.each(Game.DOM.operationButtons(), (i, op) => {\n if(Game.isOperationSelected(op)) {\n result = true\n }\n })\n return result\n },\n\n isOperationSelected: (op) => {\n return $(op).hasClass(Game.OPERATION_SELECTED_CLASS)\n },\n\n isOperationActive: (op) => {\n return $(op).hasClass(Game.OPERATION_ACTIVE_CLASS)\n },\n\n resetKeyedNumber: () => {\n Game.keyedNumber = null\n if(Game.keyedNumberTimeout != null) {\n clearTimeout(Game.keyedNumberTimeout)\n Game.keyedNumberTimeout = null\n }\n },\n\n gameControlKeyPressed: (event) => {\n if(Game.interactionPaused && !Game.gameOver) return;\n\n var isKeyPress = event.type == \"keypress\"\n var isKeyDown = event.type == \"keydown\"\n var k = event.which\n\n if(isKeyPress) {\n if(k == 43) {\n Game.resetKeyedNumber()\n Game.addButtonClicked(event)\n }\n else if(k == 45) {\n Game.resetKeyedNumber()\n Game.subtractButtonClicked(event)\n }\n else if(k == 120 || k == 42) {\n Game.resetKeyedNumber()\n Game.multiplyButtonClicked(event)\n }\n else if(k == 47 || k == 92) {\n Game.resetKeyedNumber()\n Game.divideButtonClicked(event)\n }\n else if(k == 82 || k == 114) {\n Game.resetButtonClicked(event)\n }\n else if(k == 78 || k == 110) {\n Game.newGameButtonClicked(event)\n }\n else if(k == 72 || k == 104) {\n Game.getHintButtonClicked(event)\n }\n else if(k >= 48 && k <= 57) {\n if(Game.keyedNumberTimeout != null) {\n clearTimeout(Game.keyedNumberTimeout)\n Game.keyedNumberTimeout = null\n }\n\n var num = String.fromCharCode(k)\n Game.keyedNumber = (Game.keyedNumber == null) ? num : (Game.keyedNumber + num)\n Game.keyedNumberTimeout = setTimeout(() => {\n Game.keyedNumber = null\n }, 1000)\n\n var number = Game.DOM.unusedNumbers().filter((i, el) => {\n return $(el).html() == Game.keyedNumber\n }).first()\n\n var couldBeAnotherNumber = Game.DOM.unusedNumbers().filter((i, el) => {\n return $(el).html().indexOf(Game.keyedNumber) == 0 && $(el).html() != Game.keyedNumber\n }).length > 0\n\n if(number.length > 0) {\n if(Game.keyedNumberDisambiguateTimeout != null) {\n clearTimeout(Game.keyedNumberDisambiguateTimeout)\n }\n if(Game.hasSelectedNumber() && Game.hasSelectedOperation() && couldBeAnotherNumber) {\n Game.keyedNumberDisambiguateTimeout = setTimeout(() => {\n Game.numberSelected(number)\n }, 500)\n } else {\n Game.numberSelected(number)\n }\n }\n }\n }\n else if(isKeyDown) {\n if(k == 27 || k == 12)\n Game.clickedAway(event)\n }\n },\n\n commitKeyedNumber: (number) => {\n if(number.length > 0) {\n Game.numberSelected(number)\n }\n },\n\n addButtonClicked: (event) => {\n event.stopPropagation()\n Game.blurElementForEvent(event, Game.DOM.addButton())\n if(Game.gameOver) return;\n\n if(Game.isOperationActive(Game.DOM.addButton())) {\n Game.DOM.operationButtons().removeClass(Game.OPERATION_SELECTED_CLASS)\n Game.DOM.addButton().addClass(Game.OPERATION_SELECTED_CLASS)\n alert\n Game.DOM.addButton().attr(\"aria-label\",\"addition selected\")\n Game.ariaSay(\"addition selected\")\n } else {\n showModal(\"Select a number first!\", \"To add two numbers, first click on a number to select it, then click this button, then click the other number.\")\n }\n },\n\n isAddSelected: () => {\n return Game.hasSelectedOperation() && Game.DOM.selectedOperation().hasClass(\"add\")\n },\n\n subtractButtonClicked: (event) => {\n event.stopPropagation()\n Game.blurElementForEvent(event, Game.DOM.subtractButton())\n if(Game.gameOver) return;\n\n if(Game.isOperationActive(Game.DOM.subtractButton())) {\n Game.DOM.operationButtons().removeClass(Game.OPERATION_SELECTED_CLASS)\n Game.DOM.subtractButton().addClass(Game.OPERATION_SELECTED_CLASS)\n Game.resetOperationButtonsAria()\n Game.DOM.subtractButton().attr(\"aria-label\",\"subtraction selected\")\n Game.ariaSay(\"subtraction selected\")\n } else {\n showModal(\"Select a number first!\", \"To subtract two numbers, first click the number you want to subtract from to select it, then click this button, then click the number you want to subtract with.\")\n }\n },\n\n isSubtractSelected: () => {\n return Game.hasSelectedOperation() && Game.DOM.selectedOperation().hasClass(\"sub\")\n },\n\n multiplyButtonClicked: (event) => {\n event.stopPropagation()\n Game.blurElementForEvent(event, Game.DOM.multiplyButton())\n if(Game.gameOver) return;\n\n if(Game.isOperationActive(Game.DOM.multiplyButton())) {\n Game.DOM.operationButtons().removeClass(Game.OPERATION_SELECTED_CLASS)\n Game.DOM.multiplyButton().addClass(Game.OPERATION_SELECTED_CLASS)\n Game.resetOperationButtonsAria()\n Game.DOM.multiplyButton().attr(\"aria-label\",\"multiplication selected\")\n Game.ariaSay(\"multiplication selected\")\n } else {\n showModal(\"Select a number first!\", \"To multiply two numbers, first click a number, then click this button, then click the other number.\")\n }\n },\n\n isMultiplySelected: () => {\n return Game.hasSelectedOperation() && Game.DOM.selectedOperation().hasClass(\"mul\")\n },\n\n divideButtonClicked: (event) => {\n Game.blurElementForEvent(event, Game.DOM.divideButton())\n event.stopPropagation()\n if(Game.gameOver) return;\n\n if(Game.isOperationActive(Game.DOM.divideButton())) {\n Game.DOM.operationButtons().removeClass(Game.OPERATION_SELECTED_CLASS)\n Game.DOM.divideButton().addClass(Game.OPERATION_SELECTED_CLASS)\n Game.resetOperationButtonsAria()\n Game.DOM.divideButton().attr(\"aria-label\",\"division selected\")\n Game.ariaSay(\"division selected\")\n } else {\n showModal(\"Select a number first!\", \"To divide two numbers, first click the number you want to divide from, then click this button, then click the number you want to divide with.\")\n }\n },\n\n isDivideSelected: () => {\n return Game.hasSelectedOperation() && Game.DOM.selectedOperation().hasClass(\"div\")\n },\n\n resetButtonClicked: (event) => {\n event.stopPropagation()\n Game.blurElementForEvent(event, Game.DOM.resetButton())\n if(Game.interactionPaused && !Game.gameOver) return;\n Game.reset()\n },\n\n reset: () => {\n Game.gameOver = false\n Game.interactionPaused = false\n Game.showedUseMoreNumbersPopUp = false\n Game.resetKeyedNumber()\n\n // Game.interactionPaused = true\n Game.resetHints()\n Game.DOM.playSection().removeClass(\"win\")\n Game.DOM.winMonster().hide()\n Game.DOM.newGameButton().removeClass(Game.NEW_BTN_PULSE_CLASS)\n Game.displayCurrentCard()\n Game.DOM.sectionNumbers().removeClass(Game.NUMBER_SELECTED_CLASS)\n Game.DOM.sectionNumbers().removeClass(Game.NUMBER_USED_CLASS)\n Game.DOM.sectionNumbers().attr(Game.NUM_USED_NUMBERS_ATTR, \"1\")\n Game.DOM.sectionNumbers().removeAttr(\"tabindex\")\n Game.DOM.cardSections().removeClass(Game.NUMBER_USED_CLASS)\n\n Game.DOM.playLevelLabels().attr(\"tabindex\", \"-1\")\n Game.currentPlayLevelLabel().removeAttr(\"tabindex\")\n Game.DOM.playLevelLabels().hide()\n Game.currentPlayLevelLabel().show()\n\n gsap.killTweensOf(Game.DOM.sectionNumbers())\n gsap.to(Game.DOM.sectionNumbers(), {\n duration: 0,\n scale: 1,\n opacity: 1,\n rotate: 0,\n transformOrigin: \"50% 50%\",\n onComplete: () => {\n Game.bounce(Game.DOM.sectionNumbers(), 1, () => {\n // Game.interactionPaused = false\n })\n }\n });\n Game.DOM.operationButtons().removeClass(Game.OPERATION_ACTIVE_CLASS)\n Game.DOM.operationButtons().removeClass(Game.OPERATION_SELECTED_CLASS)\n Game.resetOperationButtonsAria()\n },\n\n sectionClicked: (event) => {\n event.stopPropagation()\n if(Game.interactionPaused) return;\n\n var section = $(event.target)\n Game.numberSelected(Game.DOM.numberForSection(section))\n },\n\n numberClicked: (event) => {\n if(Game.shouldNotAllowKeydownEvent(event)) return;\n\n var number = $(event.target)\n Game.blurElementForEvent(event, number)\n event.stopPropagation()\n\n if(Game.interactionPaused) return;\n\n Game.numberSelected(number)\n },\n\n clickedAway: () => {\n if(Game.interactionPaused) return;\n if(Game.DOM.selectedNumber().length > 0) {\n Game.deselectNumber(Game.DOM.selectedNumber())\n }\n },\n\n adsumudisAnswerClicked: (event) => {\n if(Game.interactionPaused) return;\n if(Game.shouldNotAllowKeydownEvent(event)) return;\n\n var desc = \"For this card, Adsumudi's answer is \" + Game.currentCard.target + \". It's the target number you're trying to make by combining the 5 other numbers with \"\n if(Game.isClassicMode()) {\n desc += \"addition, subtraction, multiplication, and division.\"\n } else { \n desc += \"addition and subtraction (and multiplication and division if you want).\"\n } \n if(HINT_MODE) {\n desc += \" Try it yourself by clicking on one of the numbers and then a math symbol, or click the 'Hint' button at top right if you're stuck.\"\n } else {\n desc += \" Get started by clicking on one of the 5 numbers around the outside of the card.\"\n }\n\n showModal(\"Adsumudi's Answer\", desc)\n },\n\n cardDifficultyHitAreaClicked: (event) => {\n if(Game.interactionPaused) return;\n if(Game.shouldNotAllowKeydownEvent(event)) return;\n\n var formattedDifficulty = Utils.pluralize(Game.currentCard.difficulty.split(\"_\").join(\" \"), Game.currentCardNumStars())\n var formattedCapitalizedDifficulty = $.map(formattedDifficulty.split(\" \"), (w, i) => {\n return Utils.capitalize(w)\n }).join(\" \")\n\n var cardDifficultyDesc = \"\"\n if(Game.currentCard.difficulty == Game.CardDifficulty.STAR1) {\n cardDifficultyDesc = \"it's the easiest type of card\"\n } else if(Game.currentCard.difficulty == Game.CardDifficulty.STAR2) {\n cardDifficultyDesc = \"it's of medium difficulty\"\n } else if(Game.currentCard.difficulty == Game.CardDifficulty.STAR3) {\n cardDifficultyDesc = \"it's the hardest type of card\"\n }\n\n var settingsDesc = \"\"\n if(!HINT_MODE) {\n settingsDesc = \"You can change this setting at the bottom of the page.\"\n }\n\n var explanation = `This card has an overall rating of ${formattedDifficulty}, meaning that generally, ${cardDifficultyDesc}. ${settingsDesc}`\n\n showModal(formattedCapitalizedDifficulty, explanation)\n },\n\n playLevelHitAreaClicked: (event) => {\n if(Game.interactionPaused) return;\n if(Game.shouldNotAllowKeydownEvent(event)) return;\n\n var playLevelDesc = Game.numCardsNeededForPlayLevel(Game.PLAY_LEVEL) + \" or more numbers\"\n if(Game.isMonstrousMode()) {\n playLevelDesc = \"all 5 numbers\"\n }\n\n var settingsDesc = \"You can change this setting at the bottom of the page.\"\n\n var explanation = `You're currently playing on ${Game.PLAY_LEVEL}, which means you have to use ${playLevelDesc} to make Adsumudi's answer. ${settingsDesc}`\n\n var title = Utils.capitalize(Game.PLAY_LEVEL) + \" Level\"\n\n showModal(title, explanation)\n },\n\n modeLogoHitAreaClicked: (event) => {\n if(Game.interactionPaused) return;\n if(Game.shouldNotAllowKeydownEvent(event)) return;\n\n var title = Game.isClassicMode() ? \"Classic Adsumudi\" : \"Adsumudi Fun Ones\"\n var explanation = `You're currently playing on ${title} mode, which means `\n if(Game.isClassicMode())\n explanation += \"you may need any one or all of + - × ÷ to solve cards and numbers range up to 30.\"\n else\n explanation += \"only + and - are needed to solve cards and numbers only go up to 12. You can still use × and ÷ if you want, but you don't have to.\"\n\n explanation += \" You can change this setting at the bottom of the page.\"\n\n showModal(title, explanation)\n },\n\n selectNumber: (number) => {\n number.addClass(Game.NUMBER_SELECTED_CLASS)\n number.attr(\"aria-label\", `${number.html()}, selected`)\n Game.ariaSay(`${number.html()}, selected`)\n\n // Game.interactionPaused = true\n gsap.killTweensOf(number)\n gsap.to(number, {\n duration: 0.25,\n scale: Game.NUMBER_SELECTED_SCALE,\n transformOrigin: \"50% 50%\",\n onComplete: () => {\n // Game.interactionPaused = false\n }\n });\n\n Game.DOM.operationButtons().addClass(Game.OPERATION_ACTIVE_CLASS)\n },\n\n deselectNumber: (number) => {\n number.removeClass(Game.NUMBER_SELECTED_CLASS)\n number.attr(\"aria-label\", number.html())\n Game.ariaSay(`${number.html()}, deselected`)\n\n // Game.interactionPaused = true\n gsap.killTweensOf(number)\n gsap.to(number, {\n duration: 0.25,\n scale: 1,\n transformOrigin: \"50% 50%\",\n onComplete: () => {\n // Game.interactionPaused = false\n }\n });\n Game.DOM.operationButtons().removeClass(Game.OPERATION_ACTIVE_CLASS)\n Game.DOM.operationButtons().removeClass(Game.OPERATION_SELECTED_CLASS)\n Game.resetOperationButtonsAria()\n },\n\n numberSelected: (number) => {\n if(number.html() == \"\") return\n\n if(!Game.hasSelectedOperation()) {\n if(Game.hasSelectedNumber()) {\n if(Game.isNumberSelected(number)) {\n Game.deselectNumber(number)\n } else {\n Game.deselectNumber(Game.DOM.selectedNumber())\n Game.selectNumber(number)\n\n }\n } else {\n Game.selectNumber(number)\n }\n } else {\n if(Game.hasSelectedNumber()) {\n if(!Game.isNumberSelected(number)) {\n Game.performOperation(number)\n }\n }\n }\n },\n\n performOperation: (secondNumber) => {\n var selectedNumber = Game.DOM.selectedNumber()\n var operand1 = parseInt(selectedNumber.html())\n var operand2 = parseInt($(secondNumber).html())\n var result = null;\n if(Game.isAddSelected()) {\n result = operand1 + operand2\n } else if(Game.isSubtractSelected()) {\n result = operand1 - operand2\n } else if(Game.isMultiplySelected()) {\n result = operand1 * operand2\n } else if(Game.isDivideSelected()) {\n result = operand1 / operand2\n }\n\n if(Game.validateResult(result)) {\n Game.DOM.operationButtons().removeClass(Game.OPERATION_SELECTED_CLASS)\n Game.resetOperationButtonsAria()\n secondNumber.addClass(Game.NUMBER_USED_CLASS)\n secondNumber.attr(\"tabindex\",\"-1\")\n Game.DOM.sectionForNumber(secondNumber).addClass(Game.NUMBER_USED_CLASS)\n gsap.killTweensOf(secondNumber)\n gsap.to(secondNumber, {\n duration: 0.5,\n scale: 0.3,\n rotate: 360,\n opacity: 0,\n transformOrigin: \"50% 50%\"\n });\n\n Game.setNumber(selectedNumber, result)\n Game.ariaSay(`${result} created`)\n\n var numUsedNumbers = parseInt(secondNumber.attr(Game.NUM_USED_NUMBERS_ATTR)) +\n parseInt(selectedNumber.attr(Game.NUM_USED_NUMBERS_ATTR))\n selectedNumber.attr(Game.NUM_USED_NUMBERS_ATTR, numUsedNumbers)\n\n // don't let the user continue clicking things if the game is over!\n let {hasWinningMatch, hasMatch, numUsedInMatch} = Game.checkForWin()\n if(hasWinningMatch || (hasMatch && numUsedInMatch > 1 && !Game.showedUseMoreNumbersPopUp)) {\n Game.interactionPaused = true\n }\n\n Game.bounce(selectedNumber, Game.NUMBER_SELECTED_SCALE, () => {\n if(hasWinningMatch) {\n Game.win()\n } else if(hasMatch && numUsedInMatch > 1 && !Game.showedUseMoreNumbersPopUp) {\n var atLeastAll = Game.isMonstrousMode() ? \"all\" : \"at least\"\n showModal(\"Use more numbers!\",\"Good job making that \" + Game.currentCard.target + \", but you only used \" + numUsedInMatch + \" numbers to make it. Since you're playing on \" + Game.PLAY_LEVEL + \" mode, you have to use \" + atLeastAll + \" \" + Game.numCardsNeededForPlayLevel(Game.PLAY_LEVEL) + \" numbers to make Adsumudi's answer. Keep going or hit 'Reset' to try again. You can also change your play level towards the bottom of the page.\")\n Game.interactionPaused = false\n Game.showedUseMoreNumbersPopUp = true\n }\n })\n }\n },\n\n validateResult: (result) => {\n if(result == Infinity) {\n showModal(\"That's not possible!\", \"Nice try, but it's not possible to divide a number by zero. See if you can try something else.\")\n return false\n } else if(result < 0) {\n showModal(\"No need for negatives!\", \"Sure you could do that, but it would make \" + result + \" and there's no need for negative numbers in this game. See if you can try something else.\")\n return false\n } else if (result > 999) {\n showModal(\"That's too big!\", \"Sure you could do that, but it would make \" + result + \" and there's no need for really large numbers in this game. See if you can try something else.\")\n return false\n } else if (result != Math.round(result)) {\n showModal(\"No need for decimals!\", \"Sure you could do that, but it would make \" + result.toFixed(5).replace(/0+$/g,\"\") + \" and there's no need for decimals or fractions in this game. See if you can try something else.\")\n return false\n }\n return true\n },\n\n bounce: (elements, backTo = 1, onComplete = () => {}) => {\n // Game.interactionPaused = true\n\n gsap.killTweensOf(elements)\n gsap.to(elements, {\n duration: 0.25,\n scale: backTo * 1.3,\n transformOrigin: \"50% 50%\",\n ease: \"power4.out\",\n onComplete: () => {\n gsap.to(elements, {\n duration: 1,\n scale: backTo,\n transformOrigin: \"50% 50%\",\n ease: \"elastic.out(1, 0.3)\",\n onComplete: () => {\n // Game.interactionPaused = false\n onComplete()\n }\n })\n }\n })\n },\n\n checkForWin: () => {\n var hasWinningMatch = false\n var hasMatch = false\n var numUsedInMatch = null\n\n var selectedNumber = Game.DOM.selectedNumber()\n var num = parseInt($(selectedNumber).html())\n var numUsed = parseInt($(selectedNumber).attr(Game.NUM_USED_NUMBERS_ATTR))\n if(num == Game.currentCard.target) {\n hasMatch = true\n numUsedInMatch = numUsed\n hasWinningMatch = (numUsed >= Game.numCardsNeededForPlayLevel())\n }\n\n return {hasWinningMatch, hasMatch, numUsedInMatch}\n },\n\n win: () => {\n Game.interactionPaused = true\n\n Game.recordWin()\n\n Game.DOM.operationButtons().removeClass(Game.OPERATION_ACTIVE_CLASS)\n\n let finishUp = () => {\n Game.DOM.unselectedUnusedNumbers().addClass(Game.NUMBER_USED_CLASS)\n Game.DOM.cardSections().addClass(Game.NUMBER_USED_CLASS)\n Game.DOM.playSection().addClass(\"win\")\n Game.DOM.hintTextCollapse().collapse(\"hide\")\n Game.DOM.playLevelLabels().hide()\n\n var adsumudi = Game.DOM.winMonster()\n adsumudi.attr(\"transform\",\"translate(0, 30)\")\n adsumudi.show()\n gsap.to(adsumudi, {duration: 0.5, ease: \"power4.out\", translateY: 0});\n\n setTimeout(() => {\n Game.DOM.newGameButton().addClass(Game.NEW_BTN_PULSE_CLASS)\n if(Game.numWins() == 1) {\n showModal(\"You did it!\", Game.DOM.winMessage().html())\n } else if(Game.numWins() == 3 || (((Game.numWins() - 3) % 10 == 0) && !window.gaveEmail())) {\n showModal(\"Enjoying Adsumudi?
Get 10% Off!\", Game.DOM.signUpMessage().html())\n Nav.handleSmoothScrollLinks()\n $(\".modal .smooth-scroll\").on(\"click touchstart\", () => { $(\".modal\").modal(\"hide\") })\n }\n Game.resetHints()\n Game.gameOver = true\n }, 1000)\n }\n\n var unselectedUnusedNumbers = Game.DOM.unselectedUnusedNumbers()\n if(unselectedUnusedNumbers.length == 0) {\n finishUp()\n } else {\n gsap.killTweensOf(unselectedUnusedNumbers)\n gsap.to(unselectedUnusedNumbers, {\n duration: 0.5,\n scale: 0.3,\n rotate: 360,\n opacity: 0,\n transformOrigin: \"50% 50%\",\n onComplete: finishUp\n });\n }\n },\n\n numWins: () => {\n var num = Cookies.get(\"num-wins\")\n return (num && !isNaN(num)) ? num : 0\n },\n\n recordWin: () => {\n var numWins = parseInt(Game.numWins())\n Cookies.set(\"num-wins\", numWins + 1)\n },\n\n ariaSay: (str) => {\n Game.DOM.ariaAlert().html(str)\n }\n}\n\nwindow.unsetGaveEmail = () => {\n Cookies.remove(\"gave-email\")\n}\n\nwindow.setGaveEmail = () => {\n Cookies.set(\"gave-email\", \"yes\")\n}\n\nwindow.gaveEmail = () => {\n return Cookies.get(\"gave-email\") == \"yes\"\n}\n","import { Utils } from './utils';\nimport Fraction from \"fraction.js\";\n\nexport let Hints = {\n DOM: {\n window() { return $(window) },\n entireBody() { return $('html,body') },\n body() { return $('body') },\n hintForm() { return $(\"section.hints form\")},\n cardNumberFields() { return $(\"section.hints input[type=number]\")},\n getHintButtons() { return $(\"section.card-hints .hint-button-wrapper button\") },\n hintText(difficulty) { return $(\"section.card-hints .hint-button-wrapper p.hint-text.\" + difficulty) }\n },\n\n PlayLevel: {\n EASY: \"easy\",\n MEDIUM: \"medium\",\n HARD: \"hard\",\n MONSTROUS: \"monstrous\"\n },\n\n currentCard: null,\n currentPlayLevel: null,\n currentHintNumbers: {},\n\n setCard(card) {\n Hints.currentCard = card;\n Hints.resetHints()\n },\n\n setPlayLevel(playLevel) {\n if(playLevel != Hints.currentPlayLevel) {\n Hints.currentPlayLevel = playLevel\n Hints.resetHints()\n }\n },\n\n resetHints() {\n Hints.currentHintNumbers[Hints.currentPlayLevel] = -1\n },\n\n currentHintNumber() {\n return Hints.currentHintNumbers[Hints.currentPlayLevel]\n },\n\n currentHint() {\n return Hints.currentHints()[Hints.currentHintNumber()]\n },\n\n nextHint() {\n if(Hints.isFinalHint()) {\n return null\n }\n\n Hints.currentHintNumbers[Hints.currentPlayLevel] += 1\n return Hints.currentHint()\n },\n\n isFirstHint() {\n return Hints.currentHintNumber() == 0\n },\n\n isFinalHint() {\n return Hints.currentHintNumber() == Hints.currentHints().length - 1\n },\n\n isFinalHintNext() {\n return Hints.currentHintNumber() == Hints.currentHints().length - 2\n },\n\n currentHints: () => {\n return {\n [Hints.PlayLevel.EASY]: [\n Hints.formattedTryUsingCardsHint(Hints.currentCard.easy_hint1, true),\n Hints.formattedTryUsingCardsHint(Hints.currentCard.easy_hint2),\n Hints.formattedFinalHint(Hints.currentCard.easy_hint3, false)\n ],\n [Hints.PlayLevel.MEDIUM]: [\n Hints.formattedTryUsingCardsHint(Hints.currentCard.medium_hint1),\n Hints.formattedStartWithEqHint(Hints.currentCard.medium_hint2),\n Hints.formattedFinalHint(Hints.currentCard.medium_hint3)\n ],\n [Hints.PlayLevel.HARD]: [\n Hints.formattedTryUsingCardsHint(Hints.currentCard.hard_hint1),\n Hints.formattedStartWithEqHint(Hints.currentCard.hard_hint2),\n Hints.formattedThenDoEqHint(Hints.currentCard.hard_hint3),\n Hints.formattedFinalHint(Hints.currentCard.hard_hint4)\n ],\n [Hints.PlayLevel.MONSTROUS]: [\n Hints.formattedStartWithEqHint(Hints.currentCard.monstrous_hint1),\n Hints.formattedThenDoEqHint(Hints.currentCard.monstrous_hint2),\n Hints.formattedThenDoEqHint(Hints.currentCard.monstrous_hint3),\n Hints.formattedFinalHint(Hints.currentCard.monstrous_hint4)\n ]\n }[Hints.currentPlayLevel]\n },\n\n formattedTryUsingCardsHint(hintText, startWith = false) {\n if(hintText == null) return \"\"\n var tryUsing = startWith ? \"Start with\" : \"Try using\"\n return tryUsing + \" the \" + Utils.listify(hintText.split(\" | \"))\n },\n\n formattedFinalHint(hintText, useThen = true) {\n if(hintText == null) return \"\"\n var result = useThen ? \"Then do \" : \"Do \"\n return result + Hints.formattedHintEq(hintText) + \" to make Adsumudi's answer of \" + Hints.evalEq(hintText)\n },\n\n formattedThenDoEqHint(hintText) {\n if(hintText == null) return \"\"\n return \"Then do \" + Hints.formattedHintEq(hintText) + \" to make \" + Hints.evalEq(hintText)\n },\n\n formattedStartWithEqHint(hintText) {\n if(hintText == null) return \"\"\n return \"Start with \" + Hints.formattedHintEq(hintText) + \" to make \" + Hints.evalEq(hintText)\n },\n\n formattedHintEq(eqText) {\n if(eqText == null) return null;\n if(Hints.hintEqInvolvedFractions(eqText)) {\n return eqText;\n } else {\n return eqText.replace(/\\//g,\"÷\")\n }\n },\n\n hintEqInvolvedFractions(eqStr) {\n var eqParts = eqStr.split(\" \")\n var n1 = eqParts[0]\n var n2 = eqParts[2] \n return n1.match(\"/\") != null || n2.match(\"/\") != null\n },\n\n evalEq(eqStr) {\n var stdEqStr = eqStr.replace(/÷/g,\"/\").replace(/x/g,\"*\").replace(/×/g,\"*\").replace(/\\$/g,\"\")\n \n if(Hints.hintEqInvolvedFractions(eqStr)) {\n var eqParts = stdEqStr.split(\" \")\n var n1 = eqParts[0]\n var n2 = eqParts[2] \n var symbol = eqParts[1]\n n1 = Fraction(n1)\n n2 = Fraction(n2)\n var res = null\n if(symbol == \"+\") {\n res = n1.add(n2)\n } else if(symbol == \"-\") {\n res = n1.sub(n2)\n } else if(symbol == \"*\") {\n res = n1.mul(n2)\n } else if(symbol == \"/\") {\n res = n1.div(n2)\n }\n if(res.d == 1) return res.toString()\n else return res.n + \"/\" + res.d\n } else {\n var isMoney = eqStr.match(\"\\\\$\") != null\n var result = eval(stdEqStr)\n if(isMoney) {\n if(result == Math.round(result)) {\n return \"$\" + result;\n } else {\n return \"$\" + parseFloat(result).toFixed(2)\n }\n } else {\n return result;\n }\n }\n },\n\n handleGetHints() {\n if(Hints.DOM.getHintButtons().length == 0) return \n let touchEvent = Utils.isMobile() ? \"touchend\" : \"click\"\n Hints.DOM.getHintButtons().on(touchEvent, Hints.getHintButtonClicked)\n Hints.setCard(CARD_FOR_HINTS)\n },\n\n getHintButtonClicked(event) {\n var button = $(event.target)\n var difficulty = button.attr(\"adsumudi-data-difficulty\")\n var hintText = Hints.DOM.hintText(difficulty)\n Hints.setPlayLevel(difficulty)\n var hint = Hints.nextHint()\n if(Hints.isFirstHint()) {\n hintText.html(hint)\n } else {\n hintText.html(hintText.html() + \"
\" + hint)\n }\n if(Hints.isFinalHintNext()) {\n button.html(\"SHOW SOLUTION\")\n } else if(Hints.isFinalHint()) {\n button.hide()\n } else {\n button.html(\"NEXT HINT\")\n }\n },\n\n handleFormSubmission() {\n Hints.DOM.hintForm().on(\"submit\", Hints.checkForErrors)\n Hints.DOM.cardNumberFields().on(\"keyup change\", Hints.formatCardNumberFields)\n },\n\n checkForErrors(event) {\n var hasError = false;\n $.each(Hints.DOM.cardNumberFields(), function(i, field) {\n if($(field).val() == \"\") {\n $(field).addClass(\"error\")\n if(!hasError) {\n $(field).focus()\n }\n hasError = true\n }\n })\n if(hasError) {\n event.stopPropagation()\n event.preventDefault();\n }\n return !hasError\n },\n\n formatCardNumberFields(event) {\n var field = $(event.target)\n if(field.val().match(/[^0-9]/)) {\n field.val(field.val().replace(/[^0-9]/g, \"\").trim())\n }\n if(parseInt(field.val()) == 0) {\n field.val(0)\n } else {\n field.val(field.val().replace(/^0+/g, \"\").trim())\n }\n if(parseInt(field.val()) > 99) {\n field.val(field.val().substring(0,2))\n }\n if(field.val() != \"\") {\n $(field).removeClass(\"error\")\n }\n }\n}\n","import { Nav } from \"./nav.js\";\nimport { Hints } from \"./hints.js\";\nimport { Game } from \"./game.js\";\n\nlet App = {\n DOM: {\n window: () => $(window),\n entireBody: () => $('html,body'),\n body: () => $('body'),\n fillHeightSection: () => $(\"section.fill-height\"),\n collapseElements: () => $(\".collapse\")\n },\n\n handleFillHeight: () => {\n if(App.DOM.fillHeightSection().length > 0) {\n App.fillHeight()\n $(window).resize(App.fillHeight)\n $(document).on(\"turbolinks:render\", App.fillHeight)\n $(App.DOM.collapseElements()).on(\"shown.bs.collapse\", App.fillHeight)\n onElementHeightChange(document.body, App.fillHeight)\n }\n },\n\n fillHeight: () => {\n App.DOM.fillHeightSection().css(\"height\",\"auto\")\n\n var windowHeight = App.DOM.window().outerHeight()\n var bodyHeight = App.DOM.body().outerHeight()\n var diff = windowHeight - bodyHeight\n if(diff > 0) {\n App.DOM.fillHeightSection().outerHeight(App.DOM.fillHeightSection().outerHeight() + diff)\n }\n }\n}\n\nlet onElementHeightChange = (elm, callback) => {\n\tvar lastHeight = elm.clientHeight, newHeight;\n var lastScrollY = window.pageYOffset, newScrollY;\n\t(function run(){\n\t\tnewHeight = elm.clientHeight;\n\t\tif( lastHeight != newHeight )\n\t\t\tcallback();\n\t\tlastHeight = newHeight;\n if (elm.onElementHeightChangeTimer)\n clearTimeout(elm.onElementHeightChangeTimer);\n\t\telm.onElementHeightChangeTimer = setTimeout(run, 200);\n\t})();\n}\n\n$(document).ready(() => {\n Nav.setUpNavbar();\n Nav.handleSmoothScrollLinks();\n Nav.tmpDisableAnimateNavBar();\n App.handleFillHeight();\n Hints.handleFormSubmission();\n Hints.handleGetHints()\n Game.handleGame();\n});\n","export let Nav = {\n DOM: {\n window: () => $(window),\n entireBody: () => $('html,body'),\n body: () => $('body'),\n navbar: () => $(\".navbar\"),\n navbarContainer: () => $(\".navbar .container-fluid\"),\n navbarCollapse: () => $(\".navbar-collapse\"),\n navbarToggler: () => $(\"button.navbar-toggler\"),\n navbarLinks: () => $(\"a.nav-link\"),\n anyNonNavElement: () => $(\"body *\").not(\".navbar\").not(\".navbar *\"),\n smoothScrollLinks: () => $(\"a.smooth-scroll\")\n },\n\n SCROLL_TO_OFFSET: 50,\n NAV_SCROLL_SPEED : 250,\n\n windowScrollTop: () => {\n return window.pageYOffset || document.documentElement.scrollTop\n },\n\n scrollTo: (el, onComplete) => {\n if(typeof(onComplete) === \"undefined\") {\n onComplete = () => {}\n }\n var elTop = el.offset().top\n var offset = Nav.SCROLL_TO_OFFSET\n var navOffset = Nav.DOM.navbar().hasClass(\"fixed-top\") ? parseInt(Nav.DOM.navbar().css(\"top\")) : (-1 * Nav.DOM.navbar().outerHeight())\n offset += (Nav.DOM.navbar().outerHeight() + navOffset)\n Nav.tmpDisableAnimateNavBar()\n Nav.DOM.entireBody().animate({ scrollTop: elTop - offset }, 'slow', () => {\n $(el).focus()\n onComplete()\n });\n },\n\n lastScrollTop: 0,\n\n setUpNavbar: () => {\n Nav.lastScrollTop = Nav.windowScrollTop()\n Nav.DOM.window().scroll(Nav.animateNavbar)\n\n if(Nav.DOM.navbarToggler().is(\":visible\")) {\n Nav.DOM.navbarLinks().attr(\"tabindex\", \"-1\")\n }\n\n Nav.DOM.anyNonNavElement().focus(() => {\n Nav.DOM.navbarCollapse().collapse(\"hide\")\n })\n\n Nav.DOM.navbarCollapse().on(\"show.bs.collapse\", () => {\n Nav.DOM.navbarToggler().focus()\n Nav.DOM.navbarToggler().attr(\"aria-label\",\"close mobile menu\")\n })\n\n Nav.DOM.navbarCollapse().on(\"shown.bs.collapse\", () => {\n Nav.DOM.navbarLinks().removeAttr(\"tabindex\")\n })\n\n Nav.DOM.navbarCollapse().on(\"hide.bs.collapse\", () => {\n Nav.DOM.navbarLinks().attr(\"tabindex\", \"-1\")\n Nav.DOM.navbarToggler().attr(\"aria-label\",\"open mobile menu\")\n })\n },\n\n scrollDir: null,\n\n animateNavbar: () => {\n if(Nav.disableNavAnimation) return;\n\n var st = Nav.windowScrollTop();\n var navbarHeight = Nav.DOM.navbar().outerHeight();\n\n if(st > navbarHeight) {\n if(!Nav.DOM.navbar().hasClass(\"fixed-top\")) {\n Nav.DOM.navbar().css(\"top\", -1 * navbarHeight)\n Nav.DOM.navbar().addClass(\"fixed-top\")\n Nav.DOM.body().css(\"padding-top\",navbarHeight)\n }\n\n if (st > Nav.lastScrollTop && Nav.scrollDir != \"down\") {\n Nav.DOM.navbar().stop(true, false)\n Nav.DOM.navbar().animate({top: -1 * navbarHeight}, Nav.NAV_SCROLL_SPEED)\n Nav.scrollDir = \"down\"\n } else if (st < Nav.lastScrollTop && Nav.scrollDir != \"up\") {\n Nav.DOM.navbar().stop(true, false)\n Nav.DOM.navbar().animate({top: 0}, Nav.NAV_SCROLL_SPEED)\n Nav.scrollDir = \"up\"\n }\n\n if(Nav.DOM.navbarCollapse().hasClass(\"show\")) {\n setTimeout(function() { Nav.DOM.navbarToggler().click() }, Nav.NAV_SCROLL_SPEED)\n }\n } else if(st <= 0) {\n Nav.DOM.navbar().removeClass(\"fixed-top\")\n Nav.DOM.body().css(\"padding-top\",0)\n }\n\n Nav.lastScrollTop = st;\n },\n\n disableNavAnimation: false,\n disableNavAnimationTimeout: null,\n tmpDisableAnimateNavBar: () => {\n Nav.disableNavAnimation = true;\n if(Nav.disableNavAnimationTimeout != null) {\n clearTimeout(Nav.disableNavAnimationTimeout);\n Nav.disableNavAnimationTimeout = null;\n }\n Nav.disableNavAnimationTimeout = setTimeout(() => {\n Nav.disableNavAnimation = false\n }, 1000)\n },\n\n handleSmoothScrollLinks: () => {\n Nav.DOM.smoothScrollLinks().on(\"click touchstart\", (event) => {\n var scrollToId = $(event.target).attr(\"href\")\n var scrollToEl = $(scrollToId)\n Nav.scrollTo(scrollToEl)\n return false;\n })\n if(window.location.hash != \"\") {\n var scrollToEl = $(window.location.hash)\n Nav.scrollTo(scrollToEl)\n }\n }\n}\n","// This file is automatically compiled by Webpack, along with any other files\n// present in this directory. You're encouraged to place your actual application logic in\n// a relevant structure within app/javascript and only use these pack files to reference\n// that code so it'll be compiled.\n\nrequire(\"@rails/ujs\").start()\n// require(\"turbolinks\").start()\nrequire(\"@rails/activestorage\").start()\nrequire(\"channels\")\nrequire(\"jquery\")\nrequire(\"jquery-ui-app\")\nrequire(\"bootstrap\")\nrequire(\"main\")\n\n// Uncomment to copy all static images under ../images to the output folder and reference\n// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)\n// or the `imagePath` JavaScript helper below.\n//\n// const images = require.context('../images', true)\n// const imagePath = (name) => images(name, true)\n","var pluralize = require('pluralize')\n\nexport let Utils = {\n capitalize: (str) => {\n var result = str.replace(/\\b[a-z]/g, function(letter) {\n return letter.toUpperCase();\n });\n return result\n },\n\n pluralize: (str, num) => {\n return pluralize(str, num)\n },\n\n listify: (arr, conjunction = \"and\") => {\n return arr.join(\", \").replace(/, ([^,]*)$/, ' ' + conjunction + ' $1')\n },\n\n isMobile: () => {\n var isMobile = false;\n if(/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)\n || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(navigator.userAgent.substr(0,4))) {\n isMobile = true;\n }\n return isMobile;\n }\n}\n","(function (global, factory) {\n typeof exports === \"object\" && typeof module !== \"undefined\" ? factory(exports) : typeof define === \"function\" && define.amd ? define([\"exports\"], factory) : factory(global.ActiveStorage = {});\n})(this, function (exports) {\n \"use strict\";\n\n function createCommonjsModule(fn, module) {\n return module = {\n exports: {}\n }, fn(module, module.exports), module.exports;\n }\n var sparkMd5 = createCommonjsModule(function (module, exports) {\n (function (factory) {\n {\n module.exports = factory();\n }\n })(function (undefined) {\n var hex_chr = [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\"];\n function md5cycle(x, k) {\n var a = x[0],\n b = x[1],\n c = x[2],\n d = x[3];\n a += (b & c | ~b & d) + k[0] - 680876936 | 0;\n a = (a << 7 | a >>> 25) + b | 0;\n d += (a & b | ~a & c) + k[1] - 389564586 | 0;\n d = (d << 12 | d >>> 20) + a | 0;\n c += (d & a | ~d & b) + k[2] + 606105819 | 0;\n c = (c << 17 | c >>> 15) + d | 0;\n b += (c & d | ~c & a) + k[3] - 1044525330 | 0;\n b = (b << 22 | b >>> 10) + c | 0;\n a += (b & c | ~b & d) + k[4] - 176418897 | 0;\n a = (a << 7 | a >>> 25) + b | 0;\n d += (a & b | ~a & c) + k[5] + 1200080426 | 0;\n d = (d << 12 | d >>> 20) + a | 0;\n c += (d & a | ~d & b) + k[6] - 1473231341 | 0;\n c = (c << 17 | c >>> 15) + d | 0;\n b += (c & d | ~c & a) + k[7] - 45705983 | 0;\n b = (b << 22 | b >>> 10) + c | 0;\n a += (b & c | ~b & d) + k[8] + 1770035416 | 0;\n a = (a << 7 | a >>> 25) + b | 0;\n d += (a & b | ~a & c) + k[9] - 1958414417 | 0;\n d = (d << 12 | d >>> 20) + a | 0;\n c += (d & a | ~d & b) + k[10] - 42063 | 0;\n c = (c << 17 | c >>> 15) + d | 0;\n b += (c & d | ~c & a) + k[11] - 1990404162 | 0;\n b = (b << 22 | b >>> 10) + c | 0;\n a += (b & c | ~b & d) + k[12] + 1804603682 | 0;\n a = (a << 7 | a >>> 25) + b | 0;\n d += (a & b | ~a & c) + k[13] - 40341101 | 0;\n d = (d << 12 | d >>> 20) + a | 0;\n c += (d & a | ~d & b) + k[14] - 1502002290 | 0;\n c = (c << 17 | c >>> 15) + d | 0;\n b += (c & d | ~c & a) + k[15] + 1236535329 | 0;\n b = (b << 22 | b >>> 10) + c | 0;\n a += (b & d | c & ~d) + k[1] - 165796510 | 0;\n a = (a << 5 | a >>> 27) + b | 0;\n d += (a & c | b & ~c) + k[6] - 1069501632 | 0;\n d = (d << 9 | d >>> 23) + a | 0;\n c += (d & b | a & ~b) + k[11] + 643717713 | 0;\n c = (c << 14 | c >>> 18) + d | 0;\n b += (c & a | d & ~a) + k[0] - 373897302 | 0;\n b = (b << 20 | b >>> 12) + c | 0;\n a += (b & d | c & ~d) + k[5] - 701558691 | 0;\n a = (a << 5 | a >>> 27) + b | 0;\n d += (a & c | b & ~c) + k[10] + 38016083 | 0;\n d = (d << 9 | d >>> 23) + a | 0;\n c += (d & b | a & ~b) + k[15] - 660478335 | 0;\n c = (c << 14 | c >>> 18) + d | 0;\n b += (c & a | d & ~a) + k[4] - 405537848 | 0;\n b = (b << 20 | b >>> 12) + c | 0;\n a += (b & d | c & ~d) + k[9] + 568446438 | 0;\n a = (a << 5 | a >>> 27) + b | 0;\n d += (a & c | b & ~c) + k[14] - 1019803690 | 0;\n d = (d << 9 | d >>> 23) + a | 0;\n c += (d & b | a & ~b) + k[3] - 187363961 | 0;\n c = (c << 14 | c >>> 18) + d | 0;\n b += (c & a | d & ~a) + k[8] + 1163531501 | 0;\n b = (b << 20 | b >>> 12) + c | 0;\n a += (b & d | c & ~d) + k[13] - 1444681467 | 0;\n a = (a << 5 | a >>> 27) + b | 0;\n d += (a & c | b & ~c) + k[2] - 51403784 | 0;\n d = (d << 9 | d >>> 23) + a | 0;\n c += (d & b | a & ~b) + k[7] + 1735328473 | 0;\n c = (c << 14 | c >>> 18) + d | 0;\n b += (c & a | d & ~a) + k[12] - 1926607734 | 0;\n b = (b << 20 | b >>> 12) + c | 0;\n a += (b ^ c ^ d) + k[5] - 378558 | 0;\n a = (a << 4 | a >>> 28) + b | 0;\n d += (a ^ b ^ c) + k[8] - 2022574463 | 0;\n d = (d << 11 | d >>> 21) + a | 0;\n c += (d ^ a ^ b) + k[11] + 1839030562 | 0;\n c = (c << 16 | c >>> 16) + d | 0;\n b += (c ^ d ^ a) + k[14] - 35309556 | 0;\n b = (b << 23 | b >>> 9) + c | 0;\n a += (b ^ c ^ d) + k[1] - 1530992060 | 0;\n a = (a << 4 | a >>> 28) + b | 0;\n d += (a ^ b ^ c) + k[4] + 1272893353 | 0;\n d = (d << 11 | d >>> 21) + a | 0;\n c += (d ^ a ^ b) + k[7] - 155497632 | 0;\n c = (c << 16 | c >>> 16) + d | 0;\n b += (c ^ d ^ a) + k[10] - 1094730640 | 0;\n b = (b << 23 | b >>> 9) + c | 0;\n a += (b ^ c ^ d) + k[13] + 681279174 | 0;\n a = (a << 4 | a >>> 28) + b | 0;\n d += (a ^ b ^ c) + k[0] - 358537222 | 0;\n d = (d << 11 | d >>> 21) + a | 0;\n c += (d ^ a ^ b) + k[3] - 722521979 | 0;\n c = (c << 16 | c >>> 16) + d | 0;\n b += (c ^ d ^ a) + k[6] + 76029189 | 0;\n b = (b << 23 | b >>> 9) + c | 0;\n a += (b ^ c ^ d) + k[9] - 640364487 | 0;\n a = (a << 4 | a >>> 28) + b | 0;\n d += (a ^ b ^ c) + k[12] - 421815835 | 0;\n d = (d << 11 | d >>> 21) + a | 0;\n c += (d ^ a ^ b) + k[15] + 530742520 | 0;\n c = (c << 16 | c >>> 16) + d | 0;\n b += (c ^ d ^ a) + k[2] - 995338651 | 0;\n b = (b << 23 | b >>> 9) + c | 0;\n a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;\n a = (a << 6 | a >>> 26) + b | 0;\n d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;\n d = (d << 10 | d >>> 22) + a | 0;\n c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;\n c = (c << 15 | c >>> 17) + d | 0;\n b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;\n b = (b << 21 | b >>> 11) + c | 0;\n a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;\n a = (a << 6 | a >>> 26) + b | 0;\n d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;\n d = (d << 10 | d >>> 22) + a | 0;\n c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;\n c = (c << 15 | c >>> 17) + d | 0;\n b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;\n b = (b << 21 | b >>> 11) + c | 0;\n a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;\n a = (a << 6 | a >>> 26) + b | 0;\n d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;\n d = (d << 10 | d >>> 22) + a | 0;\n c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;\n c = (c << 15 | c >>> 17) + d | 0;\n b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;\n b = (b << 21 | b >>> 11) + c | 0;\n a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;\n a = (a << 6 | a >>> 26) + b | 0;\n d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;\n d = (d << 10 | d >>> 22) + a | 0;\n c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;\n c = (c << 15 | c >>> 17) + d | 0;\n b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;\n b = (b << 21 | b >>> 11) + c | 0;\n x[0] = a + x[0] | 0;\n x[1] = b + x[1] | 0;\n x[2] = c + x[2] | 0;\n x[3] = d + x[3] | 0;\n }\n function md5blk(s) {\n var md5blks = [],\n i;\n for (i = 0; i < 64; i += 4) {\n md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);\n }\n return md5blks;\n }\n function md5blk_array(a) {\n var md5blks = [],\n i;\n for (i = 0; i < 64; i += 4) {\n md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);\n }\n return md5blks;\n }\n function md51(s) {\n var n = s.length,\n state = [1732584193, -271733879, -1732584194, 271733878],\n i,\n length,\n tail,\n tmp,\n lo,\n hi;\n for (i = 64; i <= n; i += 64) {\n md5cycle(state, md5blk(s.substring(i - 64, i)));\n }\n s = s.substring(i - 64);\n length = s.length;\n tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n for (i = 0; i < length; i += 1) {\n tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);\n }\n tail[i >> 2] |= 128 << (i % 4 << 3);\n if (i > 55) {\n md5cycle(state, tail);\n for (i = 0; i < 16; i += 1) {\n tail[i] = 0;\n }\n }\n tmp = n * 8;\n tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);\n lo = parseInt(tmp[2], 16);\n hi = parseInt(tmp[1], 16) || 0;\n tail[14] = lo;\n tail[15] = hi;\n md5cycle(state, tail);\n return state;\n }\n function md51_array(a) {\n var n = a.length,\n state = [1732584193, -271733879, -1732584194, 271733878],\n i,\n length,\n tail,\n tmp,\n lo,\n hi;\n for (i = 64; i <= n; i += 64) {\n md5cycle(state, md5blk_array(a.subarray(i - 64, i)));\n }\n a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0);\n length = a.length;\n tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n for (i = 0; i < length; i += 1) {\n tail[i >> 2] |= a[i] << (i % 4 << 3);\n }\n tail[i >> 2] |= 128 << (i % 4 << 3);\n if (i > 55) {\n md5cycle(state, tail);\n for (i = 0; i < 16; i += 1) {\n tail[i] = 0;\n }\n }\n tmp = n * 8;\n tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);\n lo = parseInt(tmp[2], 16);\n hi = parseInt(tmp[1], 16) || 0;\n tail[14] = lo;\n tail[15] = hi;\n md5cycle(state, tail);\n return state;\n }\n function rhex(n) {\n var s = \"\",\n j;\n for (j = 0; j < 4; j += 1) {\n s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15];\n }\n return s;\n }\n function hex(x) {\n var i;\n for (i = 0; i < x.length; i += 1) {\n x[i] = rhex(x[i]);\n }\n return x.join(\"\");\n }\n if (hex(md51(\"hello\")) !== \"5d41402abc4b2a76b9719d911017c592\") ;\n if (typeof ArrayBuffer !== \"undefined\" && !ArrayBuffer.prototype.slice) {\n (function () {\n function clamp(val, length) {\n val = val | 0 || 0;\n if (val < 0) {\n return Math.max(val + length, 0);\n }\n return Math.min(val, length);\n }\n ArrayBuffer.prototype.slice = function (from, to) {\n var length = this.byteLength,\n begin = clamp(from, length),\n end = length,\n num,\n target,\n targetArray,\n sourceArray;\n if (to !== undefined) {\n end = clamp(to, length);\n }\n if (begin > end) {\n return new ArrayBuffer(0);\n }\n num = end - begin;\n target = new ArrayBuffer(num);\n targetArray = new Uint8Array(target);\n sourceArray = new Uint8Array(this, begin, num);\n targetArray.set(sourceArray);\n return target;\n };\n })();\n }\n function toUtf8(str) {\n if (/[\\u0080-\\uFFFF]/.test(str)) {\n str = unescape(encodeURIComponent(str));\n }\n return str;\n }\n function utf8Str2ArrayBuffer(str, returnUInt8Array) {\n var length = str.length,\n buff = new ArrayBuffer(length),\n arr = new Uint8Array(buff),\n i;\n for (i = 0; i < length; i += 1) {\n arr[i] = str.charCodeAt(i);\n }\n return returnUInt8Array ? arr : buff;\n }\n function arrayBuffer2Utf8Str(buff) {\n return String.fromCharCode.apply(null, new Uint8Array(buff));\n }\n function concatenateArrayBuffers(first, second, returnUInt8Array) {\n var result = new Uint8Array(first.byteLength + second.byteLength);\n result.set(new Uint8Array(first));\n result.set(new Uint8Array(second), first.byteLength);\n return returnUInt8Array ? result : result.buffer;\n }\n function hexToBinaryString(hex) {\n var bytes = [],\n length = hex.length,\n x;\n for (x = 0; x < length - 1; x += 2) {\n bytes.push(parseInt(hex.substr(x, 2), 16));\n }\n return String.fromCharCode.apply(String, bytes);\n }\n function SparkMD5() {\n this.reset();\n }\n SparkMD5.prototype.append = function (str) {\n this.appendBinary(toUtf8(str));\n return this;\n };\n SparkMD5.prototype.appendBinary = function (contents) {\n this._buff += contents;\n this._length += contents.length;\n var length = this._buff.length,\n i;\n for (i = 64; i <= length; i += 64) {\n md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));\n }\n this._buff = this._buff.substring(i - 64);\n return this;\n };\n SparkMD5.prototype.end = function (raw) {\n var buff = this._buff,\n length = buff.length,\n i,\n tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n ret;\n for (i = 0; i < length; i += 1) {\n tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3);\n }\n this._finish(tail, length);\n ret = hex(this._hash);\n if (raw) {\n ret = hexToBinaryString(ret);\n }\n this.reset();\n return ret;\n };\n SparkMD5.prototype.reset = function () {\n this._buff = \"\";\n this._length = 0;\n this._hash = [1732584193, -271733879, -1732584194, 271733878];\n return this;\n };\n SparkMD5.prototype.getState = function () {\n return {\n buff: this._buff,\n length: this._length,\n hash: this._hash\n };\n };\n SparkMD5.prototype.setState = function (state) {\n this._buff = state.buff;\n this._length = state.length;\n this._hash = state.hash;\n return this;\n };\n SparkMD5.prototype.destroy = function () {\n delete this._hash;\n delete this._buff;\n delete this._length;\n };\n SparkMD5.prototype._finish = function (tail, length) {\n var i = length,\n tmp,\n lo,\n hi;\n tail[i >> 2] |= 128 << (i % 4 << 3);\n if (i > 55) {\n md5cycle(this._hash, tail);\n for (i = 0; i < 16; i += 1) {\n tail[i] = 0;\n }\n }\n tmp = this._length * 8;\n tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);\n lo = parseInt(tmp[2], 16);\n hi = parseInt(tmp[1], 16) || 0;\n tail[14] = lo;\n tail[15] = hi;\n md5cycle(this._hash, tail);\n };\n SparkMD5.hash = function (str, raw) {\n return SparkMD5.hashBinary(toUtf8(str), raw);\n };\n SparkMD5.hashBinary = function (content, raw) {\n var hash = md51(content),\n ret = hex(hash);\n return raw ? hexToBinaryString(ret) : ret;\n };\n SparkMD5.ArrayBuffer = function () {\n this.reset();\n };\n SparkMD5.ArrayBuffer.prototype.append = function (arr) {\n var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),\n length = buff.length,\n i;\n this._length += arr.byteLength;\n for (i = 64; i <= length; i += 64) {\n md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));\n }\n this._buff = i - 64 < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);\n return this;\n };\n SparkMD5.ArrayBuffer.prototype.end = function (raw) {\n var buff = this._buff,\n length = buff.length,\n tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n i,\n ret;\n for (i = 0; i < length; i += 1) {\n tail[i >> 2] |= buff[i] << (i % 4 << 3);\n }\n this._finish(tail, length);\n ret = hex(this._hash);\n if (raw) {\n ret = hexToBinaryString(ret);\n }\n this.reset();\n return ret;\n };\n SparkMD5.ArrayBuffer.prototype.reset = function () {\n this._buff = new Uint8Array(0);\n this._length = 0;\n this._hash = [1732584193, -271733879, -1732584194, 271733878];\n return this;\n };\n SparkMD5.ArrayBuffer.prototype.getState = function () {\n var state = SparkMD5.prototype.getState.call(this);\n state.buff = arrayBuffer2Utf8Str(state.buff);\n return state;\n };\n SparkMD5.ArrayBuffer.prototype.setState = function (state) {\n state.buff = utf8Str2ArrayBuffer(state.buff, true);\n return SparkMD5.prototype.setState.call(this, state);\n };\n SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;\n SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;\n SparkMD5.ArrayBuffer.hash = function (arr, raw) {\n var hash = md51_array(new Uint8Array(arr)),\n ret = hex(hash);\n return raw ? hexToBinaryString(ret) : ret;\n };\n return SparkMD5;\n });\n });\n var classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n };\n var createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n }();\n var fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;\n var FileChecksum = function () {\n createClass(FileChecksum, null, [{\n key: \"create\",\n value: function create(file, callback) {\n var instance = new FileChecksum(file);\n instance.create(callback);\n }\n }]);\n function FileChecksum(file) {\n classCallCheck(this, FileChecksum);\n this.file = file;\n this.chunkSize = 2097152;\n this.chunkCount = Math.ceil(this.file.size / this.chunkSize);\n this.chunkIndex = 0;\n }\n createClass(FileChecksum, [{\n key: \"create\",\n value: function create(callback) {\n var _this = this;\n this.callback = callback;\n this.md5Buffer = new sparkMd5.ArrayBuffer();\n this.fileReader = new FileReader();\n this.fileReader.addEventListener(\"load\", function (event) {\n return _this.fileReaderDidLoad(event);\n });\n this.fileReader.addEventListener(\"error\", function (event) {\n return _this.fileReaderDidError(event);\n });\n this.readNextChunk();\n }\n }, {\n key: \"fileReaderDidLoad\",\n value: function fileReaderDidLoad(event) {\n this.md5Buffer.append(event.target.result);\n if (!this.readNextChunk()) {\n var binaryDigest = this.md5Buffer.end(true);\n var base64digest = btoa(binaryDigest);\n this.callback(null, base64digest);\n }\n }\n }, {\n key: \"fileReaderDidError\",\n value: function fileReaderDidError(event) {\n this.callback(\"Error reading \" + this.file.name);\n }\n }, {\n key: \"readNextChunk\",\n value: function readNextChunk() {\n if (this.chunkIndex < this.chunkCount || this.chunkIndex == 0 && this.chunkCount == 0) {\n var start = this.chunkIndex * this.chunkSize;\n var end = Math.min(start + this.chunkSize, this.file.size);\n var bytes = fileSlice.call(this.file, start, end);\n this.fileReader.readAsArrayBuffer(bytes);\n this.chunkIndex++;\n return true;\n } else {\n return false;\n }\n }\n }]);\n return FileChecksum;\n }();\n function getMetaValue(name) {\n var element = findElement(document.head, 'meta[name=\"' + name + '\"]');\n if (element) {\n return element.getAttribute(\"content\");\n }\n }\n function findElements(root, selector) {\n if (typeof root == \"string\") {\n selector = root;\n root = document;\n }\n var elements = root.querySelectorAll(selector);\n return toArray$1(elements);\n }\n function findElement(root, selector) {\n if (typeof root == \"string\") {\n selector = root;\n root = document;\n }\n return root.querySelector(selector);\n }\n function dispatchEvent(element, type) {\n var eventInit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var disabled = element.disabled;\n var bubbles = eventInit.bubbles,\n cancelable = eventInit.cancelable,\n detail = eventInit.detail;\n var event = document.createEvent(\"Event\");\n event.initEvent(type, bubbles || true, cancelable || true);\n event.detail = detail || {};\n try {\n element.disabled = false;\n element.dispatchEvent(event);\n } finally {\n element.disabled = disabled;\n }\n return event;\n }\n function toArray$1(value) {\n if (Array.isArray(value)) {\n return value;\n } else if (Array.from) {\n return Array.from(value);\n } else {\n return [].slice.call(value);\n }\n }\n var BlobRecord = function () {\n function BlobRecord(file, checksum, url) {\n var _this = this;\n classCallCheck(this, BlobRecord);\n this.file = file;\n this.attributes = {\n filename: file.name,\n content_type: file.type || \"application/octet-stream\",\n byte_size: file.size,\n checksum: checksum\n };\n this.xhr = new XMLHttpRequest();\n this.xhr.open(\"POST\", url, true);\n this.xhr.responseType = \"json\";\n this.xhr.setRequestHeader(\"Content-Type\", \"application/json\");\n this.xhr.setRequestHeader(\"Accept\", \"application/json\");\n this.xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n var csrfToken = getMetaValue(\"csrf-token\");\n if (csrfToken != undefined) {\n this.xhr.setRequestHeader(\"X-CSRF-Token\", csrfToken);\n }\n this.xhr.addEventListener(\"load\", function (event) {\n return _this.requestDidLoad(event);\n });\n this.xhr.addEventListener(\"error\", function (event) {\n return _this.requestDidError(event);\n });\n }\n createClass(BlobRecord, [{\n key: \"create\",\n value: function create(callback) {\n this.callback = callback;\n this.xhr.send(JSON.stringify({\n blob: this.attributes\n }));\n }\n }, {\n key: \"requestDidLoad\",\n value: function requestDidLoad(event) {\n if (this.status >= 200 && this.status < 300) {\n var response = this.response;\n var direct_upload = response.direct_upload;\n delete response.direct_upload;\n this.attributes = response;\n this.directUploadData = direct_upload;\n this.callback(null, this.toJSON());\n } else {\n this.requestDidError(event);\n }\n }\n }, {\n key: \"requestDidError\",\n value: function requestDidError(event) {\n this.callback('Error creating Blob for \"' + this.file.name + '\". Status: ' + this.status);\n }\n }, {\n key: \"toJSON\",\n value: function toJSON() {\n var result = {};\n for (var key in this.attributes) {\n result[key] = this.attributes[key];\n }\n return result;\n }\n }, {\n key: \"status\",\n get: function get$$1() {\n return this.xhr.status;\n }\n }, {\n key: \"response\",\n get: function get$$1() {\n var _xhr = this.xhr,\n responseType = _xhr.responseType,\n response = _xhr.response;\n if (responseType == \"json\") {\n return response;\n } else {\n return JSON.parse(response);\n }\n }\n }]);\n return BlobRecord;\n }();\n var BlobUpload = function () {\n function BlobUpload(blob) {\n var _this = this;\n classCallCheck(this, BlobUpload);\n this.blob = blob;\n this.file = blob.file;\n var _blob$directUploadDat = blob.directUploadData,\n url = _blob$directUploadDat.url,\n headers = _blob$directUploadDat.headers;\n this.xhr = new XMLHttpRequest();\n this.xhr.open(\"PUT\", url, true);\n this.xhr.responseType = \"text\";\n for (var key in headers) {\n this.xhr.setRequestHeader(key, headers[key]);\n }\n this.xhr.addEventListener(\"load\", function (event) {\n return _this.requestDidLoad(event);\n });\n this.xhr.addEventListener(\"error\", function (event) {\n return _this.requestDidError(event);\n });\n }\n createClass(BlobUpload, [{\n key: \"create\",\n value: function create(callback) {\n this.callback = callback;\n this.xhr.send(this.file.slice());\n }\n }, {\n key: \"requestDidLoad\",\n value: function requestDidLoad(event) {\n var _xhr = this.xhr,\n status = _xhr.status,\n response = _xhr.response;\n if (status >= 200 && status < 300) {\n this.callback(null, response);\n } else {\n this.requestDidError(event);\n }\n }\n }, {\n key: \"requestDidError\",\n value: function requestDidError(event) {\n this.callback('Error storing \"' + this.file.name + '\". Status: ' + this.xhr.status);\n }\n }]);\n return BlobUpload;\n }();\n var id = 0;\n var DirectUpload = function () {\n function DirectUpload(file, url, delegate) {\n classCallCheck(this, DirectUpload);\n this.id = ++id;\n this.file = file;\n this.url = url;\n this.delegate = delegate;\n }\n createClass(DirectUpload, [{\n key: \"create\",\n value: function create(callback) {\n var _this = this;\n FileChecksum.create(this.file, function (error, checksum) {\n if (error) {\n callback(error);\n return;\n }\n var blob = new BlobRecord(_this.file, checksum, _this.url);\n notify(_this.delegate, \"directUploadWillCreateBlobWithXHR\", blob.xhr);\n blob.create(function (error) {\n if (error) {\n callback(error);\n } else {\n var upload = new BlobUpload(blob);\n notify(_this.delegate, \"directUploadWillStoreFileWithXHR\", upload.xhr);\n upload.create(function (error) {\n if (error) {\n callback(error);\n } else {\n callback(null, blob.toJSON());\n }\n });\n }\n });\n });\n }\n }]);\n return DirectUpload;\n }();\n function notify(object, methodName) {\n if (object && typeof object[methodName] == \"function\") {\n for (var _len = arguments.length, messages = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n messages[_key - 2] = arguments[_key];\n }\n return object[methodName].apply(object, messages);\n }\n }\n var DirectUploadController = function () {\n function DirectUploadController(input, file) {\n classCallCheck(this, DirectUploadController);\n this.input = input;\n this.file = file;\n this.directUpload = new DirectUpload(this.file, this.url, this);\n this.dispatch(\"initialize\");\n }\n createClass(DirectUploadController, [{\n key: \"start\",\n value: function start(callback) {\n var _this = this;\n var hiddenInput = document.createElement(\"input\");\n hiddenInput.type = \"hidden\";\n hiddenInput.name = this.input.name;\n this.input.insertAdjacentElement(\"beforebegin\", hiddenInput);\n this.dispatch(\"start\");\n this.directUpload.create(function (error, attributes) {\n if (error) {\n hiddenInput.parentNode.removeChild(hiddenInput);\n _this.dispatchError(error);\n } else {\n hiddenInput.value = attributes.signed_id;\n }\n _this.dispatch(\"end\");\n callback(error);\n });\n }\n }, {\n key: \"uploadRequestDidProgress\",\n value: function uploadRequestDidProgress(event) {\n var progress = event.loaded / event.total * 100;\n if (progress) {\n this.dispatch(\"progress\", {\n progress: progress\n });\n }\n }\n }, {\n key: \"dispatch\",\n value: function dispatch(name) {\n var detail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n detail.file = this.file;\n detail.id = this.directUpload.id;\n return dispatchEvent(this.input, \"direct-upload:\" + name, {\n detail: detail\n });\n }\n }, {\n key: \"dispatchError\",\n value: function dispatchError(error) {\n var event = this.dispatch(\"error\", {\n error: error\n });\n if (!event.defaultPrevented) {\n alert(error);\n }\n }\n }, {\n key: \"directUploadWillCreateBlobWithXHR\",\n value: function directUploadWillCreateBlobWithXHR(xhr) {\n this.dispatch(\"before-blob-request\", {\n xhr: xhr\n });\n }\n }, {\n key: \"directUploadWillStoreFileWithXHR\",\n value: function directUploadWillStoreFileWithXHR(xhr) {\n var _this2 = this;\n this.dispatch(\"before-storage-request\", {\n xhr: xhr\n });\n xhr.upload.addEventListener(\"progress\", function (event) {\n return _this2.uploadRequestDidProgress(event);\n });\n }\n }, {\n key: \"url\",\n get: function get$$1() {\n return this.input.getAttribute(\"data-direct-upload-url\");\n }\n }]);\n return DirectUploadController;\n }();\n var inputSelector = \"input[type=file][data-direct-upload-url]:not([disabled])\";\n var DirectUploadsController = function () {\n function DirectUploadsController(form) {\n classCallCheck(this, DirectUploadsController);\n this.form = form;\n this.inputs = findElements(form, inputSelector).filter(function (input) {\n return input.files.length;\n });\n }\n createClass(DirectUploadsController, [{\n key: \"start\",\n value: function start(callback) {\n var _this = this;\n var controllers = this.createDirectUploadControllers();\n var startNextController = function startNextController() {\n var controller = controllers.shift();\n if (controller) {\n controller.start(function (error) {\n if (error) {\n callback(error);\n _this.dispatch(\"end\");\n } else {\n startNextController();\n }\n });\n } else {\n callback();\n _this.dispatch(\"end\");\n }\n };\n this.dispatch(\"start\");\n startNextController();\n }\n }, {\n key: \"createDirectUploadControllers\",\n value: function createDirectUploadControllers() {\n var controllers = [];\n this.inputs.forEach(function (input) {\n toArray$1(input.files).forEach(function (file) {\n var controller = new DirectUploadController(input, file);\n controllers.push(controller);\n });\n });\n return controllers;\n }\n }, {\n key: \"dispatch\",\n value: function dispatch(name) {\n var detail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n return dispatchEvent(this.form, \"direct-uploads:\" + name, {\n detail: detail\n });\n }\n }]);\n return DirectUploadsController;\n }();\n var processingAttribute = \"data-direct-uploads-processing\";\n var submitButtonsByForm = new WeakMap();\n var started = false;\n function start() {\n if (!started) {\n started = true;\n document.addEventListener(\"click\", didClick, true);\n document.addEventListener(\"submit\", didSubmitForm);\n document.addEventListener(\"ajax:before\", didSubmitRemoteElement);\n }\n }\n function didClick(event) {\n var target = event.target;\n if ((target.tagName == \"INPUT\" || target.tagName == \"BUTTON\") && target.type == \"submit\" && target.form) {\n submitButtonsByForm.set(target.form, target);\n }\n }\n function didSubmitForm(event) {\n handleFormSubmissionEvent(event);\n }\n function didSubmitRemoteElement(event) {\n if (event.target.tagName == \"FORM\") {\n handleFormSubmissionEvent(event);\n }\n }\n function handleFormSubmissionEvent(event) {\n var form = event.target;\n if (form.hasAttribute(processingAttribute)) {\n event.preventDefault();\n return;\n }\n var controller = new DirectUploadsController(form);\n var inputs = controller.inputs;\n if (inputs.length) {\n event.preventDefault();\n form.setAttribute(processingAttribute, \"\");\n inputs.forEach(disable);\n controller.start(function (error) {\n form.removeAttribute(processingAttribute);\n if (error) {\n inputs.forEach(enable);\n } else {\n submitForm(form);\n }\n });\n }\n }\n function submitForm(form) {\n var button = submitButtonsByForm.get(form) || findElement(form, \"input[type=submit], button[type=submit]\");\n if (button) {\n var _button = button,\n disabled = _button.disabled;\n button.disabled = false;\n button.focus();\n button.click();\n button.disabled = disabled;\n } else {\n button = document.createElement(\"input\");\n button.type = \"submit\";\n button.style.display = \"none\";\n form.appendChild(button);\n button.click();\n form.removeChild(button);\n }\n submitButtonsByForm.delete(form);\n }\n function disable(input) {\n input.disabled = true;\n }\n function enable(input) {\n input.disabled = false;\n }\n function autostart() {\n if (window.ActiveStorage) {\n start();\n }\n }\n setTimeout(autostart, 1);\n exports.start = start;\n exports.DirectUpload = DirectUpload;\n Object.defineProperty(exports, \"__esModule\", {\n value: true\n });\n});","/*\nUnobtrusive JavaScript\nhttps://github.com/rails/rails/blob/main/actionview/app/assets/javascripts\nReleased under the MIT license\n */;\n(function () {\n var context = this;\n (function () {\n (function () {\n this.Rails = {\n linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',\n buttonClickSelector: {\n selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])',\n exclude: 'form button'\n },\n inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',\n formSubmitSelector: 'form:not([data-turbo=true])',\n formInputClickSelector: 'form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',\n formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',\n formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',\n fileInputSelector: 'input[name][type=file]:not([disabled])',\n linkDisableSelector: 'a[data-disable-with], a[data-disable]',\n buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]'\n };\n }).call(this);\n }).call(context);\n var Rails = context.Rails;\n (function () {\n (function () {\n var nonce;\n nonce = null;\n Rails.loadCSPNonce = function () {\n var ref;\n return nonce = (ref = document.querySelector(\"meta[name=csp-nonce]\")) != null ? ref.content : void 0;\n };\n Rails.cspNonce = function () {\n return nonce != null ? nonce : Rails.loadCSPNonce();\n };\n }).call(this);\n (function () {\n var expando, m;\n m = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector;\n Rails.matches = function (element, selector) {\n if (selector.exclude != null) {\n return m.call(element, selector.selector) && !m.call(element, selector.exclude);\n } else {\n return m.call(element, selector);\n }\n };\n expando = '_ujsData';\n Rails.getData = function (element, key) {\n var ref;\n return (ref = element[expando]) != null ? ref[key] : void 0;\n };\n Rails.setData = function (element, key, value) {\n if (element[expando] == null) {\n element[expando] = {};\n }\n return element[expando][key] = value;\n };\n Rails.$ = function (selector) {\n return Array.prototype.slice.call(document.querySelectorAll(selector));\n };\n }).call(this);\n (function () {\n var $, csrfParam, csrfToken;\n $ = Rails.$;\n csrfToken = Rails.csrfToken = function () {\n var meta;\n meta = document.querySelector('meta[name=csrf-token]');\n return meta && meta.content;\n };\n csrfParam = Rails.csrfParam = function () {\n var meta;\n meta = document.querySelector('meta[name=csrf-param]');\n return meta && meta.content;\n };\n Rails.CSRFProtection = function (xhr) {\n var token;\n token = csrfToken();\n if (token != null) {\n return xhr.setRequestHeader('X-CSRF-Token', token);\n }\n };\n Rails.refreshCSRFTokens = function () {\n var param, token;\n token = csrfToken();\n param = csrfParam();\n if (token != null && param != null) {\n return $('form input[name=\"' + param + '\"]').forEach(function (input) {\n return input.value = token;\n });\n }\n };\n }).call(this);\n (function () {\n var CustomEvent, fire, matches, preventDefault;\n matches = Rails.matches;\n CustomEvent = window.CustomEvent;\n if (typeof CustomEvent !== 'function') {\n CustomEvent = function (event, params) {\n var evt;\n evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n return evt;\n };\n CustomEvent.prototype = window.Event.prototype;\n preventDefault = CustomEvent.prototype.preventDefault;\n CustomEvent.prototype.preventDefault = function () {\n var result;\n result = preventDefault.call(this);\n if (this.cancelable && !this.defaultPrevented) {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function () {\n return true;\n }\n });\n }\n return result;\n };\n }\n fire = Rails.fire = function (obj, name, data) {\n var event;\n event = new CustomEvent(name, {\n bubbles: true,\n cancelable: true,\n detail: data\n });\n obj.dispatchEvent(event);\n return !event.defaultPrevented;\n };\n Rails.stopEverything = function (e) {\n fire(e.target, 'ujs:everythingStopped');\n e.preventDefault();\n e.stopPropagation();\n return e.stopImmediatePropagation();\n };\n Rails.delegate = function (element, selector, eventType, handler) {\n return element.addEventListener(eventType, function (e) {\n var target;\n target = e.target;\n while (!(!(target instanceof Element) || matches(target, selector))) {\n target = target.parentNode;\n }\n if (target instanceof Element && handler.call(target, e) === false) {\n e.preventDefault();\n return e.stopPropagation();\n }\n });\n };\n }).call(this);\n (function () {\n var AcceptHeaders, CSRFProtection, createXHR, cspNonce, fire, prepareOptions, processResponse;\n cspNonce = Rails.cspNonce, CSRFProtection = Rails.CSRFProtection, fire = Rails.fire;\n AcceptHeaders = {\n '*': '*/*',\n text: 'text/plain',\n html: 'text/html',\n xml: 'application/xml, text/xml',\n json: 'application/json, text/javascript',\n script: 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript'\n };\n Rails.ajax = function (options) {\n var xhr;\n options = prepareOptions(options);\n xhr = createXHR(options, function () {\n var ref, response;\n response = processResponse((ref = xhr.response) != null ? ref : xhr.responseText, xhr.getResponseHeader('Content-Type'));\n if (Math.floor(xhr.status / 100) === 2) {\n if (typeof options.success === \"function\") {\n options.success(response, xhr.statusText, xhr);\n }\n } else {\n if (typeof options.error === \"function\") {\n options.error(response, xhr.statusText, xhr);\n }\n }\n return typeof options.complete === \"function\" ? options.complete(xhr, xhr.statusText) : void 0;\n });\n if (options.beforeSend != null && !options.beforeSend(xhr, options)) {\n return false;\n }\n if (xhr.readyState === XMLHttpRequest.OPENED) {\n return xhr.send(options.data);\n }\n };\n prepareOptions = function (options) {\n options.url = options.url || location.href;\n options.type = options.type.toUpperCase();\n if (options.type === 'GET' && options.data) {\n if (options.url.indexOf('?') < 0) {\n options.url += '?' + options.data;\n } else {\n options.url += '&' + options.data;\n }\n }\n if (AcceptHeaders[options.dataType] == null) {\n options.dataType = '*';\n }\n options.accept = AcceptHeaders[options.dataType];\n if (options.dataType !== '*') {\n options.accept += ', */*; q=0.01';\n }\n return options;\n };\n createXHR = function (options, done) {\n var xhr;\n xhr = new XMLHttpRequest();\n xhr.open(options.type, options.url, true);\n xhr.setRequestHeader('Accept', options.accept);\n if (typeof options.data === 'string') {\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');\n }\n if (!options.crossDomain) {\n xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n CSRFProtection(xhr);\n }\n xhr.withCredentials = !!options.withCredentials;\n xhr.onreadystatechange = function () {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n return done(xhr);\n }\n };\n return xhr;\n };\n processResponse = function (response, type) {\n var parser, script;\n if (typeof response === 'string' && typeof type === 'string') {\n if (type.match(/\\bjson\\b/)) {\n try {\n response = JSON.parse(response);\n } catch (error) {}\n } else if (type.match(/\\b(?:java|ecma)script\\b/)) {\n script = document.createElement('script');\n script.setAttribute('nonce', cspNonce());\n script.text = response;\n document.head.appendChild(script).parentNode.removeChild(script);\n } else if (type.match(/\\b(xml|html|svg)\\b/)) {\n parser = new DOMParser();\n type = type.replace(/;.+/, '');\n try {\n response = parser.parseFromString(response, type);\n } catch (error) {}\n }\n }\n return response;\n };\n Rails.href = function (element) {\n return element.href;\n };\n Rails.isCrossDomain = function (url) {\n var e, originAnchor, urlAnchor;\n originAnchor = document.createElement('a');\n originAnchor.href = location.href;\n urlAnchor = document.createElement('a');\n try {\n urlAnchor.href = url;\n return !((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host || originAnchor.protocol + '//' + originAnchor.host === urlAnchor.protocol + '//' + urlAnchor.host);\n } catch (error) {\n e = error;\n return true;\n }\n };\n }).call(this);\n (function () {\n var matches, toArray;\n matches = Rails.matches;\n toArray = function (e) {\n return Array.prototype.slice.call(e);\n };\n Rails.serializeElement = function (element, additionalParam) {\n var inputs, params;\n inputs = [element];\n if (matches(element, 'form')) {\n inputs = toArray(element.elements);\n }\n params = [];\n inputs.forEach(function (input) {\n if (!input.name || input.disabled) {\n return;\n }\n if (matches(input, 'fieldset[disabled] *')) {\n return;\n }\n if (matches(input, 'select')) {\n return toArray(input.options).forEach(function (option) {\n if (option.selected) {\n return params.push({\n name: input.name,\n value: option.value\n });\n }\n });\n } else if (input.checked || ['radio', 'checkbox', 'submit'].indexOf(input.type) === -1) {\n return params.push({\n name: input.name,\n value: input.value\n });\n }\n });\n if (additionalParam) {\n params.push(additionalParam);\n }\n return params.map(function (param) {\n if (param.name != null) {\n return encodeURIComponent(param.name) + \"=\" + encodeURIComponent(param.value);\n } else {\n return param;\n }\n }).join('&');\n };\n Rails.formElements = function (form, selector) {\n if (matches(form, 'form')) {\n return toArray(form.elements).filter(function (el) {\n return matches(el, selector);\n });\n } else {\n return toArray(form.querySelectorAll(selector));\n }\n };\n }).call(this);\n (function () {\n var allowAction, fire, stopEverything;\n fire = Rails.fire, stopEverything = Rails.stopEverything;\n Rails.handleConfirm = function (e) {\n if (!allowAction(this)) {\n return stopEverything(e);\n }\n };\n Rails.confirm = function (message, element) {\n return confirm(message);\n };\n allowAction = function (element) {\n var answer, callback, message;\n message = element.getAttribute('data-confirm');\n if (!message) {\n return true;\n }\n answer = false;\n if (fire(element, 'confirm')) {\n try {\n answer = Rails.confirm(message, element);\n } catch (error) {}\n callback = fire(element, 'confirm:complete', [answer]);\n }\n return answer && callback;\n };\n }).call(this);\n (function () {\n var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, isXhrRedirect, matches, setData, stopEverything;\n matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;\n Rails.handleDisabledElement = function (e) {\n var element;\n element = this;\n if (element.disabled) {\n return stopEverything(e);\n }\n };\n Rails.enableElement = function (e) {\n var element;\n if (e instanceof Event) {\n if (isXhrRedirect(e)) {\n return;\n }\n element = e.target;\n } else {\n element = e;\n }\n if (matches(element, Rails.linkDisableSelector)) {\n return enableLinkElement(element);\n } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {\n return enableFormElement(element);\n } else if (matches(element, Rails.formSubmitSelector)) {\n return enableFormElements(element);\n }\n };\n Rails.disableElement = function (e) {\n var element;\n element = e instanceof Event ? e.target : e;\n if (matches(element, Rails.linkDisableSelector)) {\n return disableLinkElement(element);\n } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) {\n return disableFormElement(element);\n } else if (matches(element, Rails.formSubmitSelector)) {\n return disableFormElements(element);\n }\n };\n disableLinkElement = function (element) {\n var replacement;\n if (getData(element, 'ujs:disabled')) {\n return;\n }\n replacement = element.getAttribute('data-disable-with');\n if (replacement != null) {\n setData(element, 'ujs:enable-with', element.innerHTML);\n element.innerHTML = replacement;\n }\n element.addEventListener('click', stopEverything);\n return setData(element, 'ujs:disabled', true);\n };\n enableLinkElement = function (element) {\n var originalText;\n originalText = getData(element, 'ujs:enable-with');\n if (originalText != null) {\n element.innerHTML = originalText;\n setData(element, 'ujs:enable-with', null);\n }\n element.removeEventListener('click', stopEverything);\n return setData(element, 'ujs:disabled', null);\n };\n disableFormElements = function (form) {\n return formElements(form, Rails.formDisableSelector).forEach(disableFormElement);\n };\n disableFormElement = function (element) {\n var replacement;\n if (getData(element, 'ujs:disabled')) {\n return;\n }\n replacement = element.getAttribute('data-disable-with');\n if (replacement != null) {\n if (matches(element, 'button')) {\n setData(element, 'ujs:enable-with', element.innerHTML);\n element.innerHTML = replacement;\n } else {\n setData(element, 'ujs:enable-with', element.value);\n element.value = replacement;\n }\n }\n element.disabled = true;\n return setData(element, 'ujs:disabled', true);\n };\n enableFormElements = function (form) {\n return formElements(form, Rails.formEnableSelector).forEach(enableFormElement);\n };\n enableFormElement = function (element) {\n var originalText;\n originalText = getData(element, 'ujs:enable-with');\n if (originalText != null) {\n if (matches(element, 'button')) {\n element.innerHTML = originalText;\n } else {\n element.value = originalText;\n }\n setData(element, 'ujs:enable-with', null);\n }\n element.disabled = false;\n return setData(element, 'ujs:disabled', null);\n };\n isXhrRedirect = function (event) {\n var ref, xhr;\n xhr = (ref = event.detail) != null ? ref[0] : void 0;\n return (xhr != null ? xhr.getResponseHeader(\"X-Xhr-Redirect\") : void 0) != null;\n };\n }).call(this);\n (function () {\n var stopEverything;\n stopEverything = Rails.stopEverything;\n Rails.handleMethod = function (e) {\n var csrfParam, csrfToken, form, formContent, href, link, method;\n link = this;\n method = link.getAttribute('data-method');\n if (!method) {\n return;\n }\n href = Rails.href(link);\n csrfToken = Rails.csrfToken();\n csrfParam = Rails.csrfParam();\n form = document.createElement('form');\n formContent = \"\";\n if (csrfParam != null && csrfToken != null && !Rails.isCrossDomain(href)) {\n formContent += \"\";\n }\n formContent += '';\n form.method = 'post';\n form.action = href;\n form.target = link.target;\n form.innerHTML = formContent;\n form.style.display = 'none';\n document.body.appendChild(form);\n form.querySelector('[type=\"submit\"]').click();\n return stopEverything(e);\n };\n }).call(this);\n (function () {\n var ajax,\n fire,\n getData,\n isCrossDomain,\n isRemote,\n matches,\n serializeElement,\n setData,\n stopEverything,\n slice = [].slice;\n matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement;\n isRemote = function (element) {\n var value;\n value = element.getAttribute('data-remote');\n return value != null && value !== 'false';\n };\n Rails.handleRemote = function (e) {\n var button, data, dataType, element, method, url, withCredentials;\n element = this;\n if (!isRemote(element)) {\n return true;\n }\n if (!fire(element, 'ajax:before')) {\n fire(element, 'ajax:stopped');\n return false;\n }\n withCredentials = element.getAttribute('data-with-credentials');\n dataType = element.getAttribute('data-type') || 'script';\n if (matches(element, Rails.formSubmitSelector)) {\n button = getData(element, 'ujs:submit-button');\n method = getData(element, 'ujs:submit-button-formmethod') || element.method;\n url = getData(element, 'ujs:submit-button-formaction') || element.getAttribute('action') || location.href;\n if (method.toUpperCase() === 'GET') {\n url = url.replace(/\\?.*$/, '');\n }\n if (element.enctype === 'multipart/form-data') {\n data = new FormData(element);\n if (button != null) {\n data.append(button.name, button.value);\n }\n } else {\n data = serializeElement(element, button);\n }\n setData(element, 'ujs:submit-button', null);\n setData(element, 'ujs:submit-button-formmethod', null);\n setData(element, 'ujs:submit-button-formaction', null);\n } else if (matches(element, Rails.buttonClickSelector) || matches(element, Rails.inputChangeSelector)) {\n method = element.getAttribute('data-method');\n url = element.getAttribute('data-url');\n data = serializeElement(element, element.getAttribute('data-params'));\n } else {\n method = element.getAttribute('data-method');\n url = Rails.href(element);\n data = element.getAttribute('data-params');\n }\n ajax({\n type: method || 'GET',\n url: url,\n data: data,\n dataType: dataType,\n beforeSend: function (xhr, options) {\n if (fire(element, 'ajax:beforeSend', [xhr, options])) {\n return fire(element, 'ajax:send', [xhr]);\n } else {\n fire(element, 'ajax:stopped');\n return false;\n }\n },\n success: function () {\n var args;\n args = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n return fire(element, 'ajax:success', args);\n },\n error: function () {\n var args;\n args = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n return fire(element, 'ajax:error', args);\n },\n complete: function () {\n var args;\n args = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n return fire(element, 'ajax:complete', args);\n },\n crossDomain: isCrossDomain(url),\n withCredentials: withCredentials != null && withCredentials !== 'false'\n });\n return stopEverything(e);\n };\n Rails.formSubmitButtonClick = function (e) {\n var button, form;\n button = this;\n form = button.form;\n if (!form) {\n return;\n }\n if (button.name) {\n setData(form, 'ujs:submit-button', {\n name: button.name,\n value: button.value\n });\n }\n setData(form, 'ujs:formnovalidate-button', button.formNoValidate);\n setData(form, 'ujs:submit-button-formaction', button.getAttribute('formaction'));\n return setData(form, 'ujs:submit-button-formmethod', button.getAttribute('formmethod'));\n };\n Rails.preventInsignificantClick = function (e) {\n var data, insignificantMetaClick, link, metaClick, method, nonPrimaryMouseClick;\n link = this;\n method = (link.getAttribute('data-method') || 'GET').toUpperCase();\n data = link.getAttribute('data-params');\n metaClick = e.metaKey || e.ctrlKey;\n insignificantMetaClick = metaClick && method === 'GET' && !data;\n nonPrimaryMouseClick = e.button != null && e.button !== 0;\n if (nonPrimaryMouseClick || insignificantMetaClick) {\n return e.stopImmediatePropagation();\n }\n };\n }).call(this);\n (function () {\n var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMethod, handleRemote, loadCSPNonce, preventInsignificantClick, refreshCSRFTokens;\n fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection, loadCSPNonce = Rails.loadCSPNonce, enableElement = Rails.enableElement, disableElement = Rails.disableElement, handleDisabledElement = Rails.handleDisabledElement, handleConfirm = Rails.handleConfirm, preventInsignificantClick = Rails.preventInsignificantClick, handleRemote = Rails.handleRemote, formSubmitButtonClick = Rails.formSubmitButtonClick, handleMethod = Rails.handleMethod;\n if (typeof jQuery !== \"undefined\" && jQuery !== null && jQuery.ajax != null) {\n if (jQuery.rails) {\n throw new Error('If you load both jquery_ujs and rails-ujs, use rails-ujs only.');\n }\n jQuery.rails = Rails;\n jQuery.ajaxPrefilter(function (options, originalOptions, xhr) {\n if (!options.crossDomain) {\n return CSRFProtection(xhr);\n }\n });\n }\n Rails.start = function () {\n if (window._rails_loaded) {\n throw new Error('rails-ujs has already been loaded!');\n }\n window.addEventListener('pageshow', function () {\n $(Rails.formEnableSelector).forEach(function (el) {\n if (getData(el, 'ujs:disabled')) {\n return enableElement(el);\n }\n });\n return $(Rails.linkDisableSelector).forEach(function (el) {\n if (getData(el, 'ujs:disabled')) {\n return enableElement(el);\n }\n });\n });\n delegate(document, Rails.linkDisableSelector, 'ajax:complete', enableElement);\n delegate(document, Rails.linkDisableSelector, 'ajax:stopped', enableElement);\n delegate(document, Rails.buttonDisableSelector, 'ajax:complete', enableElement);\n delegate(document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement);\n delegate(document, Rails.linkClickSelector, 'click', preventInsignificantClick);\n delegate(document, Rails.linkClickSelector, 'click', handleDisabledElement);\n delegate(document, Rails.linkClickSelector, 'click', handleConfirm);\n delegate(document, Rails.linkClickSelector, 'click', disableElement);\n delegate(document, Rails.linkClickSelector, 'click', handleRemote);\n delegate(document, Rails.linkClickSelector, 'click', handleMethod);\n delegate(document, Rails.buttonClickSelector, 'click', preventInsignificantClick);\n delegate(document, Rails.buttonClickSelector, 'click', handleDisabledElement);\n delegate(document, Rails.buttonClickSelector, 'click', handleConfirm);\n delegate(document, Rails.buttonClickSelector, 'click', disableElement);\n delegate(document, Rails.buttonClickSelector, 'click', handleRemote);\n delegate(document, Rails.inputChangeSelector, 'change', handleDisabledElement);\n delegate(document, Rails.inputChangeSelector, 'change', handleConfirm);\n delegate(document, Rails.inputChangeSelector, 'change', handleRemote);\n delegate(document, Rails.formSubmitSelector, 'submit', handleDisabledElement);\n delegate(document, Rails.formSubmitSelector, 'submit', handleConfirm);\n delegate(document, Rails.formSubmitSelector, 'submit', handleRemote);\n delegate(document, Rails.formSubmitSelector, 'submit', function (e) {\n return setTimeout(function () {\n return disableElement(e);\n }, 13);\n });\n delegate(document, Rails.formSubmitSelector, 'ajax:send', disableElement);\n delegate(document, Rails.formSubmitSelector, 'ajax:complete', enableElement);\n delegate(document, Rails.formInputClickSelector, 'click', preventInsignificantClick);\n delegate(document, Rails.formInputClickSelector, 'click', handleDisabledElement);\n delegate(document, Rails.formInputClickSelector, 'click', handleConfirm);\n delegate(document, Rails.formInputClickSelector, 'click', formSubmitButtonClick);\n document.addEventListener('DOMContentLoaded', refreshCSRFTokens);\n document.addEventListener('DOMContentLoaded', loadCSPNonce);\n return window._rails_loaded = true;\n };\n if (window.Rails === Rails && fire(document, 'rails:attachBindings')) {\n Rails.start();\n }\n }).call(this);\n }).call(this);\n if (typeof module === \"object\" && module.exports) {\n module.exports = Rails;\n } else if (typeof define === \"function\" && define.amd) {\n define(Rails);\n }\n}).call(this);","/*!\n * Bootstrap v4.3.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery'), require('popper.js')) : typeof define === 'function' && define.amd ? define(['exports', 'jquery', 'popper.js'], factory) : (global = global || self, factory(global.bootstrap = {}, global.jQuery, global.Popper));\n})(this, function (exports, $, Popper) {\n 'use strict';\n\n $ = $ && $.hasOwnProperty('default') ? $['default'] : $;\n Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper;\n function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n }\n function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n }\n function _objectSpread(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i] != null ? arguments[i] : {};\n var ownKeys = Object.keys(source);\n if (typeof Object.getOwnPropertySymbols === 'function') {\n ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {\n return Object.getOwnPropertyDescriptor(source, sym).enumerable;\n }));\n }\n ownKeys.forEach(function (key) {\n _defineProperty(target, key, source[key]);\n });\n }\n return target;\n }\n function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n }\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.3.1): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n /**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\n var TRANSITION_END = 'transitionend';\n var MAX_UID = 1000000;\n var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)\n\n function toType(obj) {\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase();\n }\n function getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle: function handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params\n }\n return undefined; // eslint-disable-line no-undefined\n }\n };\n }\n function transitionEndEmulator(duration) {\n var _this = this;\n var called = false;\n $(this).one(Util.TRANSITION_END, function () {\n called = true;\n });\n setTimeout(function () {\n if (!called) {\n Util.triggerTransitionEnd(_this);\n }\n }, duration);\n return this;\n }\n function setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator;\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();\n }\n /**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\n var Util = {\n TRANSITION_END: 'bsTransitionEnd',\n getUID: function getUID(prefix) {\n do {\n // eslint-disable-next-line no-bitwise\n prefix += ~~(Math.random() * MAX_UID); // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix));\n return prefix;\n },\n getSelectorFromElement: function getSelectorFromElement(element) {\n var selector = element.getAttribute('data-target');\n if (!selector || selector === '#') {\n var hrefAttr = element.getAttribute('href');\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '';\n }\n try {\n return document.querySelector(selector) ? selector : null;\n } catch (err) {\n return null;\n }\n },\n getTransitionDurationFromElement: function getTransitionDurationFromElement(element) {\n if (!element) {\n return 0;\n } // Get transition-duration of the element\n\n var transitionDuration = $(element).css('transition-duration');\n var transitionDelay = $(element).css('transition-delay');\n var floatTransitionDuration = parseFloat(transitionDuration);\n var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found\n\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0;\n } // If multiple durations are defined, take the first\n\n transitionDuration = transitionDuration.split(',')[0];\n transitionDelay = transitionDelay.split(',')[0];\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n },\n reflow: function reflow(element) {\n return element.offsetHeight;\n },\n triggerTransitionEnd: function triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END);\n },\n // TODO: Remove in v5\n supportsTransitionEnd: function supportsTransitionEnd() {\n return Boolean(TRANSITION_END);\n },\n isElement: function isElement(obj) {\n return (obj[0] || obj).nodeType;\n },\n typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {\n for (var property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n var expectedTypes = configTypes[property];\n var value = config[property];\n var valueType = value && Util.isElement(value) ? 'element' : toType(value);\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(componentName.toUpperCase() + \": \" + (\"Option \\\"\" + property + \"\\\" provided type \\\"\" + valueType + \"\\\" \") + (\"but expected type \\\"\" + expectedTypes + \"\\\".\"));\n }\n }\n }\n },\n findShadowRoot: function findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null;\n } // Can find the shadow root otherwise it'll return the document\n\n if (typeof element.getRootNode === 'function') {\n var root = element.getRootNode();\n return root instanceof ShadowRoot ? root : null;\n }\n if (element instanceof ShadowRoot) {\n return element;\n } // when we don't find a shadow root\n\n if (!element.parentNode) {\n return null;\n }\n return Util.findShadowRoot(element.parentNode);\n }\n };\n setTransitionEndSupport();\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME = 'alert';\n var VERSION = '4.3.1';\n var DATA_KEY = 'bs.alert';\n var EVENT_KEY = \".\" + DATA_KEY;\n var DATA_API_KEY = '.data-api';\n var JQUERY_NO_CONFLICT = $.fn[NAME];\n var Selector = {\n DISMISS: '[data-dismiss=\"alert\"]'\n };\n var Event = {\n CLOSE: \"close\" + EVENT_KEY,\n CLOSED: \"closed\" + EVENT_KEY,\n CLICK_DATA_API: \"click\" + EVENT_KEY + DATA_API_KEY\n };\n var ClassName = {\n ALERT: 'alert',\n FADE: 'fade',\n SHOW: 'show'\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var Alert = /*#__PURE__*/\n function () {\n function Alert(element) {\n this._element = element;\n } // Getters\n\n var _proto = Alert.prototype;\n\n // Public\n _proto.close = function close(element) {\n var rootElement = this._element;\n if (element) {\n rootElement = this._getRootElement(element);\n }\n var customEvent = this._triggerCloseEvent(rootElement);\n if (customEvent.isDefaultPrevented()) {\n return;\n }\n this._removeElement(rootElement);\n };\n _proto.dispose = function dispose() {\n $.removeData(this._element, DATA_KEY);\n this._element = null;\n } // Private\n ;\n _proto._getRootElement = function _getRootElement(element) {\n var selector = Util.getSelectorFromElement(element);\n var parent = false;\n if (selector) {\n parent = document.querySelector(selector);\n }\n if (!parent) {\n parent = $(element).closest(\".\" + ClassName.ALERT)[0];\n }\n return parent;\n };\n _proto._triggerCloseEvent = function _triggerCloseEvent(element) {\n var closeEvent = $.Event(Event.CLOSE);\n $(element).trigger(closeEvent);\n return closeEvent;\n };\n _proto._removeElement = function _removeElement(element) {\n var _this = this;\n $(element).removeClass(ClassName.SHOW);\n if (!$(element).hasClass(ClassName.FADE)) {\n this._destroyElement(element);\n return;\n }\n var transitionDuration = Util.getTransitionDurationFromElement(element);\n $(element).one(Util.TRANSITION_END, function (event) {\n return _this._destroyElement(element, event);\n }).emulateTransitionEnd(transitionDuration);\n };\n _proto._destroyElement = function _destroyElement(element) {\n $(element).detach().trigger(Event.CLOSED).remove();\n } // Static\n ;\n Alert._jQueryInterface = function _jQueryInterface(config) {\n return this.each(function () {\n var $element = $(this);\n var data = $element.data(DATA_KEY);\n if (!data) {\n data = new Alert(this);\n $element.data(DATA_KEY, data);\n }\n if (config === 'close') {\n data[config](this);\n }\n });\n };\n Alert._handleDismiss = function _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault();\n }\n alertInstance.close(this);\n };\n };\n _createClass(Alert, null, [{\n key: \"VERSION\",\n get: function get() {\n return VERSION;\n }\n }]);\n return Alert;\n }();\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert()));\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Alert._jQueryInterface;\n $.fn[NAME].Constructor = Alert;\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT;\n return Alert._jQueryInterface;\n };\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME$1 = 'button';\n var VERSION$1 = '4.3.1';\n var DATA_KEY$1 = 'bs.button';\n var EVENT_KEY$1 = \".\" + DATA_KEY$1;\n var DATA_API_KEY$1 = '.data-api';\n var JQUERY_NO_CONFLICT$1 = $.fn[NAME$1];\n var ClassName$1 = {\n ACTIVE: 'active',\n BUTTON: 'btn',\n FOCUS: 'focus'\n };\n var Selector$1 = {\n DATA_TOGGLE_CARROT: '[data-toggle^=\"button\"]',\n DATA_TOGGLE: '[data-toggle=\"buttons\"]',\n INPUT: 'input:not([type=\"hidden\"])',\n ACTIVE: '.active',\n BUTTON: '.btn'\n };\n var Event$1 = {\n CLICK_DATA_API: \"click\" + EVENT_KEY$1 + DATA_API_KEY$1,\n FOCUS_BLUR_DATA_API: \"focus\" + EVENT_KEY$1 + DATA_API_KEY$1 + \" \" + (\"blur\" + EVENT_KEY$1 + DATA_API_KEY$1)\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var Button = /*#__PURE__*/\n function () {\n function Button(element) {\n this._element = element;\n } // Getters\n\n var _proto = Button.prototype;\n\n // Public\n _proto.toggle = function toggle() {\n var triggerChangeEvent = true;\n var addAriaPressed = true;\n var rootElement = $(this._element).closest(Selector$1.DATA_TOGGLE)[0];\n if (rootElement) {\n var input = this._element.querySelector(Selector$1.INPUT);\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(ClassName$1.ACTIVE)) {\n triggerChangeEvent = false;\n } else {\n var activeElement = rootElement.querySelector(Selector$1.ACTIVE);\n if (activeElement) {\n $(activeElement).removeClass(ClassName$1.ACTIVE);\n }\n }\n }\n if (triggerChangeEvent) {\n if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || input.classList.contains('disabled') || rootElement.classList.contains('disabled')) {\n return;\n }\n input.checked = !this._element.classList.contains(ClassName$1.ACTIVE);\n $(input).trigger('change');\n }\n input.focus();\n addAriaPressed = false;\n }\n }\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(ClassName$1.ACTIVE));\n }\n if (triggerChangeEvent) {\n $(this._element).toggleClass(ClassName$1.ACTIVE);\n }\n };\n _proto.dispose = function dispose() {\n $.removeData(this._element, DATA_KEY$1);\n this._element = null;\n } // Static\n ;\n Button._jQueryInterface = function _jQueryInterface(config) {\n return this.each(function () {\n var data = $(this).data(DATA_KEY$1);\n if (!data) {\n data = new Button(this);\n $(this).data(DATA_KEY$1, data);\n }\n if (config === 'toggle') {\n data[config]();\n }\n });\n };\n _createClass(Button, null, [{\n key: \"VERSION\",\n get: function get() {\n return VERSION$1;\n }\n }]);\n return Button;\n }();\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event$1.CLICK_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) {\n event.preventDefault();\n var button = event.target;\n if (!$(button).hasClass(ClassName$1.BUTTON)) {\n button = $(button).closest(Selector$1.BUTTON);\n }\n Button._jQueryInterface.call($(button), 'toggle');\n }).on(Event$1.FOCUS_BLUR_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) {\n var button = $(event.target).closest(Selector$1.BUTTON)[0];\n $(button).toggleClass(ClassName$1.FOCUS, /^focus(in)?$/.test(event.type));\n });\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME$1] = Button._jQueryInterface;\n $.fn[NAME$1].Constructor = Button;\n $.fn[NAME$1].noConflict = function () {\n $.fn[NAME$1] = JQUERY_NO_CONFLICT$1;\n return Button._jQueryInterface;\n };\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME$2 = 'carousel';\n var VERSION$2 = '4.3.1';\n var DATA_KEY$2 = 'bs.carousel';\n var EVENT_KEY$2 = \".\" + DATA_KEY$2;\n var DATA_API_KEY$2 = '.data-api';\n var JQUERY_NO_CONFLICT$2 = $.fn[NAME$2];\n var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key\n\n var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key\n\n var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\n var SWIPE_THRESHOLD = 40;\n var Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n };\n var DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n };\n var Direction = {\n NEXT: 'next',\n PREV: 'prev',\n LEFT: 'left',\n RIGHT: 'right'\n };\n var Event$2 = {\n SLIDE: \"slide\" + EVENT_KEY$2,\n SLID: \"slid\" + EVENT_KEY$2,\n KEYDOWN: \"keydown\" + EVENT_KEY$2,\n MOUSEENTER: \"mouseenter\" + EVENT_KEY$2,\n MOUSELEAVE: \"mouseleave\" + EVENT_KEY$2,\n TOUCHSTART: \"touchstart\" + EVENT_KEY$2,\n TOUCHMOVE: \"touchmove\" + EVENT_KEY$2,\n TOUCHEND: \"touchend\" + EVENT_KEY$2,\n POINTERDOWN: \"pointerdown\" + EVENT_KEY$2,\n POINTERUP: \"pointerup\" + EVENT_KEY$2,\n DRAG_START: \"dragstart\" + EVENT_KEY$2,\n LOAD_DATA_API: \"load\" + EVENT_KEY$2 + DATA_API_KEY$2,\n CLICK_DATA_API: \"click\" + EVENT_KEY$2 + DATA_API_KEY$2\n };\n var ClassName$2 = {\n CAROUSEL: 'carousel',\n ACTIVE: 'active',\n SLIDE: 'slide',\n RIGHT: 'carousel-item-right',\n LEFT: 'carousel-item-left',\n NEXT: 'carousel-item-next',\n PREV: 'carousel-item-prev',\n ITEM: 'carousel-item',\n POINTER_EVENT: 'pointer-event'\n };\n var Selector$2 = {\n ACTIVE: '.active',\n ACTIVE_ITEM: '.active.carousel-item',\n ITEM: '.carousel-item',\n ITEM_IMG: '.carousel-item img',\n NEXT_PREV: '.carousel-item-next, .carousel-item-prev',\n INDICATORS: '.carousel-indicators',\n DATA_SLIDE: '[data-slide], [data-slide-to]',\n DATA_RIDE: '[data-ride=\"carousel\"]'\n };\n var PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var Carousel = /*#__PURE__*/\n function () {\n function Carousel(element, config) {\n this._items = null;\n this._interval = null;\n this._activeElement = null;\n this._isPaused = false;\n this._isSliding = false;\n this.touchTimeout = null;\n this.touchStartX = 0;\n this.touchDeltaX = 0;\n this._config = this._getConfig(config);\n this._element = element;\n this._indicatorsElement = this._element.querySelector(Selector$2.INDICATORS);\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent);\n this._addEventListeners();\n } // Getters\n\n var _proto = Carousel.prototype;\n\n // Public\n _proto.next = function next() {\n if (!this._isSliding) {\n this._slide(Direction.NEXT);\n }\n };\n _proto.nextWhenVisible = function nextWhenVisible() {\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && $(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden') {\n this.next();\n }\n };\n _proto.prev = function prev() {\n if (!this._isSliding) {\n this._slide(Direction.PREV);\n }\n };\n _proto.pause = function pause(event) {\n if (!event) {\n this._isPaused = true;\n }\n if (this._element.querySelector(Selector$2.NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element);\n this.cycle(true);\n }\n clearInterval(this._interval);\n this._interval = null;\n };\n _proto.cycle = function cycle(event) {\n if (!event) {\n this._isPaused = false;\n }\n if (this._interval) {\n clearInterval(this._interval);\n this._interval = null;\n }\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);\n }\n };\n _proto.to = function to(index) {\n var _this = this;\n this._activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM);\n var activeIndex = this._getItemIndex(this._activeElement);\n if (index > this._items.length - 1 || index < 0) {\n return;\n }\n if (this._isSliding) {\n $(this._element).one(Event$2.SLID, function () {\n return _this.to(index);\n });\n return;\n }\n if (activeIndex === index) {\n this.pause();\n this.cycle();\n return;\n }\n var direction = index > activeIndex ? Direction.NEXT : Direction.PREV;\n this._slide(direction, this._items[index]);\n };\n _proto.dispose = function dispose() {\n $(this._element).off(EVENT_KEY$2);\n $.removeData(this._element, DATA_KEY$2);\n this._items = null;\n this._config = null;\n this._element = null;\n this._interval = null;\n this._isPaused = null;\n this._isSliding = null;\n this._activeElement = null;\n this._indicatorsElement = null;\n } // Private\n ;\n _proto._getConfig = function _getConfig(config) {\n config = _objectSpread({}, Default, config);\n Util.typeCheckConfig(NAME$2, config, DefaultType);\n return config;\n };\n _proto._handleSwipe = function _handleSwipe() {\n var absDeltax = Math.abs(this.touchDeltaX);\n if (absDeltax <= SWIPE_THRESHOLD) {\n return;\n }\n var direction = absDeltax / this.touchDeltaX; // swipe left\n\n if (direction > 0) {\n this.prev();\n } // swipe right\n\n if (direction < 0) {\n this.next();\n }\n };\n _proto._addEventListeners = function _addEventListeners() {\n var _this2 = this;\n if (this._config.keyboard) {\n $(this._element).on(Event$2.KEYDOWN, function (event) {\n return _this2._keydown(event);\n });\n }\n if (this._config.pause === 'hover') {\n $(this._element).on(Event$2.MOUSEENTER, function (event) {\n return _this2.pause(event);\n }).on(Event$2.MOUSELEAVE, function (event) {\n return _this2.cycle(event);\n });\n }\n if (this._config.touch) {\n this._addTouchEventListeners();\n }\n };\n _proto._addTouchEventListeners = function _addTouchEventListeners() {\n var _this3 = this;\n if (!this._touchSupported) {\n return;\n }\n var start = function start(event) {\n if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n _this3.touchStartX = event.originalEvent.clientX;\n } else if (!_this3._pointerEvent) {\n _this3.touchStartX = event.originalEvent.touches[0].clientX;\n }\n };\n var move = function move(event) {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n _this3.touchDeltaX = 0;\n } else {\n _this3.touchDeltaX = event.originalEvent.touches[0].clientX - _this3.touchStartX;\n }\n };\n var end = function end(event) {\n if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX;\n }\n _this3._handleSwipe();\n if (_this3._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n _this3.pause();\n if (_this3.touchTimeout) {\n clearTimeout(_this3.touchTimeout);\n }\n _this3.touchTimeout = setTimeout(function (event) {\n return _this3.cycle(event);\n }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval);\n }\n };\n $(this._element.querySelectorAll(Selector$2.ITEM_IMG)).on(Event$2.DRAG_START, function (e) {\n return e.preventDefault();\n });\n if (this._pointerEvent) {\n $(this._element).on(Event$2.POINTERDOWN, function (event) {\n return start(event);\n });\n $(this._element).on(Event$2.POINTERUP, function (event) {\n return end(event);\n });\n this._element.classList.add(ClassName$2.POINTER_EVENT);\n } else {\n $(this._element).on(Event$2.TOUCHSTART, function (event) {\n return start(event);\n });\n $(this._element).on(Event$2.TOUCHMOVE, function (event) {\n return move(event);\n });\n $(this._element).on(Event$2.TOUCHEND, function (event) {\n return end(event);\n });\n }\n };\n _proto._keydown = function _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return;\n }\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault();\n this.prev();\n break;\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault();\n this.next();\n break;\n default:\n }\n };\n _proto._getItemIndex = function _getItemIndex(element) {\n this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(Selector$2.ITEM)) : [];\n return this._items.indexOf(element);\n };\n _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {\n var isNextDirection = direction === Direction.NEXT;\n var isPrevDirection = direction === Direction.PREV;\n var activeIndex = this._getItemIndex(activeElement);\n var lastItemIndex = this._items.length - 1;\n var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement;\n }\n var delta = direction === Direction.PREV ? -1 : 1;\n var itemIndex = (activeIndex + delta) % this._items.length;\n return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];\n };\n _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {\n var targetIndex = this._getItemIndex(relatedTarget);\n var fromIndex = this._getItemIndex(this._element.querySelector(Selector$2.ACTIVE_ITEM));\n var slideEvent = $.Event(Event$2.SLIDE, {\n relatedTarget: relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n });\n $(this._element).trigger(slideEvent);\n return slideEvent;\n };\n _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector$2.ACTIVE));\n $(indicators).removeClass(ClassName$2.ACTIVE);\n var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];\n if (nextIndicator) {\n $(nextIndicator).addClass(ClassName$2.ACTIVE);\n }\n }\n };\n _proto._slide = function _slide(direction, element) {\n var _this4 = this;\n var activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM);\n var activeElementIndex = this._getItemIndex(activeElement);\n var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);\n var nextElementIndex = this._getItemIndex(nextElement);\n var isCycling = Boolean(this._interval);\n var directionalClassName;\n var orderClassName;\n var eventDirectionName;\n if (direction === Direction.NEXT) {\n directionalClassName = ClassName$2.LEFT;\n orderClassName = ClassName$2.NEXT;\n eventDirectionName = Direction.LEFT;\n } else {\n directionalClassName = ClassName$2.RIGHT;\n orderClassName = ClassName$2.PREV;\n eventDirectionName = Direction.RIGHT;\n }\n if (nextElement && $(nextElement).hasClass(ClassName$2.ACTIVE)) {\n this._isSliding = false;\n return;\n }\n var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);\n if (slideEvent.isDefaultPrevented()) {\n return;\n }\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return;\n }\n this._isSliding = true;\n if (isCycling) {\n this.pause();\n }\n this._setActiveIndicatorElement(nextElement);\n var slidEvent = $.Event(Event$2.SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n });\n if ($(this._element).hasClass(ClassName$2.SLIDE)) {\n $(nextElement).addClass(orderClassName);\n Util.reflow(nextElement);\n $(activeElement).addClass(directionalClassName);\n $(nextElement).addClass(directionalClassName);\n var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10);\n if (nextElementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval;\n this._config.interval = nextElementInterval;\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval;\n }\n var transitionDuration = Util.getTransitionDurationFromElement(activeElement);\n $(activeElement).one(Util.TRANSITION_END, function () {\n $(nextElement).removeClass(directionalClassName + \" \" + orderClassName).addClass(ClassName$2.ACTIVE);\n $(activeElement).removeClass(ClassName$2.ACTIVE + \" \" + orderClassName + \" \" + directionalClassName);\n _this4._isSliding = false;\n setTimeout(function () {\n return $(_this4._element).trigger(slidEvent);\n }, 0);\n }).emulateTransitionEnd(transitionDuration);\n } else {\n $(activeElement).removeClass(ClassName$2.ACTIVE);\n $(nextElement).addClass(ClassName$2.ACTIVE);\n this._isSliding = false;\n $(this._element).trigger(slidEvent);\n }\n if (isCycling) {\n this.cycle();\n }\n } // Static\n ;\n Carousel._jQueryInterface = function _jQueryInterface(config) {\n return this.each(function () {\n var data = $(this).data(DATA_KEY$2);\n var _config = _objectSpread({}, Default, $(this).data());\n if (typeof config === 'object') {\n _config = _objectSpread({}, _config, config);\n }\n var action = typeof config === 'string' ? config : _config.slide;\n if (!data) {\n data = new Carousel(this, _config);\n $(this).data(DATA_KEY$2, data);\n }\n if (typeof config === 'number') {\n data.to(config);\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(\"No method named \\\"\" + action + \"\\\"\");\n }\n data[action]();\n } else if (_config.interval && _config.ride) {\n data.pause();\n data.cycle();\n }\n });\n };\n Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {\n var selector = Util.getSelectorFromElement(this);\n if (!selector) {\n return;\n }\n var target = $(selector)[0];\n if (!target || !$(target).hasClass(ClassName$2.CAROUSEL)) {\n return;\n }\n var config = _objectSpread({}, $(target).data(), $(this).data());\n var slideIndex = this.getAttribute('data-slide-to');\n if (slideIndex) {\n config.interval = false;\n }\n Carousel._jQueryInterface.call($(target), config);\n if (slideIndex) {\n $(target).data(DATA_KEY$2).to(slideIndex);\n }\n event.preventDefault();\n };\n _createClass(Carousel, null, [{\n key: \"VERSION\",\n get: function get() {\n return VERSION$2;\n }\n }, {\n key: \"Default\",\n get: function get() {\n return Default;\n }\n }]);\n return Carousel;\n }();\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event$2.CLICK_DATA_API, Selector$2.DATA_SLIDE, Carousel._dataApiClickHandler);\n $(window).on(Event$2.LOAD_DATA_API, function () {\n var carousels = [].slice.call(document.querySelectorAll(Selector$2.DATA_RIDE));\n for (var i = 0, len = carousels.length; i < len; i++) {\n var $carousel = $(carousels[i]);\n Carousel._jQueryInterface.call($carousel, $carousel.data());\n }\n });\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME$2] = Carousel._jQueryInterface;\n $.fn[NAME$2].Constructor = Carousel;\n $.fn[NAME$2].noConflict = function () {\n $.fn[NAME$2] = JQUERY_NO_CONFLICT$2;\n return Carousel._jQueryInterface;\n };\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME$3 = 'collapse';\n var VERSION$3 = '4.3.1';\n var DATA_KEY$3 = 'bs.collapse';\n var EVENT_KEY$3 = \".\" + DATA_KEY$3;\n var DATA_API_KEY$3 = '.data-api';\n var JQUERY_NO_CONFLICT$3 = $.fn[NAME$3];\n var Default$1 = {\n toggle: true,\n parent: ''\n };\n var DefaultType$1 = {\n toggle: 'boolean',\n parent: '(string|element)'\n };\n var Event$3 = {\n SHOW: \"show\" + EVENT_KEY$3,\n SHOWN: \"shown\" + EVENT_KEY$3,\n HIDE: \"hide\" + EVENT_KEY$3,\n HIDDEN: \"hidden\" + EVENT_KEY$3,\n CLICK_DATA_API: \"click\" + EVENT_KEY$3 + DATA_API_KEY$3\n };\n var ClassName$3 = {\n SHOW: 'show',\n COLLAPSE: 'collapse',\n COLLAPSING: 'collapsing',\n COLLAPSED: 'collapsed'\n };\n var Dimension = {\n WIDTH: 'width',\n HEIGHT: 'height'\n };\n var Selector$3 = {\n ACTIVES: '.show, .collapsing',\n DATA_TOGGLE: '[data-toggle=\"collapse\"]'\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var Collapse = /*#__PURE__*/\n function () {\n function Collapse(element, config) {\n this._isTransitioning = false;\n this._element = element;\n this._config = this._getConfig(config);\n this._triggerArray = [].slice.call(document.querySelectorAll(\"[data-toggle=\\\"collapse\\\"][href=\\\"#\" + element.id + \"\\\"],\" + (\"[data-toggle=\\\"collapse\\\"][data-target=\\\"#\" + element.id + \"\\\"]\")));\n var toggleList = [].slice.call(document.querySelectorAll(Selector$3.DATA_TOGGLE));\n for (var i = 0, len = toggleList.length; i < len; i++) {\n var elem = toggleList[i];\n var selector = Util.getSelectorFromElement(elem);\n var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) {\n return foundElem === element;\n });\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector;\n this._triggerArray.push(elem);\n }\n }\n this._parent = this._config.parent ? this._getParent() : null;\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray);\n }\n if (this._config.toggle) {\n this.toggle();\n }\n } // Getters\n\n var _proto = Collapse.prototype;\n\n // Public\n _proto.toggle = function toggle() {\n if ($(this._element).hasClass(ClassName$3.SHOW)) {\n this.hide();\n } else {\n this.show();\n }\n };\n _proto.show = function show() {\n var _this = this;\n if (this._isTransitioning || $(this._element).hasClass(ClassName$3.SHOW)) {\n return;\n }\n var actives;\n var activesData;\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(Selector$3.ACTIVES)).filter(function (elem) {\n if (typeof _this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === _this._config.parent;\n }\n return elem.classList.contains(ClassName$3.COLLAPSE);\n });\n if (actives.length === 0) {\n actives = null;\n }\n }\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY$3);\n if (activesData && activesData._isTransitioning) {\n return;\n }\n }\n var startEvent = $.Event(Event$3.SHOW);\n $(this._element).trigger(startEvent);\n if (startEvent.isDefaultPrevented()) {\n return;\n }\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide');\n if (!activesData) {\n $(actives).data(DATA_KEY$3, null);\n }\n }\n var dimension = this._getDimension();\n $(this._element).removeClass(ClassName$3.COLLAPSE).addClass(ClassName$3.COLLAPSING);\n this._element.style[dimension] = 0;\n if (this._triggerArray.length) {\n $(this._triggerArray).removeClass(ClassName$3.COLLAPSED).attr('aria-expanded', true);\n }\n this.setTransitioning(true);\n var complete = function complete() {\n $(_this._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).addClass(ClassName$3.SHOW);\n _this._element.style[dimension] = '';\n _this.setTransitioning(false);\n $(_this._element).trigger(Event$3.SHOWN);\n };\n var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n var scrollSize = \"scroll\" + capitalizedDimension;\n var transitionDuration = Util.getTransitionDurationFromElement(this._element);\n $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);\n this._element.style[dimension] = this._element[scrollSize] + \"px\";\n };\n _proto.hide = function hide() {\n var _this2 = this;\n if (this._isTransitioning || !$(this._element).hasClass(ClassName$3.SHOW)) {\n return;\n }\n var startEvent = $.Event(Event$3.HIDE);\n $(this._element).trigger(startEvent);\n if (startEvent.isDefaultPrevented()) {\n return;\n }\n var dimension = this._getDimension();\n this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + \"px\";\n Util.reflow(this._element);\n $(this._element).addClass(ClassName$3.COLLAPSING).removeClass(ClassName$3.COLLAPSE).removeClass(ClassName$3.SHOW);\n var triggerArrayLength = this._triggerArray.length;\n if (triggerArrayLength > 0) {\n for (var i = 0; i < triggerArrayLength; i++) {\n var trigger = this._triggerArray[i];\n var selector = Util.getSelectorFromElement(trigger);\n if (selector !== null) {\n var $elem = $([].slice.call(document.querySelectorAll(selector)));\n if (!$elem.hasClass(ClassName$3.SHOW)) {\n $(trigger).addClass(ClassName$3.COLLAPSED).attr('aria-expanded', false);\n }\n }\n }\n }\n this.setTransitioning(true);\n var complete = function complete() {\n _this2.setTransitioning(false);\n $(_this2._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).trigger(Event$3.HIDDEN);\n };\n this._element.style[dimension] = '';\n var transitionDuration = Util.getTransitionDurationFromElement(this._element);\n $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);\n };\n _proto.setTransitioning = function setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning;\n };\n _proto.dispose = function dispose() {\n $.removeData(this._element, DATA_KEY$3);\n this._config = null;\n this._parent = null;\n this._element = null;\n this._triggerArray = null;\n this._isTransitioning = null;\n } // Private\n ;\n _proto._getConfig = function _getConfig(config) {\n config = _objectSpread({}, Default$1, config);\n config.toggle = Boolean(config.toggle); // Coerce string values\n\n Util.typeCheckConfig(NAME$3, config, DefaultType$1);\n return config;\n };\n _proto._getDimension = function _getDimension() {\n var hasWidth = $(this._element).hasClass(Dimension.WIDTH);\n return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;\n };\n _proto._getParent = function _getParent() {\n var _this3 = this;\n var parent;\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent; // It's a jQuery object\n\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0];\n }\n } else {\n parent = document.querySelector(this._config.parent);\n }\n var selector = \"[data-toggle=\\\"collapse\\\"][data-parent=\\\"\" + this._config.parent + \"\\\"]\";\n var children = [].slice.call(parent.querySelectorAll(selector));\n $(children).each(function (i, element) {\n _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);\n });\n return parent;\n };\n _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {\n var isOpen = $(element).hasClass(ClassName$3.SHOW);\n if (triggerArray.length) {\n $(triggerArray).toggleClass(ClassName$3.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);\n }\n } // Static\n ;\n Collapse._getTargetFromElement = function _getTargetFromElement(element) {\n var selector = Util.getSelectorFromElement(element);\n return selector ? document.querySelector(selector) : null;\n };\n Collapse._jQueryInterface = function _jQueryInterface(config) {\n return this.each(function () {\n var $this = $(this);\n var data = $this.data(DATA_KEY$3);\n var _config = _objectSpread({}, Default$1, $this.data(), typeof config === 'object' && config ? config : {});\n if (!data && _config.toggle && /show|hide/.test(config)) {\n _config.toggle = false;\n }\n if (!data) {\n data = new Collapse(this, _config);\n $this.data(DATA_KEY$3, data);\n }\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(\"No method named \\\"\" + config + \"\\\"\");\n }\n data[config]();\n }\n });\n };\n _createClass(Collapse, null, [{\n key: \"VERSION\",\n get: function get() {\n return VERSION$3;\n }\n }, {\n key: \"Default\",\n get: function get() {\n return Default$1;\n }\n }]);\n return Collapse;\n }();\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event$3.CLICK_DATA_API, Selector$3.DATA_TOGGLE, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault();\n }\n var $trigger = $(this);\n var selector = Util.getSelectorFromElement(this);\n var selectors = [].slice.call(document.querySelectorAll(selector));\n $(selectors).each(function () {\n var $target = $(this);\n var data = $target.data(DATA_KEY$3);\n var config = data ? 'toggle' : $trigger.data();\n Collapse._jQueryInterface.call($target, config);\n });\n });\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME$3] = Collapse._jQueryInterface;\n $.fn[NAME$3].Constructor = Collapse;\n $.fn[NAME$3].noConflict = function () {\n $.fn[NAME$3] = JQUERY_NO_CONFLICT$3;\n return Collapse._jQueryInterface;\n };\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME$4 = 'dropdown';\n var VERSION$4 = '4.3.1';\n var DATA_KEY$4 = 'bs.dropdown';\n var EVENT_KEY$4 = \".\" + DATA_KEY$4;\n var DATA_API_KEY$4 = '.data-api';\n var JQUERY_NO_CONFLICT$4 = $.fn[NAME$4];\n var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key\n\n var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key\n\n var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key\n\n var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key\n\n var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key\n\n var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)\n\n var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + \"|\" + ARROW_DOWN_KEYCODE + \"|\" + ESCAPE_KEYCODE);\n var Event$4 = {\n HIDE: \"hide\" + EVENT_KEY$4,\n HIDDEN: \"hidden\" + EVENT_KEY$4,\n SHOW: \"show\" + EVENT_KEY$4,\n SHOWN: \"shown\" + EVENT_KEY$4,\n CLICK: \"click\" + EVENT_KEY$4,\n CLICK_DATA_API: \"click\" + EVENT_KEY$4 + DATA_API_KEY$4,\n KEYDOWN_DATA_API: \"keydown\" + EVENT_KEY$4 + DATA_API_KEY$4,\n KEYUP_DATA_API: \"keyup\" + EVENT_KEY$4 + DATA_API_KEY$4\n };\n var ClassName$4 = {\n DISABLED: 'disabled',\n SHOW: 'show',\n DROPUP: 'dropup',\n DROPRIGHT: 'dropright',\n DROPLEFT: 'dropleft',\n MENURIGHT: 'dropdown-menu-right',\n MENULEFT: 'dropdown-menu-left',\n POSITION_STATIC: 'position-static'\n };\n var Selector$4 = {\n DATA_TOGGLE: '[data-toggle=\"dropdown\"]',\n FORM_CHILD: '.dropdown form',\n MENU: '.dropdown-menu',\n NAVBAR_NAV: '.navbar-nav',\n VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n };\n var AttachmentMap = {\n TOP: 'top-start',\n TOPEND: 'top-end',\n BOTTOM: 'bottom-start',\n BOTTOMEND: 'bottom-end',\n RIGHT: 'right-start',\n RIGHTEND: 'right-end',\n LEFT: 'left-start',\n LEFTEND: 'left-end'\n };\n var Default$2 = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic'\n };\n var DefaultType$2 = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string'\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var Dropdown = /*#__PURE__*/\n function () {\n function Dropdown(element, config) {\n this._element = element;\n this._popper = null;\n this._config = this._getConfig(config);\n this._menu = this._getMenuElement();\n this._inNavbar = this._detectNavbar();\n this._addEventListeners();\n } // Getters\n\n var _proto = Dropdown.prototype;\n\n // Public\n _proto.toggle = function toggle() {\n if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED)) {\n return;\n }\n var parent = Dropdown._getParentFromElement(this._element);\n var isActive = $(this._menu).hasClass(ClassName$4.SHOW);\n Dropdown._clearMenus();\n if (isActive) {\n return;\n }\n var relatedTarget = {\n relatedTarget: this._element\n };\n var showEvent = $.Event(Event$4.SHOW, relatedTarget);\n $(parent).trigger(showEvent);\n if (showEvent.isDefaultPrevented()) {\n return;\n } // Disable totally Popper.js for Dropdown in Navbar\n\n if (!this._inNavbar) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper.js (https://popper.js.org/)');\n }\n var referenceElement = this._element;\n if (this._config.reference === 'parent') {\n referenceElement = parent;\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference; // Check if it's jQuery element\n\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0];\n }\n } // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(ClassName$4.POSITION_STATIC);\n }\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());\n } // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n if ('ontouchstart' in document.documentElement && $(parent).closest(Selector$4.NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop);\n }\n this._element.focus();\n this._element.setAttribute('aria-expanded', true);\n $(this._menu).toggleClass(ClassName$4.SHOW);\n $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.SHOWN, relatedTarget));\n };\n _proto.show = function show() {\n if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || $(this._menu).hasClass(ClassName$4.SHOW)) {\n return;\n }\n var relatedTarget = {\n relatedTarget: this._element\n };\n var showEvent = $.Event(Event$4.SHOW, relatedTarget);\n var parent = Dropdown._getParentFromElement(this._element);\n $(parent).trigger(showEvent);\n if (showEvent.isDefaultPrevented()) {\n return;\n }\n $(this._menu).toggleClass(ClassName$4.SHOW);\n $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.SHOWN, relatedTarget));\n };\n _proto.hide = function hide() {\n if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || !$(this._menu).hasClass(ClassName$4.SHOW)) {\n return;\n }\n var relatedTarget = {\n relatedTarget: this._element\n };\n var hideEvent = $.Event(Event$4.HIDE, relatedTarget);\n var parent = Dropdown._getParentFromElement(this._element);\n $(parent).trigger(hideEvent);\n if (hideEvent.isDefaultPrevented()) {\n return;\n }\n $(this._menu).toggleClass(ClassName$4.SHOW);\n $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget));\n };\n _proto.dispose = function dispose() {\n $.removeData(this._element, DATA_KEY$4);\n $(this._element).off(EVENT_KEY$4);\n this._element = null;\n this._menu = null;\n if (this._popper !== null) {\n this._popper.destroy();\n this._popper = null;\n }\n };\n _proto.update = function update() {\n this._inNavbar = this._detectNavbar();\n if (this._popper !== null) {\n this._popper.scheduleUpdate();\n }\n } // Private\n ;\n _proto._addEventListeners = function _addEventListeners() {\n var _this = this;\n $(this._element).on(Event$4.CLICK, function (event) {\n event.preventDefault();\n event.stopPropagation();\n _this.toggle();\n });\n };\n _proto._getConfig = function _getConfig(config) {\n config = _objectSpread({}, this.constructor.Default, $(this._element).data(), config);\n Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);\n return config;\n };\n _proto._getMenuElement = function _getMenuElement() {\n if (!this._menu) {\n var parent = Dropdown._getParentFromElement(this._element);\n if (parent) {\n this._menu = parent.querySelector(Selector$4.MENU);\n }\n }\n return this._menu;\n };\n _proto._getPlacement = function _getPlacement() {\n var $parentDropdown = $(this._element.parentNode);\n var placement = AttachmentMap.BOTTOM; // Handle dropup\n\n if ($parentDropdown.hasClass(ClassName$4.DROPUP)) {\n placement = AttachmentMap.TOP;\n if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) {\n placement = AttachmentMap.TOPEND;\n }\n } else if ($parentDropdown.hasClass(ClassName$4.DROPRIGHT)) {\n placement = AttachmentMap.RIGHT;\n } else if ($parentDropdown.hasClass(ClassName$4.DROPLEFT)) {\n placement = AttachmentMap.LEFT;\n } else if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) {\n placement = AttachmentMap.BOTTOMEND;\n }\n return placement;\n };\n _proto._detectNavbar = function _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0;\n };\n _proto._getOffset = function _getOffset() {\n var _this2 = this;\n var offset = {};\n if (typeof this._config.offset === 'function') {\n offset.fn = function (data) {\n data.offsets = _objectSpread({}, data.offsets, _this2._config.offset(data.offsets, _this2._element) || {});\n return data;\n };\n } else {\n offset.offset = this._config.offset;\n }\n return offset;\n };\n _proto._getPopperConfig = function _getPopperConfig() {\n var popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n } // Disable Popper.js if we have a static display\n };\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n };\n }\n return popperConfig;\n } // Static\n ;\n Dropdown._jQueryInterface = function _jQueryInterface(config) {\n return this.each(function () {\n var data = $(this).data(DATA_KEY$4);\n var _config = typeof config === 'object' ? config : null;\n if (!data) {\n data = new Dropdown(this, _config);\n $(this).data(DATA_KEY$4, data);\n }\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(\"No method named \\\"\" + config + \"\\\"\");\n }\n data[config]();\n }\n });\n };\n Dropdown._clearMenus = function _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return;\n }\n var toggles = [].slice.call(document.querySelectorAll(Selector$4.DATA_TOGGLE));\n for (var i = 0, len = toggles.length; i < len; i++) {\n var parent = Dropdown._getParentFromElement(toggles[i]);\n var context = $(toggles[i]).data(DATA_KEY$4);\n var relatedTarget = {\n relatedTarget: toggles[i]\n };\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event;\n }\n if (!context) {\n continue;\n }\n var dropdownMenu = context._menu;\n if (!$(parent).hasClass(ClassName$4.SHOW)) {\n continue;\n }\n if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {\n continue;\n }\n var hideEvent = $.Event(Event$4.HIDE, relatedTarget);\n $(parent).trigger(hideEvent);\n if (hideEvent.isDefaultPrevented()) {\n continue;\n } // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop);\n }\n toggles[i].setAttribute('aria-expanded', 'false');\n $(dropdownMenu).removeClass(ClassName$4.SHOW);\n $(parent).removeClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget));\n }\n };\n Dropdown._getParentFromElement = function _getParentFromElement(element) {\n var parent;\n var selector = Util.getSelectorFromElement(element);\n if (selector) {\n parent = document.querySelector(selector);\n }\n return parent || element.parentNode;\n } // eslint-disable-next-line complexity\n ;\n Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(Selector$4.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n if (this.disabled || $(this).hasClass(ClassName$4.DISABLED)) {\n return;\n }\n var parent = Dropdown._getParentFromElement(this);\n var isActive = $(parent).hasClass(ClassName$4.SHOW);\n if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n var toggle = parent.querySelector(Selector$4.DATA_TOGGLE);\n $(toggle).trigger('focus');\n }\n $(this).trigger('click');\n return;\n }\n var items = [].slice.call(parent.querySelectorAll(Selector$4.VISIBLE_ITEMS));\n if (items.length === 0) {\n return;\n }\n var index = items.indexOf(event.target);\n if (event.which === ARROW_UP_KEYCODE && index > 0) {\n // Up\n index--;\n }\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {\n // Down\n index++;\n }\n if (index < 0) {\n index = 0;\n }\n items[index].focus();\n };\n _createClass(Dropdown, null, [{\n key: \"VERSION\",\n get: function get() {\n return VERSION$4;\n }\n }, {\n key: \"Default\",\n get: function get() {\n return Default$2;\n }\n }, {\n key: \"DefaultType\",\n get: function get() {\n return DefaultType$2;\n }\n }]);\n return Dropdown;\n }();\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event$4.KEYDOWN_DATA_API, Selector$4.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event$4.KEYDOWN_DATA_API, Selector$4.MENU, Dropdown._dataApiKeydownHandler).on(Event$4.CLICK_DATA_API + \" \" + Event$4.KEYUP_DATA_API, Dropdown._clearMenus).on(Event$4.CLICK_DATA_API, Selector$4.DATA_TOGGLE, function (event) {\n event.preventDefault();\n event.stopPropagation();\n Dropdown._jQueryInterface.call($(this), 'toggle');\n }).on(Event$4.CLICK_DATA_API, Selector$4.FORM_CHILD, function (e) {\n e.stopPropagation();\n });\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME$4] = Dropdown._jQueryInterface;\n $.fn[NAME$4].Constructor = Dropdown;\n $.fn[NAME$4].noConflict = function () {\n $.fn[NAME$4] = JQUERY_NO_CONFLICT$4;\n return Dropdown._jQueryInterface;\n };\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME$5 = 'modal';\n var VERSION$5 = '4.3.1';\n var DATA_KEY$5 = 'bs.modal';\n var EVENT_KEY$5 = \".\" + DATA_KEY$5;\n var DATA_API_KEY$5 = '.data-api';\n var JQUERY_NO_CONFLICT$5 = $.fn[NAME$5];\n var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key\n\n var Default$3 = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n };\n var DefaultType$3 = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n };\n var Event$5 = {\n HIDE: \"hide\" + EVENT_KEY$5,\n HIDDEN: \"hidden\" + EVENT_KEY$5,\n SHOW: \"show\" + EVENT_KEY$5,\n SHOWN: \"shown\" + EVENT_KEY$5,\n FOCUSIN: \"focusin\" + EVENT_KEY$5,\n RESIZE: \"resize\" + EVENT_KEY$5,\n CLICK_DISMISS: \"click.dismiss\" + EVENT_KEY$5,\n KEYDOWN_DISMISS: \"keydown.dismiss\" + EVENT_KEY$5,\n MOUSEUP_DISMISS: \"mouseup.dismiss\" + EVENT_KEY$5,\n MOUSEDOWN_DISMISS: \"mousedown.dismiss\" + EVENT_KEY$5,\n CLICK_DATA_API: \"click\" + EVENT_KEY$5 + DATA_API_KEY$5\n };\n var ClassName$5 = {\n SCROLLABLE: 'modal-dialog-scrollable',\n SCROLLBAR_MEASURER: 'modal-scrollbar-measure',\n BACKDROP: 'modal-backdrop',\n OPEN: 'modal-open',\n FADE: 'fade',\n SHOW: 'show'\n };\n var Selector$5 = {\n DIALOG: '.modal-dialog',\n MODAL_BODY: '.modal-body',\n DATA_TOGGLE: '[data-toggle=\"modal\"]',\n DATA_DISMISS: '[data-dismiss=\"modal\"]',\n FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',\n STICKY_CONTENT: '.sticky-top'\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var Modal = /*#__PURE__*/\n function () {\n function Modal(element, config) {\n this._config = this._getConfig(config);\n this._element = element;\n this._dialog = element.querySelector(Selector$5.DIALOG);\n this._backdrop = null;\n this._isShown = false;\n this._isBodyOverflowing = false;\n this._ignoreBackdropClick = false;\n this._isTransitioning = false;\n this._scrollbarWidth = 0;\n } // Getters\n\n var _proto = Modal.prototype;\n\n // Public\n _proto.toggle = function toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n };\n _proto.show = function show(relatedTarget) {\n var _this = this;\n if (this._isShown || this._isTransitioning) {\n return;\n }\n if ($(this._element).hasClass(ClassName$5.FADE)) {\n this._isTransitioning = true;\n }\n var showEvent = $.Event(Event$5.SHOW, {\n relatedTarget: relatedTarget\n });\n $(this._element).trigger(showEvent);\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return;\n }\n this._isShown = true;\n this._checkScrollbar();\n this._setScrollbar();\n this._adjustDialog();\n this._setEscapeEvent();\n this._setResizeEvent();\n $(this._element).on(Event$5.CLICK_DISMISS, Selector$5.DATA_DISMISS, function (event) {\n return _this.hide(event);\n });\n $(this._dialog).on(Event$5.MOUSEDOWN_DISMISS, function () {\n $(_this._element).one(Event$5.MOUSEUP_DISMISS, function (event) {\n if ($(event.target).is(_this._element)) {\n _this._ignoreBackdropClick = true;\n }\n });\n });\n this._showBackdrop(function () {\n return _this._showElement(relatedTarget);\n });\n };\n _proto.hide = function hide(event) {\n var _this2 = this;\n if (event) {\n event.preventDefault();\n }\n if (!this._isShown || this._isTransitioning) {\n return;\n }\n var hideEvent = $.Event(Event$5.HIDE);\n $(this._element).trigger(hideEvent);\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return;\n }\n this._isShown = false;\n var transition = $(this._element).hasClass(ClassName$5.FADE);\n if (transition) {\n this._isTransitioning = true;\n }\n this._setEscapeEvent();\n this._setResizeEvent();\n $(document).off(Event$5.FOCUSIN);\n $(this._element).removeClass(ClassName$5.SHOW);\n $(this._element).off(Event$5.CLICK_DISMISS);\n $(this._dialog).off(Event$5.MOUSEDOWN_DISMISS);\n if (transition) {\n var transitionDuration = Util.getTransitionDurationFromElement(this._element);\n $(this._element).one(Util.TRANSITION_END, function (event) {\n return _this2._hideModal(event);\n }).emulateTransitionEnd(transitionDuration);\n } else {\n this._hideModal();\n }\n };\n _proto.dispose = function dispose() {\n [window, this._element, this._dialog].forEach(function (htmlElement) {\n return $(htmlElement).off(EVENT_KEY$5);\n });\n /**\n * `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `Event.CLICK_DATA_API` event that should remain\n */\n\n $(document).off(Event$5.FOCUSIN);\n $.removeData(this._element, DATA_KEY$5);\n this._config = null;\n this._element = null;\n this._dialog = null;\n this._backdrop = null;\n this._isShown = null;\n this._isBodyOverflowing = null;\n this._ignoreBackdropClick = null;\n this._isTransitioning = null;\n this._scrollbarWidth = null;\n };\n _proto.handleUpdate = function handleUpdate() {\n this._adjustDialog();\n } // Private\n ;\n _proto._getConfig = function _getConfig(config) {\n config = _objectSpread({}, Default$3, config);\n Util.typeCheckConfig(NAME$5, config, DefaultType$3);\n return config;\n };\n _proto._showElement = function _showElement(relatedTarget) {\n var _this3 = this;\n var transition = $(this._element).hasClass(ClassName$5.FADE);\n if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element);\n }\n this._element.style.display = 'block';\n this._element.removeAttribute('aria-hidden');\n this._element.setAttribute('aria-modal', true);\n if ($(this._dialog).hasClass(ClassName$5.SCROLLABLE)) {\n this._dialog.querySelector(Selector$5.MODAL_BODY).scrollTop = 0;\n } else {\n this._element.scrollTop = 0;\n }\n if (transition) {\n Util.reflow(this._element);\n }\n $(this._element).addClass(ClassName$5.SHOW);\n if (this._config.focus) {\n this._enforceFocus();\n }\n var shownEvent = $.Event(Event$5.SHOWN, {\n relatedTarget: relatedTarget\n });\n var transitionComplete = function transitionComplete() {\n if (_this3._config.focus) {\n _this3._element.focus();\n }\n _this3._isTransitioning = false;\n $(_this3._element).trigger(shownEvent);\n };\n if (transition) {\n var transitionDuration = Util.getTransitionDurationFromElement(this._dialog);\n $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration);\n } else {\n transitionComplete();\n }\n };\n _proto._enforceFocus = function _enforceFocus() {\n var _this4 = this;\n $(document).off(Event$5.FOCUSIN) // Guard against infinite focus loop\n .on(Event$5.FOCUSIN, function (event) {\n if (document !== event.target && _this4._element !== event.target && $(_this4._element).has(event.target).length === 0) {\n _this4._element.focus();\n }\n });\n };\n _proto._setEscapeEvent = function _setEscapeEvent() {\n var _this5 = this;\n if (this._isShown && this._config.keyboard) {\n $(this._element).on(Event$5.KEYDOWN_DISMISS, function (event) {\n if (event.which === ESCAPE_KEYCODE$1) {\n event.preventDefault();\n _this5.hide();\n }\n });\n } else if (!this._isShown) {\n $(this._element).off(Event$5.KEYDOWN_DISMISS);\n }\n };\n _proto._setResizeEvent = function _setResizeEvent() {\n var _this6 = this;\n if (this._isShown) {\n $(window).on(Event$5.RESIZE, function (event) {\n return _this6.handleUpdate(event);\n });\n } else {\n $(window).off(Event$5.RESIZE);\n }\n };\n _proto._hideModal = function _hideModal() {\n var _this7 = this;\n this._element.style.display = 'none';\n this._element.setAttribute('aria-hidden', true);\n this._element.removeAttribute('aria-modal');\n this._isTransitioning = false;\n this._showBackdrop(function () {\n $(document.body).removeClass(ClassName$5.OPEN);\n _this7._resetAdjustments();\n _this7._resetScrollbar();\n $(_this7._element).trigger(Event$5.HIDDEN);\n });\n };\n _proto._removeBackdrop = function _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove();\n this._backdrop = null;\n }\n };\n _proto._showBackdrop = function _showBackdrop(callback) {\n var _this8 = this;\n var animate = $(this._element).hasClass(ClassName$5.FADE) ? ClassName$5.FADE : '';\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div');\n this._backdrop.className = ClassName$5.BACKDROP;\n if (animate) {\n this._backdrop.classList.add(animate);\n }\n $(this._backdrop).appendTo(document.body);\n $(this._element).on(Event$5.CLICK_DISMISS, function (event) {\n if (_this8._ignoreBackdropClick) {\n _this8._ignoreBackdropClick = false;\n return;\n }\n if (event.target !== event.currentTarget) {\n return;\n }\n if (_this8._config.backdrop === 'static') {\n _this8._element.focus();\n } else {\n _this8.hide();\n }\n });\n if (animate) {\n Util.reflow(this._backdrop);\n }\n $(this._backdrop).addClass(ClassName$5.SHOW);\n if (!callback) {\n return;\n }\n if (!animate) {\n callback();\n return;\n }\n var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);\n $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration);\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(ClassName$5.SHOW);\n var callbackRemove = function callbackRemove() {\n _this8._removeBackdrop();\n if (callback) {\n callback();\n }\n };\n if ($(this._element).hasClass(ClassName$5.FADE)) {\n var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);\n $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration);\n } else {\n callbackRemove();\n }\n } else if (callback) {\n callback();\n }\n } // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n ;\n _proto._adjustDialog = function _adjustDialog() {\n var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = this._scrollbarWidth + \"px\";\n }\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = this._scrollbarWidth + \"px\";\n }\n };\n _proto._resetAdjustments = function _resetAdjustments() {\n this._element.style.paddingLeft = '';\n this._element.style.paddingRight = '';\n };\n _proto._checkScrollbar = function _checkScrollbar() {\n var rect = document.body.getBoundingClientRect();\n this._isBodyOverflowing = rect.left + rect.right < window.innerWidth;\n this._scrollbarWidth = this._getScrollbarWidth();\n };\n _proto._setScrollbar = function _setScrollbar() {\n var _this9 = this;\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT));\n var stickyContent = [].slice.call(document.querySelectorAll(Selector$5.STICKY_CONTENT)); // Adjust fixed content padding\n\n $(fixedContent).each(function (index, element) {\n var actualPadding = element.style.paddingRight;\n var calculatedPadding = $(element).css('padding-right');\n $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + \"px\");\n }); // Adjust sticky content margin\n\n $(stickyContent).each(function (index, element) {\n var actualMargin = element.style.marginRight;\n var calculatedMargin = $(element).css('margin-right');\n $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + \"px\");\n }); // Adjust body padding\n\n var actualPadding = document.body.style.paddingRight;\n var calculatedPadding = $(document.body).css('padding-right');\n $(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + \"px\");\n }\n $(document.body).addClass(ClassName$5.OPEN);\n };\n _proto._resetScrollbar = function _resetScrollbar() {\n // Restore fixed content padding\n var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT));\n $(fixedContent).each(function (index, element) {\n var padding = $(element).data('padding-right');\n $(element).removeData('padding-right');\n element.style.paddingRight = padding ? padding : '';\n }); // Restore sticky content\n\n var elements = [].slice.call(document.querySelectorAll(\"\" + Selector$5.STICKY_CONTENT));\n $(elements).each(function (index, element) {\n var margin = $(element).data('margin-right');\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right');\n }\n }); // Restore body padding\n\n var padding = $(document.body).data('padding-right');\n $(document.body).removeData('padding-right');\n document.body.style.paddingRight = padding ? padding : '';\n };\n _proto._getScrollbarWidth = function _getScrollbarWidth() {\n // thx d.walsh\n var scrollDiv = document.createElement('div');\n scrollDiv.className = ClassName$5.SCROLLBAR_MEASURER;\n document.body.appendChild(scrollDiv);\n var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;\n document.body.removeChild(scrollDiv);\n return scrollbarWidth;\n } // Static\n ;\n Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n var data = $(this).data(DATA_KEY$5);\n var _config = _objectSpread({}, Default$3, $(this).data(), typeof config === 'object' && config ? config : {});\n if (!data) {\n data = new Modal(this, _config);\n $(this).data(DATA_KEY$5, data);\n }\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(\"No method named \\\"\" + config + \"\\\"\");\n }\n data[config](relatedTarget);\n } else if (_config.show) {\n data.show(relatedTarget);\n }\n });\n };\n _createClass(Modal, null, [{\n key: \"VERSION\",\n get: function get() {\n return VERSION$5;\n }\n }, {\n key: \"Default\",\n get: function get() {\n return Default$3;\n }\n }]);\n return Modal;\n }();\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event$5.CLICK_DATA_API, Selector$5.DATA_TOGGLE, function (event) {\n var _this10 = this;\n var target;\n var selector = Util.getSelectorFromElement(this);\n if (selector) {\n target = document.querySelector(selector);\n }\n var config = $(target).data(DATA_KEY$5) ? 'toggle' : _objectSpread({}, $(target).data(), $(this).data());\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault();\n }\n var $target = $(target).one(Event$5.SHOW, function (showEvent) {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return;\n }\n $target.one(Event$5.HIDDEN, function () {\n if ($(_this10).is(':visible')) {\n _this10.focus();\n }\n });\n });\n Modal._jQueryInterface.call($(target), config, this);\n });\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME$5] = Modal._jQueryInterface;\n $.fn[NAME$5].Constructor = Modal;\n $.fn[NAME$5].noConflict = function () {\n $.fn[NAME$5] = JQUERY_NO_CONFLICT$5;\n return Modal._jQueryInterface;\n };\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.3.1): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];\n var ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\n var DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n /**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\n };\n var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;\n /**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\n\n var DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;\n function allowedAttribute(attr, allowedAttributeList) {\n var attrName = attr.nodeName.toLowerCase();\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));\n }\n return true;\n }\n var regExp = allowedAttributeList.filter(function (attrRegex) {\n return attrRegex instanceof RegExp;\n }); // Check if a regular expression validates the attribute.\n\n for (var i = 0, l = regExp.length; i < l; i++) {\n if (attrName.match(regExp[i])) {\n return true;\n }\n }\n return false;\n }\n function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml;\n }\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml);\n }\n var domParser = new window.DOMParser();\n var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n var whitelistKeys = Object.keys(whiteList);\n var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));\n var _loop = function _loop(i, len) {\n var el = elements[i];\n var elName = el.nodeName.toLowerCase();\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el);\n return \"continue\";\n }\n var attributeList = [].slice.call(el.attributes);\n var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);\n attributeList.forEach(function (attr) {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName);\n }\n });\n };\n for (var i = 0, len = elements.length; i < len; i++) {\n var _ret = _loop(i, len);\n if (_ret === \"continue\") continue;\n }\n return createdDocument.body.innerHTML;\n }\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME$6 = 'tooltip';\n var VERSION$6 = '4.3.1';\n var DATA_KEY$6 = 'bs.tooltip';\n var EVENT_KEY$6 = \".\" + DATA_KEY$6;\n var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6];\n var CLASS_PREFIX = 'bs-tooltip';\n var BSCLS_PREFIX_REGEX = new RegExp(\"(^|\\\\s)\" + CLASS_PREFIX + \"\\\\S+\", 'g');\n var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];\n var DefaultType$4 = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object'\n };\n var AttachmentMap$1 = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n };\n var Default$4 = {\n animation: true,\n template: '
' + '
' + '
',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist\n };\n var HoverState = {\n SHOW: 'show',\n OUT: 'out'\n };\n var Event$6 = {\n HIDE: \"hide\" + EVENT_KEY$6,\n HIDDEN: \"hidden\" + EVENT_KEY$6,\n SHOW: \"show\" + EVENT_KEY$6,\n SHOWN: \"shown\" + EVENT_KEY$6,\n INSERTED: \"inserted\" + EVENT_KEY$6,\n CLICK: \"click\" + EVENT_KEY$6,\n FOCUSIN: \"focusin\" + EVENT_KEY$6,\n FOCUSOUT: \"focusout\" + EVENT_KEY$6,\n MOUSEENTER: \"mouseenter\" + EVENT_KEY$6,\n MOUSELEAVE: \"mouseleave\" + EVENT_KEY$6\n };\n var ClassName$6 = {\n FADE: 'fade',\n SHOW: 'show'\n };\n var Selector$6 = {\n TOOLTIP: '.tooltip',\n TOOLTIP_INNER: '.tooltip-inner',\n ARROW: '.arrow'\n };\n var Trigger = {\n HOVER: 'hover',\n FOCUS: 'focus',\n CLICK: 'click',\n MANUAL: 'manual'\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var Tooltip = /*#__PURE__*/\n function () {\n function Tooltip(element, config) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper.js (https://popper.js.org/)');\n } // private\n\n this._isEnabled = true;\n this._timeout = 0;\n this._hoverState = '';\n this._activeTrigger = {};\n this._popper = null; // Protected\n\n this.element = element;\n this.config = this._getConfig(config);\n this.tip = null;\n this._setListeners();\n } // Getters\n\n var _proto = Tooltip.prototype;\n\n // Public\n _proto.enable = function enable() {\n this._isEnabled = true;\n };\n _proto.disable = function disable() {\n this._isEnabled = false;\n };\n _proto.toggleEnabled = function toggleEnabled() {\n this._isEnabled = !this._isEnabled;\n };\n _proto.toggle = function toggle(event) {\n if (!this._isEnabled) {\n return;\n }\n if (event) {\n var dataKey = this.constructor.DATA_KEY;\n var context = $(event.currentTarget).data(dataKey);\n if (!context) {\n context = new this.constructor(event.currentTarget, this._getDelegateConfig());\n $(event.currentTarget).data(dataKey, context);\n }\n context._activeTrigger.click = !context._activeTrigger.click;\n if (context._isWithActiveTrigger()) {\n context._enter(null, context);\n } else {\n context._leave(null, context);\n }\n } else {\n if ($(this.getTipElement()).hasClass(ClassName$6.SHOW)) {\n this._leave(null, this);\n return;\n }\n this._enter(null, this);\n }\n };\n _proto.dispose = function dispose() {\n clearTimeout(this._timeout);\n $.removeData(this.element, this.constructor.DATA_KEY);\n $(this.element).off(this.constructor.EVENT_KEY);\n $(this.element).closest('.modal').off('hide.bs.modal');\n if (this.tip) {\n $(this.tip).remove();\n }\n this._isEnabled = null;\n this._timeout = null;\n this._hoverState = null;\n this._activeTrigger = null;\n if (this._popper !== null) {\n this._popper.destroy();\n }\n this._popper = null;\n this.element = null;\n this.config = null;\n this.tip = null;\n };\n _proto.show = function show() {\n var _this = this;\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements');\n }\n var showEvent = $.Event(this.constructor.Event.SHOW);\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent);\n var shadowRoot = Util.findShadowRoot(this.element);\n var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return;\n }\n var tip = this.getTipElement();\n var tipId = Util.getUID(this.constructor.NAME);\n tip.setAttribute('id', tipId);\n this.element.setAttribute('aria-describedby', tipId);\n this.setContent();\n if (this.config.animation) {\n $(tip).addClass(ClassName$6.FADE);\n }\n var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;\n var attachment = this._getAttachment(placement);\n this.addAttachmentClass(attachment);\n var container = this._getContainer();\n $(tip).data(this.constructor.DATA_KEY, this);\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container);\n }\n $(this.element).trigger(this.constructor.Event.INSERTED);\n this._popper = new Popper(this.element, tip, {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: Selector$6.ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: function onCreate(data) {\n if (data.originalPlacement !== data.placement) {\n _this._handlePopperPlacementChange(data);\n }\n },\n onUpdate: function onUpdate(data) {\n return _this._handlePopperPlacementChange(data);\n }\n });\n $(tip).addClass(ClassName$6.SHOW); // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop);\n }\n var complete = function complete() {\n if (_this.config.animation) {\n _this._fixTransition();\n }\n var prevHoverState = _this._hoverState;\n _this._hoverState = null;\n $(_this.element).trigger(_this.constructor.Event.SHOWN);\n if (prevHoverState === HoverState.OUT) {\n _this._leave(null, _this);\n }\n };\n if ($(this.tip).hasClass(ClassName$6.FADE)) {\n var transitionDuration = Util.getTransitionDurationFromElement(this.tip);\n $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);\n } else {\n complete();\n }\n }\n };\n _proto.hide = function hide(callback) {\n var _this2 = this;\n var tip = this.getTipElement();\n var hideEvent = $.Event(this.constructor.Event.HIDE);\n var complete = function complete() {\n if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip);\n }\n _this2._cleanTipClass();\n _this2.element.removeAttribute('aria-describedby');\n $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);\n if (_this2._popper !== null) {\n _this2._popper.destroy();\n }\n if (callback) {\n callback();\n }\n };\n $(this.element).trigger(hideEvent);\n if (hideEvent.isDefaultPrevented()) {\n return;\n }\n $(tip).removeClass(ClassName$6.SHOW); // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop);\n }\n this._activeTrigger[Trigger.CLICK] = false;\n this._activeTrigger[Trigger.FOCUS] = false;\n this._activeTrigger[Trigger.HOVER] = false;\n if ($(this.tip).hasClass(ClassName$6.FADE)) {\n var transitionDuration = Util.getTransitionDurationFromElement(tip);\n $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);\n } else {\n complete();\n }\n this._hoverState = '';\n };\n _proto.update = function update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate();\n }\n } // Protected\n ;\n _proto.isWithContent = function isWithContent() {\n return Boolean(this.getTitle());\n };\n _proto.addAttachmentClass = function addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(CLASS_PREFIX + \"-\" + attachment);\n };\n _proto.getTipElement = function getTipElement() {\n this.tip = this.tip || $(this.config.template)[0];\n return this.tip;\n };\n _proto.setContent = function setContent() {\n var tip = this.getTipElement();\n this.setElementContent($(tip.querySelectorAll(Selector$6.TOOLTIP_INNER)), this.getTitle());\n $(tip).removeClass(ClassName$6.FADE + \" \" + ClassName$6.SHOW);\n };\n _proto.setElementContent = function setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content);\n }\n } else {\n $element.text($(content).text());\n }\n return;\n }\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);\n }\n $element.html(content);\n } else {\n $element.text(content);\n }\n };\n _proto.getTitle = function getTitle() {\n var title = this.element.getAttribute('data-original-title');\n if (!title) {\n title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;\n }\n return title;\n } // Private\n ;\n _proto._getOffset = function _getOffset() {\n var _this3 = this;\n var offset = {};\n if (typeof this.config.offset === 'function') {\n offset.fn = function (data) {\n data.offsets = _objectSpread({}, data.offsets, _this3.config.offset(data.offsets, _this3.element) || {});\n return data;\n };\n } else {\n offset.offset = this.config.offset;\n }\n return offset;\n };\n _proto._getContainer = function _getContainer() {\n if (this.config.container === false) {\n return document.body;\n }\n if (Util.isElement(this.config.container)) {\n return $(this.config.container);\n }\n return $(document).find(this.config.container);\n };\n _proto._getAttachment = function _getAttachment(placement) {\n return AttachmentMap$1[placement.toUpperCase()];\n };\n _proto._setListeners = function _setListeners() {\n var _this4 = this;\n var triggers = this.config.trigger.split(' ');\n triggers.forEach(function (trigger) {\n if (trigger === 'click') {\n $(_this4.element).on(_this4.constructor.Event.CLICK, _this4.config.selector, function (event) {\n return _this4.toggle(event);\n });\n } else if (trigger !== Trigger.MANUAL) {\n var eventIn = trigger === Trigger.HOVER ? _this4.constructor.Event.MOUSEENTER : _this4.constructor.Event.FOCUSIN;\n var eventOut = trigger === Trigger.HOVER ? _this4.constructor.Event.MOUSELEAVE : _this4.constructor.Event.FOCUSOUT;\n $(_this4.element).on(eventIn, _this4.config.selector, function (event) {\n return _this4._enter(event);\n }).on(eventOut, _this4.config.selector, function (event) {\n return _this4._leave(event);\n });\n }\n });\n $(this.element).closest('.modal').on('hide.bs.modal', function () {\n if (_this4.element) {\n _this4.hide();\n }\n });\n if (this.config.selector) {\n this.config = _objectSpread({}, this.config, {\n trigger: 'manual',\n selector: ''\n });\n } else {\n this._fixTitle();\n }\n };\n _proto._fixTitle = function _fixTitle() {\n var titleType = typeof this.element.getAttribute('data-original-title');\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');\n this.element.setAttribute('title', '');\n }\n };\n _proto._enter = function _enter(event, context) {\n var dataKey = this.constructor.DATA_KEY;\n context = context || $(event.currentTarget).data(dataKey);\n if (!context) {\n context = new this.constructor(event.currentTarget, this._getDelegateConfig());\n $(event.currentTarget).data(dataKey, context);\n }\n if (event) {\n context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true;\n }\n if ($(context.getTipElement()).hasClass(ClassName$6.SHOW) || context._hoverState === HoverState.SHOW) {\n context._hoverState = HoverState.SHOW;\n return;\n }\n clearTimeout(context._timeout);\n context._hoverState = HoverState.SHOW;\n if (!context.config.delay || !context.config.delay.show) {\n context.show();\n return;\n }\n context._timeout = setTimeout(function () {\n if (context._hoverState === HoverState.SHOW) {\n context.show();\n }\n }, context.config.delay.show);\n };\n _proto._leave = function _leave(event, context) {\n var dataKey = this.constructor.DATA_KEY;\n context = context || $(event.currentTarget).data(dataKey);\n if (!context) {\n context = new this.constructor(event.currentTarget, this._getDelegateConfig());\n $(event.currentTarget).data(dataKey, context);\n }\n if (event) {\n context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;\n }\n if (context._isWithActiveTrigger()) {\n return;\n }\n clearTimeout(context._timeout);\n context._hoverState = HoverState.OUT;\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide();\n return;\n }\n context._timeout = setTimeout(function () {\n if (context._hoverState === HoverState.OUT) {\n context.hide();\n }\n }, context.config.delay.hide);\n };\n _proto._isWithActiveTrigger = function _isWithActiveTrigger() {\n for (var trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true;\n }\n }\n return false;\n };\n _proto._getConfig = function _getConfig(config) {\n var dataAttributes = $(this.element).data();\n Object.keys(dataAttributes).forEach(function (dataAttr) {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr];\n }\n });\n config = _objectSpread({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {});\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n };\n }\n if (typeof config.title === 'number') {\n config.title = config.title.toString();\n }\n if (typeof config.content === 'number') {\n config.content = config.content.toString();\n }\n Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType);\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);\n }\n return config;\n };\n _proto._getDelegateConfig = function _getDelegateConfig() {\n var config = {};\n if (this.config) {\n for (var key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key];\n }\n }\n }\n return config;\n };\n _proto._cleanTipClass = function _cleanTipClass() {\n var $tip = $(this.getTipElement());\n var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''));\n }\n };\n _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {\n var popperInstance = popperData.instance;\n this.tip = popperInstance.popper;\n this._cleanTipClass();\n this.addAttachmentClass(this._getAttachment(popperData.placement));\n };\n _proto._fixTransition = function _fixTransition() {\n var tip = this.getTipElement();\n var initConfigAnimation = this.config.animation;\n if (tip.getAttribute('x-placement') !== null) {\n return;\n }\n $(tip).removeClass(ClassName$6.FADE);\n this.config.animation = false;\n this.hide();\n this.show();\n this.config.animation = initConfigAnimation;\n } // Static\n ;\n Tooltip._jQueryInterface = function _jQueryInterface(config) {\n return this.each(function () {\n var data = $(this).data(DATA_KEY$6);\n var _config = typeof config === 'object' && config;\n if (!data && /dispose|hide/.test(config)) {\n return;\n }\n if (!data) {\n data = new Tooltip(this, _config);\n $(this).data(DATA_KEY$6, data);\n }\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(\"No method named \\\"\" + config + \"\\\"\");\n }\n data[config]();\n }\n });\n };\n _createClass(Tooltip, null, [{\n key: \"VERSION\",\n get: function get() {\n return VERSION$6;\n }\n }, {\n key: \"Default\",\n get: function get() {\n return Default$4;\n }\n }, {\n key: \"NAME\",\n get: function get() {\n return NAME$6;\n }\n }, {\n key: \"DATA_KEY\",\n get: function get() {\n return DATA_KEY$6;\n }\n }, {\n key: \"Event\",\n get: function get() {\n return Event$6;\n }\n }, {\n key: \"EVENT_KEY\",\n get: function get() {\n return EVENT_KEY$6;\n }\n }, {\n key: \"DefaultType\",\n get: function get() {\n return DefaultType$4;\n }\n }]);\n return Tooltip;\n }();\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME$6] = Tooltip._jQueryInterface;\n $.fn[NAME$6].Constructor = Tooltip;\n $.fn[NAME$6].noConflict = function () {\n $.fn[NAME$6] = JQUERY_NO_CONFLICT$6;\n return Tooltip._jQueryInterface;\n };\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME$7 = 'popover';\n var VERSION$7 = '4.3.1';\n var DATA_KEY$7 = 'bs.popover';\n var EVENT_KEY$7 = \".\" + DATA_KEY$7;\n var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7];\n var CLASS_PREFIX$1 = 'bs-popover';\n var BSCLS_PREFIX_REGEX$1 = new RegExp(\"(^|\\\\s)\" + CLASS_PREFIX$1 + \"\\\\S+\", 'g');\n var Default$5 = _objectSpread({}, Tooltip.Default, {\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '
' + '
' + '

' + '
'\n });\n var DefaultType$5 = _objectSpread({}, Tooltip.DefaultType, {\n content: '(string|element|function)'\n });\n var ClassName$7 = {\n FADE: 'fade',\n SHOW: 'show'\n };\n var Selector$7 = {\n TITLE: '.popover-header',\n CONTENT: '.popover-body'\n };\n var Event$7 = {\n HIDE: \"hide\" + EVENT_KEY$7,\n HIDDEN: \"hidden\" + EVENT_KEY$7,\n SHOW: \"show\" + EVENT_KEY$7,\n SHOWN: \"shown\" + EVENT_KEY$7,\n INSERTED: \"inserted\" + EVENT_KEY$7,\n CLICK: \"click\" + EVENT_KEY$7,\n FOCUSIN: \"focusin\" + EVENT_KEY$7,\n FOCUSOUT: \"focusout\" + EVENT_KEY$7,\n MOUSEENTER: \"mouseenter\" + EVENT_KEY$7,\n MOUSELEAVE: \"mouseleave\" + EVENT_KEY$7\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var Popover = /*#__PURE__*/\n function (_Tooltip) {\n _inheritsLoose(Popover, _Tooltip);\n function Popover() {\n return _Tooltip.apply(this, arguments) || this;\n }\n var _proto = Popover.prototype;\n\n // Overrides\n _proto.isWithContent = function isWithContent() {\n return this.getTitle() || this._getContent();\n };\n _proto.addAttachmentClass = function addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(CLASS_PREFIX$1 + \"-\" + attachment);\n };\n _proto.getTipElement = function getTipElement() {\n this.tip = this.tip || $(this.config.template)[0];\n return this.tip;\n };\n _proto.setContent = function setContent() {\n var $tip = $(this.getTipElement()); // We use append for html objects to maintain js events\n\n this.setElementContent($tip.find(Selector$7.TITLE), this.getTitle());\n var content = this._getContent();\n if (typeof content === 'function') {\n content = content.call(this.element);\n }\n this.setElementContent($tip.find(Selector$7.CONTENT), content);\n $tip.removeClass(ClassName$7.FADE + \" \" + ClassName$7.SHOW);\n } // Private\n ;\n _proto._getContent = function _getContent() {\n return this.element.getAttribute('data-content') || this.config.content;\n };\n _proto._cleanTipClass = function _cleanTipClass() {\n var $tip = $(this.getTipElement());\n var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1);\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''));\n }\n } // Static\n ;\n Popover._jQueryInterface = function _jQueryInterface(config) {\n return this.each(function () {\n var data = $(this).data(DATA_KEY$7);\n var _config = typeof config === 'object' ? config : null;\n if (!data && /dispose|hide/.test(config)) {\n return;\n }\n if (!data) {\n data = new Popover(this, _config);\n $(this).data(DATA_KEY$7, data);\n }\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(\"No method named \\\"\" + config + \"\\\"\");\n }\n data[config]();\n }\n });\n };\n _createClass(Popover, null, [{\n key: \"VERSION\",\n // Getters\n get: function get() {\n return VERSION$7;\n }\n }, {\n key: \"Default\",\n get: function get() {\n return Default$5;\n }\n }, {\n key: \"NAME\",\n get: function get() {\n return NAME$7;\n }\n }, {\n key: \"DATA_KEY\",\n get: function get() {\n return DATA_KEY$7;\n }\n }, {\n key: \"Event\",\n get: function get() {\n return Event$7;\n }\n }, {\n key: \"EVENT_KEY\",\n get: function get() {\n return EVENT_KEY$7;\n }\n }, {\n key: \"DefaultType\",\n get: function get() {\n return DefaultType$5;\n }\n }]);\n return Popover;\n }(Tooltip);\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME$7] = Popover._jQueryInterface;\n $.fn[NAME$7].Constructor = Popover;\n $.fn[NAME$7].noConflict = function () {\n $.fn[NAME$7] = JQUERY_NO_CONFLICT$7;\n return Popover._jQueryInterface;\n };\n\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n var NAME$8 = 'scrollspy';\n var VERSION$8 = '4.3.1';\n var DATA_KEY$8 = 'bs.scrollspy';\n var EVENT_KEY$8 = \".\" + DATA_KEY$8;\n var DATA_API_KEY$6 = '.data-api';\n var JQUERY_NO_CONFLICT$8 = $.fn[NAME$8];\n var Default$6 = {\n offset: 10,\n method: 'auto',\n target: ''\n };\n var DefaultType$6 = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n };\n var Event$8 = {\n ACTIVATE: \"activate\" + EVENT_KEY$8,\n SCROLL: \"scroll\" + EVENT_KEY$8,\n LOAD_DATA_API: \"load\" + EVENT_KEY$8 + DATA_API_KEY$6\n };\n var ClassName$8 = {\n DROPDOWN_ITEM: 'dropdown-item',\n DROPDOWN_MENU: 'dropdown-menu',\n ACTIVE: 'active'\n };\n var Selector$8 = {\n DATA_SPY: '[data-spy=\"scroll\"]',\n ACTIVE: '.active',\n NAV_LIST_GROUP: '.nav, .list-group',\n NAV_LINKS: '.nav-link',\n NAV_ITEMS: '.nav-item',\n LIST_ITEMS: '.list-group-item',\n DROPDOWN: '.dropdown',\n DROPDOWN_ITEMS: '.dropdown-item',\n DROPDOWN_TOGGLE: '.dropdown-toggle'\n };\n var OffsetMethod = {\n OFFSET: 'offset',\n POSITION: 'position'\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n };\n var ScrollSpy = /*#__PURE__*/\n function () {\n function ScrollSpy(element, config) {\n var _this = this;\n this._element = element;\n this._scrollElement = element.tagName === 'BODY' ? window : element;\n this._config = this._getConfig(config);\n this._selector = this._config.target + \" \" + Selector$8.NAV_LINKS + \",\" + (this._config.target + \" \" + Selector$8.LIST_ITEMS + \",\") + (this._config.target + \" \" + Selector$8.DROPDOWN_ITEMS);\n this._offsets = [];\n this._targets = [];\n this._activeTarget = null;\n this._scrollHeight = 0;\n $(this._scrollElement).on(Event$8.SCROLL, function (event) {\n return _this._process(event);\n });\n this.refresh();\n this._process();\n } // Getters\n\n var _proto = ScrollSpy.prototype;\n\n // Public\n _proto.refresh = function refresh() {\n var _this2 = this;\n var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION;\n var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;\n var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;\n this._offsets = [];\n this._targets = [];\n this._scrollHeight = this._getScrollHeight();\n var targets = [].slice.call(document.querySelectorAll(this._selector));\n targets.map(function (element) {\n var target;\n var targetSelector = Util.getSelectorFromElement(element);\n if (targetSelector) {\n target = document.querySelector(targetSelector);\n }\n if (target) {\n var targetBCR = target.getBoundingClientRect();\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [$(target)[offsetMethod]().top + offsetBase, targetSelector];\n }\n }\n return null;\n }).filter(function (item) {\n return item;\n }).sort(function (a, b) {\n return a[0] - b[0];\n }).forEach(function (item) {\n _this2._offsets.push(item[0]);\n _this2._targets.push(item[1]);\n });\n };\n _proto.dispose = function dispose() {\n $.removeData(this._element, DATA_KEY$8);\n $(this._scrollElement).off(EVENT_KEY$8);\n this._element = null;\n this._scrollElement = null;\n this._config = null;\n this._selector = null;\n this._offsets = null;\n this._targets = null;\n this._activeTarget = null;\n this._scrollHeight = null;\n } // Private\n ;\n _proto._getConfig = function _getConfig(config) {\n config = _objectSpread({}, Default$6, typeof config === 'object' && config ? config : {});\n if (typeof config.target !== 'string') {\n var id = $(config.target).attr('id');\n if (!id) {\n id = Util.getUID(NAME$8);\n $(config.target).attr('id', id);\n }\n config.target = \"#\" + id;\n }\n Util.typeCheckConfig(NAME$8, config, DefaultType$6);\n return config;\n };\n _proto._getScrollTop = function _getScrollTop() {\n return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;\n };\n _proto._getScrollHeight = function _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);\n };\n _proto._getOffsetHeight = function _getOffsetHeight() {\n return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;\n };\n _proto._process = function _process() {\n var scrollTop = this._getScrollTop() + this._config.offset;\n var scrollHeight = this._getScrollHeight();\n var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();\n if (this._scrollHeight !== scrollHeight) {\n this.refresh();\n }\n if (scrollTop >= maxScroll) {\n var target = this._targets[this._targets.length - 1];\n if (this._activeTarget !== target) {\n this._activate(target);\n }\n return;\n }\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null;\n this._clear();\n return;\n }\n var offsetLength = this._offsets.length;\n for (var i = offsetLength; i--;) {\n var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);\n if (isActiveTarget) {\n this._activate(this._targets[i]);\n }\n }\n };\n _proto._activate = function _activate(target) {\n this._activeTarget = target;\n this._clear();\n var queries = this._selector.split(',').map(function (selector) {\n return selector + \"[data-target=\\\"\" + target + \"\\\"],\" + selector + \"[href=\\\"\" + target + \"\\\"]\";\n });\n var $link = $([].slice.call(document.querySelectorAll(queries.join(','))));\n if ($link.hasClass(ClassName$8.DROPDOWN_ITEM)) {\n $link.closest(Selector$8.DROPDOWN).find(Selector$8.DROPDOWN_TOGGLE).addClass(ClassName$8.ACTIVE);\n $link.addClass(ClassName$8.ACTIVE);\n } else {\n // Set triggered link as active\n $link.addClass(ClassName$8.ACTIVE); // Set triggered links parents as active\n // With both