\n\n The above example will apply the following classes to the element when it is\n connected: `transition ease-out duration-300 opacity-0`. Then, on the next frame,\n it will remove the `opacity-0` class and add the `opacity-100` class. Finally,\n it will remove the `transition ease-out duration-300` classes.\n\n For the leave transition, the `opacity-100` class will be removed and the\n `opacity-0` class will be added. Then, the `transition ease-in duration-200`\n classes will be removed.\n\n ## Removing an element\n\n The controller ***monkey-patches** the `remove` method on the element to\n automatically run the leave transition before removing the element from the DOM.\n\n This can be disabled by passing `true` to the `remove` method, like so:\n\n ```js\n element.remove(true) # will not wait for the leave transition\n ```\n\n ## Events\n The controller will dispatch the following events on the element:\n\n - `transition:enter-complete` when the enter transition is complete\n - `transition:leave-complete` when the leave transition is complete\n\n*/\n\nexport default class extends ApplicationController {\n static classes = [ \"enter\", \"enterFrom\", \"enterTo\", \"leave\", \"leaveFrom\", \"leaveTo\" ]\n\n connect() {\n super.connect()\n\n this.attachEventListener(this.element, \"turbo:before-morph-attribute\", (event) => {\n const { detail } = event\n\n // We'd to prevent removing the `data-transition-entered` attribute when a morph if performed\n // as this would cause the element to go back to it's pre-entering state. Since the element\n // has already appeared on the page, just keep it as-is by cancelling it.\n if (detail.attributeName === \"data-transition-entered\") {\n event.preventDefault()\n }\n })\n\n if (!this.element.getAttribute(\"data-transition-entered\")) {\n this.enter()\n }\n\n this.patchRemove()\n }\n\n disconnect() {\n super.disconnect()\n\n this.restoreRemove()\n }\n\n enter = async () => {\n await this.runTransition(\"enter\")\n this.dispatchCompletion(\"enter\")\n\n this.element.setAttribute(\"data-transition-entered\", true)\n }\n\n leave = async () => {\n await this.runTransition(\"leave\")\n this.dispatchCompletion(\"leave\")\n\n this.element.setAttribute(\"data-transition-entered\", null)\n }\n\n // Private\n\n patchRemove = () => {\n this.element.originalRemove = this.element.remove\n this.element.remove = async (skipTransition) => {\n if (!skipTransition) {\n await this.leave()\n }\n this.element.originalRemove()\n }\n }\n\n restoreRemove = () => {\n this.element.remove = this.element.originalRemove\n delete this.element.originalRemove\n }\n\n runTransition = async (direction) => {\n const classes = this.getTransitionClasses(`${direction}`)\n const fromClasses = this.getTransitionClasses(`${direction}From`)\n const toClasses = this.getTransitionClasses(`${direction}To`)\n\n this.element.classList.add(...classes)\n this.element.classList.add(...fromClasses)\n\n await nextFrame();\n\n this.element.classList.remove(...fromClasses)\n this.element.classList.add(...toClasses)\n\n await transitionComplete(this.element)\n\n this.element.classList.remove(...toClasses)\n this.element.classList.remove(...classes)\n }\n\n getTransitionClasses = (name) => {\n if (!this[`has${capitalize(name)}Class`]) { return [] }\n\n return this[`${name}Classes`]\n }\n\n dispatchCompletion = (direction) => {\n const eventName = `transition:${direction}-complete`\n const event = new CustomEvent(eventName, { bubbles: true })\n this.element.dispatchEvent(event)\n }\n}\n\nfunction capitalize(value) {\n return value.charAt(0).toUpperCase() + value.slice(1)\n}\n","import ApplicationController from \"./application_controller\"\n\nexport default class extends ApplicationController {\n clearCache () {\n Turbo.cache.clear()\n }\n\n visit ({ params: { url, options } }) {\n Turbo.visit(url, options)\n }\n\n refresh () {\n Turbo.session.refresh(document.baseURI)\n }\n}\n","export default function has(object, key) {\n return Object.prototype.hasOwnProperty.call(object, key);\n}","function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError(\"attempted to use private field on non-instance\"); } return receiver; }\n\nvar id = 0;\n\nfunction _classPrivateFieldLooseKey(name) { return \"__private_\" + id++ + \"_\" + name; }\n\nimport has from './hasProperty.js';\n\nfunction insertReplacement(source, rx, replacement) {\n const newParts = [];\n source.forEach(chunk => {\n // When the source contains multiple placeholders for interpolation,\n // we should ignore chunks that are not strings, because those\n // can be JSX objects and will be otherwise incorrectly turned into strings.\n // Without this condition we’d get this: [object Object] hello [object Object] my