diff --git a/.containers.example.yml b/.containers.example.yml new file mode 100644 index 00000000..aeb02458 --- /dev/null +++ b/.containers.example.yml @@ -0,0 +1,13 @@ +--- +organization: + name: turbo_boost + +app: + name: turbo_boost-commands + directory: /path/to/turbo_boost-commands + +docker: + directory: /path/to/turbo_boost-commands + compose_files: + - /path/to/turbo_boost-commands/docker-compose.yml + default_service: web diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml index 6f8deda5..16d14757 100644 --- a/.github/workflows/prettier.yml +++ b/.github/workflows/prettier.yml @@ -14,15 +14,19 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + + - name: Enable Corepack + run: corepack enable + - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: version: '20.x' cache: 'yarn' - name: Yarn install - run: yarn install --frozen-lockfile + run: 'yarn install --frozen-lockfile' - name: Run Prettier - run: yarn run prettier --check package.json prettier.config.js bin/build.mjs app/javascript/**/*.js test/dummy/app/javascript/**/*.js test/dummy/app/assets/stylesheets/**/*.css test/dummy/app/views/**/*.css + run: 'yarn run prettier --check --fail-on-errors .' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 90db938f..5b0dff03 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,14 +18,18 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Set up Ruby ${{ matrix.ruby-version }} uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true + - name: Enable Corepack + run: corepack enable + - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '20.x' cache: 'yarn' diff --git a/.gitignore b/.gitignore index 3d63ae9d..d5e4e428 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ *.gem *.key +*.metafile.json .containers.yml +.yarn /.bundle/ /doc/ /log/*.log diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..f4fdd080 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +*.md +*.yml +builds diff --git a/.standard.yml b/.standard.yml index 96a76071..cbdebc4d 100644 --- a/.standard.yml +++ b/.standard.yml @@ -4,7 +4,6 @@ parallel: true ignore: - test/dummy/bin/* - - test/dummy/config/initializers/inspect_helpers.rb - test/dummy/db/schema.rb Lint/RescueException: diff --git a/Dockerfile b/Dockerfile index 5c4a53c7..b2fcc5eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,8 @@ tzdata RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - RUN apt-get -y --no-install-recommends install nodejs && \ -npm install -g npm@latest yarn +corepack enable && \ +yarn set version stable RUN apt-get clean RUN gem update --system diff --git a/README.md b/README.md index a8a05a08..997d3aff 100644 --- a/README.md +++ b/README.md @@ -169,19 +169,6 @@ rails app:template LOCATION='https://railsbytes.com/script/xkjsbB' +import '@turbo-boost/commands' ``` -3. Add TurboBoost to your Rails app - - ```diff - # app/views/layouts/application.html.erb - - - + <%= turbo_boost.meta_tag %> - - - - - ``` - ## Usage This example illustrates how to use TurboBoost Commands to manage upvotes on a Post. @@ -556,14 +543,23 @@ fly deploy ## Releasing -1. Run `yarn` and `bundle` to pick up the latest +> [!TIP] +> Run these commands on the host machine _(i.e. not inside the dev container)_ + +> [!TIP] +> Ensure you're using the latest stable version of `yarn` +> `corepack enable && yarn set version stable` + +1. Run `yarn upgrade-interactive` and `bundle update` to pick up the latest dependencies 1. Bump version number at `lib/turbo_boost-streams/version.rb`. Pre-release versions use `.preN` 1. Bump version number at `package.json` _(make sure it matches)_. Pre-release versions use `-preN` -1. Run `yarn build` and `rake build` -1. Commit and push changes to GitHub +1. Run `bin/standardize` +1. Run `rake build` +1. Run `yarn build` +1. Commit and push any changes to GitHub 1. Run `rake release` -1. Run `yarn publish --no-git-tag-version --access public --new-version X.X.X` _(use same version number)_ -1. Create a new release on GitHub ([here](https://github.com/hopsoft/turbo_boost-streams/releases)) and generate the changelog for the stable release for it +1. Run `yarn npm publish --access public` +1. Create a new release on GitHub ([here](https://github.com/hopsoft/turbo_boost-commands/releases)) and generate the changelog for the stable release for it ## About TurboBoost diff --git a/app/assets/builds/@turbo-boost/commands.js b/app/assets/builds/@turbo-boost/commands.js index 90b5a41f..5006462a 100644 --- a/app/assets/builds/@turbo-boost/commands.js +++ b/app/assets/builds/@turbo-boost/commands.js @@ -1,2 +1,2 @@ -var Z=Object.defineProperty,ee=Object.defineProperties;var te=Object.getOwnPropertyDescriptors;var X=Object.getOwnPropertySymbols;var re=Object.prototype.hasOwnProperty,oe=Object.prototype.propertyIsEnumerable;var _=(e,t,r)=>t in e?Z(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,s=(e,t)=>{for(var r in t||(t={}))re.call(t,r)&&_(e,r,t[r]);if(X)for(var r of X(t))oe.call(t,r)&&_(e,r,t[r]);return e},u=(e,t)=>ee(e,te(t));var O=class{get element(){return document.querySelector('meta[name="turbo-boost"]')}get token(){return this.element.getAttribute("content")}get busy(){return this.element.dataset.busy==="true"}set busy(t=!1){return this.element.dataset.busy=!!t}get state(){return this.element.dataset.state}get signedState(){return this.element.dataset.signedState}},i=new O;var a={start:"turbo-boost:command:start",success:"turbo-boost:command:success",finish:"turbo-boost:command:finish",abort:"turbo-boost:command:abort",clientError:"turbo-boost:command:client-error",serverError:"turbo-boost:command:server-error"},f={stateLoad:"turbo-boost:state:load",stateChange:"turbo-boost:state:change"},l=s(s({},a),f);function d(e,t,r={}){return new Promise(o=>{r=r||{},r.detail=r.detail||{},t=t||document;let n=new CustomEvent(e,u(s({},r),{bubbles:!0}));t.dispatchEvent(n),o(n)})}var B;function A(e,t=null){if(!e||typeof e!="object")return e;let r=new Proxy(e,{deleteProperty(o,n){return delete o[n],d(f.stateChange,i.element,{detail:{state:B}}),!0},set(o,n,c,C){return o[n]=A(c,this),d(f.stateChange,i.element,{detail:{state:B}}),!0}});if(Array.isArray(e))e.forEach((o,n)=>e[n]=A(o,r));else if(typeof e=="object")for(let[o,n]of Object.entries(e))e[o]=A(n,r);return t||(B=r),r}var F=A;var T,y,D,M;function N(){if(!i.element)return h();let e=JSON.parse(i.element.dataset.state);T=s({},e),y=F(e),D={},setTimeout(()=>d(f.stateLoad,i.element,{detail:{state:y}}))}function h(){clearTimeout(M),M=setTimeout(N,10)}T||N();addEventListener("DOMContentLoaded",h);addEventListener("load",h);addEventListener("turbo:load",h);addEventListener("turbo:frame-load",h);addEventListener(a.success,h);addEventListener(f.stateChange,e=>{for(let[t,r]of Object.entries(y))T[t]!==r&&(D[t]=r)});var k={events:f,get initial(){return s({},T)},get current(){return y},get changed(){return s({},D)}};function ne(e){let t="=0&&n>=0){let c=e.slice(e.indexOf(">",o)+1,n);document.documentElement.innerHTML=c}}function se(e){document.body.insertAdjacentHTML("beforeend",e)}var v={append:se,replaceDocument:ne};var L={};function ae(e){L[e.id]=e}function ie(e){delete L[e]}var w={add:ae,remove:ie,get commands(){return[...Object.values(L)]},get length(){return Object.keys(L).length}};function j(e){e.detail.endedAt=Date.now(),e.detail.milliseconds=e.detail.endedAt-e.detail.startedAt,setTimeout(()=>d(a.finish,e.target,{detail:e.detail}),25)}addEventListener(a.serverError,j);addEventListener(a.success,j);addEventListener(a.finish,e=>w.remove(e.detail.id),!0);var E={events:a};var P={};addEventListener("turbo:before-fetch-request",e=>{let t=e.target.closest("turbo-frame"),{fetchOptions:r}=e.detail;if(i.busy){let o=["text/vnd.turbo-boost.html",r.headers.Accept];o=o.filter(n=>n&&n.trim().length>0).join(", "),r.headers.Accept=o}});addEventListener("turbo:before-fetch-response",e=>{let t=e.target.closest("turbo-frame"),{fetchResponse:r}=e.detail;if(t&&(P[t.id]=t.src),r.header("TurboBoost")){if(r.statusCode<200||r.statusCode>399){let o=`Server returned a ${r.statusCode} status code! TurboBoost Commands require 2XX-3XX status codes.`;d(E.events.clientError,document,{detail:u(s({},e.detail),{error:o})},!0)}r.header("TurboBoost")==="Append"&&(e.preventDefault(),r.responseText.then(o=>v.append(o)))}});addEventListener("turbo:frame-load",e=>{let t=e.target.closest("turbo-frame");t.dataset.turboBoostSrc=P[t.id]||t.src||t.dataset.turboBoostSrc,delete P[t.id]});var de={frameAttribute:"data-turbo-frame",methodAttribute:"data-turbo-method",commandAttribute:"data-turbo-command",confirmAttribute:"data-turbo-confirm"},m=s({},de);var W={method:e=>Promise.resolve(confirm(e))},me=e=>e.detail.driver==="method",ue=e=>{if(e.detail.driver!=="form")return!1;let t=e.target,r=t.closest("turbo-frame"),o=t.closest(`[${m.frameAttribute}]`);return!!(r||o)},ce=e=>me(e)||ue(e);document.addEventListener(a.start,async e=>{let t=e.target.getAttribute(m.confirmAttribute);if(!t||(e.detail.confirmation=!0,ce(e)))return;await W.method(t)||e.preventDefault()});var J=W;var b=[],R;function fe(e,t){let r=b.find(o=>o.name===e);return r&&b.splice(b.indexOf(r),1),b=[{name:e,selectors:t},...b],document.removeEventListener(e,R,!0),document.addEventListener(e,R,!0),s({},b.find(o=>o.name===e))}function le(e){return b.find(t=>t.selectors.find(r=>Array.from(document.querySelectorAll(r)).find(o=>o===e)))}function be(e,t){let r=le(t);return r&&r.name===e}var p={register:fe,isRegisteredForElement:be,get events(){return[...b]},set handler(e){R=e}};function pe(e){return e.closest(`[${m.commandAttribute}]`)}function he(e){return e.closest("turbo-frame[src]")||e.closest("turbo-frame[data-turbo-frame-src]")||e.closest("turbo-frame")}function ve(e,t={}){if(e.tagName.toLowerCase()!=="select")return t.value=e.value||null;if(!e.multiple)return t.value=e.options[e.selectedIndex].value;t.values=Array.from(e.options).reduce((r,o)=>(o.selected&&r.push(o.value),r),[])}function ge(e){let t=Array.from(e.attributes).reduce((r,o)=>{let n=o.value;return r[o.name]=n,r},{});return t.tag=e.tagName,t.checked=!!e.checked,t.disabled=!!e.disabled,ve(e,t),delete t.class,delete t.action,delete t.href,delete t[m.commandAttribute],delete t[m.frameAttribute],t}var x={buildAttributePayload:ge,findClosestCommand:pe,findClosestFrameWithSource:he};function Ee(e,t={},r={}){t.token=i.token;let o=e.querySelector('input[name="turbo_boost_command"]')||document.createElement("input");o.type="hidden",o.name="turbo_boost_command",o.value=JSON.stringify(t),e.appendChild(o)}var U={invokeCommand:Ee};function xe(e,t={}){let r=document.createElement("a");r.href=e;let o=new URL(r);return o.searchParams.set("tbc",JSON.stringify(t)),o}var g={build:xe};function Ce(e,t){let r=t.src;t=s({},t),delete t.src,e.src=g.build(r,t)}var $={invokeCommand:Ce};function Ae(e,t={}){let r=t.src;t=s({},t),delete t.src,delete t.href,e.setAttribute("href",g.build(r,t))}var V={invokeCommand:Ae};function ye(e){let t=e.target;d(E.events.abort,document,{detail:u(s({},e.detail),{xhr:t})})}function H(e){let t=e.target;(t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html"))&&v.append(t.responseText);let o=`Server returned a ${t.status} status code! TurboBoost Commands require 2XX-3XX status codes.`;d(E.events.clientError,document,{detail:u(s({},e.detail),{error:o,xhr:t})},!0)}function Te(e){let t=e.target;if(t.status<200||t.status>399)return H(e);let r=t.responseText;t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html")?v.append(t.responseText):v.replaceDocument(t.responseText)}function ke(e){let t=e.src;e=s({},e),delete e.src;try{let r=new XMLHttpRequest;r.open("GET",g.build(t,e),!0),r.setRequestHeader("Accept","text/vnd.turbo-boost.html, text/html, application/xhtml+xml"),r.addEventListener("abort",ye),r.addEventListener("error",H),r.addEventListener("load",Te),r.send()}catch(r){let o=`Unexpected error sending HTTP request! ${r.message}`;H(r,{detail:{message:o}})}}var G={invokeCommand:ke};function q(e,t){return t=t||{dataset:{}},e.href||t.src||t.dataset.turboBoostSrc||location.href}function Le(e){let t=x.findClosestFrameWithSource(e),{turboFrame:r,turboMethod:o}=e.dataset;return e.tagName.toLowerCase()==="form"?{name:"form",reason:"Element is a form.",frame:t,src:e.action,invokeCommand:U.invokeCommand}:o&&o.length>0?{name:"method",reason:"Element defines data-turbo-method.",frame:t,src:e.href,invokeCommand:V.invokeCommand}:r&&r!=="_self"?(t=document.getElementById(r),{name:"frame",reason:"element targets a frame that is not _self",frame:t,src:q(e,t),invokeCommand:$.invokeCommand}):(!r||r==="_self")&&t?{name:"frame",reason:"element does NOT target a frame or targets _self and is contained by a frame",frame:t,src:q(e,t),invokeCommand:$.invokeCommand}:{name:"window",reason:"element matches one or more of the following conditions (targets _top, does NOT target a frame, is NOT contained by a frame)",frame:null,src:q(e),invokeCommand:G.invokeCommand}}var I={find:Le};var S="unknown",z={debug:Object.values(l),info:Object.values(l),warn:[l.abort,l.clientError,l.serverError],error:[l.clientError,l.serverError],unknown:[]};Object.values(l).forEach(e=>{addEventListener(e,t=>{if(z[S].includes(t.type)){let{target:r,detail:o}=t;console[S](t.type,{target:r,detail:o})}})});var K={get level(){return S},set level(e){return Object.keys(z).includes(e)||(e="unknown"),S=e}};function we(){return("10000000-1000-4000-8000"+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}var Q={v4:we};function Y(e,t){return{id:e,name:t.getAttribute(m.commandAttribute),elementId:t.id.length>0?t.id:null,elementAttributes:x.buildAttributePayload(t),startedAt:Date.now(),token:i.token,signedState:i.signedState,state:k.changed}}async function Se(e){let t,r={};try{if(t=x.findClosestCommand(e.target),!t||!p.isRegisteredForElement(e.type,t))return;let o=`turbo-command-${Q.v4()}`,n=I.find(t),c=u(s({},Y(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),C=await d(a.start,t,{cancelable:!0,detail:c});if(C.defaultPrevented||C.detail.confirmation&&e.defaultPrevented)return d(a.abort,t,{detail:{message:`An event handler for '${a.start}' prevented default behavior and blocked command invocation!`,source:C}});switch(n=I.find(t),c=u(s({},Y(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),w.add(c),["frame","window"].includes(n.name)&&e.preventDefault(),i.busy=!0,setTimeout(()=>i.busy=!1,10),n.name){case"method":return n.invokeCommand(t,c);case"form":return n.invokeCommand(t,c,e);case"frame":return n.invokeCommand(n.frame,c);case"window":return n.invokeCommand(c)}}catch(o){d(a.clientError,t,{detail:u(s({},r),{error:o})})}}self.TurboBoost=self.TurboBoost||{};self.TurboBoost=u(s({},self.TurboBoost),{stateEvents:f,get state(){return k.current},get stateChanges(){return k.changed}});self.TurboBoost.Commands||(p.handler=Se,p.register("click",[`[${m.commandAttribute}]`]),p.register("submit",[`form[${m.commandAttribute}]`]),p.register("change",[`input[${m.commandAttribute}]`,`select[${m.commandAttribute}]`,`textarea[${m.commandAttribute}]`]),self.TurboBoost.Commands={confirmation:J,logger:K,schema:m,events:a,registerEventDelegate:p.register,get eventDelegates(){return p.events}});var er=self.TurboBoost.Commands;export{er as default}; +var K=Object.defineProperty,Q=Object.defineProperties;var Y=Object.getOwnPropertyDescriptors;var I=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var X=(e,t,r)=>t in e?K(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,s=(e,t)=>{for(var r in t||(t={}))Z.call(t,r)&&X(e,r,t[r]);if(I)for(var r of I(t))ee.call(t,r)&&X(e,r,t[r]);return e},c=(e,t)=>Q(e,Y(t));var d={start:"turbo-boost:command:start",success:"turbo-boost:command:success",finish:"turbo-boost:command:finish",abort:"turbo-boost:command:abort",clientError:"turbo-boost:command:client-error",serverError:"turbo-boost:command:server-error"},f={stateLoad:"turbo-boost:state:load",stateChange:"turbo-boost:state:change"},u=s(s({},d),f);function a(e,t,r={}){return new Promise(o=>{r=r||{},r.detail=r.detail||{},t=t||document;let n=new CustomEvent(e,c(s({},r),{bubbles:!0}));t.dispatchEvent(n),o(n)})}var L;function C(e,t=null){if(!e||typeof e!="object")return e;let r=new Proxy(e,{deleteProperty(o,n){return delete o[n],a(f.stateChange,document,{detail:{state:L}}),!0},set(o,n,i,b){return o[n]=C(i,this),a(f.stateChange,document,{detail:{state:L}}),!0}});if(Array.isArray(e))e.forEach((o,n)=>e[n]=C(o,r));else if(typeof e=="object")for(let[o,n]of Object.entries(e))e[o]=C(n,r);return t||(L=r),r}var _=C;var S,A,O,q;function te(e,t){let r=JSON.parse(e);S=s({},r),q=t,A=_(r),O={},setTimeout(()=>a(f.stateLoad,document,{detail:{state:A}}))}addEventListener(f.stateChange,e=>{for(let[t,r]of Object.entries(A))S[t]!==r&&(O[t]=r)});var y={initialize:te,events:f,get initial(){return S},get current(){return A},get changed(){return O},get signed(){return q}};function re(e){let t="=0&&n>=0){let i=e.slice(e.indexOf(">",o)+1,n);document.documentElement.innerHTML=i}}function oe(e){document.body.insertAdjacentHTML("beforeend",e)}var h={append:oe,replaceDocument:re};var T={};function ne(e){T[e.id]=e}function se(e){delete T[e]}var k={add:ne,remove:se,get commands(){return[...Object.values(T)]},get length(){return Object.keys(T).length}};function F(e){e.detail.endedAt=Date.now(),e.detail.milliseconds=e.detail.endedAt-e.detail.startedAt,setTimeout(()=>a(d.finish,e.target,{detail:e.detail}),25)}addEventListener(d.serverError,F);addEventListener(d.success,F);addEventListener(d.finish,e=>k.remove(e.detail.id),!0);var g={events:d};var B={};addEventListener("turbo:before-fetch-request",e=>{var o,n;let t=e.target.closest("turbo-frame"),{fetchOptions:r}=e.detail;if((n=(o=self.TurboBoost)==null?void 0:o.Commands)!=null&&n.busy){let i=["text/vnd.turbo-boost.html",r.headers.Accept];i=i.filter(b=>b&&b.trim().length>0).join(", "),r.headers.Accept=i}});addEventListener("turbo:before-fetch-response",e=>{let t=e.target.closest("turbo-frame"),{fetchResponse:r}=e.detail;if(t&&(B[t.id]=t.src),r.header("TurboBoost")){if(r.statusCode<200||r.statusCode>399){let o=`Server returned a ${r.statusCode} status code! TurboBoost Commands require 2XX-3XX status codes.`;a(g.events.clientError,document,{detail:c(s({},e.detail),{error:o})},!0)}r.header("TurboBoost")==="Append"&&(e.preventDefault(),r.responseText.then(o=>h.append(o)))}});addEventListener("turbo:frame-load",e=>{let t=e.target.closest("turbo-frame");t.dataset.turboBoostSrc=B[t.id]||t.src||t.dataset.turboBoostSrc,delete B[t.id]});var ae={frameAttribute:"data-turbo-frame",methodAttribute:"data-turbo-method",commandAttribute:"data-turbo-command",confirmAttribute:"data-turbo-confirm"},m=s({},ae);var M={method:e=>Promise.resolve(confirm(e))},ie=e=>e.detail.driver==="method",de=e=>{if(e.detail.driver!=="form")return!1;let t=e.target,r=t.closest("turbo-frame"),o=t.closest(`[${m.frameAttribute}]`);return!!(r||o)},me=e=>ie(e)||de(e);document.addEventListener(d.start,async e=>{let t=e.target.getAttribute(m.confirmAttribute);if(!t||(e.detail.confirmation=!0,me(e)))return;await M.method(t)||e.preventDefault()});var N=M;var l=[],D;function ce(e,t){let r=l.find(o=>o.name===e);return r&&l.splice(l.indexOf(r),1),l=[{name:e,selectors:t},...l],document.removeEventListener(e,D,!0),document.addEventListener(e,D,!0),s({},l.find(o=>o.name===e))}function ue(e){return l.find(t=>t.selectors.find(r=>Array.from(document.querySelectorAll(r)).find(o=>o===e)))}function fe(e,t){let r=ue(t);return r&&r.name===e}var p={register:ce,isRegisteredForElement:fe,get events(){return[...l]},set handler(e){D=e}};function le(e){return e.closest(`[${m.commandAttribute}]`)}function pe(e){return e.closest("turbo-frame[src]")||e.closest("turbo-frame[data-turbo-frame-src]")||e.closest("turbo-frame")}function be(e,t={}){if(e.tagName.toLowerCase()!=="select")return t.value=e.value||null;if(!e.multiple)return t.value=e.options[e.selectedIndex].value;t.values=Array.from(e.options).reduce((r,o)=>(o.selected&&r.push(o.value),r),[])}function he(e){let t=Array.from(e.attributes).reduce((r,o)=>{let n=o.value;return r[o.name]=n,r},{});return t.tag=e.tagName,t.checked=!!e.checked,t.disabled=!!e.disabled,be(e,t),delete t.class,delete t.action,delete t.href,delete t[m.commandAttribute],delete t[m.frameAttribute],t}var E={buildAttributePayload:he,findClosestCommand:le,findClosestFrameWithSource:pe};function ve(e,t={},r={}){let o=e.querySelector('input[name="turbo_boost_command"]')||document.createElement("input");o.type="hidden",o.name="turbo_boost_command",o.value=JSON.stringify(t),e.appendChild(o)}var j={invokeCommand:ve};function ge(e,t={}){let r=document.createElement("a");r.href=e;let o=new URL(r);return o.searchParams.set("tbc",JSON.stringify(t)),o}var v={build:ge};function Ee(e,t){let r=t.src;t=s({},t),delete t.src,e.src=v.build(r,t)}var P={invokeCommand:Ee};function xe(e,t={}){let r=t.src;t=s({},t),delete t.src,delete t.href,e.setAttribute("href",v.build(r,t))}var W={invokeCommand:xe};function Ce(e){let t=e.target;a(g.events.abort,document,{detail:c(s({},e.detail),{xhr:t})})}function R(e){let t=e.target;(t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html"))&&h.append(t.responseText);let o=`Server returned a ${t.status} status code! TurboBoost Commands require 2XX-3XX status codes.`;a(g.events.clientError,document,{detail:c(s({},e.detail),{error:o,xhr:t})},!0)}function Ae(e){let t=e.target;if(t.status<200||t.status>399)return R(e);let r=t.responseText;t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html")?h.append(t.responseText):h.replaceDocument(t.responseText)}function ye(e){let t=e.src;e=s({},e),delete e.src;try{let r=new XMLHttpRequest;r.open("GET",v.build(t,e),!0),r.setRequestHeader("Accept","text/vnd.turbo-boost.html, text/html, application/xhtml+xml"),r.addEventListener("abort",Ce),r.addEventListener("error",R),r.addEventListener("load",Ae),r.send()}catch(r){let o=`Unexpected error sending HTTP request! ${r.message}`;R(r,{detail:{message:o}})}}var J={invokeCommand:ye};function $(e,t){return t=t||{dataset:{}},e.href||t.src||t.dataset.turboBoostSrc||location.href}function Te(e){let t=E.findClosestFrameWithSource(e),{turboFrame:r,turboMethod:o}=e.dataset;return e.tagName.toLowerCase()==="form"?{name:"form",reason:"Element is a form.",frame:t,src:e.action,invokeCommand:j.invokeCommand}:o&&o.length>0?{name:"method",reason:"Element defines data-turbo-method.",frame:t,src:e.href,invokeCommand:W.invokeCommand}:r&&r!=="_self"?(t=document.getElementById(r),{name:"frame",reason:"element targets a frame that is not _self",frame:t,src:$(e,t),invokeCommand:P.invokeCommand}):(!r||r==="_self")&&t?{name:"frame",reason:"element does NOT target a frame or targets _self and is contained by a frame",frame:t,src:$(e,t),invokeCommand:P.invokeCommand}:{name:"window",reason:"element matches one or more of the following conditions (targets _top, does NOT target a frame, is NOT contained by a frame)",frame:null,src:$(e),invokeCommand:J.invokeCommand}}var H={find:Te};var w="unknown",U={debug:Object.values(u),info:Object.values(u),warn:[u.abort,u.clientError,u.serverError],error:[u.clientError,u.serverError],unknown:[]};Object.values(u).forEach(e=>{addEventListener(e,t=>{if(U[w].includes(t.type)){let{target:r,detail:o}=t;console[w](t.type,{target:r,detail:o})}})});var V={get level(){return w},set level(e){return Object.keys(U).includes(e)||(e="unknown"),w=e}};function ke(){return("10000000-1000-4000-8000"+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}var z={v4:ke};var we=self.TurboBoost||{},x={busy:!1,confirmation:N,logger:V,schema:m,events:d,registerEventDelegate:p.register,get eventDelegates(){return p.events}};function G(e,t){return{id:e,name:t.getAttribute(m.commandAttribute),elementId:t.id.length>0?t.id:null,elementAttributes:E.buildAttributePayload(t),startedAt:Date.now(),token:x.token,signedState:y.signed,clientState:y.changed}}async function Le(e){let t,r={};try{if(t=E.findClosestCommand(e.target),!t||!p.isRegisteredForElement(e.type,t))return;let o=`turbo-command-${z.v4()}`,n=H.find(t),i=c(s({},G(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),b=await a(d.start,t,{cancelable:!0,detail:i});if(b.defaultPrevented||b.detail.confirmation&&e.defaultPrevented)return a(d.abort,t,{detail:{message:`An event handler for '${d.start}' prevented default behavior and blocked command invocation!`,source:b}});switch(n=H.find(t),i=c(s({},G(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),k.add(i),["frame","window"].includes(n.name)&&e.preventDefault(),x.busy=!0,setTimeout(()=>x.busy=!1,10),n.name){case"method":return n.invokeCommand(t,i);case"form":return n.invokeCommand(t,i,e);case"frame":return n.invokeCommand(n.frame,i);case"window":return n.invokeCommand(i)}}catch(o){a(d.clientError,t,{detail:c(s({},r),{error:o})})}}self.TurboBoost=s({},we);self.TurboBoost.Commands||(p.handler=Le,p.register("click",[`[${m.commandAttribute}]`]),p.register("submit",[`form[${m.commandAttribute}]`]),p.register("change",[`input[${m.commandAttribute}]`,`select[${m.commandAttribute}]`,`textarea[${m.commandAttribute}]`]),self.TurboBoost.Commands=x,self.TurboBoost.State=y);var Ut=x;export{Ut as default}; //# sourceMappingURL=commands.js.map diff --git a/app/assets/builds/@turbo-boost/commands.js.map b/app/assets/builds/@turbo-boost/commands.js.map index 7b37482b..2cc2ff98 100644 --- a/app/assets/builds/@turbo-boost/commands.js.map +++ b/app/assets/builds/@turbo-boost/commands.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../../../javascript/meta.js", "../../../javascript/events.js", "../../../javascript/state/observable.js", "../../../javascript/state/index.js", "../../../javascript/renderer.js", "../../../javascript/activity.js", "../../../javascript/lifecycle.js", "../../../javascript/turbo.js", "../../../javascript/schema.js", "../../../javascript/confirmation.js", "../../../javascript/delegates.js", "../../../javascript/elements.js", "../../../javascript/drivers/form.js", "../../../javascript/urls.js", "../../../javascript/drivers/frame.js", "../../../javascript/drivers/method.js", "../../../javascript/drivers/window.js", "../../../javascript/drivers/index.js", "../../../javascript/logger.js", "../../../javascript/uuids.js", "../../../javascript/index.js"], - "sourcesContent": ["class Meta {\n get element() {\n return document.querySelector('meta[name=\"turbo-boost\"]')\n }\n\n // token that can be used to verify the authenticity of a command\n get token() {\n return this.element.getAttribute('content')\n }\n\n // indicates if a command is active\n get busy() {\n return this.element.dataset.busy === 'true'\n }\n\n set busy(value = false) {\n return (this.element.dataset.busy = !!value)\n }\n\n // mutable state representation for use on the client\n get state() {\n return this.element.dataset.state\n }\n\n // signed and immutable server state determined by the last command\n get signedState() {\n return this.element.dataset.signedState\n }\n}\n\nexport default new Meta()\n", "export const commandEvents = {\n start: 'turbo-boost:command:start',\n success: 'turbo-boost:command:success',\n finish: 'turbo-boost:command:finish',\n abort: 'turbo-boost:command:abort',\n clientError: 'turbo-boost:command:client-error',\n serverError: 'turbo-boost:command:server-error'\n}\n\nexport const stateEvents = {\n stateLoad: 'turbo-boost:state:load',\n stateChange: 'turbo-boost:state:change'\n}\n\nexport const allEvents = { ...commandEvents, ...stateEvents }\n\nexport function dispatch(name, target, options = {}) {\n return new Promise(resolve => {\n options = options || {}\n options.detail = options.detail || {}\n target = target || document\n const evt = new CustomEvent(name, { ...options, bubbles: true })\n target.dispatchEvent(evt)\n resolve(evt)\n })\n}\n", "import meta from '../meta'\nimport { dispatch, stateEvents as events } from '../events'\n\nlet head\n\nfunction observable(object, parent = null) {\n if (!object || typeof object !== 'object') return object\n\n const proxy = new Proxy(object, {\n deleteProperty(target, key) {\n delete target[key]\n dispatch(events.stateChange, meta.element, { detail: { state: head } })\n return true\n },\n\n set(target, key, value, receiver) {\n target[key] = observable(value, this)\n dispatch(events.stateChange, meta.element, { detail: { state: head } })\n return true\n }\n })\n\n if (Array.isArray(object)) {\n object.forEach((value, index) => (object[index] = observable(value, proxy)))\n } else if (typeof object === 'object') {\n for (const [key, value] of Object.entries(object)) object[key] = observable(value, proxy)\n }\n\n if (!parent) head = proxy\n return proxy\n}\n\nexport default observable\n", "import meta from '../meta'\nimport observable from './observable'\nimport { dispatch, commandEvents, stateEvents } from '../events'\n\nlet initialState, currentState, changedState\nlet loadStateTimeout\n\nfunction loadState() {\n if (!meta.element) return loadStateLater()\n const json = JSON.parse(meta.element.dataset.state)\n initialState = { ...json }\n currentState = observable(json)\n changedState = {}\n setTimeout(() =>\n dispatch(stateEvents.stateLoad, meta.element, {\n detail: { state: currentState }\n })\n )\n}\n\nfunction loadStateLater() {\n clearTimeout(loadStateTimeout)\n loadStateTimeout = setTimeout(loadState, 10)\n}\n\nif (!initialState) loadState()\n\naddEventListener('DOMContentLoaded', loadStateLater)\naddEventListener('load', loadStateLater)\naddEventListener('turbo:load', loadStateLater)\naddEventListener('turbo:frame-load', loadStateLater)\naddEventListener(commandEvents.success, loadStateLater)\n\naddEventListener(stateEvents.stateChange, event => {\n for (const [key, value] of Object.entries(currentState))\n if (initialState[key] !== value) changedState[key] = value\n})\n\nexport default {\n events: stateEvents,\n\n get initial() {\n return { ...initialState }\n },\n\n get current() {\n return currentState\n },\n\n get changed() {\n return { ...changedState }\n }\n}\n", "function replaceDocument(content) {\n const head = '= 0 && tailIndex >= 0) {\n const html = content.slice(content.indexOf('>', headIndex) + 1, tailIndex)\n document.documentElement.innerHTML = html\n }\n}\n\nfunction append(content) {\n document.body.insertAdjacentHTML('beforeend', content)\n}\n\nexport default { append, replaceDocument }\n", "const active = {}\n\nfunction add(payload) {\n active[payload.id] = payload\n}\n\nfunction remove(id) {\n delete active[id]\n}\n\nexport default {\n add,\n remove,\n get commands() {\n return [...Object.values(active)]\n },\n get length() {\n return Object.keys(active).length\n }\n}\n", "import activity from './activity'\nimport { dispatch, commandEvents } from './events'\n\nfunction finish(event) {\n event.detail.endedAt = Date.now()\n event.detail.milliseconds = event.detail.endedAt - event.detail.startedAt\n setTimeout(() => dispatch(commandEvents.finish, event.target, { detail: event.detail }), 25)\n}\n\n// TODO: forward source event to finish (error or success)\naddEventListener(commandEvents.serverError, finish)\naddEventListener(commandEvents.success, finish)\naddEventListener(commandEvents.finish, event => activity.remove(event.detail.id), true)\n\nexport default { events: commandEvents }\n", "import meta from './meta'\nimport state from './state'\nimport renderer from './renderer'\nimport { dispatch } from './events'\nimport lifecycle from './lifecycle'\n\nconst frameSources = {}\n\n// fires before making a turbo HTTP request\naddEventListener('turbo:before-fetch-request', event => {\n const frame = event.target.closest('turbo-frame')\n const { fetchOptions } = event.detail\n\n // command invoked and busy\n if (meta.busy) {\n let acceptHeaders = ['text/vnd.turbo-boost.html', fetchOptions.headers['Accept']]\n acceptHeaders = acceptHeaders.filter(entry => entry && entry.trim().length > 0).join(', ')\n fetchOptions.headers['Accept'] = acceptHeaders\n }\n})\n\n// fires after receiving a turbo HTTP response\naddEventListener('turbo:before-fetch-response', event => {\n const frame = event.target.closest('turbo-frame')\n const { fetchResponse: response } = event.detail\n\n if (frame) frameSources[frame.id] = frame.src\n\n if (response.header('TurboBoost')) {\n if (response.statusCode < 200 || response.statusCode > 399) {\n const error = `Server returned a ${response.statusCode} status code! TurboBoost Commands require 2XX-3XX status codes.`\n dispatch(lifecycle.events.clientError, document, { detail: { ...event.detail, error } }, true)\n }\n\n if (response.header('TurboBoost') === 'Append') {\n event.preventDefault()\n response.responseText.then(content => renderer.append(content))\n }\n }\n})\n\n// fires when a frame element is navigated and finishes loading\naddEventListener('turbo:frame-load', event => {\n const frame = event.target.closest('turbo-frame')\n frame.dataset.turboBoostSrc = frameSources[frame.id] || frame.src || frame.dataset.turboBoostSrc\n delete frameSources[frame.id]\n})\n", "const schema = {\n // attributes\n frameAttribute: 'data-turbo-frame',\n methodAttribute: 'data-turbo-method',\n commandAttribute: 'data-turbo-command',\n confirmAttribute: 'data-turbo-confirm'\n}\n\nexport default { ...schema }\n", "import { commandEvents } from './events'\nimport schema from './schema'\n\nconst confirmation = {\n method: message => Promise.resolve(confirm(message))\n}\n\nconst isTurboMethod = event => event.detail.driver === 'method'\n\nconst isTurboForm = event => {\n if (event.detail.driver !== 'form') return false\n\n const element = event.target\n const frame = element.closest('turbo-frame')\n const target = element.closest(`[${schema.frameAttribute}]`)\n return !!(frame || target)\n}\n\nconst shouldDelegate = event => isTurboMethod(event) || isTurboForm(event)\n\ndocument.addEventListener(commandEvents.start, async event => {\n const message = event.target.getAttribute(schema.confirmAttribute)\n if (!message) return\n\n event.detail.confirmation = true\n\n if (shouldDelegate(event)) return // delegate confirmation handling to Turbo\n\n const proceed = await confirmation.method(message)\n if (!proceed) event.preventDefault()\n})\n\nexport default confirmation\n", "let events = []\nlet eventListener\n\nfunction register(eventName, selectors) {\n const match = events.find(evt => evt.name === eventName)\n if (match) events.splice(events.indexOf(match), 1)\n events = [{ name: eventName, selectors }, ...events]\n\n document.removeEventListener(eventName, eventListener, true)\n document.addEventListener(eventName, eventListener, true)\n\n return { ...events.find(evt => evt.name === eventName) }\n}\n\nfunction getRegisteredEventForElement(element) {\n return events.find(evt =>\n evt.selectors.find(selector => Array.from(document.querySelectorAll(selector)).find(el => el === element))\n )\n}\n\nfunction isRegisteredForElement(eventName, element) {\n const evt = getRegisteredEventForElement(element)\n return evt && evt.name === eventName\n}\n\nexport default {\n register,\n isRegisteredForElement,\n get events() {\n return [...events]\n },\n set handler(fn) {\n eventListener = fn\n }\n}\n", "import schema from './schema'\nimport lifecycle from './lifecycle'\n\nfunction findClosestCommand(element) {\n return element.closest(`[${schema.commandAttribute}]`)\n}\n\nfunction findClosestFrameWithSource(element) {\n return (\n element.closest('turbo-frame[src]') ||\n element.closest('turbo-frame[data-turbo-frame-src]') ||\n element.closest('turbo-frame')\n )\n}\n\nfunction assignElementValueToPayload(element, payload = {}) {\n if (element.tagName.toLowerCase() !== 'select') return (payload.value = element.value || null)\n\n if (!element.multiple) return (payload.value = element.options[element.selectedIndex].value)\n\n payload.values = Array.from(element.options).reduce((memo, option) => {\n if (option.selected) memo.push(option.value)\n return memo\n }, [])\n}\n\nfunction buildAttributePayload(element) {\n const payload = Array.from(element.attributes).reduce((memo, attr) => {\n let value = attr.value\n memo[attr.name] = value\n return memo\n }, {})\n\n payload.tag = element.tagName\n payload.checked = !!element.checked\n payload.disabled = !!element.disabled\n assignElementValueToPayload(element, payload)\n\n // reduce payload size to keep URL length smaller\n delete payload.class\n delete payload.action\n delete payload.href\n delete payload[schema.commandAttribute]\n delete payload[schema.frameAttribute]\n\n return payload\n}\n\nexport default {\n buildAttributePayload,\n findClosestCommand,\n findClosestFrameWithSource\n}\n", "import meta from '../meta'\n\nfunction invokeCommand(form, payload = {}, event = {}) {\n payload.token = meta.token\n const input = form.querySelector('input[name=\"turbo_boost_command\"]') || document.createElement('input')\n input.type = 'hidden'\n input.name = 'turbo_boost_command'\n input.value = JSON.stringify(payload)\n form.appendChild(input)\n}\n\nexport default { invokeCommand }\n", "function build(urlString, payload = {}) {\n const a = document.createElement('a')\n a.href = urlString\n const url = new URL(a)\n url.searchParams.set('tbc', JSON.stringify(payload))\n return url\n}\n\nexport default { build }\n", "import urls from '../urls'\n\nfunction invokeCommand(frame, payload) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n frame.src = urls.build(src, payload)\n}\n\nexport default { invokeCommand }\n", "import urls from '../urls'\n\nfunction invokeCommand(element, payload = {}) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n delete payload.href\n element.setAttribute('href', urls.build(src, payload))\n}\n\nexport default { invokeCommand }\n", "import meta from '../meta'\nimport state from '../state'\nimport { dispatch } from '../events'\nimport lifecycle from '../lifecycle'\nimport urls from '../urls'\nimport renderer from '../renderer'\n\nfunction aborted(event) {\n const xhr = event.target\n dispatch(lifecycle.events.abort, document, {\n detail: { ...event.detail, xhr }\n })\n}\n\nfunction errored(event) {\n const xhr = event.target\n\n const append =\n xhr.getResponseHeader('TurboBoost') === 'Append' ||\n xhr.getResponseHeader('Content-Type').startsWith('text/vnd.turbo-boost.html')\n\n if (append) renderer.append(xhr.responseText)\n\n const error = `Server returned a ${xhr.status} status code! TurboBoost Commands require 2XX-3XX status codes.`\n\n dispatch(lifecycle.events.clientError, document, { detail: { ...event.detail, error, xhr } }, true)\n}\n\nfunction loaded(event) {\n const xhr = event.target\n if (xhr.status < 200 || xhr.status > 399) return errored(event)\n const content = xhr.responseText\n const append =\n xhr.getResponseHeader('TurboBoost') === 'Append' ||\n xhr.getResponseHeader('Content-Type').startsWith('text/vnd.turbo-boost.html')\n append ? renderer.append(xhr.responseText) : renderer.replaceDocument(xhr.responseText)\n}\n\nfunction invokeCommand(payload) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n\n try {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', urls.build(src, payload), true)\n xhr.setRequestHeader('Accept', 'text/vnd.turbo-boost.html, text/html, application/xhtml+xml')\n xhr.addEventListener('abort', aborted)\n xhr.addEventListener('error', errored)\n xhr.addEventListener('load', loaded)\n xhr.send()\n } catch (ex) {\n const message = `Unexpected error sending HTTP request! ${ex.message}`\n errored(ex, { detail: { message } })\n }\n}\n\nexport default { invokeCommand }\n", "import elements from '../elements'\nimport formDriver from './form'\nimport frameDriver from './frame'\nimport methodDriver from './method'\nimport windowDriver from './window'\n\nfunction src(element, frame) {\n frame = frame || { dataset: {} }\n return element.href || frame.src || frame.dataset.turboBoostSrc || location.href\n}\n\nfunction find(element) {\n let frame = elements.findClosestFrameWithSource(element)\n\n const { turboFrame, turboMethod } = element.dataset\n\n if (element.tagName.toLowerCase() === 'form')\n return {\n name: 'form',\n reason: 'Element is a form.',\n frame,\n src: element.action,\n invokeCommand: formDriver.invokeCommand\n }\n\n if (turboMethod && turboMethod.length > 0)\n return {\n name: 'method',\n reason: 'Element defines data-turbo-method.',\n frame,\n src: element.href,\n invokeCommand: methodDriver.invokeCommand\n }\n\n // element targets a frame that is not _self\n if (turboFrame && turboFrame !== '_self') {\n frame = document.getElementById(turboFrame)\n return {\n name: 'frame',\n reason: 'element targets a frame that is not _self',\n frame,\n src: src(element, frame),\n invokeCommand: frameDriver.invokeCommand\n }\n }\n\n // element does NOT target a frame or targets _self and is contained by a frame\n if ((!turboFrame || turboFrame === '_self') && frame)\n return {\n name: 'frame',\n reason: 'element does NOT target a frame or targets _self and is contained by a frame',\n frame,\n src: src(element, frame),\n invokeCommand: frameDriver.invokeCommand\n }\n\n // element matches one or more of the following conditions\n // - targets _top\n // - does NOT target a frame\n // - is NOT contained by a frame\n return {\n name: 'window',\n reason:\n 'element matches one or more of the following conditions (targets _top, does NOT target a frame, is NOT contained by a frame)',\n frame: null,\n src: src(element),\n invokeCommand: windowDriver.invokeCommand\n }\n}\n\nexport default { find }\n", "import { allEvents as events } from './events'\n\nlet currentLevel = 'unknown'\n\nconst logLevels = {\n debug: Object.values(events),\n info: Object.values(events),\n warn: [events.abort, events.clientError, events.serverError],\n error: [events.clientError, events.serverError],\n unknown: []\n}\n\nObject.values(events).forEach(name => {\n addEventListener(name, event => {\n if (logLevels[currentLevel].includes(event.type)) {\n const { target, detail } = event\n console[currentLevel](event.type, { target, detail })\n }\n })\n})\n\nexport default {\n get level() {\n return currentLevel\n },\n set level(value) {\n if (!Object.keys(logLevels).includes(value)) value = 'unknown'\n return (currentLevel = value)\n }\n}\n", "function v4() {\n return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>\n (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\n )\n}\n\nexport default { v4 }\n", "import './turbo'\nimport schema from './schema'\nimport { dispatch, commandEvents, stateEvents } from './events'\nimport activity from './activity'\nimport confirmation from './confirmation'\nimport delegates from './delegates'\nimport drivers from './drivers'\nimport meta from './meta'\nimport elements from './elements'\nimport lifecycle from './lifecycle'\nimport logger from './logger'\nimport state from './state'\nimport urls from './urls'\nimport uuids from './uuids'\n\nfunction buildCommandPayload(id, element) {\n return {\n id, // uniquely identifies the command\n name: element.getAttribute(schema.commandAttribute),\n elementId: element.id.length > 0 ? element.id : null,\n elementAttributes: elements.buildAttributePayload(element),\n startedAt: Date.now(),\n token: meta.token, // authenticity token\n signedState: meta.signedState, // server side state\n state: state.changed // client side state (optimistic updates)\n }\n}\n\nasync function invokeCommand(event) {\n let element\n let payload = {}\n\n try {\n element = elements.findClosestCommand(event.target)\n if (!element) return\n if (!delegates.isRegisteredForElement(event.type, element)) return\n\n const commandId = `turbo-command-${uuids.v4()}`\n let driver = drivers.find(element)\n let payload = {\n ...buildCommandPayload(commandId, element),\n driver: driver.name,\n frameId: driver.frame ? driver.frame.id : null,\n src: driver.src\n }\n\n const startEvent = await dispatch(commandEvents.start, element, {\n cancelable: true,\n detail: payload\n })\n\n if (startEvent.defaultPrevented || (startEvent.detail.confirmation && event.defaultPrevented))\n return dispatch(commandEvents.abort, element, {\n detail: {\n message: `An event handler for '${commandEvents.start}' prevented default behavior and blocked command invocation!`,\n source: startEvent\n }\n })\n\n // the element and thus the driver may have changed based on the start event handler(s)\n driver = drivers.find(element)\n payload = {\n ...buildCommandPayload(commandId, element),\n driver: driver.name,\n frameId: driver.frame ? driver.frame.id : null,\n src: driver.src\n }\n\n activity.add(payload)\n\n if (['frame', 'window'].includes(driver.name)) event.preventDefault()\n\n meta.busy = true\n setTimeout(() => (meta.busy = false), 10)\n\n switch (driver.name) {\n case 'method':\n return driver.invokeCommand(element, payload)\n case 'form':\n return driver.invokeCommand(element, payload, event)\n case 'frame':\n return driver.invokeCommand(driver.frame, payload)\n case 'window':\n return driver.invokeCommand(payload)\n }\n } catch (error) {\n dispatch(commandEvents.clientError, element, {\n detail: { ...payload, error }\n })\n }\n}\n\nself.TurboBoost = self.TurboBoost || {}\n\nself.TurboBoost = {\n ...self.TurboBoost,\n\n stateEvents,\n\n get state() {\n return state.current\n },\n\n get stateChanges() {\n return state.changed\n }\n}\n\nif (!self.TurboBoost.Commands) {\n // wire things up and setup defaults for event delegation\n delegates.handler = invokeCommand\n delegates.register('click', [`[${schema.commandAttribute}]`])\n delegates.register('submit', [`form[${schema.commandAttribute}]`])\n delegates.register('change', [\n `input[${schema.commandAttribute}]`,\n `select[${schema.commandAttribute}]`,\n `textarea[${schema.commandAttribute}]`\n ])\n\n self.TurboBoost.Commands = {\n confirmation,\n logger,\n schema,\n events: commandEvents,\n registerEventDelegate: delegates.register,\n get eventDelegates() {\n return delegates.events\n }\n }\n}\n\nexport default self.TurboBoost.Commands\n"], - "mappings": "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", - "names": ["Meta", "value", "meta_default", "commandEvents", "stateEvents", "allEvents", "__spreadValues", "dispatch", "name", "target", "options", "resolve", "evt", "__spreadProps", "head", "observable", "object", "parent", "proxy", "target", "key", "dispatch", "stateEvents", "meta_default", "value", "receiver", "index", "observable_default", "initialState", "currentState", "changedState", "loadStateTimeout", "loadState", "meta_default", "loadStateLater", "json", "__spreadValues", "observable_default", "dispatch", "stateEvents", "commandEvents", "event", "key", "value", "state_default", "replaceDocument", "content", "head", "tail", "headIndex", "tailIndex", "html", "append", "renderer_default", "active", "add", "payload", "remove", "id", "activity_default", "finish", "event", "dispatch", "commandEvents", "activity_default", "lifecycle_default", "frameSources", "event", "frame", "fetchOptions", "meta_default", "acceptHeaders", "entry", "response", "error", "dispatch", "lifecycle_default", "__spreadProps", "__spreadValues", "content", "renderer_default", "schema", "schema_default", "__spreadValues", "confirmation", "message", "isTurboMethod", "event", "isTurboForm", "element", "frame", "target", "schema_default", "shouldDelegate", "commandEvents", "confirmation_default", "events", "eventListener", "register", "eventName", "selectors", "match", "evt", "__spreadValues", "getRegisteredEventForElement", "element", "selector", "el", "isRegisteredForElement", "delegates_default", "fn", "findClosestCommand", "element", "schema_default", "findClosestFrameWithSource", "assignElementValueToPayload", "payload", "memo", "option", "buildAttributePayload", "attr", "value", "elements_default", "invokeCommand", "form", "payload", "event", "meta_default", "input", "form_default", "build", "urlString", "payload", "a", "url", "urls_default", "invokeCommand", "frame", "payload", "src", "__spreadValues", "urls_default", "frame_default", "invokeCommand", "element", "payload", "src", "__spreadValues", "urls_default", "method_default", "aborted", "event", "xhr", "dispatch", "lifecycle_default", "__spreadProps", "__spreadValues", "errored", "renderer_default", "error", "loaded", "content", "invokeCommand", "payload", "src", "urls_default", "ex", "message", "window_default", "src", "element", "frame", "find", "elements_default", "turboFrame", "turboMethod", "form_default", "method_default", "frame_default", "window_default", "drivers_default", "currentLevel", "logLevels", "allEvents", "name", "event", "target", "detail", "logger_default", "value", "v4", "c", "uuids_default", "buildCommandPayload", "id", "element", "schema_default", "elements_default", "meta_default", "state_default", "invokeCommand", "event", "payload", "delegates_default", "commandId", "uuids_default", "driver", "drivers_default", "__spreadProps", "__spreadValues", "startEvent", "dispatch", "commandEvents", "activity_default", "error", "stateEvents", "confirmation_default", "logger_default", "javascript_default"] + "sources": ["../../../javascript/events.js", "../../../javascript/state/observable.js", "../../../javascript/state/index.js", "../../../javascript/renderer.js", "../../../javascript/activity.js", "../../../javascript/lifecycle.js", "../../../javascript/turbo.js", "../../../javascript/schema.js", "../../../javascript/confirmation.js", "../../../javascript/delegates.js", "../../../javascript/elements.js", "../../../javascript/drivers/form.js", "../../../javascript/urls.js", "../../../javascript/drivers/frame.js", "../../../javascript/drivers/method.js", "../../../javascript/drivers/window.js", "../../../javascript/drivers/index.js", "../../../javascript/logger.js", "../../../javascript/uuids.js", "../../../javascript/index.js"], + "sourcesContent": ["export const commandEvents = {\n start: 'turbo-boost:command:start',\n success: 'turbo-boost:command:success',\n finish: 'turbo-boost:command:finish',\n abort: 'turbo-boost:command:abort',\n clientError: 'turbo-boost:command:client-error',\n serverError: 'turbo-boost:command:server-error'\n}\n\nexport const stateEvents = {\n stateLoad: 'turbo-boost:state:load',\n stateChange: 'turbo-boost:state:change'\n}\n\nexport const allEvents = { ...commandEvents, ...stateEvents }\n\nexport function dispatch(name, target, options = {}) {\n return new Promise(resolve => {\n options = options || {}\n options.detail = options.detail || {}\n target = target || document\n const evt = new CustomEvent(name, { ...options, bubbles: true })\n target.dispatchEvent(evt)\n resolve(evt)\n })\n}\n", "import { dispatch, stateEvents as events } from '../events'\n\nlet head\n\nfunction observable(object, parent = null) {\n if (!object || typeof object !== 'object') return object\n\n const proxy = new Proxy(object, {\n deleteProperty(target, key) {\n delete target[key]\n dispatch(events.stateChange, document, { detail: { state: head } })\n return true\n },\n\n set(target, key, value, receiver) {\n target[key] = observable(value, this)\n dispatch(events.stateChange, document, { detail: { state: head } })\n return true\n }\n })\n\n if (Array.isArray(object)) {\n object.forEach((value, index) => (object[index] = observable(value, proxy)))\n } else if (typeof object === 'object') {\n for (const [key, value] of Object.entries(object)) object[key] = observable(value, proxy)\n }\n\n if (!parent) head = proxy\n return proxy\n}\n\nexport default observable\n", "// TODO: Consider moving State to its own library\nimport observable from './observable'\nimport { dispatch, commandEvents, stateEvents } from '../events'\n\nlet initialState, currentState, changedState, signedState\n\nfunction initialize(initial, signed) {\n const json = JSON.parse(initial)\n initialState = { ...json }\n signedState = signed\n currentState = observable(json)\n changedState = {}\n setTimeout(() =>\n dispatch(stateEvents.stateLoad, document, {\n detail: { state: currentState }\n })\n )\n}\n\naddEventListener(stateEvents.stateChange, event => {\n for (const [key, value] of Object.entries(currentState))\n if (initialState[key] !== value) changedState[key] = value\n})\n\nexport default {\n initialize,\n events: stateEvents,\n\n get initial() {\n return initialState\n },\n\n get current() {\n return currentState\n },\n\n get changed() {\n return changedState\n },\n\n get signed() {\n return signedState\n }\n}\n", "function replaceDocument(content) {\n const head = '= 0 && tailIndex >= 0) {\n const html = content.slice(content.indexOf('>', headIndex) + 1, tailIndex)\n document.documentElement.innerHTML = html\n }\n}\n\nfunction append(content) {\n document.body.insertAdjacentHTML('beforeend', content)\n}\n\nexport default { append, replaceDocument }\n", "const active = {}\n\nfunction add(payload) {\n active[payload.id] = payload\n}\n\nfunction remove(id) {\n delete active[id]\n}\n\nexport default {\n add,\n remove,\n get commands() {\n return [...Object.values(active)]\n },\n get length() {\n return Object.keys(active).length\n }\n}\n", "import activity from './activity'\nimport { dispatch, commandEvents } from './events'\n\nfunction finish(event) {\n event.detail.endedAt = Date.now()\n event.detail.milliseconds = event.detail.endedAt - event.detail.startedAt\n setTimeout(() => dispatch(commandEvents.finish, event.target, { detail: event.detail }), 25)\n}\n\n// TODO: forward source event to finish (error or success)\naddEventListener(commandEvents.serverError, finish)\naddEventListener(commandEvents.success, finish)\naddEventListener(commandEvents.finish, event => activity.remove(event.detail.id), true)\n\nexport default { events: commandEvents }\n", "import state from './state'\nimport renderer from './renderer'\nimport { dispatch } from './events'\nimport lifecycle from './lifecycle'\n\nconst frameSources = {}\n\n// fires before making a turbo HTTP request\naddEventListener('turbo:before-fetch-request', event => {\n const frame = event.target.closest('turbo-frame')\n const { fetchOptions } = event.detail\n\n // command invoked and busy\n if (self.TurboBoost?.Commands?.busy) {\n let acceptHeaders = ['text/vnd.turbo-boost.html', fetchOptions.headers['Accept']]\n acceptHeaders = acceptHeaders.filter(entry => entry && entry.trim().length > 0).join(', ')\n fetchOptions.headers['Accept'] = acceptHeaders\n }\n})\n\n// fires after receiving a turbo HTTP response\naddEventListener('turbo:before-fetch-response', event => {\n const frame = event.target.closest('turbo-frame')\n const { fetchResponse: response } = event.detail\n\n if (frame) frameSources[frame.id] = frame.src\n\n if (response.header('TurboBoost')) {\n if (response.statusCode < 200 || response.statusCode > 399) {\n const error = `Server returned a ${response.statusCode} status code! TurboBoost Commands require 2XX-3XX status codes.`\n dispatch(lifecycle.events.clientError, document, { detail: { ...event.detail, error } }, true)\n }\n\n if (response.header('TurboBoost') === 'Append') {\n event.preventDefault()\n response.responseText.then(content => renderer.append(content))\n }\n }\n})\n\n// fires when a frame element is navigated and finishes loading\naddEventListener('turbo:frame-load', event => {\n const frame = event.target.closest('turbo-frame')\n frame.dataset.turboBoostSrc = frameSources[frame.id] || frame.src || frame.dataset.turboBoostSrc\n delete frameSources[frame.id]\n})\n", "const schema = {\n // attributes\n frameAttribute: 'data-turbo-frame',\n methodAttribute: 'data-turbo-method',\n commandAttribute: 'data-turbo-command',\n confirmAttribute: 'data-turbo-confirm'\n}\n\nexport default { ...schema }\n", "import { commandEvents } from './events'\nimport schema from './schema'\n\nconst confirmation = {\n method: message => Promise.resolve(confirm(message))\n}\n\nconst isTurboMethod = event => event.detail.driver === 'method'\n\nconst isTurboForm = event => {\n if (event.detail.driver !== 'form') return false\n\n const element = event.target\n const frame = element.closest('turbo-frame')\n const target = element.closest(`[${schema.frameAttribute}]`)\n return !!(frame || target)\n}\n\nconst shouldDelegate = event => isTurboMethod(event) || isTurboForm(event)\n\ndocument.addEventListener(commandEvents.start, async event => {\n const message = event.target.getAttribute(schema.confirmAttribute)\n if (!message) return\n\n event.detail.confirmation = true\n\n if (shouldDelegate(event)) return // delegate confirmation handling to Turbo\n\n const proceed = await confirmation.method(message)\n if (!proceed) event.preventDefault()\n})\n\nexport default confirmation\n", "let events = []\nlet eventListener\n\nfunction register(eventName, selectors) {\n const match = events.find(evt => evt.name === eventName)\n if (match) events.splice(events.indexOf(match), 1)\n events = [{ name: eventName, selectors }, ...events]\n\n document.removeEventListener(eventName, eventListener, true)\n document.addEventListener(eventName, eventListener, true)\n\n return { ...events.find(evt => evt.name === eventName) }\n}\n\nfunction getRegisteredEventForElement(element) {\n return events.find(evt =>\n evt.selectors.find(selector => Array.from(document.querySelectorAll(selector)).find(el => el === element))\n )\n}\n\nfunction isRegisteredForElement(eventName, element) {\n const evt = getRegisteredEventForElement(element)\n return evt && evt.name === eventName\n}\n\nexport default {\n register,\n isRegisteredForElement,\n get events() {\n return [...events]\n },\n set handler(fn) {\n eventListener = fn\n }\n}\n", "import schema from './schema'\nimport lifecycle from './lifecycle'\n\nfunction findClosestCommand(element) {\n return element.closest(`[${schema.commandAttribute}]`)\n}\n\nfunction findClosestFrameWithSource(element) {\n return (\n element.closest('turbo-frame[src]') ||\n element.closest('turbo-frame[data-turbo-frame-src]') ||\n element.closest('turbo-frame')\n )\n}\n\nfunction assignElementValueToPayload(element, payload = {}) {\n if (element.tagName.toLowerCase() !== 'select') return (payload.value = element.value || null)\n\n if (!element.multiple) return (payload.value = element.options[element.selectedIndex].value)\n\n payload.values = Array.from(element.options).reduce((memo, option) => {\n if (option.selected) memo.push(option.value)\n return memo\n }, [])\n}\n\nfunction buildAttributePayload(element) {\n const payload = Array.from(element.attributes).reduce((memo, attr) => {\n let value = attr.value\n memo[attr.name] = value\n return memo\n }, {})\n\n payload.tag = element.tagName\n payload.checked = !!element.checked\n payload.disabled = !!element.disabled\n assignElementValueToPayload(element, payload)\n\n // reduce payload size to keep URL length smaller\n delete payload.class\n delete payload.action\n delete payload.href\n delete payload[schema.commandAttribute]\n delete payload[schema.frameAttribute]\n\n return payload\n}\n\nexport default {\n buildAttributePayload,\n findClosestCommand,\n findClosestFrameWithSource\n}\n", "function invokeCommand(form, payload = {}, event = {}) {\n const input = form.querySelector('input[name=\"turbo_boost_command\"]') || document.createElement('input')\n input.type = 'hidden'\n input.name = 'turbo_boost_command'\n input.value = JSON.stringify(payload)\n form.appendChild(input)\n}\n\nexport default { invokeCommand }\n", "function build(urlString, payload = {}) {\n const a = document.createElement('a')\n a.href = urlString\n const url = new URL(a)\n url.searchParams.set('tbc', JSON.stringify(payload))\n return url\n}\n\nexport default { build }\n", "import urls from '../urls'\n\nfunction invokeCommand(frame, payload) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n frame.src = urls.build(src, payload)\n}\n\nexport default { invokeCommand }\n", "import urls from '../urls'\n\nfunction invokeCommand(element, payload = {}) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n delete payload.href\n element.setAttribute('href', urls.build(src, payload))\n}\n\nexport default { invokeCommand }\n", "import state from '../state'\nimport { dispatch } from '../events'\nimport lifecycle from '../lifecycle'\nimport urls from '../urls'\nimport renderer from '../renderer'\n\nfunction aborted(event) {\n const xhr = event.target\n dispatch(lifecycle.events.abort, document, {\n detail: { ...event.detail, xhr }\n })\n}\n\nfunction errored(event) {\n const xhr = event.target\n\n const append =\n xhr.getResponseHeader('TurboBoost') === 'Append' ||\n xhr.getResponseHeader('Content-Type').startsWith('text/vnd.turbo-boost.html')\n\n if (append) renderer.append(xhr.responseText)\n\n const error = `Server returned a ${xhr.status} status code! TurboBoost Commands require 2XX-3XX status codes.`\n\n dispatch(lifecycle.events.clientError, document, { detail: { ...event.detail, error, xhr } }, true)\n}\n\nfunction loaded(event) {\n const xhr = event.target\n if (xhr.status < 200 || xhr.status > 399) return errored(event)\n const content = xhr.responseText\n const append =\n xhr.getResponseHeader('TurboBoost') === 'Append' ||\n xhr.getResponseHeader('Content-Type').startsWith('text/vnd.turbo-boost.html')\n append ? renderer.append(xhr.responseText) : renderer.replaceDocument(xhr.responseText)\n}\n\nfunction invokeCommand(payload) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n\n try {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', urls.build(src, payload), true)\n xhr.setRequestHeader('Accept', 'text/vnd.turbo-boost.html, text/html, application/xhtml+xml')\n xhr.addEventListener('abort', aborted)\n xhr.addEventListener('error', errored)\n xhr.addEventListener('load', loaded)\n xhr.send()\n } catch (ex) {\n const message = `Unexpected error sending HTTP request! ${ex.message}`\n errored(ex, { detail: { message } })\n }\n}\n\nexport default { invokeCommand }\n", "import elements from '../elements'\nimport formDriver from './form'\nimport frameDriver from './frame'\nimport methodDriver from './method'\nimport windowDriver from './window'\n\nfunction src(element, frame) {\n frame = frame || { dataset: {} }\n return element.href || frame.src || frame.dataset.turboBoostSrc || location.href\n}\n\nfunction find(element) {\n let frame = elements.findClosestFrameWithSource(element)\n\n const { turboFrame, turboMethod } = element.dataset\n\n if (element.tagName.toLowerCase() === 'form')\n return {\n name: 'form',\n reason: 'Element is a form.',\n frame,\n src: element.action,\n invokeCommand: formDriver.invokeCommand\n }\n\n if (turboMethod && turboMethod.length > 0)\n return {\n name: 'method',\n reason: 'Element defines data-turbo-method.',\n frame,\n src: element.href,\n invokeCommand: methodDriver.invokeCommand\n }\n\n // element targets a frame that is not _self\n if (turboFrame && turboFrame !== '_self') {\n frame = document.getElementById(turboFrame)\n return {\n name: 'frame',\n reason: 'element targets a frame that is not _self',\n frame,\n src: src(element, frame),\n invokeCommand: frameDriver.invokeCommand\n }\n }\n\n // element does NOT target a frame or targets _self and is contained by a frame\n if ((!turboFrame || turboFrame === '_self') && frame)\n return {\n name: 'frame',\n reason: 'element does NOT target a frame or targets _self and is contained by a frame',\n frame,\n src: src(element, frame),\n invokeCommand: frameDriver.invokeCommand\n }\n\n // element matches one or more of the following conditions\n // - targets _top\n // - does NOT target a frame\n // - is NOT contained by a frame\n return {\n name: 'window',\n reason:\n 'element matches one or more of the following conditions (targets _top, does NOT target a frame, is NOT contained by a frame)',\n frame: null,\n src: src(element),\n invokeCommand: windowDriver.invokeCommand\n }\n}\n\nexport default { find }\n", "import { allEvents as events } from './events'\n\nlet currentLevel = 'unknown'\n\nconst logLevels = {\n debug: Object.values(events),\n info: Object.values(events),\n warn: [events.abort, events.clientError, events.serverError],\n error: [events.clientError, events.serverError],\n unknown: []\n}\n\nObject.values(events).forEach(name => {\n addEventListener(name, event => {\n if (logLevels[currentLevel].includes(event.type)) {\n const { target, detail } = event\n console[currentLevel](event.type, { target, detail })\n }\n })\n})\n\nexport default {\n get level() {\n return currentLevel\n },\n set level(value) {\n if (!Object.keys(logLevels).includes(value)) value = 'unknown'\n return (currentLevel = value)\n }\n}\n", "function v4() {\n return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>\n (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\n )\n}\n\nexport default { v4 }\n", "import './turbo'\nimport schema from './schema'\nimport { dispatch, commandEvents } from './events'\nimport activity from './activity'\nimport confirmation from './confirmation'\nimport delegates from './delegates'\nimport drivers from './drivers'\nimport elements from './elements'\nimport lifecycle from './lifecycle'\nimport logger from './logger'\nimport state from './state'\nimport urls from './urls'\nimport uuids from './uuids'\n\nconst TurboBoost = self.TurboBoost || {}\n\nconst Commands = {\n busy: false,\n confirmation,\n logger,\n schema,\n events: commandEvents,\n registerEventDelegate: delegates.register,\n get eventDelegates() {\n return delegates.events\n }\n}\n\nfunction buildCommandPayload(id, element) {\n return {\n id, // uniquely identifies the command\n name: element.getAttribute(schema.commandAttribute),\n elementId: element.id.length > 0 ? element.id : null,\n elementAttributes: elements.buildAttributePayload(element),\n startedAt: Date.now(),\n token: Commands.token, // command token (used for CSRF protection)\n signedState: state.signed, // server side state\n clientState: state.changed // client side state (optimistic updates)\n }\n}\n\nasync function invokeCommand(event) {\n let element\n let payload = {}\n\n try {\n element = elements.findClosestCommand(event.target)\n if (!element) return\n if (!delegates.isRegisteredForElement(event.type, element)) return\n\n const commandId = `turbo-command-${uuids.v4()}`\n let driver = drivers.find(element)\n let payload = {\n ...buildCommandPayload(commandId, element),\n driver: driver.name,\n frameId: driver.frame ? driver.frame.id : null,\n src: driver.src\n }\n\n const startEvent = await dispatch(commandEvents.start, element, {\n cancelable: true,\n detail: payload\n })\n\n if (startEvent.defaultPrevented || (startEvent.detail.confirmation && event.defaultPrevented))\n return dispatch(commandEvents.abort, element, {\n detail: {\n message: `An event handler for '${commandEvents.start}' prevented default behavior and blocked command invocation!`,\n source: startEvent\n }\n })\n\n // the element and thus the driver may have changed based on the start event handler(s)\n driver = drivers.find(element)\n payload = {\n ...buildCommandPayload(commandId, element),\n driver: driver.name,\n frameId: driver.frame ? driver.frame.id : null,\n src: driver.src\n }\n\n activity.add(payload)\n\n if (['frame', 'window'].includes(driver.name)) event.preventDefault()\n\n Commands.busy = true\n setTimeout(() => (Commands.busy = false), 10)\n\n switch (driver.name) {\n case 'method':\n return driver.invokeCommand(element, payload)\n case 'form':\n return driver.invokeCommand(element, payload, event)\n case 'frame':\n return driver.invokeCommand(driver.frame, payload)\n case 'window':\n return driver.invokeCommand(payload)\n }\n } catch (error) {\n dispatch(commandEvents.clientError, element, {\n detail: { ...payload, error }\n })\n }\n}\n\nself.TurboBoost = { ...TurboBoost }\n\nif (!self.TurboBoost.Commands) {\n // wire things up and setup defaults for event delegation\n delegates.handler = invokeCommand\n delegates.register('click', [`[${schema.commandAttribute}]`])\n delegates.register('submit', [`form[${schema.commandAttribute}]`])\n delegates.register('change', [\n `input[${schema.commandAttribute}]`,\n `select[${schema.commandAttribute}]`,\n `textarea[${schema.commandAttribute}]`\n ])\n\n self.TurboBoost.Commands = Commands\n self.TurboBoost.State = state\n}\n\nexport default Commands\n"], + "mappings": "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", + "names": ["commandEvents", "stateEvents", "allEvents", "__spreadValues", "dispatch", "name", "target", "options", "resolve", "evt", "__spreadProps", "head", "observable", "object", "parent", "proxy", "target", "key", "dispatch", "stateEvents", "value", "receiver", "index", "observable_default", "initialState", "currentState", "changedState", "signedState", "initialize", "initial", "signed", "json", "__spreadValues", "observable_default", "dispatch", "stateEvents", "event", "key", "value", "state_default", "replaceDocument", "content", "head", "tail", "headIndex", "tailIndex", "html", "append", "renderer_default", "active", "add", "payload", "remove", "id", "activity_default", "finish", "event", "dispatch", "commandEvents", "activity_default", "lifecycle_default", "frameSources", "event", "_a", "_b", "frame", "fetchOptions", "acceptHeaders", "entry", "response", "error", "dispatch", "lifecycle_default", "__spreadProps", "__spreadValues", "content", "renderer_default", "schema", "schema_default", "__spreadValues", "confirmation", "message", "isTurboMethod", "event", "isTurboForm", "element", "frame", "target", "schema_default", "shouldDelegate", "commandEvents", "confirmation_default", "events", "eventListener", "register", "eventName", "selectors", "match", "evt", "__spreadValues", "getRegisteredEventForElement", "element", "selector", "el", "isRegisteredForElement", "delegates_default", "fn", "findClosestCommand", "element", "schema_default", "findClosestFrameWithSource", "assignElementValueToPayload", "payload", "memo", "option", "buildAttributePayload", "attr", "value", "elements_default", "invokeCommand", "form", "payload", "event", "input", "form_default", "build", "urlString", "payload", "a", "url", "urls_default", "invokeCommand", "frame", "payload", "src", "__spreadValues", "urls_default", "frame_default", "invokeCommand", "element", "payload", "src", "__spreadValues", "urls_default", "method_default", "aborted", "event", "xhr", "dispatch", "lifecycle_default", "__spreadProps", "__spreadValues", "errored", "renderer_default", "error", "loaded", "content", "invokeCommand", "payload", "src", "urls_default", "ex", "message", "window_default", "src", "element", "frame", "find", "elements_default", "turboFrame", "turboMethod", "form_default", "method_default", "frame_default", "window_default", "drivers_default", "currentLevel", "logLevels", "allEvents", "name", "event", "target", "detail", "logger_default", "value", "v4", "c", "uuids_default", "TurboBoost", "Commands", "confirmation_default", "logger_default", "schema_default", "commandEvents", "delegates_default", "buildCommandPayload", "id", "element", "elements_default", "state_default", "invokeCommand", "event", "payload", "commandId", "uuids_default", "driver", "drivers_default", "__spreadProps", "__spreadValues", "startEvent", "dispatch", "activity_default", "error", "javascript_default"] } diff --git a/app/assets/builds/@turbo-boost/commands.metafile.json b/app/assets/builds/@turbo-boost/commands.metafile.json deleted file mode 100644 index b471a3da..00000000 --- a/app/assets/builds/@turbo-boost/commands.metafile.json +++ /dev/null @@ -1 +0,0 @@ -{"inputs":{"app/javascript/meta.js":{"bytes":707,"imports":[],"format":"esm"},"app/javascript/events.js":{"bytes":783,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/state/observable.js":{"bytes":920,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"}],"format":"esm"},"app/javascript/state/index.js":{"bytes":1298,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/state/observable.js","kind":"import-statement","original":"./observable"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/renderer.js":{"bytes":475,"imports":[],"format":"esm"},"app/javascript/activity.js":{"bytes":279,"imports":[],"format":"esm"},"app/javascript/lifecycle.js":{"bytes":610,"imports":[{"path":"app/javascript/activity.js","kind":"import-statement","original":"./activity"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"}],"format":"esm"},"app/javascript/turbo.js":{"bytes":1733,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"./meta"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"./state"},{"path":"app/javascript/renderer.js","kind":"import-statement","original":"./renderer"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/schema.js":{"bytes":226,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/confirmation.js":{"bytes":947,"imports":[{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"}],"format":"esm"},"app/javascript/delegates.js":{"bytes":923,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/elements.js":{"bytes":1451,"imports":[{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"}],"format":"esm"},"app/javascript/drivers/form.js":{"bytes":384,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"}],"format":"esm"},"app/javascript/urls.js":{"bytes":224,"imports":[],"format":"esm"},"app/javascript/drivers/frame.js":{"bytes":218,"imports":[{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/method.js":{"bytes":265,"imports":[{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/window.js":{"bytes":1836,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"../state"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"../lifecycle"},{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"app/javascript/renderer.js","kind":"import-statement","original":"../renderer"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/index.js":{"bytes":2044,"imports":[{"path":"app/javascript/elements.js","kind":"import-statement","original":"../elements"},{"path":"app/javascript/drivers/form.js","kind":"import-statement","original":"./form"},{"path":"app/javascript/drivers/frame.js","kind":"import-statement","original":"./frame"},{"path":"app/javascript/drivers/method.js","kind":"import-statement","original":"./method"},{"path":"app/javascript/drivers/window.js","kind":"import-statement","original":"./window"}],"format":"esm"},"app/javascript/logger.js":{"bytes":729,"imports":[{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"}],"format":"esm"},"app/javascript/uuids.js":{"bytes":202,"imports":[],"format":"esm"},"app/javascript/index.js":{"bytes":3731,"imports":[{"path":"app/javascript/turbo.js","kind":"import-statement","original":"./turbo"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/activity.js","kind":"import-statement","original":"./activity"},{"path":"app/javascript/confirmation.js","kind":"import-statement","original":"./confirmation"},{"path":"app/javascript/delegates.js","kind":"import-statement","original":"./delegates"},{"path":"app/javascript/drivers/index.js","kind":"import-statement","original":"./drivers"},{"path":"app/javascript/meta.js","kind":"import-statement","original":"./meta"},{"path":"app/javascript/elements.js","kind":"import-statement","original":"./elements"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"},{"path":"app/javascript/logger.js","kind":"import-statement","original":"./logger"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"./state"},{"path":"app/javascript/urls.js","kind":"import-statement","original":"./urls"},{"path":"app/javascript/uuids.js","kind":"import-statement","original":"./uuids"},{"path":"","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"app/assets/builds/@turbo-boost/commands.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":36721},"app/assets/builds/@turbo-boost/commands.js":{"imports":[],"exports":["default"],"entryPoint":"app/javascript/index.js","inputs":{"app/javascript/meta.js":{"bytesInOutput":359},"app/javascript/events.js":{"bytesInOutput":500},"app/javascript/state/observable.js":{"bytesInOutput":405},"app/javascript/state/index.js":{"bytesInOutput":587},"app/javascript/renderer.js":{"bytesInOutput":263},"app/javascript/activity.js":{"bytesInOutput":173},"app/javascript/lifecycle.js":{"bytesInOutput":294},"app/javascript/turbo.js":{"bytesInOutput":889},"app/javascript/schema.js":{"bytesInOutput":166},"app/javascript/confirmation.js":{"bytesInOutput":424},"app/javascript/delegates.js":{"bytesInOutput":473},"app/javascript/elements.js":{"bytesInOutput":782},"app/javascript/drivers/form.js":{"bytesInOutput":246},"app/javascript/urls.js":{"bytesInOutput":150},"app/javascript/drivers/frame.js":{"bytesInOutput":96},"app/javascript/drivers/method.js":{"bytesInOutput":130},"app/javascript/drivers/window.js":{"bytesInOutput":1146},"app/javascript/drivers/index.js":{"bytesInOutput":991},"app/javascript/logger.js":{"bytesInOutput":399},"app/javascript/uuids.js":{"bytesInOutput":159},"app/javascript/index.js":{"bytesInOutput":1746}},"bytes":10875}}} \ No newline at end of file diff --git a/app/javascript/drivers/form.js b/app/javascript/drivers/form.js index d8c86953..84bb2e3d 100644 --- a/app/javascript/drivers/form.js +++ b/app/javascript/drivers/form.js @@ -1,7 +1,4 @@ -import meta from '../meta' - function invokeCommand(form, payload = {}, event = {}) { - payload.token = meta.token const input = form.querySelector('input[name="turbo_boost_command"]') || document.createElement('input') input.type = 'hidden' input.name = 'turbo_boost_command' diff --git a/app/javascript/drivers/window.js b/app/javascript/drivers/window.js index 244d4cc6..c44bc6ea 100644 --- a/app/javascript/drivers/window.js +++ b/app/javascript/drivers/window.js @@ -1,4 +1,3 @@ -import meta from '../meta' import state from '../state' import { dispatch } from '../events' import lifecycle from '../lifecycle' diff --git a/app/javascript/index.js b/app/javascript/index.js index 206f5c7a..0ca8c2af 100644 --- a/app/javascript/index.js +++ b/app/javascript/index.js @@ -1,11 +1,10 @@ import './turbo' import schema from './schema' -import { dispatch, commandEvents, stateEvents } from './events' +import { dispatch, commandEvents } from './events' import activity from './activity' import confirmation from './confirmation' import delegates from './delegates' import drivers from './drivers' -import meta from './meta' import elements from './elements' import lifecycle from './lifecycle' import logger from './logger' @@ -13,6 +12,20 @@ import state from './state' import urls from './urls' import uuids from './uuids' +const TurboBoost = self.TurboBoost || {} + +const Commands = { + busy: false, + confirmation, + logger, + schema, + events: commandEvents, + registerEventDelegate: delegates.register, + get eventDelegates() { + return delegates.events + } +} + function buildCommandPayload(id, element) { return { id, // uniquely identifies the command @@ -20,9 +33,9 @@ function buildCommandPayload(id, element) { elementId: element.id.length > 0 ? element.id : null, elementAttributes: elements.buildAttributePayload(element), startedAt: Date.now(), - token: meta.token, // authenticity token - signedState: meta.signedState, // server side state - state: state.changed // client side state (optimistic updates) + token: Commands.token, // command token (used for CSRF protection) + signedState: state.signed, // server side state + clientState: state.changed // client side state (optimistic updates) } } @@ -70,8 +83,8 @@ async function invokeCommand(event) { if (['frame', 'window'].includes(driver.name)) event.preventDefault() - meta.busy = true - setTimeout(() => (meta.busy = false), 10) + Commands.busy = true + setTimeout(() => (Commands.busy = false), 10) switch (driver.name) { case 'method': @@ -90,21 +103,7 @@ async function invokeCommand(event) { } } -self.TurboBoost = self.TurboBoost || {} - -self.TurboBoost = { - ...self.TurboBoost, - - stateEvents, - - get state() { - return state.current - }, - - get stateChanges() { - return state.changed - } -} +self.TurboBoost = { ...TurboBoost } if (!self.TurboBoost.Commands) { // wire things up and setup defaults for event delegation @@ -117,16 +116,8 @@ if (!self.TurboBoost.Commands) { `textarea[${schema.commandAttribute}]` ]) - self.TurboBoost.Commands = { - confirmation, - logger, - schema, - events: commandEvents, - registerEventDelegate: delegates.register, - get eventDelegates() { - return delegates.events - } - } + self.TurboBoost.Commands = Commands + self.TurboBoost.State = state } -export default self.TurboBoost.Commands +export default Commands diff --git a/app/javascript/meta.js b/app/javascript/meta.js deleted file mode 100644 index 3ee2b3a4..00000000 --- a/app/javascript/meta.js +++ /dev/null @@ -1,31 +0,0 @@ -class Meta { - get element() { - return document.querySelector('meta[name="turbo-boost"]') - } - - // token that can be used to verify the authenticity of a command - get token() { - return this.element.getAttribute('content') - } - - // indicates if a command is active - get busy() { - return this.element.dataset.busy === 'true' - } - - set busy(value = false) { - return (this.element.dataset.busy = !!value) - } - - // mutable state representation for use on the client - get state() { - return this.element.dataset.state - } - - // signed and immutable server state determined by the last command - get signedState() { - return this.element.dataset.signedState - } -} - -export default new Meta() diff --git a/app/javascript/state/index.js b/app/javascript/state/index.js index 16d48069..cb169cd6 100644 --- a/app/javascript/state/index.js +++ b/app/javascript/state/index.js @@ -1,46 +1,33 @@ -import meta from '../meta' +// TODO: Consider moving State to its own library import observable from './observable' import { dispatch, commandEvents, stateEvents } from '../events' -let initialState, currentState, changedState -let loadStateTimeout +let initialState, currentState, changedState, signedState -function loadState() { - if (!meta.element) return loadStateLater() - const json = JSON.parse(meta.element.dataset.state) +function initialize(initial, signed) { + const json = JSON.parse(initial) initialState = { ...json } + signedState = signed currentState = observable(json) changedState = {} setTimeout(() => - dispatch(stateEvents.stateLoad, meta.element, { + dispatch(stateEvents.stateLoad, document, { detail: { state: currentState } }) ) } -function loadStateLater() { - clearTimeout(loadStateTimeout) - loadStateTimeout = setTimeout(loadState, 10) -} - -if (!initialState) loadState() - -addEventListener('DOMContentLoaded', loadStateLater) -addEventListener('load', loadStateLater) -addEventListener('turbo:load', loadStateLater) -addEventListener('turbo:frame-load', loadStateLater) -addEventListener(commandEvents.success, loadStateLater) - addEventListener(stateEvents.stateChange, event => { for (const [key, value] of Object.entries(currentState)) if (initialState[key] !== value) changedState[key] = value }) export default { + initialize, events: stateEvents, get initial() { - return { ...initialState } + return initialState }, get current() { @@ -48,6 +35,10 @@ export default { }, get changed() { - return { ...changedState } + return changedState + }, + + get signed() { + return signedState } } diff --git a/app/javascript/state/observable.js b/app/javascript/state/observable.js index f1c54bf8..e62de944 100644 --- a/app/javascript/state/observable.js +++ b/app/javascript/state/observable.js @@ -1,4 +1,3 @@ -import meta from '../meta' import { dispatch, stateEvents as events } from '../events' let head @@ -9,13 +8,13 @@ function observable(object, parent = null) { const proxy = new Proxy(object, { deleteProperty(target, key) { delete target[key] - dispatch(events.stateChange, meta.element, { detail: { state: head } }) + dispatch(events.stateChange, document, { detail: { state: head } }) return true }, set(target, key, value, receiver) { target[key] = observable(value, this) - dispatch(events.stateChange, meta.element, { detail: { state: head } }) + dispatch(events.stateChange, document, { detail: { state: head } }) return true } }) diff --git a/app/javascript/turbo.js b/app/javascript/turbo.js index 67cdb1fb..24cd7308 100644 --- a/app/javascript/turbo.js +++ b/app/javascript/turbo.js @@ -1,4 +1,3 @@ -import meta from './meta' import state from './state' import renderer from './renderer' import { dispatch } from './events' @@ -12,7 +11,7 @@ addEventListener('turbo:before-fetch-request', event => { const { fetchOptions } = event.detail // command invoked and busy - if (meta.busy) { + if (self.TurboBoost?.Commands?.busy) { let acceptHeaders = ['text/vnd.turbo-boost.html', fetchOptions.headers['Accept']] acceptHeaders = acceptHeaders.filter(entry => entry && entry.trim().length > 0).join(', ') fetchOptions.headers['Accept'] = acceptHeaders diff --git a/bin/docker/run/local b/bin/docker/run/local index 1c182fda..f17883e0 100755 --- a/bin/docker/run/local +++ b/bin/docker/run/local @@ -21,38 +21,15 @@ fi # ============================================================================================================ rm -rfv /app/node_modules ln -snv /mnt/external/node_modules /app/node_modules +yarn set version stable yarn install - bundle install # ============================================================================================================ # Playwright Dependencies - SEE: https://playwright.dev # ============================================================================================================ -apt-get -y --no-install-recommends install \ -libasound2 \ -libatk-bridge2.0-0 \ -libatk1.0-0 \ -libc6 \ -libcairo-gobject2 \ -libcairo2 \ -libcups2 \ -libdbus-1-3 \ -libexpat1 \ -libfontconfig1 \ -libfreetype6 \ -libgbm1 \ -libgdk-pixbuf2.0-0 \ -libglib2.0-0 \ -libgtk-3-0 \ -libnss3 \ -libpango-1.0-0 \ -libpangocairo-1.0-0 \ -libstdc++6 \ -zlib1g - -apt-get clean -yarn playwright install +yarn playwright install --with-deps # ============================================================================================================ diff --git a/bin/standardize b/bin/standardize index ceac538e..2509a5a4 100755 --- a/bin/standardize +++ b/bin/standardize @@ -1,7 +1,7 @@ #!/bin/bash +shopt -s globstar bundle exec magic_frozen_string_literal bundle exec standardrb --fix -yarn run prettier --write package.json prettier.config.js bin/build.mjs app/javascript/**/**/**/**/*.js test/dummy/app/javascript/**/**/**/**/*.js test/dummy/app/assets/stylesheets/**/**/**/**/*.css test/dummy/app/views/**/**/**/**/*.css - +yarn run prettier --write . cd test/dummy && bin/rails tailwindcss:clobber tailwindcss:build && cd - diff --git a/docker-compose.yml b/docker-compose.yml index 8da2582d..ab32dc21 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,13 +26,13 @@ x-default-app: &default_app - external:/mnt/external services: - # ========================================================================================================== - # Shell - # ========================================================================================================== - shell: - <<: *default_app - container_name: turbo_boost-commands-shell - command: tail -f /dev/null + ## ========================================================================================================== + ## Shell + ## ========================================================================================================== + #shell: + # <<: *default_app + # container_name: turbo_boost-commands-shell + # command: tail -f /dev/null # ========================================================================================================== # Web - Runs the test/dummy Rails app diff --git a/lib/turbo_boost/commands/controller_pack.rb b/lib/turbo_boost/commands/controller_pack.rb index d4d07f02..7b4d464a 100644 --- a/lib/turbo_boost/commands/controller_pack.rb +++ b/lib/turbo_boost/commands/controller_pack.rb @@ -15,7 +15,6 @@ class TurboBoost::Commands::ControllerPack :command_requested?, :command_succeeded?, :controller, - :meta_tag, :state, to: :runner ) diff --git a/lib/turbo_boost/commands/runner.rb b/lib/turbo_boost/commands/runner.rb index e4f71208..042b009a 100644 --- a/lib/turbo_boost/commands/runner.rb +++ b/lib/turbo_boost/commands/runner.rb @@ -16,21 +16,6 @@ def initialize(controller) @controller = controller end - def meta_tag - masked_token = message_verifier.generate(new_token) - options = { - id: "turbo-boost", - name: "turbo-boost", - content: masked_token, # A signed token that can be used to verify command invocation - data: { - busy: false, # Indicates if a Command is active - state: state.to_json, # JSON that represents the current state - signed_state: state.to_sgid_param # Signed value that represents the current state (restored when commands are invoked) - } - } - controller.view_context.tag("meta", options).html_safe - end - def state @state ||= begin sgid = command_params[:signed_state] @@ -138,6 +123,7 @@ def run return if command_errored? return if command_performing? return if command_performed? + state.resolve command_params[:state] command_instance.perform_with_callbacks command_method_name end @@ -160,7 +146,8 @@ def prevent_controller_action(error: nil) append_error_to_response error end - append_meta_tag_to_response_body + append_authenticity_token_to_response_body + append_command_state_to_response_body end def update_response @@ -170,7 +157,8 @@ def update_response return if controller_action_prevented? append_to_response_headers - append_meta_tag_to_response_body + append_authenticity_token_to_response_body + append_command_state_to_response_body append_success_to_response if command_succeeded? rescue => error Rails.logger.error "TurboBoost::Commands::Runner failed to update the response! #{error.message}" @@ -264,10 +252,16 @@ def append_streams_to_response_body command_instance.turbo_streams.each { |stream| append_to_response_body stream } end - def append_meta_tag_to_response_body - append_to_response_body turbo_stream.invoke("morph", args: [meta_tag], selector: "#turbo-boost") + def append_authenticity_token_to_response_body + append_to_response_body turbo_stream.invoke("TurboBoost.Commands.token=", args: [new_token], camelize: false) + rescue => error + Rails.logger.error "TurboBoost::Commands::Runner failed to append the Command token to the response! #{error.message}" + end + + def append_command_state_to_response_body + append_to_response_body turbo_stream.invoke("TurboBoost.State.initialize", args: [state.to_json, state.to_sgid_param], camelize: false) rescue => error - Rails.logger.error "TurboBoost::Commands::Runner failed to append the meta tag to the response! #{error.message}" + Rails.logger.error "TurboBoost::Commands::Runner failed to append the Command state to the response! #{error.message}" end def append_success_event_to_response_body diff --git a/lib/turbo_boost/commands/state.rb b/lib/turbo_boost/commands/state.rb index 11ebd8d4..7ef7e4f7 100644 --- a/lib/turbo_boost/commands/state.rb +++ b/lib/turbo_boost/commands/state.rb @@ -1,27 +1,39 @@ # frozen_string_literal: true class TurboBoost::Commands::State + include Enumerable + class << self def from_sgid_param(sgid) new URI::UID.from_sgid(sgid, for: name)&.decode end + attr_reader :resolver + def assign_resolver(&block) @resolver = block end - - def resolver - @resolver || ->(*_) {} - end end def initialize(store = nil) - @store = store || ActiveSupport::Cache::MemoryStore.new(expires_in: 1.week, size: 32.kilobytes) + @store = store || ActiveSupport::Cache::MemoryStore.new(expires_in: 1.day, size: 2.kilobytes) @store.cleanup end delegate_missing_to :store + def each + data.keys.each do |key| + yield key, self[key] + end + end + + # TODO: implement state resolution + def resolve(client_state) + # return unless self.class.resolver + # self.class.resolver.call self, client_state + end + def cache_key "TurboBoost::Commands::State/#{Digest::SHA2.base64digest(to_json)}" end @@ -34,13 +46,6 @@ def []=(...) store.write(...) end - def to_h - store.cleanup - data.each_with_object(HashWithIndifferentAccess.new) do |(key, entry), memo| - memo[key] = entry.value - end - end - def to_json to_h.to_json end diff --git a/package.json b/package.json index e6fa5ff1..cbab957f 100644 --- a/package.json +++ b/package.json @@ -9,37 +9,45 @@ "turbo", "turbo-boost" ], - "main": "app/assets/builds/@turbo-boost/commands.js", + "main": "commands.js", "files": [ - "app/assets/builds/*" + "app/assets/builds/@turbo-boost/**/*{.js,.map}" ], "repository": "https://github.com/hopsoft/turbo_boost-commands", "author": "Nate Hopkins (hopsoft) ", "license": "MIT", - "dependencies": {}, + "dependencies": { + "@turbo-boost/streams": "^0.1.6" + }, "peerDependencies": { + "@alpinejs/morph": ">= 3.13.5", "@hotwired/turbo-rails": ">= 7.2.0", - "@turbo-boost/streams": "^0.0.8" - }, - "peerDependenciesMeta": { - "@turbo-boost/streams": { - "optional": true - } + "alpinejs": ">= 3.13.5" }, "devDependencies": { "@tailwindcss/aspect-ratio": "^0.4.2", - "@tailwindcss/forms": "^0.5.4", - "@tailwindcss/typography": "^0.5.9", + "@tailwindcss/forms": "^0.5.7", + "@tailwindcss/typography": "^0.5.10", "esbuild": "^0.20.0", - "flowbite": "1.8.1", - "playwright": "^1.36.2", - "prettier": "^3.0.0", - "prettier-plugin-tailwindcss": "^0.5.4", - "tailwindcss": "^3.3.3" + "flowbite": "1.7.0", + "playwright": "^1.41.2", + "prettier": "^3.2.5", + "prettier-plugin-tailwindcss": "^0.5.11", + "tailwindcss": "^3.4.1" }, "scripts": { - "build": "bin/standardize && node bin/build.mjs", - "build:all": "bin/standardize && node bin/build.mjs && rake build", + "build": "node bin/build.mjs", "build:watch": "yarn build --watch" + }, + "resolutions": { + "postcss-selector-parser": "6.0.10", + "fsevents": "2.3.2", + "glob-parent": "6.0.2", + "lilconfig": "2.1.0", + "string-width": "5.1.2", + "strip-ansi": "7.1.0", + "emoji-regex": "9.2.2", + "ansi-regex": "6.0.1", + "ansi-styles": "6.2.1" } } diff --git a/test/dummy/app/assets/builds/tailwind.css b/test/dummy/app/assets/builds/tailwind.css index a8dc39b6..2be55b7d 100644 --- a/test/dummy/app/assets/builds/tailwind.css +++ b/test/dummy/app/assets/builds/tailwind.css @@ -1 +1 @@ -/*! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:Raleway,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:Consolas,Menlo,Courier New;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236B7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E")}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=radio]:checked:focus,[type=radio]:checked:hover{background-color:currentColor;border-color:#0000}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-size:100% 100%}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}.tooltip-arrow,.tooltip-arrow:before{background:inherit;height:8px;position:absolute;width:8px}.tooltip-arrow{visibility:hidden}.tooltip-arrow:before{content:"";transform:rotate(45deg);visibility:visible}[data-tooltip-style^=light]+.tooltip>.tooltip-arrow:before{border-color:#e5e7eb;border-style:solid}[data-tooltip-style^=light]+.tooltip[data-popper-placement^=top]>.tooltip-arrow:before{border-bottom-width:1px;border-right-width:1px}[data-tooltip-style^=light]+.tooltip[data-popper-placement^=right]>.tooltip-arrow:before{border-bottom-width:1px;border-left-width:1px}[data-tooltip-style^=light]+.tooltip[data-popper-placement^=bottom]>.tooltip-arrow:before{border-left-width:1px;border-top-width:1px}[data-tooltip-style^=light]+.tooltip[data-popper-placement^=left]>.tooltip-arrow:before{border-right-width:1px;border-top-width:1px}.tooltip[data-popper-placement^=top]>.tooltip-arrow{bottom:-4px}.tooltip[data-popper-placement^=bottom]>.tooltip-arrow{top:-4px}.tooltip[data-popper-placement^=left]>.tooltip-arrow{right:-4px}.tooltip[data-popper-placement^=right]>.tooltip-arrow{left:-4px}.tooltip.invisible>.tooltip-arrow:before{visibility:hidden}[data-popper-arrow],[data-popper-arrow]:before{background:inherit;height:8px;position:absolute;width:8px}[data-popper-arrow]{visibility:hidden}[data-popper-arrow]:after,[data-popper-arrow]:before{content:"";transform:rotate(45deg);visibility:visible}[data-popper-arrow]:after{background:inherit;height:9px;position:absolute;width:9px}[role=tooltip]>[data-popper-arrow]:before{border-color:#e5e7eb;border-style:solid}.dark [role=tooltip]>[data-popper-arrow]:before{border-color:#4b5563;border-style:solid}[role=tooltip]>[data-popper-arrow]:after{border-color:#e5e7eb;border-style:solid}.dark [role=tooltip]>[data-popper-arrow]:after{border-color:#4b5563;border-style:solid}[data-popover][role=tooltip][data-popper-placement^=top]>[data-popper-arrow]:after,[data-popover][role=tooltip][data-popper-placement^=top]>[data-popper-arrow]:before{border-bottom-width:1px;border-right-width:1px}[data-popover][role=tooltip][data-popper-placement^=right]>[data-popper-arrow]:after,[data-popover][role=tooltip][data-popper-placement^=right]>[data-popper-arrow]:before{border-bottom-width:1px;border-left-width:1px}[data-popover][role=tooltip][data-popper-placement^=bottom]>[data-popper-arrow]:after,[data-popover][role=tooltip][data-popper-placement^=bottom]>[data-popper-arrow]:before{border-left-width:1px;border-top-width:1px}[data-popover][role=tooltip][data-popper-placement^=left]>[data-popper-arrow]:after,[data-popover][role=tooltip][data-popper-placement^=left]>[data-popper-arrow]:before{border-right-width:1px;border-top-width:1px}[data-popover][role=tooltip][data-popper-placement^=top]>[data-popper-arrow]{bottom:-5px}[data-popover][role=tooltip][data-popper-placement^=bottom]>[data-popper-arrow]{top:-5px}[data-popover][role=tooltip][data-popper-placement^=left]>[data-popper-arrow]{right:-5px}[data-popover][role=tooltip][data-popper-placement^=right]>[data-popper-arrow]{left:-5px}[role=tooltip].invisible>[data-popper-arrow]:after,[role=tooltip].invisible>[data-popper-arrow]:before{visibility:hidden}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],select,textarea{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,select:focus,textarea:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#1c64f2;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#1c64f2;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em}select:not([size]){background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' aria-hidden='true' viewBox='0 0 10 6'%3E%3Cpath stroke='%236B7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 1 4 4 4-4'/%3E%3C/svg%3E");background-position:right .75rem center;background-repeat:no-repeat;background-size:.75em .75em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple]{background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#1c64f2;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1rem}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#1c64f2;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}.dark [type=checkbox]:checked,.dark [type=radio]:checked,[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:.55em .55em;border-color:#0000}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' aria-hidden='true' viewBox='0 0 16 12'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M1 5.917 5.724 10.5 15 1.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:.55em .55em;-webkit-print-color-adjust:exact;print-color-adjust:exact}.dark [type=radio]:checked,[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E");background-size:1em 1em}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' aria-hidden='true' viewBox='0 0 16 12'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M1 5.917 5.724 10.5 15 1.5'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:.55em .55em;-webkit-print-color-adjust:exact;print-color-adjust:exact}[type=checkbox]:indeterminate,[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}[type=file]{background:unset;border-color:inherit;border-radius:0;border-width:0;font-size:unset;line-height:inherit;padding:0}[type=file]:focus{outline:1px auto inherit}input[type=file]::file-selector-button{background:#1f2937;border:0;color:#fff;cursor:pointer;font-size:.875rem;font-weight:500;margin-inline-end:1rem;margin-inline-start:-1rem;padding:.625rem 1rem .625rem 2rem}input[type=file]::file-selector-button:hover{background:#374151}.dark input[type=file]::file-selector-button{background:#4b5563;color:#fff}.dark input[type=file]::file-selector-button:hover{background:#6b7280}input[type=range]::-webkit-slider-thumb{appearance:none;-moz-appearance:none;-webkit-appearance:none;background:#1c64f2;border:0;border-radius:9999px;cursor:pointer;height:1.25rem;width:1.25rem}input[type=range]:disabled::-webkit-slider-thumb{background:#9ca3af}.dark input[type=range]:disabled::-webkit-slider-thumb{background:#6b7280}input[type=range]:focus::-webkit-slider-thumb{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1px;--tw-ring-color:rgb(164 202 254/var(--tw-ring-opacity));box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);outline:2px solid #0000;outline-offset:2px}input[type=range]::-moz-range-thumb{appearance:none;-moz-appearance:none;-webkit-appearance:none;background:#1c64f2;border:0;border-radius:9999px;cursor:pointer;height:1.25rem;width:1.25rem}input[type=range]:disabled::-moz-range-thumb{background:#9ca3af}.dark input[type=range]:disabled::-moz-range-thumb{background:#6b7280}input[type=range]::-moz-range-progress{background:#3f83f8}input[type=range]::-ms-fill-lower{background:#3f83f8}code{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity));border-radius:.25rem;font-size:.875rem;line-height:1.25rem;padding:.125rem .25rem}:is(.dark code){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3f83f880;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }#basic_command-no-frame,#basic_command-turbo-frame{border-radius:.5rem;border-width:1px;display:block;margin-left:auto;margin-right:auto;max-width:1280px;position:relative}#basic_command-no-frame{--tw-border-opacity:1;border-color:rgb(14 165 233/var(--tw-border-opacity));padding:1rem}:is(.dark #basic_command-no-frame){--tw-border-opacity:1;border-color:rgb(7 89 133/var(--tw-border-opacity))}#basic_command-no-frame:before{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(14 165 233/var(--tw-bg-opacity));border-top-left-radius:.25rem;border-top-right-radius:.25rem;color:rgb(255 255 255/var(--tw-text-opacity));content:"";display:inline-block;font-family:Consolas,Menlo,Courier New;font-size:.75rem;left:1rem;line-height:1rem;padding-left:.5rem;padding-right:.5rem;position:absolute;top:-1rem}:is(.dark #basic_command-no-frame):before{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(7 89 133/var(--tw-bg-opacity));color:rgb(186 230 253/var(--tw-text-opacity))}#basic_command-turbo-frame{--tw-border-opacity:1;border-color:rgb(244 63 94/var(--tw-border-opacity));padding:1rem}:is(.dark #basic_command-turbo-frame){--tw-border-opacity:1;border-color:rgb(159 18 57/var(--tw-border-opacity))}#basic_command-turbo-frame:before{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(244 63 94/var(--tw-bg-opacity));border-top-left-radius:.25rem;border-top-right-radius:.25rem;color:rgb(255 255 255/var(--tw-text-opacity));content:"";display:inline-block;font-family:Consolas,Menlo,Courier New;font-size:.75rem;left:1rem;line-height:1rem;padding-left:.5rem;padding-right:.5rem;position:absolute;top:-1rem}:is(.dark #basic_command-turbo-frame):before{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(159 18 57/var(--tw-bg-opacity));color:rgb(254 205 211/var(--tw-text-opacity))}#basic_command-no-frame>h3,#basic_command-turbo-frame>h3{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity));font-size:1.5rem;font-weight:600;line-height:2rem}:is(.dark #basic_command-no-frame>h3),:is(.dark #basic_command-turbo-frame>h3){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}@media (min-width:768px){#basic_command-no-frame>h3,#basic_command-turbo-frame>h3{font-size:1.5rem;line-height:2rem}}#basic_command-no-frame>p,#basic_command-turbo-frame>p{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity));font-weight:300;margin-bottom:1rem}:is(.dark #basic_command-no-frame>p),:is(.dark #basic_command-turbo-frame>p){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}#basic_command-no-frame>code,#basic_command-turbo-frame>code{--tw-text-opacity:1;color:rgb(240 82 82/var(--tw-text-opacity));font-size:1.875rem;font-weight:700;line-height:2.25rem;padding:.25rem .75rem}@media (min-width:768px){#basic_command-no-frame>code,#basic_command-turbo-frame>code{font-size:2.25rem;line-height:2.5rem}}#basic_command-no-frame>div,#basic_command-turbo-frame>div{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);border-radius:.375rem;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);display:flex}#basic_command-no-frame>div:last-child,#basic_command-turbo-frame>div:last-child{margin-top:1.25rem}#basic_command-no-frame>div>button,#basic_command-turbo-frame>div>button{--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1;align-items:center;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-color:rgb(229 231 235/var(--tw-border-opacity));border-width:1px;color:rgb(17 24 39/var(--tw-text-opacity));display:inline-flex;font-size:.875rem;font-weight:500;line-height:1.25rem;padding:.5rem 1rem}#basic_command-no-frame>div>button:hover,#basic_command-turbo-frame>div>button:hover{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity));color:rgb(26 86 219/var(--tw-text-opacity))}#basic_command-no-frame>div>button:focus,#basic_command-turbo-frame>div>button:focus{--tw-text-opacity:1;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(26 86 219/var(--tw-ring-opacity));box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:rgb(26 86 219/var(--tw-text-opacity));z-index:10}:is(.dark #basic_command-no-frame>div>button),:is(.dark #basic_command-turbo-frame>div>button){--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity));border-color:rgb(75 85 99/var(--tw-border-opacity));color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark #basic_command-no-frame>div>button:hover),:is(.dark #basic_command-turbo-frame>div>button:hover){--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity));color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark #basic_command-no-frame>div>button:focus),:is(.dark #basic_command-turbo-frame>div>button:focus){--tw-text-opacity:1;--tw-ring-opacity:1;--tw-ring-color:rgb(63 131 248/var(--tw-ring-opacity));color:rgb(255 255 255/var(--tw-text-opacity))}#basic_command-no-frame>div>button:first-child,#basic_command-turbo-frame>div>button:first-child{border-bottom-left-radius:.5rem;border-top-left-radius:.5rem}#basic_command-no-frame>div>button:last-child,#basic_command-turbo-frame>div>button:last-child{border-bottom-right-radius:.375rem;border-top-right-radius:.375rem}#basic_command-no-frame>div>button>svg,#basic_command-turbo-frame>div>button>svg{height:.75rem;margin-right:.25rem;width:.75rem}.feature p em{--tw-text-opacity:1;color:rgb(255 152 0/var(--tw-text-opacity));font-style:normal}:is(.dark .feature p em){--tw-text-opacity:1;color:rgb(255 183 77/var(--tw-text-opacity))}.feature p i{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity));font-style:normal;text-decoration-color:#4b5563;text-decoration-line:underline;text-decoration-style:dotted;text-underline-offset:4px}:is(.dark .feature p i){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity));text-decoration-color:#9ca3af}.instruction>p{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity));font-size:1rem;font-weight:400;line-height:1.5rem;margin-bottom:.5rem;margin-top:.5rem}:is(.dark .instruction>p){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}@media (min-width:640px){.instruction>p{font-size:1.125rem;line-height:1.75rem}}.sr-only{clip:rect(0,0,0,0);border-width:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-y-0{bottom:0;top:0}.bottom-0{bottom:0}.left-0{left:0}.right-0{right:0}.top-0{top:0}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.m-5{margin:1.25rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-auto{margin-left:auto;margin-right:auto}.my-12{margin-bottom:3rem;margin-top:3rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-4{margin-bottom:1rem;margin-top:1rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.\!mt-6{margin-top:1.5rem!important}.-mr-1{margin-right:-.25rem}.-mt-5{margin-top:-1.25rem}.-mt-px{margin-top:-1px}.mb-0{margin-bottom:0}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-6{margin-left:1.5rem}.ml-px{margin-left:1px}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.mt-10{margin-top:2.5rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-14{height:3.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.w-1\/2{width:50%}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-14{width:3.5rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-full{width:100%}.max-w-2xl{max-width:42rem}.max-w-screen-md{max-width:768px}.max-w-screen-xl{max-width:1280px}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%}.-translate-x-full,.rotate-180{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}.cursor-pointer{cursor:pointer}.list-decimal{list-style-type:decimal}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-gray-100>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(243 244 246/var(--tw-divide-opacity))}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-b-none{border-bottom-left-radius:0;border-bottom-right-radius:0}.rounded-l-lg{border-bottom-left-radius:.5rem;border-top-left-radius:.5rem}.rounded-r-lg{border-bottom-right-radius:.5rem}.rounded-r-lg,.rounded-t-lg{border-top-right-radius:.5rem}.rounded-t-lg{border-top-left-radius:.5rem}.rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.border{border-width:1px}.border-0{border-width:0}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-0{border-bottom-width:0}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t-0{border-top-width:0}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-rose-400{--tw-border-opacity:1;border-color:rgb(251 113 133/var(--tw-border-opacity))}.border-white{--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}.\!bg-red-500{--tw-bg-opacity:1!important;background-color:rgb(240 82 82/var(--tw-bg-opacity))!important}.bg-blue-100{--tw-bg-opacity:1;background-color:rgb(225 239 254/var(--tw-bg-opacity))}.bg-blue-50{--tw-bg-opacity:1;background-color:rgb(235 245 255/var(--tw-bg-opacity))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(63 131 248/var(--tw-bg-opacity))}.bg-blue-700{--tw-bg-opacity:1;background-color:rgb(26 86 219/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-gray-300{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-50\/30{background-color:#f9fafb4d}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.bg-green-400{--tw-bg-opacity:1;background-color:rgb(49 196 141/var(--tw-bg-opacity))}.bg-green-50{--tw-bg-opacity:1;background-color:rgb(243 250 247/var(--tw-bg-opacity))}.bg-primary-100{--tw-bg-opacity:1;background-color:rgb(187 222 251/var(--tw-bg-opacity))}.bg-primary-700{--tw-bg-opacity:1;background-color:rgb(25 118 210/var(--tw-bg-opacity))}.bg-primary-800{--tw-bg-opacity:1;background-color:rgb(21 101 192/var(--tw-bg-opacity))}.bg-purple-500{--tw-bg-opacity:1;background-color:rgb(144 97 249/var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(240 82 82/var(--tw-bg-opacity))}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(224 36 36/var(--tw-bg-opacity))}.bg-transparent{background-color:initial}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-yellow-50{--tw-bg-opacity:1;background-color:rgb(253 253 234/var(--tw-bg-opacity))}.object-cover{-o-object-fit:cover;object-fit:cover}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-2\.5{padding-bottom:.625rem;padding-top:.625rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-5{padding-bottom:1.25rem;padding-top:1.25rem}.py-8{padding-bottom:2rem;padding-top:2rem}.pl-10{padding-left:2.5rem}.pl-3{padding-left:.75rem}.pr-5{padding-right:1.25rem}.pt-14{padding-top:3.5rem}.pt-20{padding-top:5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-bottom{vertical-align:bottom}.font-mono{font-family:Consolas,Menlo,Courier New}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-light{font-weight:300}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.italic{font-style:italic}.leading-6{line-height:1.5rem}.leading-9{line-height:2.25rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.text-blue-600{--tw-text-opacity:1;color:rgb(28 100 242/var(--tw-text-opacity))}.text-blue-800{--tw-text-opacity:1;color:rgb(30 66 159/var(--tw-text-opacity))}.text-emerald-500{--tw-text-opacity:1;color:rgb(16 185 129/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-green-500{--tw-text-opacity:1;color:rgb(14 159 110/var(--tw-text-opacity))}.text-green-800{--tw-text-opacity:1;color:rgb(3 84 63/var(--tw-text-opacity))}.text-primary-300{--tw-text-opacity:1;color:rgb(100 181 246/var(--tw-text-opacity))}.text-primary-600{--tw-text-opacity:1;color:rgb(30 136 229/var(--tw-text-opacity))}.text-primary-700{--tw-text-opacity:1;color:rgb(25 118 210/var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgb(240 82 82/var(--tw-text-opacity))}.text-rose-400{--tw-text-opacity:1;color:rgb(251 113 133/var(--tw-text-opacity))}.text-secondary-400{--tw-text-opacity:1;color:rgb(92 107 192/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-yellow-800{--tw-text-opacity:1;color:rgb(114 59 19/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.decoration-gray-500{text-decoration-color:#6b7280}.decoration-gray-600{text-decoration-color:#4b5563}.decoration-red-500\/80{text-decoration-color:#f05252cc}.decoration-dotted{text-decoration-style:dotted}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.underline-offset-8{text-underline-offset:8px}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-md,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-gray-100{--tw-shadow-color:#f3f4f6;--tw-shadow:var(--tw-shadow-colored)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-75{transition-duration:75ms}.hover\:bg-blue-100:hover{--tw-bg-opacity:1;background-color:rgb(225 239 254/var(--tw-bg-opacity))}.hover\:bg-blue-800:hover{--tw-bg-opacity:1;background-color:rgb(30 66 159/var(--tw-bg-opacity))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.hover\:bg-primary-800:hover{--tw-bg-opacity:1;background-color:rgb(21 101 192/var(--tw-bg-opacity))}.hover\:bg-primary-900:hover{--tw-bg-opacity:1;background-color:rgb(13 71 161/var(--tw-bg-opacity))}.hover\:text-blue-600:hover{--tw-text-opacity:1;color:rgb(28 100 242/var(--tw-text-opacity))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.hover\:text-primary-700:hover{--tw-text-opacity:1;color:rgb(25 118 210/var(--tw-text-opacity))}.hover\:underline:hover{text-decoration-line:underline}.focus\:z-10:focus{z-index:10}.focus\:border-primary-500:focus{--tw-border-opacity:1;border-color:rgb(33 150 243/var(--tw-border-opacity))}.focus\:bg-gray-100:focus{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.focus\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring-2:focus,.focus\:ring-4:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-4:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring-blue-200:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(195 221 253/var(--tw-ring-opacity))}.focus\:ring-blue-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(164 202 254/var(--tw-ring-opacity))}.focus\:ring-gray-100:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(243 244 246/var(--tw-ring-opacity))}.focus\:ring-gray-200:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(229 231 235/var(--tw-ring-opacity))}.focus\:ring-gray-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(209 213 219/var(--tw-ring-opacity))}.focus\:ring-primary-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(100 181 246/var(--tw-ring-opacity))}.focus\:ring-primary-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(33 150 243/var(--tw-ring-opacity))}.group:hover .group-hover\:text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}:is(.dark .dark\:divide-gray-600)>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(75 85 99/var(--tw-divide-opacity))}:is(.dark .dark\:border-black){--tw-border-opacity:1;border-color:rgb(0 0 0/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-500){--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-600){--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:bg-blue-600){--tw-bg-opacity:1;background-color:rgb(28 100 242/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-500){--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-600){--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-700){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-800){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-900){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}:is(.dark .dark\:bg-primary-600){--tw-bg-opacity:1;background-color:rgb(30 136 229/var(--tw-bg-opacity))}:is(.dark .dark\:bg-primary-900){--tw-bg-opacity:1;background-color:rgb(13 71 161/var(--tw-bg-opacity))}:is(.dark .dark\:text-blue-400){--tw-text-opacity:1;color:rgb(118 169 250/var(--tw-text-opacity))}:is(.dark .dark\:text-blue-500){--tw-text-opacity:1;color:rgb(63 131 248/var(--tw-text-opacity))}:is(.dark .dark\:text-emerald-400){--tw-text-opacity:1;color:rgb(52 211 153/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-300){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400\/60){color:#9ca3af99}:is(.dark .dark\:text-gray-500){--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-600){--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}:is(.dark .dark\:text-green-400){--tw-text-opacity:1;color:rgb(49 196 141/var(--tw-text-opacity))}:is(.dark .dark\:text-primary-300){--tw-text-opacity:1;color:rgb(100 181 246/var(--tw-text-opacity))}:is(.dark .dark\:text-primary-500){--tw-text-opacity:1;color:rgb(33 150 243/var(--tw-text-opacity))}:is(.dark .dark\:text-white){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:text-yellow-300){--tw-text-opacity:1;color:rgb(250 202 21/var(--tw-text-opacity))}:is(.dark .dark\:decoration-gray-500){text-decoration-color:#6b7280}:is(.dark .dark\:placeholder-gray-400)::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(156 163 175/var(--tw-placeholder-opacity))}:is(.dark .dark\:placeholder-gray-400)::placeholder{--tw-placeholder-opacity:1;color:rgb(156 163 175/var(--tw-placeholder-opacity))}:is(.dark .dark\:shadow-gray-950){--tw-shadow-color:#030712;--tw-shadow:var(--tw-shadow-colored)}:is(.dark .dark\:hover\:bg-blue-700:hover){--tw-bg-opacity:1;background-color:rgb(26 86 219/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:bg-gray-600:hover){--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:bg-gray-700:hover){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:bg-gray-800:hover){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:bg-primary-700:hover){--tw-bg-opacity:1;background-color:rgb(25 118 210/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:text-white:hover){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:hover\:underline:hover){text-decoration-line:underline}:is(.dark .dark\:focus\:border-primary-500:focus){--tw-border-opacity:1;border-color:rgb(33 150 243/var(--tw-border-opacity))}:is(.dark .dark\:focus\:bg-gray-700:focus){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}:is(.dark .dark\:focus\:ring-blue-800:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(30 66 159/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-gray-600:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(75 85 99/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-gray-700:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(55 65 81/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-gray-800:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(31 41 55/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-primary-500:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(33 150 243/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-primary-800:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(21 101 192/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-primary-900:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(13 71 161/var(--tw-ring-opacity))}:is(.dark .group:hover .dark\:group-hover\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}@media (min-width:640px){.sm\:flex-row{flex-direction:row}.sm\:justify-center{justify-content:center}.sm\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.sm\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.sm\:px-16{padding-left:4rem;padding-right:4rem}.sm\:py-16{padding-bottom:4rem;padding-top:4rem}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:text-5xl{font-size:3rem;line-height:1}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:768px){.md\:mb-14{margin-bottom:3.5rem}.md\:ml-2{margin-left:.5rem}.md\:ml-64{margin-left:16rem}.md\:mr-0{margin-right:0}.md\:block{display:block}.md\:grid{display:grid}.md\:hidden{display:none}.md\:w-64{width:16rem}.md\:w-96{width:24rem}.md\:translate-x-0{--tw-translate-x:0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-col{flex-direction:column}.md\:gap-12{gap:3rem}.md\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.md\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.md\:pl-2{padding-left:.5rem}.md\:text-2xl{font-size:1.5rem;line-height:2rem}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:1024px){.lg\:order-2{order:2}.lg\:mb-16{margin-bottom:4rem}.lg\:h-12{height:3rem}.lg\:h-6{height:1.5rem}.lg\:w-12{width:3rem}.lg\:w-6{width:1.5rem}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:space-y-12>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(3rem*var(--tw-space-y-reverse));margin-top:calc(3rem*(1 - var(--tw-space-y-reverse)))}.lg\:p-8{padding:2rem}.lg\:px-12{padding-left:3rem;padding-right:3rem}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:py-16{padding-bottom:4rem;padding-top:4rem}.lg\:text-6xl{font-size:3.75rem;line-height:1}.lg\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:1280px){.xl\:gap-12{gap:3rem}.xl\:px-48{padding-left:12rem;padding-right:12rem}} \ No newline at end of file +/*! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:Raleway,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:Consolas,Menlo,Courier New;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],select,textarea{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,select:focus,textarea:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple]{background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1rem}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E")}[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=checkbox]:indeterminate,[type=radio]:checked:focus,[type=radio]:checked:hover{background-color:currentColor;border-color:#0000}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}[type=file]{background:unset;border-color:inherit;border-radius:0;border-width:0;font-size:unset;line-height:inherit;padding:0}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}code{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity));border-radius:.25rem;font-size:.875rem;line-height:1.25rem;padding:.125rem .25rem}:is(.dark code){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }#basic_command-no-frame,#basic_command-turbo-frame{border-radius:.5rem;border-width:1px;display:block;margin-left:auto;margin-right:auto;max-width:1280px;position:relative}#basic_command-no-frame{--tw-border-opacity:1;border-color:rgb(14 165 233/var(--tw-border-opacity));padding:1rem}:is(.dark #basic_command-no-frame){--tw-border-opacity:1;border-color:rgb(7 89 133/var(--tw-border-opacity))}#basic_command-no-frame:before{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(14 165 233/var(--tw-bg-opacity));border-top-left-radius:.25rem;border-top-right-radius:.25rem;color:rgb(255 255 255/var(--tw-text-opacity));content:"";display:inline-block;font-family:Consolas,Menlo,Courier New;font-size:.75rem;left:1rem;line-height:1rem;padding-left:.5rem;padding-right:.5rem;position:absolute;top:-1rem}:is(.dark #basic_command-no-frame):before{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(7 89 133/var(--tw-bg-opacity));color:rgb(186 230 253/var(--tw-text-opacity))}#basic_command-turbo-frame{--tw-border-opacity:1;border-color:rgb(244 63 94/var(--tw-border-opacity));padding:1rem}:is(.dark #basic_command-turbo-frame){--tw-border-opacity:1;border-color:rgb(159 18 57/var(--tw-border-opacity))}#basic_command-turbo-frame:before{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(244 63 94/var(--tw-bg-opacity));border-top-left-radius:.25rem;border-top-right-radius:.25rem;color:rgb(255 255 255/var(--tw-text-opacity));content:"";display:inline-block;font-family:Consolas,Menlo,Courier New;font-size:.75rem;left:1rem;line-height:1rem;padding-left:.5rem;padding-right:.5rem;position:absolute;top:-1rem}:is(.dark #basic_command-turbo-frame):before{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(159 18 57/var(--tw-bg-opacity));color:rgb(254 205 211/var(--tw-text-opacity))}#basic_command-no-frame>h3,#basic_command-turbo-frame>h3{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity));font-size:1.5rem;font-weight:600;line-height:2rem}:is(.dark #basic_command-no-frame>h3),:is(.dark #basic_command-turbo-frame>h3){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}@media (min-width:768px){#basic_command-no-frame>h3,#basic_command-turbo-frame>h3{font-size:1.5rem;line-height:2rem}}#basic_command-no-frame>p,#basic_command-turbo-frame>p{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity));font-weight:300;margin-bottom:1rem}:is(.dark #basic_command-no-frame>p),:is(.dark #basic_command-turbo-frame>p){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}#basic_command-no-frame>code,#basic_command-turbo-frame>code{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity));font-size:1.875rem;font-weight:700;line-height:2.25rem;padding:.25rem .75rem}@media (min-width:768px){#basic_command-no-frame>code,#basic_command-turbo-frame>code{font-size:2.25rem;line-height:2.5rem}}#basic_command-no-frame>div,#basic_command-turbo-frame>div{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);border-radius:.375rem;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);display:flex}#basic_command-no-frame>div:last-child,#basic_command-turbo-frame>div:last-child{margin-top:1.25rem}#basic_command-no-frame>div>button,#basic_command-turbo-frame>div>button{--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1;align-items:center;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-color:rgb(229 231 235/var(--tw-border-opacity));border-width:1px;color:rgb(17 24 39/var(--tw-text-opacity));display:inline-flex;font-size:.875rem;font-weight:500;line-height:1.25rem;padding:.5rem 1rem}#basic_command-no-frame>div>button:hover,#basic_command-turbo-frame>div>button:hover{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity));color:rgb(29 78 216/var(--tw-text-opacity))}#basic_command-no-frame>div>button:focus,#basic_command-turbo-frame>div>button:focus{--tw-text-opacity:1;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(29 78 216/var(--tw-ring-opacity));box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:rgb(29 78 216/var(--tw-text-opacity));z-index:10}:is(.dark #basic_command-no-frame>div>button),:is(.dark #basic_command-turbo-frame>div>button){--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity));border-color:rgb(75 85 99/var(--tw-border-opacity));color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark #basic_command-no-frame>div>button:hover),:is(.dark #basic_command-turbo-frame>div>button:hover){--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity));color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark #basic_command-no-frame>div>button:focus),:is(.dark #basic_command-turbo-frame>div>button:focus){--tw-text-opacity:1;--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity));color:rgb(255 255 255/var(--tw-text-opacity))}#basic_command-no-frame>div>button:first-child,#basic_command-turbo-frame>div>button:first-child{border-bottom-left-radius:.5rem;border-top-left-radius:.5rem}#basic_command-no-frame>div>button:last-child,#basic_command-turbo-frame>div>button:last-child{border-bottom-right-radius:.375rem;border-top-right-radius:.375rem}#basic_command-no-frame>div>button>svg,#basic_command-turbo-frame>div>button>svg{height:.75rem;margin-right:.25rem;width:.75rem}.feature p em{--tw-text-opacity:1;color:rgb(255 152 0/var(--tw-text-opacity));font-style:normal}:is(.dark .feature p em){--tw-text-opacity:1;color:rgb(255 183 77/var(--tw-text-opacity))}.feature p i{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity));font-style:normal;text-decoration-color:#4b5563;text-decoration-line:underline;text-decoration-style:dotted;text-underline-offset:4px}:is(.dark .feature p i){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity));text-decoration-color:#9ca3af}.instruction>p{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity));font-size:1rem;font-weight:400;line-height:1.5rem;margin-bottom:.5rem;margin-top:.5rem}:is(.dark .instruction>p){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}@media (min-width:640px){.instruction>p{font-size:1.125rem;line-height:1.75rem}}.sr-only{clip:rect(0,0,0,0);border-width:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-y-0{bottom:0;top:0}.bottom-0{bottom:0}.left-0{left:0}.right-0{right:0}.top-0{top:0}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.m-5{margin:1.25rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-auto{margin-left:auto;margin-right:auto}.my-12{margin-bottom:3rem;margin-top:3rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-4{margin-bottom:1rem;margin-top:1rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.\!mt-6{margin-top:1.5rem!important}.-mr-1{margin-right:-.25rem}.-mt-5{margin-top:-1.25rem}.-mt-px{margin-top:-1px}.mb-0{margin-bottom:0}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-6{margin-left:1.5rem}.ml-px{margin-left:1px}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.mt-10{margin-top:2.5rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-14{height:3.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-14{width:3.5rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-full{width:100%}.max-w-2xl{max-width:42rem}.max-w-screen-md{max-width:768px}.max-w-screen-xl{max-width:1280px}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%}.-translate-x-full,.rotate-180{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}.cursor-pointer{cursor:pointer}.list-decimal{list-style-type:decimal}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-gray-100>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(243 244 246/var(--tw-divide-opacity))}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-b-none{border-bottom-left-radius:0;border-bottom-right-radius:0}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.border{border-width:1px}.border-0{border-width:0}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-0{border-bottom-width:0}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t-0{border-top-width:0}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-rose-400{--tw-border-opacity:1;border-color:rgb(251 113 133/var(--tw-border-opacity))}.border-white{--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}.\!bg-red-500{--tw-bg-opacity:1!important;background-color:rgb(239 68 68/var(--tw-bg-opacity))!important}.bg-blue-100{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity))}.bg-blue-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity))}.bg-blue-700{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-gray-300{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-50\/30{background-color:#f9fafb4d}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.bg-green-400{--tw-bg-opacity:1;background-color:rgb(74 222 128/var(--tw-bg-opacity))}.bg-green-50{--tw-bg-opacity:1;background-color:rgb(240 253 244/var(--tw-bg-opacity))}.bg-primary-100{--tw-bg-opacity:1;background-color:rgb(187 222 251/var(--tw-bg-opacity))}.bg-primary-700{--tw-bg-opacity:1;background-color:rgb(25 118 210/var(--tw-bg-opacity))}.bg-primary-800{--tw-bg-opacity:1;background-color:rgb(21 101 192/var(--tw-bg-opacity))}.bg-purple-500{--tw-bg-opacity:1;background-color:rgb(168 85 247/var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity))}.bg-transparent{background-color:initial}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-yellow-50{--tw-bg-opacity:1;background-color:rgb(254 252 232/var(--tw-bg-opacity))}.object-cover{-o-object-fit:cover;object-fit:cover}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-2\.5{padding-bottom:.625rem;padding-top:.625rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-5{padding-bottom:1.25rem;padding-top:1.25rem}.py-8{padding-bottom:2rem;padding-top:2rem}.pl-10{padding-left:2.5rem}.pl-3{padding-left:.75rem}.pr-5{padding-right:1.25rem}.pt-14{padding-top:3.5rem}.pt-20{padding-top:5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-bottom{vertical-align:bottom}.font-mono{font-family:Consolas,Menlo,Courier New}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-light{font-weight:300}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.italic{font-style:italic}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.text-blue-800{--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity))}.text-emerald-500{--tw-text-opacity:1;color:rgb(16 185 129/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}.text-green-800{--tw-text-opacity:1;color:rgb(22 101 52/var(--tw-text-opacity))}.text-primary-300{--tw-text-opacity:1;color:rgb(100 181 246/var(--tw-text-opacity))}.text-primary-600{--tw-text-opacity:1;color:rgb(30 136 229/var(--tw-text-opacity))}.text-primary-700{--tw-text-opacity:1;color:rgb(25 118 210/var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.text-rose-400{--tw-text-opacity:1;color:rgb(251 113 133/var(--tw-text-opacity))}.text-secondary-400{--tw-text-opacity:1;color:rgb(92 107 192/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-yellow-800{--tw-text-opacity:1;color:rgb(133 77 14/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.decoration-gray-500{text-decoration-color:#6b7280}.decoration-gray-600{text-decoration-color:#4b5563}.decoration-red-500\/80{text-decoration-color:#ef4444cc}.decoration-dotted{text-decoration-style:dotted}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.underline-offset-8{text-underline-offset:8px}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-md,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-gray-100{--tw-shadow-color:#f3f4f6;--tw-shadow:var(--tw-shadow-colored)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-75{transition-duration:75ms}.hover\:bg-blue-100:hover{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity))}.hover\:bg-blue-800:hover{--tw-bg-opacity:1;background-color:rgb(30 64 175/var(--tw-bg-opacity))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.hover\:bg-primary-800:hover{--tw-bg-opacity:1;background-color:rgb(21 101 192/var(--tw-bg-opacity))}.hover\:bg-primary-900:hover{--tw-bg-opacity:1;background-color:rgb(13 71 161/var(--tw-bg-opacity))}.hover\:text-blue-600:hover{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.hover\:text-primary-700:hover{--tw-text-opacity:1;color:rgb(25 118 210/var(--tw-text-opacity))}.hover\:underline:hover{text-decoration-line:underline}.focus\:z-10:focus{z-index:10}.focus\:border-primary-500:focus{--tw-border-opacity:1;border-color:rgb(33 150 243/var(--tw-border-opacity))}.focus\:bg-gray-100:focus{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.focus\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring-2:focus,.focus\:ring-4:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-4:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring-blue-200:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(191 219 254/var(--tw-ring-opacity))}.focus\:ring-blue-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(147 197 253/var(--tw-ring-opacity))}.focus\:ring-gray-100:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(243 244 246/var(--tw-ring-opacity))}.focus\:ring-gray-200:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(229 231 235/var(--tw-ring-opacity))}.focus\:ring-gray-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(209 213 219/var(--tw-ring-opacity))}.focus\:ring-primary-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(100 181 246/var(--tw-ring-opacity))}.focus\:ring-primary-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(33 150 243/var(--tw-ring-opacity))}.group:hover .group-hover\:text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}:is(.dark .dark\:divide-gray-600)>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(75 85 99/var(--tw-divide-opacity))}:is(.dark .dark\:border-black){--tw-border-opacity:1;border-color:rgb(0 0 0/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-500){--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-600){--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:bg-blue-600){--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-500){--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-600){--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-700){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-800){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-900){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}:is(.dark .dark\:bg-primary-600){--tw-bg-opacity:1;background-color:rgb(30 136 229/var(--tw-bg-opacity))}:is(.dark .dark\:bg-primary-900){--tw-bg-opacity:1;background-color:rgb(13 71 161/var(--tw-bg-opacity))}:is(.dark .dark\:text-blue-400){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}:is(.dark .dark\:text-blue-500){--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity))}:is(.dark .dark\:text-emerald-400){--tw-text-opacity:1;color:rgb(52 211 153/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-300){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400\/60){color:#9ca3af99}:is(.dark .dark\:text-gray-500){--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-600){--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}:is(.dark .dark\:text-green-400){--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity))}:is(.dark .dark\:text-primary-300){--tw-text-opacity:1;color:rgb(100 181 246/var(--tw-text-opacity))}:is(.dark .dark\:text-primary-500){--tw-text-opacity:1;color:rgb(33 150 243/var(--tw-text-opacity))}:is(.dark .dark\:text-white){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:text-yellow-300){--tw-text-opacity:1;color:rgb(253 224 71/var(--tw-text-opacity))}:is(.dark .dark\:decoration-gray-500){text-decoration-color:#6b7280}:is(.dark .dark\:placeholder-gray-400)::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(156 163 175/var(--tw-placeholder-opacity))}:is(.dark .dark\:placeholder-gray-400)::placeholder{--tw-placeholder-opacity:1;color:rgb(156 163 175/var(--tw-placeholder-opacity))}:is(.dark .dark\:shadow-gray-950){--tw-shadow-color:#030712;--tw-shadow:var(--tw-shadow-colored)}:is(.dark .dark\:hover\:bg-blue-700:hover){--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:bg-gray-600:hover){--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:bg-gray-700:hover){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:bg-gray-800:hover){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:bg-primary-700:hover){--tw-bg-opacity:1;background-color:rgb(25 118 210/var(--tw-bg-opacity))}:is(.dark .dark\:hover\:text-white:hover){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:hover\:underline:hover){text-decoration-line:underline}:is(.dark .dark\:focus\:border-primary-500:focus){--tw-border-opacity:1;border-color:rgb(33 150 243/var(--tw-border-opacity))}:is(.dark .dark\:focus\:bg-gray-700:focus){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}:is(.dark .dark\:focus\:ring-blue-800:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(30 64 175/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-gray-600:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(75 85 99/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-gray-700:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(55 65 81/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-gray-800:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(31 41 55/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-primary-500:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(33 150 243/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-primary-800:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(21 101 192/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-primary-900:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(13 71 161/var(--tw-ring-opacity))}:is(.dark .group:hover .dark\:group-hover\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}@media (min-width:640px){.sm\:flex-row{flex-direction:row}.sm\:justify-center{justify-content:center}.sm\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.sm\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.sm\:px-16{padding-left:4rem;padding-right:4rem}.sm\:py-16{padding-bottom:4rem;padding-top:4rem}.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}.sm\:text-5xl{font-size:3rem;line-height:1}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:768px){.md\:mb-14{margin-bottom:3.5rem}.md\:ml-2{margin-left:.5rem}.md\:ml-64{margin-left:16rem}.md\:mr-0{margin-right:0}.md\:block{display:block}.md\:grid{display:grid}.md\:hidden{display:none}.md\:w-64{width:16rem}.md\:w-96{width:24rem}.md\:translate-x-0{--tw-translate-x:0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-col{flex-direction:column}.md\:gap-12{gap:3rem}.md\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.md\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.md\:pl-2{padding-left:.5rem}.md\:text-2xl{font-size:1.5rem;line-height:2rem}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:1024px){.lg\:order-2{order:2}.lg\:mb-16{margin-bottom:4rem}.lg\:h-12{height:3rem}.lg\:h-6{height:1.5rem}.lg\:w-12{width:3rem}.lg\:w-6{width:1.5rem}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:space-y-12>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(3rem*var(--tw-space-y-reverse));margin-top:calc(3rem*(1 - var(--tw-space-y-reverse)))}.lg\:p-8{padding:2rem}.lg\:px-12{padding-left:3rem;padding-right:3rem}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:py-16{padding-bottom:4rem;padding-top:4rem}.lg\:text-6xl{font-size:3.75rem;line-height:1}.lg\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:1280px){.xl\:gap-12{gap:3rem}.xl\:px-48{padding-left:12rem;padding-right:12rem}} \ No newline at end of file diff --git a/test/dummy/app/controllers/application_controller.rb b/test/dummy/app/controllers/application_controller.rb index d3c5e0f7..ae85b0e6 100644 --- a/test/dummy/app/controllers/application_controller.rb +++ b/test/dummy/app/controllers/application_controller.rb @@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base def init_current session[:forced_load] = true unless session.loaded? # forces session to load (required for automated testing) - Current.state ||= turbo_boost.state + # Current.state ||= turbo_boost.state Current.user ||= User.find_or_create_by(session_id: session.id.to_s) end diff --git a/test/dummy/app/javascript/application.js b/test/dummy/app/javascript/application.js index 501f71c1..6a97e81c 100644 --- a/test/dummy/app/javascript/application.js +++ b/test/dummy/app/javascript/application.js @@ -2,6 +2,5 @@ import '@hotwired/turbo-rails' import 'flowbite' -import './debounced' import './turbo-boost' import './controllers' diff --git a/test/dummy/app/javascript/debounced/index.js b/test/dummy/app/javascript/debounced/index.js deleted file mode 100644 index 91209066..00000000 --- a/test/dummy/app/javascript/debounced/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import debounced from 'debounced' - -debounced.initialize({ - ...debounced.events, - 'turbo:load': { wait: 150 }, - 'turbo-boost:command:success': { wait: 150 }, - 'turbo-boost:command:finish': { wait: 150 } -}) diff --git a/test/dummy/app/views/installations/show.html.erb b/test/dummy/app/views/installations/show.html.erb index 08c852af..1c111594 100644 --- a/test/dummy/app/views/installations/show.html.erb +++ b/test/dummy/app/views/installations/show.html.erb @@ -6,9 +6,9 @@ <% end %> <% cache do %> -
-
-

+
+
+

Installation and Configuration

@@ -39,12 +39,6 @@ <%= render "alerts/warning", message: "Be sure to add TurboBoost Commands after the Turbo import." %> <% end %> - <%= render "instructions/instruction", step: 4, heading: "Configure your Rails app" do %> - <%= render "examples/example", language: :erb, path: "app/views/layouts/application.html.erb", source_path: "app/views/installations/source_code/_application.html.erb" %> - <%= render "alerts/warning", message: "You may need to configure additional layout files." %> - <%= render "examples/example", language: :rb, path: "config/initializers/turbo_boost.rb", source_path: "config/initializers/turbo_boost.rb" %> - <% end %> -

That's it! You're ready to start using TurboBoost Commands. 🙌 diff --git a/test/dummy/app/views/installations/source_code/_application.html.erb b/test/dummy/app/views/installations/source_code/_application.html.erb deleted file mode 100644 index 8b48a5e6..00000000 --- a/test/dummy/app/views/installations/source_code/_application.html.erb +++ /dev/null @@ -1,7 +0,0 @@ - - - <%= turbo_boost.meta_tag # <-- add this line %> - - - - diff --git a/test/dummy/app/views/layouts/application.html.erb b/test/dummy/app/views/layouts/application.html.erb index f1781536..df42f476 100644 --- a/test/dummy/app/views/layouts/application.html.erb +++ b/test/dummy/app/views/layouts/application.html.erb @@ -5,7 +5,6 @@ <%= csrf_meta_tags %> <%= csp_meta_tag %> - <%= turbo_boost.meta_tag %> <%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> diff --git a/test/dummy/config/importmap.rb b/test/dummy/config/importmap.rb index 47125074..932cc02d 100644 --- a/test/dummy/config/importmap.rb +++ b/test/dummy/config/importmap.rb @@ -2,19 +2,25 @@ # Pin npm packages by running ./bin/importmap -# link the @turbo-boost/commands build to test/dummy/app/javascript/@turbo-boost -target = File.expand_path(Rails.root.join("../../app/assets/builds/@turbo-boost")) -link = File.expand_path(Rails.root.join("app/javascript/@turbo-boost")) -FileUtils.rm_r link, force: true, verbose: true if File.exist?(link) && !File.symlink?(link) -FileUtils.ln_s target, link, force: true, verbose: true unless File.exist?(link) +pin "@hotwired/stimulus", to: "@hotwired--stimulus.js" # @3.2.2 +pin "@hotwired/turbo", to: "@hotwired--turbo.js" # @8.0.2 +pin "@hotwired/turbo-rails", to: "@hotwired--turbo-rails.js" # @8.0.2 +pin "@rails/actioncable", to: "@rails--actioncable.js" # @7.1.3 +pin "@rails/actioncable/src", to: "@rails--actioncable--src.js" # @7.1.3 -pin "@hotwired/stimulus", to: "https://ga.jspm.io/npm:@hotwired/stimulus@3.2.2/dist/stimulus.js" -pin "@hotwired/turbo", to: "https://ga.jspm.io/npm:@hotwired/turbo@8.0.2/dist/turbo.es2017-esm.js" -pin "@hotwired/turbo-rails", to: "https://ga.jspm.io/npm:@hotwired/turbo-rails@8.0.2/app/javascript/turbo/index.js" -pin "@rails/actioncable/src", to: "https://ga.jspm.io/npm:@rails/actioncable@7.1.3/src/index.js" -pin "@turbo-boost/streams", to: "https://ga.jspm.io/npm:@turbo-boost/streams@0.0.8/app/assets/builds/@turbo-boost/streams.js" -pin "debounced", to: "https://ga.jspm.io/npm:debounced@0.0.5/src/index.js" +# TODO: I have no idea why the fuck jspm.io refuses to build the latest versions of @turbo-boost libs +# You can generate URLs like the one I'm using below here → https://www.jsdelivr.com/github +pin "@turbo-boost/streams", to: "https://cdn.jsdelivr.net/gh/hopsoft/turbo_boost-streams@v0.1.6/app/assets/builds/%40turbo-boost/streams.js" + +# NOTE: The following libs stop working if we allow Rails to vendor them pin "flowbite", to: "https://cdnjs.cloudflare.com/ajax/libs/flowbite/1.7.0/flowbite.turbo.min.js" + +# HACK: This allows us to pin a lib above Rails.root in the dummy app +# It's goofy but works +FileUtils.rm_f Rails.root.join("app/javascript/@turbo-boost") +FileUtils.ln_s Rails.root.join("../../app/assets/builds/@turbo-boost"), Rails.root.join("app/javascript/@turbo-boost") pin "@turbo-boost/commands", to: "@turbo-boost/commands.js" + pin "application", preload: true -pin "add", to: "https://ga.jspm.io/npm:add@2.0.6/index.js" +pin "alpinejs" # @3.13.5 +pin "@alpinejs/morph", to: "@alpinejs--morph.js" # @3.13.5 diff --git a/test/dummy/config/tailwind.config.js b/test/dummy/config/tailwind.config.js index cc780460..aa652825 100644 --- a/test/dummy/config/tailwind.config.js +++ b/test/dummy/config/tailwind.config.js @@ -14,8 +14,8 @@ module.exports = { plugins: [ require('@tailwindcss/aspect-ratio'), require('@tailwindcss/forms'), - require('@tailwindcss/typography'), - require('flowbite/plugin') + require('@tailwindcss/typography') + //require('flowbite/plugin') ], theme: { diff --git a/test/dummy/public/404.html b/test/dummy/public/404.html index 8d884591..d0b3020e 100644 --- a/test/dummy/public/404.html +++ b/test/dummy/public/404.html @@ -1,4 +1,4 @@ - + The page you were looking for doesn't exist (404) @@ -61,9 +61,7 @@

The page you were looking for doesn't exist.

You may have mistyped the address or the page may have moved.

-

- If you are the application owner check the logs for more information. -

+

If you are the application owner check the logs for more information.

diff --git a/test/dummy/public/422.html b/test/dummy/public/422.html index 845c5328..23c73ec5 100644 --- a/test/dummy/public/422.html +++ b/test/dummy/public/422.html @@ -1,4 +1,4 @@ - + The change you wanted was rejected (422) @@ -61,9 +61,7 @@

The change you wanted was rejected.

Maybe you tried to change something you didn't have access to.

-

- If you are the application owner check the logs for more information. -

+

If you are the application owner check the logs for more information.

diff --git a/test/dummy/public/500.html b/test/dummy/public/500.html index 21fe4eca..8cec92ee 100644 --- a/test/dummy/public/500.html +++ b/test/dummy/public/500.html @@ -1,4 +1,4 @@ - + We're sorry, but something went wrong (500) @@ -60,9 +60,7 @@

We're sorry, but something went wrong.

-

- If you are the application owner check the logs for more information. -

+

If you are the application owner check the logs for more information.

diff --git a/test/dummy/vendor/javascript/@alpinejs--morph.js b/test/dummy/vendor/javascript/@alpinejs--morph.js new file mode 100644 index 00000000..3097bcbc --- /dev/null +++ b/test/dummy/vendor/javascript/@alpinejs--morph.js @@ -0,0 +1,2 @@ +function morph(e,n,i){monkeyPatchDomSetAttributeToAllowAtSymbols();let l;let o;let r,d,s,a,u,f,p,c;function assignOptions(e={}){let defaultGetKey=e=>e.getAttribute("key");let noop=()=>{};s=e.updating||noop;a=e.updated||noop;u=e.removing||noop;f=e.removed||noop;p=e.adding||noop;c=e.added||noop;r=e.key||defaultGetKey;d=e.lookahead||false}function patch(e,t){if(differentElementNamesTypesOrKeys(e,t))return swapElements(e,t);let n=false;if(!shouldSkip(s,e,t,(()=>n=true))){e.nodeType===1&&window.Alpine&&window.Alpine.cloneNode(e,t);if(textOrComment(t)){patchNodeValue(e,t);a(e,t)}else{n||patchAttributes(e,t);a(e,t);patchChildren(e,t)}}}function differentElementNamesTypesOrKeys(e,t){return e.nodeType!=t.nodeType||e.nodeName!=t.nodeName||getKey(e)!=getKey(t)}function swapElements(e,t){if(shouldSkip(u,e))return;let n=t.cloneNode(true);if(!shouldSkip(p,n)){e.replaceWith(n);f(e);c(n)}}function patchNodeValue(e,t){let n=t.nodeValue;e.nodeValue!==n&&(e.nodeValue=n)}function patchAttributes(e,t){if(e._x_transitioning)return;if(e._x_isShown&&!t._x_isShown)return;if(!e._x_isShown&&t._x_isShown)return;let n=Array.from(e.attributes);let i=Array.from(t.attributes);for(let i=n.length-1;i>=0;i--){let l=n[i].name;t.hasAttribute(l)||e.removeAttribute(l)}for(let t=i.length-1;t>=0;t--){let n=i[t].name;let l=i[t].value;e.getAttribute(n)!==l&&e.setAttribute(n,l)}}function patchChildren(e,n){e._x_teleport&&(e=e._x_teleport);n._x_teleport&&(n=n._x_teleport);let i=keyToMap(e.children);let l={};let o=getFirstNode(n);let r=getFirstNode(e);while(o){seedingMatchingId(o,r);let s=getKey(o);let a=getKey(r);if(!r){if(!s||!l[s]){if(!shouldSkip(p,o)){let t=o.cloneNode(true);e.appendChild(t);c(t)}o=getNextSibling(n,o);continue}{let t=l[s];e.appendChild(t);r=t}}let isIf=e=>e&&e.nodeType===8&&e.textContent==="[if BLOCK]>e&&e.nodeType===8&&e.textContent==="[if ENDBLOCK]>0)i--;else if(isEnd(t)&&i===0){r=t;break}r=t}let d=r;i=0;let s=o;while(o){let e=getNextSibling(n,o);if(isIf(e))i++;else if(isEnd(e)&&i>0)i--;else if(isEnd(e)&&i===0){o=e;break}o=e}let a=o;let u=new t(l,d);let f=new t(s,a);patchChildren(u,f);continue}if(r.nodeType===1&&d&&!r.isEqualNode(o)){let t=getNextSibling(n,o);let i=false;while(!i&&t){if(t.nodeType===1&&r.isEqualNode(t)){i=true;r=addNodeBefore(e,o,r);a=getKey(r)}t=getNextSibling(n,t)}}if(s!==a){if(!s&&a){l[a]=r;r=addNodeBefore(e,o,r);l[a].remove();r=getNextSibling(e,r);o=getNextSibling(n,o);continue}if(s&&!a&&i[s]){r.replaceWith(i[s]);r=i[s]}if(s&&a){let t=i[s];if(!t){l[a]=r;r=addNodeBefore(e,o,r);l[a].remove();r=getNextSibling(e,r);o=getNextSibling(n,o);continue}l[a]=r;r.replaceWith(t);r=t}}let u=r&&getNextSibling(e,r);patch(r,o);o=o&&getNextSibling(n,o);r=u}let s=[];while(r){shouldSkip(u,r)||s.push(r);r=getNextSibling(e,r)}while(s.length){let e=s.shift();e.remove();f(e)}}function getKey(e){return e&&e.nodeType===1&&r(e)}function keyToMap(e){let t={};for(let n of e){let e=getKey(n);e&&(t[e]=n)}return t}function addNodeBefore(e,t,n){if(!shouldSkip(p,t)){let i=t.cloneNode(true);e.insertBefore(i,n);c(i);return i}return t}assignOptions(i);l=e;o=typeof n==="string"?createElement(n):n;if(window.Alpine&&window.Alpine.closestDataStack&&!e._x_dataStack){o._x_dataStack=window.Alpine.closestDataStack(e);o._x_dataStack&&window.Alpine.cloneNode(e,o)}patch(e,o);l=void 0;o=void 0;return e}morph.step=()=>{};morph.log=()=>{};function shouldSkip(e,...t){let n=false;e(...t,(()=>n=true));return n}var e=false;function createElement(e){const t=document.createElement("template");t.innerHTML=e;return t.content.firstElementChild}function textOrComment(e){return e.nodeType===3||e.nodeType===8}var t=class{constructor(e,t){this.startComment=e;this.endComment=t}get children(){let e=[];let t=this.startComment.nextSibling;while(t&&t!==this.endComment){e.push(t);t=t.nextSibling}return e}appendChild(e){this.endComment.before(e)}get firstChild(){let e=this.startComment.nextSibling;if(e!==this.endComment)return e}nextNode(e){let t=e.nextSibling;if(t!==this.endComment)return t}insertBefore(e,t){t.before(e);return e}};function getFirstNode(e){return e.firstChild}function getNextSibling(e,n){let i;i=e instanceof t?e.nextNode(n):n.nextSibling;return i}function monkeyPatchDomSetAttributeToAllowAtSymbols(){if(e)return;e=true;let t=Element.prototype.setAttribute;let n=document.createElement("div");Element.prototype.setAttribute=function newSetAttribute(e,i){if(!e.includes("@"))return t.call(this,e,i);n.innerHTML=``;let l=n.firstElementChild.getAttributeNode(e);n.firstElementChild.removeAttributeNode(l);this.setAttributeNode(l)}}function seedingMatchingId(e,t){let n=t&&t._x_bindings&&t._x_bindings.id;if(n){e.setAttribute("id",n);e.id=n}}function src_default(e){e.morph=morph}var n=src_default;export{n as default,src_default as morph}; + diff --git a/test/dummy/vendor/javascript/@hotwired--stimulus.js b/test/dummy/vendor/javascript/@hotwired--stimulus.js new file mode 100644 index 00000000..98f9eabf --- /dev/null +++ b/test/dummy/vendor/javascript/@hotwired--stimulus.js @@ -0,0 +1,2 @@ +class EventListener{constructor(e,t,r){this.eventTarget=e;this.eventName=t;this.eventOptions=r;this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=extendEvent(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort(((e,t)=>{const r=e.index,s=t.index;return rs?1:0}))}}function extendEvent(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:false,stopImmediatePropagation(){this.immediatePropagationStopped=true;t.call(this)}})}}class Dispatcher{constructor(e){this.application=e;this.eventListenerMaps=new Map;this.started=false}start(){if(!this.started){this.started=true;this.eventListeners.forEach((e=>e.connect()))}}stop(){if(this.started){this.started=false;this.eventListeners.forEach((e=>e.disconnect()))}}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce(((e,t)=>e.concat(Array.from(t.values()))),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=false){this.fetchEventListenerForBinding(e).bindingDisconnected(e);t&&this.clearEventListenersForBinding(e)}handleError(e,t,r={}){this.application.handleError(e,`Error ${t}`,r)}clearEventListenersForBinding(e){const t=this.fetchEventListenerForBinding(e);if(!t.hasBindings()){t.disconnect();this.removeMappedEventListenerFor(e)}}removeMappedEventListenerFor(e){const{eventTarget:t,eventName:r,eventOptions:s}=e;const n=this.fetchEventListenerMapForEventTarget(t);const i=this.cacheKey(r,s);n.delete(i);0==n.size&&this.eventListenerMaps.delete(t)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:r,eventOptions:s}=e;return this.fetchEventListener(t,r,s)}fetchEventListener(e,t,r){const s=this.fetchEventListenerMapForEventTarget(e);const n=this.cacheKey(t,r);let i=s.get(n);if(!i){i=this.createEventListener(e,t,r);s.set(n,i)}return i}createEventListener(e,t,r){const s=new EventListener(e,t,r);this.started&&s.connect();return s}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);if(!t){t=new Map;this.eventListenerMaps.set(e,t)}return t}cacheKey(e,t){const r=[e];Object.keys(t).sort().forEach((e=>{r.push(`${t[e]?"":"!"}${e}`)}));return r.join(":")}}const e={stop({event:e,value:t}){t&&e.stopPropagation();return true},prevent({event:e,value:t}){t&&e.preventDefault();return true},self({event:e,value:t,element:r}){return!t||r===e.target}};const t=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function parseActionDescriptorString(e){const r=e.trim();const s=r.match(t)||[];let n=s[2];let i=s[3];if(i&&!["keydown","keyup","keypress"].includes(n)){n+=`.${i}`;i=""}return{eventTarget:parseEventTarget(s[4]),eventName:n,eventOptions:s[7]?parseEventOptions(s[7]):{},identifier:s[5],methodName:s[6],keyFilter:s[1]||i}}function parseEventTarget(e){return"window"==e?window:"document"==e?document:void 0}function parseEventOptions(e){return e.split(":").reduce(((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)})),{})}function stringifyEventTarget(e){return e==window?"window":e==document?"document":void 0}function camelize(e){return e.replace(/(?:[_-])([a-z0-9])/g,((e,t)=>t.toUpperCase()))}function namespaceCamelize(e){return camelize(e.replace(/--/g,"-").replace(/__/g,"_"))}function capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}function dasherize(e){return e.replace(/([A-Z])/g,((e,t)=>`-${t.toLowerCase()}`))}function tokenize(e){return e.match(/[^\s]+/g)||[]}function isSomething(e){return null!==e&&void 0!==e}function hasProperty(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const r=["meta","ctrl","alt","shift"];class Action{constructor(e,t,r,s){this.element=e;this.index=t;this.eventTarget=r.eventTarget||e;this.eventName=r.eventName||getDefaultEventNameForElement(e)||error("missing event name");this.eventOptions=r.eventOptions||{};this.identifier=r.identifier||error("missing identifier");this.methodName=r.methodName||error("missing method name");this.keyFilter=r.keyFilter||"";this.schema=s}static forToken(e,t){return new this(e.element,e.index,parseActionDescriptorString(e.content),t)}toString(){const e=this.keyFilter?`.${this.keyFilter}`:"";const t=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}${t}->${this.identifier}#${this.methodName}`}shouldIgnoreKeyboardEvent(e){if(!this.keyFilter)return false;const t=this.keyFilter.split("+");if(this.keyFilterDissatisfied(e,t))return true;const s=t.filter((e=>!r.includes(e)))[0];if(!s)return false;hasProperty(this.keyMappings,s)||error(`contains unknown key filter: ${this.keyFilter}`);return this.keyMappings[s].toLowerCase()!==e.key.toLowerCase()}shouldIgnoreMouseEvent(e){if(!this.keyFilter)return false;const t=[this.keyFilter];return!!this.keyFilterDissatisfied(e,t)}get params(){const e={};const t=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(const{name:r,value:s}of Array.from(this.element.attributes)){const n=r.match(t);const i=n&&n[1];i&&(e[camelize(i)]=typecast(s))}return e}get eventTargetName(){return stringifyEventTarget(this.eventTarget)}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(e,t){const[s,n,i,o]=r.map((e=>t.includes(e)));return e.metaKey!==s||e.ctrlKey!==n||e.altKey!==i||e.shiftKey!==o}}const s={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function getDefaultEventNameForElement(e){const t=e.tagName.toLowerCase();if(t in s)return s[t](e)}function error(e){throw new Error(e)}function typecast(e){try{return JSON.parse(e)}catch(t){return e}}class Binding{constructor(e,t){this.context=e;this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){const t=this.prepareActionEvent(e);this.willBeInvokedByEvent(e)&&this.applyEventModifiers(t)&&this.invokeWithEvent(t)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){const{element:t}=this.action;const{actionDescriptorFilters:r}=this.context.application;const{controller:s}=this.context;let n=true;for(const[i,o]of Object.entries(this.eventOptions))if(i in r){const c=r[i];n=n&&c({name:i,value:o,event:e,element:t,controller:s})}return n}prepareActionEvent(e){return Object.assign(e,{params:this.action.params})}invokeWithEvent(e){const{target:t,currentTarget:r}=e;try{this.method.call(this.controller,e);this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:r,action:this.methodName})}catch(t){const{identifier:r,controller:s,element:n,index:i}=this;const o={identifier:r,controller:s,element:n,index:i,event:e};this.context.handleError(t,`invoking action "${this.action}"`,o)}}willBeInvokedByEvent(e){const t=e.target;return!(e instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(e))&&(!(e instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element))))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class ElementObserver{constructor(e,t){this.mutationObserverInit={attributes:true,childList:true,subtree:true};this.element=e;this.started=false;this.delegate=t;this.elements=new Set;this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){if(!this.started){this.started=true;this.mutationObserver.observe(this.element,this.mutationObserverInit);this.refresh()}}pause(e){if(this.started){this.mutationObserver.disconnect();this.started=false}e();if(!this.started){this.mutationObserver.observe(this.element,this.mutationObserverInit);this.started=true}}stop(){if(this.started){this.mutationObserver.takeRecords();this.mutationObserver.disconnect();this.started=false}}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){if("attributes"==e.type)this.processAttributeChange(e.target,e.attributeName);else if("childList"==e.type){this.processRemovedNodes(e.removedNodes);this.processAddedNodes(e.addedNodes)}}processAttributeChange(e,t){this.elements.has(e)?this.delegate.elementAttributeChanged&&this.matchElement(e)?this.delegate.elementAttributeChanged(e,t):this.removeElement(e):this.matchElement(e)&&this.addElement(e)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const r of this.matchElementsInTree(e))t.call(this,r)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){if(!this.elements.has(e)&&this.elementIsActive(e)){this.elements.add(e);this.delegate.elementMatched&&this.delegate.elementMatched(e)}}removeElement(e){if(this.elements.has(e)){this.elements.delete(e);this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e)}}}class AttributeObserver{constructor(e,t,r){this.attributeName=t;this.delegate=r;this.elementObserver=new ElementObserver(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[];const r=Array.from(e.querySelectorAll(this.selector));return t.concat(r)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function add(e,t,r){fetch(e,t).add(r)}function del(e,t,r){fetch(e,t).delete(r);prune(e,t)}function fetch(e,t){let r=e.get(t);if(!r){r=new Set;e.set(t,r)}return r}function prune(e,t){const r=e.get(t);null!=r&&0==r.size&&e.delete(t)}class Multimap{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){const e=Array.from(this.valuesByKey.values());return e.reduce(((e,t)=>e.concat(Array.from(t))),[])}get size(){const e=Array.from(this.valuesByKey.values());return e.reduce(((e,t)=>e+t.size),0)}add(e,t){add(this.valuesByKey,e,t)}delete(e,t){del(this.valuesByKey,e,t)}has(e,t){const r=this.valuesByKey.get(e);return null!=r&&r.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){const t=Array.from(this.valuesByKey.values());return t.some((t=>t.has(e)))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter((([t,r])=>r.has(e))).map((([e,t])=>e))}}class IndexedMultimap extends Multimap{constructor(){super();this.keysByValue=new Map}get values(){return Array.from(this.keysByValue.keys())}add(e,t){super.add(e,t);add(this.keysByValue,t,e)}delete(e,t){super.delete(e,t);del(this.keysByValue,t,e)}hasValue(e){return this.keysByValue.has(e)}getKeysForValue(e){const t=this.keysByValue.get(e);return t?Array.from(t):[]}}class SelectorObserver{constructor(e,t,r,s){this._selector=t;this.details=s;this.elementObserver=new ElementObserver(e,this);this.delegate=r;this.matchesByElement=new Multimap}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(e){this._selector=e;this.refresh()}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){const{selector:t}=this;if(t){const r=e.matches(t);return this.delegate.selectorMatchElement?r&&this.delegate.selectorMatchElement(e,this.details):r}return false}matchElementsInTree(e){const{selector:t}=this;if(t){const r=this.matchElement(e)?[e]:[];const s=Array.from(e.querySelectorAll(t)).filter((e=>this.matchElement(e)));return r.concat(s)}return[]}elementMatched(e){const{selector:t}=this;t&&this.selectorMatched(e,t)}elementUnmatched(e){const t=this.matchesByElement.getKeysForValue(e);for(const r of t)this.selectorUnmatched(e,r)}elementAttributeChanged(e,t){const{selector:r}=this;if(r){const t=this.matchElement(e);const s=this.matchesByElement.has(r,e);t&&!s?this.selectorMatched(e,r):!t&&s&&this.selectorUnmatched(e,r)}}selectorMatched(e,t){this.delegate.selectorMatched(e,t,this.details);this.matchesByElement.add(t,e)}selectorUnmatched(e,t){this.delegate.selectorUnmatched(e,t,this.details);this.matchesByElement.delete(t,e)}}class StringMapObserver{constructor(e,t){this.element=e;this.delegate=t;this.started=false;this.stringMap=new Map;this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){if(!this.started){this.started=true;this.mutationObserver.observe(this.element,{attributes:true,attributeOldValue:true});this.refresh()}}stop(){if(this.started){this.mutationObserver.takeRecords();this.mutationObserver.disconnect();this.started=false}}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const r=this.delegate.getStringMapKeyForAttribute(e);if(null!=r){this.stringMap.has(e)||this.stringMapKeyAdded(r,e);const s=this.element.getAttribute(e);this.stringMap.get(e)!=s&&this.stringMapValueChanged(s,r,t);if(null==s){const t=this.stringMap.get(e);this.stringMap.delete(e);t&&this.stringMapKeyRemoved(r,e,t)}else this.stringMap.set(e,s)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,r){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,r)}stringMapKeyRemoved(e,t,r){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,r)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map((e=>e.name))}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class TokenListObserver{constructor(e,t,r){this.attributeObserver=new AttributeObserver(e,t,this);this.delegate=r;this.tokensByElement=new Multimap}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,r]=this.refreshTokensForElement(e);this.tokensUnmatched(t);this.tokensMatched(r)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach((e=>this.tokenMatched(e)))}tokensUnmatched(e){e.forEach((e=>this.tokenUnmatched(e)))}tokenMatched(e){this.delegate.tokenMatched(e);this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e);this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e);const r=this.readTokensForElement(e);const s=zip(t,r).findIndex((([e,t])=>!tokensAreEqual(e,t)));return-1==s?[[],[]]:[t.slice(s),r.slice(s)]}readTokensForElement(e){const t=this.attributeName;const r=e.getAttribute(t)||"";return parseTokenString(r,e,t)}}function parseTokenString(e,t,r){return e.trim().split(/\s+/).filter((e=>e.length)).map(((e,s)=>({element:t,attributeName:r,content:e,index:s})))}function zip(e,t){const r=Math.max(e.length,t.length);return Array.from({length:r},((r,s)=>[e[s],t[s]]))}function tokensAreEqual(e,t){return e&&t&&e.index==t.index&&e.content==t.content}class ValueListObserver{constructor(e,t,r){this.tokenListObserver=new TokenListObserver(e,t,this);this.delegate=r;this.parseResultsByToken=new WeakMap;this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e;const{value:r}=this.fetchParseResultForToken(e);if(r){this.fetchValuesByTokenForElement(t).set(e,r);this.delegate.elementMatchedValue(t,r)}}tokenUnmatched(e){const{element:t}=e;const{value:r}=this.fetchParseResultForToken(e);if(r){this.fetchValuesByTokenForElement(t).delete(e);this.delegate.elementUnmatchedValue(t,r)}}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);if(!t){t=this.parseToken(e);this.parseResultsByToken.set(e,t)}return t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);if(!t){t=new Map;this.valuesByTokenByElement.set(e,t)}return t}parseToken(e){try{const t=this.delegate.parseValueForToken(e);return{value:t}}catch(e){return{error:e}}}}class BindingObserver{constructor(e,t){this.context=e;this.delegate=t;this.bindingsByAction=new Map}start(){if(!this.valueListObserver){this.valueListObserver=new ValueListObserver(this.element,this.actionAttribute,this);this.valueListObserver.start()}}stop(){if(this.valueListObserver){this.valueListObserver.stop();delete this.valueListObserver;this.disconnectAllActions()}}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new Binding(this.context,e);this.bindingsByAction.set(e,t);this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);if(t){this.bindingsByAction.delete(e);this.delegate.bindingDisconnected(t)}}disconnectAllActions(){this.bindings.forEach((e=>this.delegate.bindingDisconnected(e,true)));this.bindingsByAction.clear()}parseValueForToken(e){const t=Action.forToken(e,this.schema);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class ValueObserver{constructor(e,t){this.context=e;this.receiver=t;this.stringMapObserver=new StringMapObserver(this.element,this);this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start();this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const r=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,r.writer(this.receiver[e]),r.writer(r.defaultValue))}stringMapValueChanged(e,t,r){const s=this.valueDescriptorNameMap[t];if(null!==e){null===r&&(r=s.writer(s.defaultValue));this.invokeChangedCallback(t,e,r)}}stringMapKeyRemoved(e,t,r){const s=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,s.writer(this.receiver[e]),r):this.invokeChangedCallback(e,s.writer(s.defaultValue),r)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:r,writer:s}of this.valueDescriptors)void 0==r||this.controller.data.has(e)||this.invokeChangedCallback(t,s(r),void 0)}invokeChangedCallback(e,t,r){const s=`${e}Changed`;const n=this.receiver[s];if("function"==typeof n){const s=this.valueDescriptorNameMap[e];try{const e=s.reader(t);let i=r;r&&(i=s.reader(r));n.call(this.receiver,e,i)}catch(e){e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${s.name}" - ${e.message}`);throw e}}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map((t=>e[t]))}get valueDescriptorNameMap(){const e={};Object.keys(this.valueDescriptorMap).forEach((t=>{const r=this.valueDescriptorMap[t];e[r.name]=r}));return e}hasValue(e){const t=this.valueDescriptorNameMap[e];const r=`has${capitalize(t.name)}`;return this.receiver[r]}}class TargetObserver{constructor(e,t){this.context=e;this.delegate=t;this.targetsByName=new Multimap}start(){if(!this.tokenListObserver){this.tokenListObserver=new TokenListObserver(this.element,this.attributeName,this);this.tokenListObserver.start()}}stop(){if(this.tokenListObserver){this.disconnectAllTargets();this.tokenListObserver.stop();delete this.tokenListObserver}}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var r;if(!this.targetsByName.has(t,e)){this.targetsByName.add(t,e);null===(r=this.tokenListObserver)||void 0===r?void 0:r.pause((()=>this.delegate.targetConnected(e,t)))}}disconnectTarget(e,t){var r;if(this.targetsByName.has(t,e)){this.targetsByName.delete(t,e);null===(r=this.tokenListObserver)||void 0===r?void 0:r.pause((()=>this.delegate.targetDisconnected(e,t)))}}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function readInheritableStaticArrayValues(e,t){const r=getAncestorsForConstructor(e);return Array.from(r.reduce(((e,r)=>{getOwnStaticArrayValues(r,t).forEach((t=>e.add(t)));return e}),new Set))}function readInheritableStaticObjectPairs(e,t){const r=getAncestorsForConstructor(e);return r.reduce(((e,r)=>{e.push(...getOwnStaticObjectPairs(r,t));return e}),[])}function getAncestorsForConstructor(e){const t=[];while(e){t.push(e);e=Object.getPrototypeOf(e)}return t.reverse()}function getOwnStaticArrayValues(e,t){const r=e[t];return Array.isArray(r)?r:[]}function getOwnStaticObjectPairs(e,t){const r=e[t];return r?Object.keys(r).map((e=>[e,r[e]])):[]}class OutletObserver{constructor(e,t){this.started=false;this.context=e;this.delegate=t;this.outletsByName=new Multimap;this.outletElementsByName=new Multimap;this.selectorObserverMap=new Map;this.attributeObserverMap=new Map}start(){if(!this.started){this.outletDefinitions.forEach((e=>{this.setupSelectorObserverForOutlet(e);this.setupAttributeObserverForOutlet(e)}));this.started=true;this.dependentContexts.forEach((e=>e.refresh()))}}refresh(){this.selectorObserverMap.forEach((e=>e.refresh()));this.attributeObserverMap.forEach((e=>e.refresh()))}stop(){if(this.started){this.started=false;this.disconnectAllOutlets();this.stopSelectorObservers();this.stopAttributeObservers()}}stopSelectorObservers(){if(this.selectorObserverMap.size>0){this.selectorObserverMap.forEach((e=>e.stop()));this.selectorObserverMap.clear()}}stopAttributeObservers(){if(this.attributeObserverMap.size>0){this.attributeObserverMap.forEach((e=>e.stop()));this.attributeObserverMap.clear()}}selectorMatched(e,t,{outletName:r}){const s=this.getOutlet(e,r);s&&this.connectOutlet(s,e,r)}selectorUnmatched(e,t,{outletName:r}){const s=this.getOutletFromMap(e,r);s&&this.disconnectOutlet(s,e,r)}selectorMatchElement(e,{outletName:t}){const r=this.selector(t);const s=this.hasOutlet(e,t);const n=e.matches(`[${this.schema.controllerAttribute}~=${t}]`);return!!r&&(s&&n&&e.matches(r))}elementMatchedAttribute(e,t){const r=this.getOutletNameFromOutletAttributeName(t);r&&this.updateSelectorObserverForOutlet(r)}elementAttributeValueChanged(e,t){const r=this.getOutletNameFromOutletAttributeName(t);r&&this.updateSelectorObserverForOutlet(r)}elementUnmatchedAttribute(e,t){const r=this.getOutletNameFromOutletAttributeName(t);r&&this.updateSelectorObserverForOutlet(r)}connectOutlet(e,t,r){var s;if(!this.outletElementsByName.has(r,t)){this.outletsByName.add(r,e);this.outletElementsByName.add(r,t);null===(s=this.selectorObserverMap.get(r))||void 0===s?void 0:s.pause((()=>this.delegate.outletConnected(e,t,r)))}}disconnectOutlet(e,t,r){var s;if(this.outletElementsByName.has(r,t)){this.outletsByName.delete(r,e);this.outletElementsByName.delete(r,t);null===(s=this.selectorObserverMap.get(r))||void 0===s?void 0:s.pause((()=>this.delegate.outletDisconnected(e,t,r)))}}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const r of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(r,t,e)}updateSelectorObserverForOutlet(e){const t=this.selectorObserverMap.get(e);t&&(t.selector=this.selector(e))}setupSelectorObserverForOutlet(e){const t=this.selector(e);const r=new SelectorObserver(document.body,t,this,{outletName:e});this.selectorObserverMap.set(e,r);r.start()}setupAttributeObserverForOutlet(e){const t=this.attributeNameForOutletName(e);const r=new AttributeObserver(this.scope.element,t,this);this.attributeObserverMap.set(e,r);r.start()}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}attributeNameForOutletName(e){return this.scope.schema.outletAttributeForScope(this.identifier,e)}getOutletNameFromOutletAttributeName(e){return this.outletDefinitions.find((t=>this.attributeNameForOutletName(t)===e))}get outletDependencies(){const e=new Multimap;this.router.modules.forEach((t=>{const r=t.definition.controllerConstructor;const s=readInheritableStaticArrayValues(r,"outlets");s.forEach((r=>e.add(r,t.identifier)))}));return e}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const e=this.dependentControllerIdentifiers;return this.router.contexts.filter((t=>e.includes(t.identifier)))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(e,t){return this.outletsByName.getValuesForKey(t).find((t=>t.element===e))}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class Context{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:r,controller:s,element:n}=this;t=Object.assign({identifier:r,controller:s,element:n},t);this.application.logDebugActivity(this.identifier,e,t)};this.module=e;this.scope=t;this.controller=new e.controllerConstructor(this);this.bindingObserver=new BindingObserver(this,this.dispatcher);this.valueObserver=new ValueObserver(this,this.controller);this.targetObserver=new TargetObserver(this,this);this.outletObserver=new OutletObserver(this,this);try{this.controller.initialize();this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start();this.valueObserver.start();this.targetObserver.start();this.outletObserver.start();try{this.controller.connect();this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect();this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop();this.targetObserver.stop();this.valueObserver.stop();this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,r={}){const{identifier:s,controller:n,element:i}=this;r=Object.assign({identifier:s,controller:n,element:i},r);this.application.handleError(e,`Error ${t}`,r)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}outletConnected(e,t,r){this.invokeControllerMethod(`${namespaceCamelize(r)}OutletConnected`,e,t)}outletDisconnected(e,t,r){this.invokeControllerMethod(`${namespaceCamelize(r)}OutletDisconnected`,e,t)}invokeControllerMethod(e,...t){const r=this.controller;"function"==typeof r[e]&&r[e](...t)}}function bless(e){return shadow(e,getBlessedProperties(e))}function shadow(e,t){const r=i(e);const s=getShadowProperties(e.prototype,t);Object.defineProperties(r.prototype,s);return r}function getBlessedProperties(e){const t=readInheritableStaticArrayValues(e,"blessings");return t.reduce(((t,r)=>{const s=r(e);for(const e in s){const r=t[e]||{};t[e]=Object.assign(r,s[e])}return t}),{})}function getShadowProperties(e,t){return n(t).reduce(((r,s)=>{const n=getShadowedDescriptor(e,t,s);n&&Object.assign(r,{[s]:n});return r}),{})}function getShadowedDescriptor(e,t,r){const s=Object.getOwnPropertyDescriptor(e,r);const n=s&&"value"in s;if(!n){const e=Object.getOwnPropertyDescriptor(t,r).value;if(s){e.get=s.get||e.get;e.set=s.set||e.set}return e}}const n=(()=>"function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames)();const i=(()=>{function extendWithReflect(e){function extended(){return Reflect.construct(e,arguments,new.target)}extended.prototype=Object.create(e.prototype,{constructor:{value:extended}});Reflect.setPrototypeOf(extended,e);return extended}function testReflectExtension(){const a=function(){this.a.call(this)};const e=extendWithReflect(a);e.prototype.a=function(){};return new e}try{testReflectExtension();return extendWithReflect}catch(e){return e=>class extended extends e{}}})();function blessDefinition(e){return{identifier:e.identifier,controllerConstructor:bless(e.controllerConstructor)}}class Module{constructor(e,t){this.application=e;this.definition=blessDefinition(t);this.contextsByScope=new WeakMap;this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t);t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);if(t){this.connectedContexts.delete(t);t.disconnect()}}fetchContextForScope(e){let t=this.contextsByScope.get(e);if(!t){t=new Context(this,e);this.contextsByScope.set(e,t)}return t}}class ClassMap{constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){const t=this.data.get(this.getDataKey(e))||"";return tokenize(t)}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class DataMap{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const r=this.getAttributeNameForKey(e);this.element.setAttribute(r,t);return this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);this.element.removeAttribute(t);return true}return false}getAttributeNameForKey(e){return`data-${this.identifier}-${dasherize(e)}`}}class Guide{constructor(e){this.warnedKeysByObject=new WeakMap;this.logger=e}warn(e,t,r){let s=this.warnedKeysByObject.get(e);if(!s){s=new Set;this.warnedKeysByObject.set(e,s)}if(!s.has(t)){s.add(t);this.logger.warn(r,e)}}}function attributeValueContainsToken(e,t){return`[${e}~="${t}"]`}class TargetSet{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)]),[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){const t=this.schema.targetAttributeForScope(this.identifier);return attributeValueContainsToken(t,e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map((t=>this.deprecate(t,e)))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return attributeValueContainsToken(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:r}=this;const s=this.schema.targetAttribute;const n=this.schema.targetAttributeForScope(r);this.guide.warn(e,`target:${t}`,`Please replace ${s}="${r}.${t}" with ${n}="${t}". The ${s} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class OutletSet{constructor(e,t){this.scope=e;this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findOutlet(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllOutlets(t)]),[])}getSelectorForOutletName(e){const t=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(t)}findOutlet(e){const t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){const t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(e,t){const r=this.scope.queryElements(e);return r.filter((r=>this.matchesElement(r,e,t)))[0]}findAllElements(e,t){const r=this.scope.queryElements(e);return r.filter((r=>this.matchesElement(r,e,t)))}matchesElement(e,t,r){const s=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&s.split(" ").includes(r)}}class Scope{constructor(e,t,r,s){this.targets=new TargetSet(this);this.classes=new ClassMap(this);this.data=new DataMap(this);this.containsElement=e=>e.closest(this.controllerSelector)===this.element;this.schema=e;this.element=t;this.identifier=r;this.guide=new Guide(s);this.outlets=new OutletSet(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return attributeValueContainsToken(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new Scope(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class ScopeObserver{constructor(e,t,r){this.element=e;this.schema=t;this.delegate=r;this.valueListObserver=new ValueListObserver(this.element,this.controllerAttribute,this);this.scopesByIdentifierByElement=new WeakMap;this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:r}=e;return this.parseValueForElementAndIdentifier(t,r)}parseValueForElementAndIdentifier(e,t){const r=this.fetchScopesByIdentifierForElement(e);let s=r.get(t);if(!s){s=this.delegate.createScopeForElementAndIdentifier(e,t);r.set(t,s)}return s}elementMatchedValue(e,t){const r=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,r);1==r&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const r=this.scopeReferenceCounts.get(t);if(r){this.scopeReferenceCounts.set(t,r-1);1==r&&this.delegate.scopeDisconnected(t)}}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);if(!t){t=new Map;this.scopesByIdentifierByElement.set(e,t)}return t}}class Router{constructor(e){this.application=e;this.scopeObserver=new ScopeObserver(this.element,this.schema,this);this.scopesByIdentifier=new Multimap;this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce(((e,t)=>e.concat(t.contexts)),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new Module(this.application,e);this.connectModule(t);const r=e.controllerConstructor.afterLoad;r&&r.call(e.controllerConstructor,e.identifier,this.application)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const r=this.modulesByIdentifier.get(t);if(r)return r.contexts.find((t=>t.element==e))}proposeToConnectScopeForElementAndIdentifier(e,t){const r=this.scopeObserver.parseValueForElementAndIdentifier(e,t);r?this.scopeObserver.elementMatchedValue(r.element,r):console.error(`Couldn't find or create scope for identifier: "${t}" and element:`,e)}handleError(e,t,r){this.application.handleError(e,t,r)}createScopeForElementAndIdentifier(e,t){return new Scope(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e);const t=this.scopesByIdentifier.getValuesForKey(e.identifier);t.forEach((t=>e.connectContextForScope(t)))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier);const t=this.scopesByIdentifier.getValuesForKey(e.identifier);t.forEach((t=>e.disconnectContextForScope(t)))}}const o={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},objectFromEntries("abcdefghijklmnopqrstuvwxyz".split("").map((e=>[e,e])))),objectFromEntries("0123456789".split("").map((e=>[e,e]))))};function objectFromEntries(e){return e.reduce(((e,[t,r])=>Object.assign(Object.assign({},e),{[t]:r})),{})}class Application{constructor(t=document.documentElement,r=o){this.logger=console;this.debug=false;this.logDebugActivity=(e,t,r={})=>{this.debug&&this.logFormattedMessage(e,t,r)};this.element=t;this.schema=r;this.dispatcher=new Dispatcher(this);this.router=new Router(this);this.actionDescriptorFilters=Object.assign({},e)}static start(e,t){const r=new this(e,t);r.start();return r}async start(){await domReady();this.logDebugActivity("application","starting");this.dispatcher.start();this.router.start();this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping");this.dispatcher.stop();this.router.stop();this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){const r=Array.isArray(e)?e:[e,...t];r.forEach((e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)}))}unload(e,...t){const r=Array.isArray(e)?e:[e,...t];r.forEach((e=>this.router.unloadIdentifier(e)))}get controllers(){return this.router.contexts.map((e=>e.controller))}getControllerForElementAndIdentifier(e,t){const r=this.router.getContextForElementAndIdentifier(e,t);return r?r.controller:null}handleError(e,t,r){var s;this.logger.error("%s\n\n%o\n\n%o",t,e,r);null===(s=window.onerror)||void 0===s?void 0:s.call(window,t,"",0,0,e)}logFormattedMessage(e,t,r={}){r=Object.assign({application:this},r);this.logger.groupCollapsed(`${e} #${t}`);this.logger.log("details:",Object.assign({},r));this.logger.groupEnd()}}function domReady(){return new Promise((e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",(()=>e())):e()}))}function ClassPropertiesBlessing(e){const t=readInheritableStaticArrayValues(e,"classes");return t.reduce(((e,t)=>Object.assign(e,propertiesForClassDefinition(t))),{})}function propertiesForClassDefinition(e){return{[`${e}Class`]:{get(){const{classes:t}=this;if(t.has(e))return t.get(e);{const r=t.getAttributeName(e);throw new Error(`Missing attribute "${r}"`)}}},[`${e}Classes`]:{get(){return this.classes.getAll(e)}},[`has${capitalize(e)}Class`]:{get(){return this.classes.has(e)}}}}function OutletPropertiesBlessing(e){const t=readInheritableStaticArrayValues(e,"outlets");return t.reduce(((e,t)=>Object.assign(e,propertiesForOutletDefinition(t))),{})}function getOutletController(e,t,r){return e.application.getControllerForElementAndIdentifier(t,r)}function getControllerAndEnsureConnectedScope(e,t,r){let s=getOutletController(e,t,r);if(s)return s;e.application.router.proposeToConnectScopeForElementAndIdentifier(t,r);s=getOutletController(e,t,r);return s||void 0}function propertiesForOutletDefinition(e){const t=namespaceCamelize(e);return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e);const r=this.outlets.getSelectorForOutletName(e);if(t){const r=getControllerAndEnsureConnectedScope(this,t,e);if(r)return r;throw new Error(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${r}".`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map((t=>{const r=getControllerAndEnsureConnectedScope(this,t,e);if(r)return r;console.warn(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`,t)})).filter((e=>e)):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e);const r=this.outlets.getSelectorForOutletName(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${r}".`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${capitalize(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}function TargetPropertiesBlessing(e){const t=readInheritableStaticArrayValues(e,"targets");return t.reduce(((e,t)=>Object.assign(e,propertiesForTargetDefinition(t))),{})}function propertiesForTargetDefinition(e){return{[`${e}Target`]:{get(){const t=this.targets.find(e);if(t)return t;throw new Error(`Missing target element "${e}" for "${this.identifier}" controller`)}},[`${e}Targets`]:{get(){return this.targets.findAll(e)}},[`has${capitalize(e)}Target`]:{get(){return this.targets.has(e)}}}}function ValuePropertiesBlessing(e){const t=readInheritableStaticObjectPairs(e,"values");const r={valueDescriptorMap:{get(){return t.reduce(((e,t)=>{const r=parseValueDefinitionPair(t,this.identifier);const s=this.data.getAttributeNameForKey(r.key);return Object.assign(e,{[s]:r})}),{})}}};return t.reduce(((e,t)=>Object.assign(e,propertiesForValueDefinitionPair(t))),r)}function propertiesForValueDefinitionPair(e,t){const r=parseValueDefinitionPair(e,t);const{key:s,name:n,reader:i,writer:o}=r;return{[n]:{get(){const e=this.data.get(s);return null!==e?i(e):r.defaultValue},set(e){void 0===e?this.data.delete(s):this.data.set(s,o(e))}},[`has${capitalize(n)}`]:{get(){return this.data.has(s)||r.hasCustomDefaultValue}}}}function parseValueDefinitionPair([e,t],r){return valueDescriptorForTokenAndTypeDefinition({controller:r,token:e,typeDefinition:t})}function parseValueTypeConstant(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function parseValueTypeDefault(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}function parseValueTypeObject(e){const{controller:t,token:r,typeObject:s}=e;const n=isSomething(s.type);const i=isSomething(s.default);const o=n&&i;const c=n&&!i;const l=!n&&i;const h=parseValueTypeConstant(s.type);const u=parseValueTypeDefault(e.typeObject.default);if(c)return h;if(l)return u;if(h!==u){const e=t?`${t}.${r}`:r;throw new Error(`The specified default value for the Stimulus Value "${e}" must match the defined type "${h}". The provided default value of "${s.default}" is of type "${u}".`)}return o?h:void 0}function parseValueTypeDefinition(e){const{controller:t,token:r,typeDefinition:s}=e;const n={controller:t,token:r,typeObject:s};const i=parseValueTypeObject(n);const o=parseValueTypeDefault(s);const c=parseValueTypeConstant(s);const l=i||o||c;if(l)return l;const h=t?`${t}.${s}`:r;throw new Error(`Unknown value type "${h}" for "${r}" value`)}function defaultValueForDefinition(e){const t=parseValueTypeConstant(e);if(t)return c[t];const r=hasProperty(e,"default");const s=hasProperty(e,"type");const n=e;if(r)return n.default;if(s){const{type:e}=n;const t=parseValueTypeConstant(e);if(t)return c[t]}return e}function valueDescriptorForTokenAndTypeDefinition(e){const{token:t,typeDefinition:r}=e;const s=`${dasherize(t)}-value`;const n=parseValueTypeDefinition(e);return{type:n,key:s,name:camelize(s),get defaultValue(){return defaultValueForDefinition(r)},get hasCustomDefaultValue(){return void 0!==parseValueTypeDefault(r)},reader:l[n],writer:h[n]||h.default}}const c={get array(){return[]},boolean:false,number:0,get object(){return{}},string:""};const l={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${parseValueTypeDefault(t)}"`);return t},boolean(e){return!("0"==e||"false"==String(e).toLowerCase())},number(e){return Number(e.replace(/_/g,""))},object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${parseValueTypeDefault(t)}"`);return t},string(e){return e}};const h={default:writeString,array:writeJSON,object:writeJSON};function writeJSON(e){return JSON.stringify(e)}function writeString(e){return`${e}`}class Controller{constructor(e){this.context=e}static get shouldLoad(){return true}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:r={},prefix:s=this.identifier,bubbles:n=true,cancelable:i=true}={}){const o=s?`${s}:${e}`:e;const c=new CustomEvent(o,{detail:r,bubbles:n,cancelable:i});t.dispatchEvent(c);return c}}Controller.blessings=[ClassPropertiesBlessing,TargetPropertiesBlessing,ValuePropertiesBlessing,OutletPropertiesBlessing];Controller.targets=[];Controller.outlets=[];Controller.values={};export{Application,AttributeObserver,Context,Controller,ElementObserver,IndexedMultimap,Multimap,SelectorObserver,StringMapObserver,TokenListObserver,ValueListObserver,add,o as defaultSchema,del,fetch,prune}; + diff --git a/test/dummy/vendor/javascript/@hotwired--turbo-rails.js b/test/dummy/vendor/javascript/@hotwired--turbo-rails.js new file mode 100644 index 00000000..af39c49c --- /dev/null +++ b/test/dummy/vendor/javascript/@hotwired--turbo-rails.js @@ -0,0 +1,2 @@ +import*as e from"@hotwired/turbo";import{connectStreamSource as t,disconnectStreamSource as n}from"@hotwired/turbo";export{e as Turbo};let s;async function getConsumer(){return s||setConsumer(createConsumer().then(setConsumer))}function setConsumer(e){return s=e}async function createConsumer(){const{createConsumer:e}=await import("@rails/actioncable/src");return e()}async function subscribeTo(e,t){const{subscriptions:n}=await getConsumer();return n.create(e,t)}var o=Object.freeze(Object.defineProperty({__proto__:null,createConsumer:createConsumer,getConsumer:getConsumer,setConsumer:setConsumer,subscribeTo:subscribeTo},Symbol.toStringTag,{value:"Module"}));function walk(e){return e&&typeof e==="object"?e instanceof Date||e instanceof RegExp?e:Array.isArray(e)?e.map(walk):Object.keys(e).reduce((function(t,n){var s=n[0].toLowerCase()+n.slice(1).replace(/([A-Z]+)/g,(function(e,t){return"_"+t.toLowerCase()}));t[s]=walk(e[n]);return t}),{}):e}class TurboCableStreamSourceElement extends HTMLElement{async connectedCallback(){t(this);this.subscription=await subscribeTo(this.channel,{received:this.dispatchMessageEvent.bind(this),connected:this.subscriptionConnected.bind(this),disconnected:this.subscriptionDisconnected.bind(this)})}disconnectedCallback(){n(this);this.subscription&&this.subscription.unsubscribe()}dispatchMessageEvent(e){const t=new MessageEvent("message",{data:e});return this.dispatchEvent(t)}subscriptionConnected(){this.setAttribute("connected","")}subscriptionDisconnected(){this.removeAttribute("connected")}get channel(){const e=this.getAttribute("channel");const t=this.getAttribute("signed-stream-name");return{channel:e,signed_stream_name:t,...walk({...this.dataset})}}}customElements.get("turbo-cable-stream-source")===void 0&&customElements.define("turbo-cable-stream-source",TurboCableStreamSourceElement);function encodeMethodIntoRequestBody(e){if(e.target instanceof HTMLFormElement){const{target:t,detail:{fetchOptions:n}}=e;t.addEventListener("turbo:submit-start",(({detail:{formSubmission:{submitter:e}}})=>{const s=isBodyInit(n.body)?n.body:new URLSearchParams;const o=determineFetchMethod(e,s,t);if(!/get/i.test(o)){/post/i.test(o)?s.delete("_method"):s.set("_method",o);n.method="post"}}),{once:true})}}function determineFetchMethod(e,t,n){const s=determineFormMethod(e);const o=t.get("_method");const r=n.getAttribute("method")||"get";return typeof s=="string"?s:typeof o=="string"?o:r}function determineFormMethod(e){return e instanceof HTMLButtonElement||e instanceof HTMLInputElement?e.name==="_method"?e.value:e.hasAttribute("formmethod")?e.formMethod:null:null}function isBodyInit(e){return e instanceof FormData||e instanceof URLSearchParams}window.Turbo=e;addEventListener("turbo:before-fetch-request",encodeMethodIntoRequestBody);export{o as cable}; + diff --git a/test/dummy/vendor/javascript/@hotwired--turbo.js b/test/dummy/vendor/javascript/@hotwired--turbo.js new file mode 100644 index 00000000..f8ada063 --- /dev/null +++ b/test/dummy/vendor/javascript/@hotwired--turbo.js @@ -0,0 +1,158 @@ +(function(e){typeof e.requestSubmit!="function"&&(e.requestSubmit=function(e){if(e){validateSubmitter(e,this);e.click()}else{e=document.createElement("input");e.type="submit";e.hidden=true;this.appendChild(e);e.click();this.removeChild(e)}});function validateSubmitter(e,t){e instanceof HTMLElement||raise(TypeError,"parameter 1 is not of type 'HTMLElement'");e.type=="submit"||raise(TypeError,"The specified element is not a submit button");e.form==t||raise(DOMException,"The specified element is not owned by this form element","NotFoundError")}function raise(e,t,r){throw new e("Failed to execute 'requestSubmit' on 'HTMLFormElement': "+t+".",r)}})(HTMLFormElement.prototype);const e=new WeakMap;function findSubmitterFromClickTarget(e){const t=e instanceof Element?e:e instanceof Node?e.parentElement:null;const r=t?t.closest("input, button"):null;return r?.type=="submit"?r:null}function clickCaptured(t){const r=findSubmitterFromClickTarget(t.target);r&&r.form&&e.set(r.form,r)}(function(){if("submitter"in Event.prototype)return;let t=window.Event.prototype;if("SubmitEvent"in window){const e=window.SubmitEvent.prototype;if(!/Apple Computer/.test(navigator.vendor)||"submitter"in e)return;t=e}addEventListener("click",clickCaptured,true);Object.defineProperty(t,"submitter",{get(){if(this.type=="submit"&&this.target instanceof HTMLFormElement)return e.get(this.target)}})})();const t={eager:"eager",lazy:"lazy"};class FrameElement extends HTMLElement{static delegateConstructor=void 0;loaded=Promise.resolve();static get observedAttributes(){return["disabled","complete","loading","src"]}constructor(){super();this.delegate=new FrameElement.delegateConstructor(this)}connectedCallback(){this.delegate.connect()}disconnectedCallback(){this.delegate.disconnect()}reload(){return this.delegate.sourceURLReloaded()}attributeChangedCallback(e){e=="loading"?this.delegate.loadingStyleChanged():e=="complete"?this.delegate.completeChanged():e=="src"?this.delegate.sourceURLChanged():this.delegate.disabledChanged()}get src(){return this.getAttribute("src")}set src(e){e?this.setAttribute("src",e):this.removeAttribute("src")}get refresh(){return this.getAttribute("refresh")}set refresh(e){e?this.setAttribute("refresh",e):this.removeAttribute("refresh")}get loading(){return frameLoadingStyleFromString(this.getAttribute("loading")||"")}set loading(e){e?this.setAttribute("loading",e):this.removeAttribute("loading")}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}get autoscroll(){return this.hasAttribute("autoscroll")}set autoscroll(e){e?this.setAttribute("autoscroll",""):this.removeAttribute("autoscroll")}get complete(){return!this.delegate.isLoading}get isActive(){return this.ownerDocument===document&&!this.isPreview}get isPreview(){return this.ownerDocument?.documentElement?.hasAttribute("data-turbo-preview")}}function frameLoadingStyleFromString(e){switch(e.toLowerCase()){case"lazy":return t.lazy;default:return t.eager}}function expandURL(e){return new URL(e.toString(),document.baseURI)}function getAnchor(e){let t;return e.hash?e.hash.slice(1):(t=e.href.match(/#(.*)$/))?t[1]:void 0}function getAction$1(e,t){const r=t?.getAttribute("formaction")||e.getAttribute("action")||e.action;return expandURL(r)}function getExtension(e){return(getLastPathComponent(e).match(/\.[^.]*$/)||[])[0]||""}function isHTML(e){return!!getExtension(e).match(/^(?:|\.(?:htm|html|xhtml|php))$/)}function isPrefixedBy(e,t){const r=getPrefix(t);return e.href===expandURL(r).href||e.href.startsWith(r)}function locationIsVisitable(e,t){return isPrefixedBy(e,t)&&isHTML(e)}function getRequestURL(e){const t=getAnchor(e);return t!=null?e.href.slice(0,-(t.length+1)):e.href}function toCacheKey(e){return getRequestURL(e)}function urlsAreEqual(e,t){return expandURL(e).href==expandURL(t).href}function getPathComponents(e){return e.pathname.split("/").slice(1)}function getLastPathComponent(e){return getPathComponents(e).slice(-1)[0]}function getPrefix(e){return addTrailingSlash(e.origin+e.pathname)}function addTrailingSlash(e){return e.endsWith("/")?e:e+"/"}class FetchResponse{constructor(e){this.response=e}get succeeded(){return this.response.ok}get failed(){return!this.succeeded}get clientError(){return this.statusCode>=400&&this.statusCode<=499}get serverError(){return this.statusCode>=500&&this.statusCode<=599}get redirected(){return this.response.redirected}get location(){return expandURL(this.response.url)}get isHTML(){return this.contentType&&this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/)}get statusCode(){return this.response.status}get contentType(){return this.header("Content-Type")}get responseText(){return this.response.clone().text()}get responseHTML(){return this.isHTML?this.response.clone().text():Promise.resolve(void 0)}header(e){return this.response.headers.get(e)}}function activateScriptElement(e){if(e.getAttribute("data-turbo-eval")=="false")return e;{const t=document.createElement("script");const r=getMetaContent("csp-nonce");r&&(t.nonce=r);t.textContent=e.textContent;t.async=false;copyElementAttributes(t,e);return t}}function copyElementAttributes(e,t){for(const{name:r,value:s}of t.attributes)e.setAttribute(r,s)}function createDocumentFragment(e){const t=document.createElement("template");t.innerHTML=e;return t.content}function dispatch(e,{target:t,cancelable:r,detail:s}={}){const i=new CustomEvent(e,{cancelable:r,bubbles:true,composed:true,detail:s});t&&t.isConnected?t.dispatchEvent(i):document.documentElement.dispatchEvent(i);return i}function nextRepaint(){return document.visibilityState==="hidden"?nextEventLoopTick():nextAnimationFrame()}function nextAnimationFrame(){return new Promise((e=>requestAnimationFrame((()=>e()))))}function nextEventLoopTick(){return new Promise((e=>setTimeout((()=>e()),0)))}function nextMicrotask(){return Promise.resolve()}function parseHTMLDocument(e=""){return(new DOMParser).parseFromString(e,"text/html")}function unindent(e,...t){const r=interpolate(e,t).replace(/^\n/,"").split("\n");const s=r[0].match(/^\s+/);const i=s?s[0].length:0;return r.map((e=>e.slice(i))).join("\n")}function interpolate(e,t){return e.reduce(((e,r,s)=>{const i=t[s]==void 0?"":t[s];return e+r+i}),"")}function uuid(){return Array.from({length:36}).map(((e,t)=>t==8||t==13||t==18||t==23?"-":t==14?"4":t==19?(Math.floor(Math.random()*4)+8).toString(16):Math.floor(Math.random()*15).toString(16))).join("")}function getAttribute(e,...t){for(const r of t.map((t=>t?.getAttribute(e))))if(typeof r=="string")return r;return null}function hasAttribute(e,...t){return t.some((t=>t&&t.hasAttribute(e)))}function markAsBusy(...e){for(const t of e){t.localName=="turbo-frame"&&t.setAttribute("busy","");t.setAttribute("aria-busy","true")}}function clearBusyState(...e){for(const t of e){t.localName=="turbo-frame"&&t.removeAttribute("busy");t.removeAttribute("aria-busy")}}function waitForLoad(e,t=2e3){return new Promise((r=>{const onComplete=()=>{e.removeEventListener("error",onComplete);e.removeEventListener("load",onComplete);r()};e.addEventListener("load",onComplete,{once:true});e.addEventListener("error",onComplete,{once:true});setTimeout(r,t)}))}function getHistoryMethodForAction(e){switch(e){case"replace":return history.replaceState;case"advance":case"restore":return history.pushState}}function isAction(e){return e=="advance"||e=="replace"||e=="restore"}function getVisitAction(...e){const t=getAttribute("data-turbo-action",...e);return isAction(t)?t:null}function getMetaElement(e){return document.querySelector(`meta[name="${e}"]`)}function getMetaContent(e){const t=getMetaElement(e);return t&&t.content}function setMetaContent(e,t){let r=getMetaElement(e);if(!r){r=document.createElement("meta");r.setAttribute("name",e);document.head.appendChild(r)}r.setAttribute("content",t);return r}function findClosestRecursively(e,t){if(e instanceof Element)return e.closest(t)||findClosestRecursively(e.assignedSlot||e.getRootNode()?.host,t)}function elementIsFocusable(e){const t="[inert], :disabled, [hidden], details:not([open]), dialog:not([open])";return!!e&&e.closest(t)==null&&typeof e.focus=="function"}function queryAutofocusableElement(e){return Array.from(e.querySelectorAll("[autofocus]")).find(elementIsFocusable)}async function around(e,t){const r=t();e();await nextAnimationFrame();const s=t();return[r,s]}function doesNotTargetIFrame(e){if(e.hasAttribute("target"))for(const t of document.getElementsByName(e.target))if(t instanceof HTMLIFrameElement)return false;return true}function findLinkFromClickTarget(e){return findClosestRecursively(e,"a[href]:not([target^=_]):not([download])")}function getLocationForLink(e){return expandURL(e.getAttribute("href")||"")}function debounce(e,t){let r=null;return(...s)=>{const callback=()=>e.apply(this,s);clearTimeout(r);r=setTimeout(callback,t)}}class LimitedSet extends Set{constructor(e){super();this.maxSize=e}add(e){if(this.size>=this.maxSize){const e=this.values();const t=e.next().value;this.delete(t)}super.add(e)}}const r=new LimitedSet(20);const s=window.fetch;function fetchWithTurboHeaders(e,t={}){const i=new Headers(t.headers||{});const n=uuid();r.add(n);i.append("X-Turbo-Request-Id",n);return s(e,{...t,headers:i})}function fetchMethodFromString(e){switch(e.toLowerCase()){case"get":return i.get;case"post":return i.post;case"put":return i.put;case"patch":return i.patch;case"delete":return i.delete}}const i={get:"get",post:"post",put:"put",patch:"patch",delete:"delete"};function fetchEnctypeFromString(e){switch(e.toLowerCase()){case n.multipart:return n.multipart;case n.plain:return n.plain;default:return n.urlEncoded}}const n={urlEncoded:"application/x-www-form-urlencoded",multipart:"multipart/form-data",plain:"text/plain"};class FetchRequest{abortController=new AbortController;#e=e=>{};constructor(e,t,r,s=new URLSearchParams,i=null,o=n.urlEncoded){const[a,l]=buildResourceAndBody(expandURL(r),t,s,o);this.delegate=e;this.url=a;this.target=i;this.fetchOptions={credentials:"same-origin",redirect:"follow",method:t,headers:{...this.defaultHeaders},body:l,signal:this.abortSignal,referrer:this.delegate.referrer?.href};this.enctype=o}get method(){return this.fetchOptions.method}set method(e){const t=this.isSafe?this.url.searchParams:this.fetchOptions.body||new FormData;const r=fetchMethodFromString(e)||i.get;this.url.search="";const[s,n]=buildResourceAndBody(this.url,r,t,this.enctype);this.url=s;this.fetchOptions.body=n;this.fetchOptions.method=r}get headers(){return this.fetchOptions.headers}set headers(e){this.fetchOptions.headers=e}get body(){return this.isSafe?this.url.searchParams:this.fetchOptions.body}set body(e){this.fetchOptions.body=e}get location(){return this.url}get params(){return this.url.searchParams}get entries(){return this.body?Array.from(this.body.entries()):[]}cancel(){this.abortController.abort()}async perform(){const{fetchOptions:e}=this;this.delegate.prepareRequest(this);const t=await this.#t(e);try{this.delegate.requestStarted(this);t.detail.fetchRequest?this.response=t.detail.fetchRequest.response:this.response=fetchWithTurboHeaders(this.url.href,e);const r=await this.response;return await this.receive(r)}catch(e){if(e.name!=="AbortError"){this.#r(e)&&this.delegate.requestErrored(this,e);throw e}}finally{this.delegate.requestFinished(this)}}async receive(e){const t=new FetchResponse(e);const r=dispatch("turbo:before-fetch-response",{cancelable:true,detail:{fetchResponse:t},target:this.target});r.defaultPrevented?this.delegate.requestPreventedHandlingResponse(this,t):t.succeeded?this.delegate.requestSucceededWithResponse(this,t):this.delegate.requestFailedWithResponse(this,t);return t}get defaultHeaders(){return{Accept:"text/html, application/xhtml+xml"}}get isSafe(){return isSafe(this.method)}get abortSignal(){return this.abortController.signal}acceptResponseType(e){this.headers.Accept=[e,this.headers.Accept].join(", ")}async#t(e){const t=new Promise((e=>this.#e=e));const r=dispatch("turbo:before-fetch-request",{cancelable:true,detail:{fetchOptions:e,url:this.url,resume:this.#e},target:this.target});this.url=r.detail.url;r.defaultPrevented&&await t;return r}#r(e){const t=dispatch("turbo:fetch-request-error",{target:this.target,cancelable:true,detail:{request:this,error:e}});return!t.defaultPrevented}}function isSafe(e){return fetchMethodFromString(e)==i.get}function buildResourceAndBody(e,t,r,s){const i=Array.from(r).length>0?new URLSearchParams(entriesExcludingFiles(r)):e.searchParams;return isSafe(t)?[mergeIntoURLSearchParams(e,i),null]:s==n.urlEncoded?[e,i]:[e,r]}function entriesExcludingFiles(e){const t=[];for(const[r,s]of e)s instanceof File||t.push([r,s]);return t}function mergeIntoURLSearchParams(e,t){const r=new URLSearchParams(entriesExcludingFiles(t));e.search=r.toString();return e}class AppearanceObserver{started=false;constructor(e,t){this.delegate=e;this.element=t;this.intersectionObserver=new IntersectionObserver(this.intersect)}start(){if(!this.started){this.started=true;this.intersectionObserver.observe(this.element)}}stop(){if(this.started){this.started=false;this.intersectionObserver.unobserve(this.element)}}intersect=e=>{const t=e.slice(-1)[0];t?.isIntersecting&&this.delegate.elementAppearedInViewport(this.element)}}class StreamMessage{static contentType="text/vnd.turbo-stream.html";static wrap(e){return typeof e=="string"?new this(createDocumentFragment(e)):e}constructor(e){this.fragment=importStreamElements(e)}}function importStreamElements(e){for(const t of e.querySelectorAll("turbo-stream")){const e=document.importNode(t,true);for(const t of e.templateElement.content.querySelectorAll("script"))t.replaceWith(activateScriptElement(t));t.replaceWith(e)}return e}const o=100;class PrefetchCache{#s=null;#i=null;get(e){if(this.#i&&this.#i.url===e&&this.#i.expire>Date.now())return this.#i.request}setLater(e,t,r){this.clear();this.#s=setTimeout((()=>{t.perform();this.set(e,t,r);this.#s=null}),o)}set(e,t,r){this.#i={url:e,request:t,expire:new Date((new Date).getTime()+r)}}clear(){this.#s&&clearTimeout(this.#s);this.#i=null}}const a=1e4;const l=new PrefetchCache;const c={initialized:"initialized",requesting:"requesting",waiting:"waiting",receiving:"receiving",stopping:"stopping",stopped:"stopped"};class FormSubmission{state=c.initialized;static confirmMethod(e,t,r){return Promise.resolve(confirm(e))}constructor(e,t,r,s=false){const i=getMethod(t,r);const n=getAction(getFormAction(t,r),i);const o=buildFormData(t,r);const a=getEnctype(t,r);this.delegate=e;this.formElement=t;this.submitter=r;this.fetchRequest=new FetchRequest(this,i,n,o,t,a);this.mustRedirect=s}get method(){return this.fetchRequest.method}set method(e){this.fetchRequest.method=e}get action(){return this.fetchRequest.url.toString()}set action(e){this.fetchRequest.url=expandURL(e)}get body(){return this.fetchRequest.body}get enctype(){return this.fetchRequest.enctype}get isSafe(){return this.fetchRequest.isSafe}get location(){return this.fetchRequest.url}async start(){const{initialized:e,requesting:t}=c;const r=getAttribute("data-turbo-confirm",this.submitter,this.formElement);if(typeof r==="string"){const e=await FormSubmission.confirmMethod(r,this.formElement,this.submitter);if(!e)return}if(this.state==e){this.state=t;return this.fetchRequest.perform()}}stop(){const{stopping:e,stopped:t}=c;if(this.state!=e&&this.state!=t){this.state=e;this.fetchRequest.cancel();return true}}prepareRequest(e){if(!e.isSafe){const t=getCookieValue(getMetaContent("csrf-param"))||getMetaContent("csrf-token");t&&(e.headers["X-CSRF-Token"]=t)}this.requestAcceptsTurboStreamResponse(e)&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(e){this.state=c.waiting;this.submitter?.setAttribute("disabled","");this.setSubmitsWith();markAsBusy(this.formElement);dispatch("turbo:submit-start",{target:this.formElement,detail:{formSubmission:this}});this.delegate.formSubmissionStarted(this)}requestPreventedHandlingResponse(e,t){l.clear();this.result={success:t.succeeded,fetchResponse:t}}requestSucceededWithResponse(e,t){if(t.clientError||t.serverError)this.delegate.formSubmissionFailedWithResponse(this,t);else{l.clear();if(this.requestMustRedirect(e)&&responseSucceededWithoutRedirect(t)){const e=new Error("Form responses must redirect to another location");this.delegate.formSubmissionErrored(this,e)}else{this.state=c.receiving;this.result={success:true,fetchResponse:t};this.delegate.formSubmissionSucceededWithResponse(this,t)}}}requestFailedWithResponse(e,t){this.result={success:false,fetchResponse:t};this.delegate.formSubmissionFailedWithResponse(this,t)}requestErrored(e,t){this.result={success:false,error:t};this.delegate.formSubmissionErrored(this,t)}requestFinished(e){this.state=c.stopped;this.submitter?.removeAttribute("disabled");this.resetSubmitterText();clearBusyState(this.formElement);dispatch("turbo:submit-end",{target:this.formElement,detail:{formSubmission:this,...this.result}});this.delegate.formSubmissionFinished(this)}setSubmitsWith(){if(this.submitter&&this.submitsWith)if(this.submitter.matches("button")){this.originalSubmitText=this.submitter.innerHTML;this.submitter.innerHTML=this.submitsWith}else if(this.submitter.matches("input")){const e=this.submitter;this.originalSubmitText=e.value;e.value=this.submitsWith}}resetSubmitterText(){if(this.submitter&&this.originalSubmitText)if(this.submitter.matches("button"))this.submitter.innerHTML=this.originalSubmitText;else if(this.submitter.matches("input")){const e=this.submitter;e.value=this.originalSubmitText}}requestMustRedirect(e){return!e.isSafe&&this.mustRedirect}requestAcceptsTurboStreamResponse(e){return!e.isSafe||hasAttribute("data-turbo-stream",this.submitter,this.formElement)}get submitsWith(){return this.submitter?.getAttribute("data-turbo-submits-with")}}function buildFormData(e,t){const r=new FormData(e);const s=t?.getAttribute("name");const i=t?.getAttribute("value");s&&r.append(s,i||"");return r}function getCookieValue(e){if(e!=null){const t=document.cookie?document.cookie.split("; "):[];const r=t.find((t=>t.startsWith(e)));if(r){const e=r.split("=").slice(1).join("=");return e?decodeURIComponent(e):void 0}}}function responseSucceededWithoutRedirect(e){return e.statusCode==200&&!e.redirected}function getFormAction(e,t){const r=typeof e.action==="string"?e.action:null;return t?.hasAttribute("formaction")?t.getAttribute("formaction")||"":e.getAttribute("action")||r||""}function getAction(e,t){const r=expandURL(e);isSafe(t)&&(r.search="");return r}function getMethod(e,t){const r=t?.getAttribute("formmethod")||e.getAttribute("method")||"";return fetchMethodFromString(r.toLowerCase())||i.get}function getEnctype(e,t){return fetchEnctypeFromString(t?.getAttribute("formenctype")||e.enctype)}class Snapshot{constructor(e){this.element=e}get activeElement(){return this.element.ownerDocument.activeElement}get children(){return[...this.element.children]}hasAnchor(e){return this.getElementForAnchor(e)!=null}getElementForAnchor(e){return e?this.element.querySelector(`[id='${e}'], a[name='${e}']`):null}get isConnected(){return this.element.isConnected}get firstAutofocusableElement(){return queryAutofocusableElement(this.element)}get permanentElements(){return queryPermanentElementsAll(this.element)}getPermanentElementById(e){return getPermanentElementById(this.element,e)}getPermanentElementMapForSnapshot(e){const t={};for(const r of this.permanentElements){const{id:s}=r;const i=e.getPermanentElementById(s);i&&(t[s]=[r,i])}return t}}function getPermanentElementById(e,t){return e.querySelector(`#${t}[data-turbo-permanent]`)}function queryPermanentElementsAll(e){return e.querySelectorAll("[id][data-turbo-permanent]")}class FormSubmitObserver{started=false;constructor(e,t){this.delegate=e;this.eventTarget=t}start(){if(!this.started){this.eventTarget.addEventListener("submit",this.submitCaptured,true);this.started=true}}stop(){if(this.started){this.eventTarget.removeEventListener("submit",this.submitCaptured,true);this.started=false}}submitCaptured=()=>{this.eventTarget.removeEventListener("submit",this.submitBubbled,false);this.eventTarget.addEventListener("submit",this.submitBubbled,false)};submitBubbled=e=>{if(!e.defaultPrevented){const t=e.target instanceof HTMLFormElement?e.target:void 0;const r=e.submitter||void 0;if(t&&submissionDoesNotDismissDialog(t,r)&&submissionDoesNotTargetIFrame(t,r)&&this.delegate.willSubmitForm(t,r)){e.preventDefault();e.stopImmediatePropagation();this.delegate.formSubmitted(t,r)}}}}function submissionDoesNotDismissDialog(e,t){const r=t?.getAttribute("formmethod")||e.getAttribute("method");return r!="dialog"}function submissionDoesNotTargetIFrame(e,t){if(t?.hasAttribute("formtarget")||e.hasAttribute("target")){const r=t?.getAttribute("formtarget")||e.target;for(const e of document.getElementsByName(r))if(e instanceof HTMLIFrameElement)return false;return true}return true}class View{#n=e=>{};#o=e=>{};constructor(e,t){this.delegate=e;this.element=t}scrollToAnchor(e){const t=this.snapshot.getElementForAnchor(e);if(t){this.scrollToElement(t);this.focusElement(t)}else this.scrollToPosition({x:0,y:0})}scrollToAnchorFromLocation(e){this.scrollToAnchor(getAnchor(e))}scrollToElement(e){e.scrollIntoView()}focusElement(e){if(e instanceof HTMLElement)if(e.hasAttribute("tabindex"))e.focus();else{e.setAttribute("tabindex","-1");e.focus();e.removeAttribute("tabindex")}}scrollToPosition({x:e,y:t}){this.scrollRoot.scrollTo(e,t)}scrollToTop(){this.scrollToPosition({x:0,y:0})}get scrollRoot(){return window}async render(e){const{isPreview:t,shouldRender:r,willRender:s,newSnapshot:i}=e;const n=s;if(r)try{this.renderPromise=new Promise((e=>this.#n=e));this.renderer=e;await this.prepareToRenderSnapshot(e);const r=new Promise((e=>this.#o=e));const s={resume:this.#o,render:this.renderer.renderElement,renderMethod:this.renderer.renderMethod};const n=this.delegate.allowsImmediateRender(i,s);n||await r;await this.renderSnapshot(e);this.delegate.viewRenderedSnapshot(i,t,this.renderer.renderMethod);this.delegate.preloadOnLoadLinksForView(this.element);this.finishRenderingSnapshot(e)}finally{delete this.renderer;this.#n(void 0);delete this.renderPromise}else n&&this.invalidate(e.reloadReason)}invalidate(e){this.delegate.viewInvalidated(e)}async prepareToRenderSnapshot(e){this.markAsPreview(e.isPreview);await e.prepareToRender()}markAsPreview(e){e?this.element.setAttribute("data-turbo-preview",""):this.element.removeAttribute("data-turbo-preview")}markVisitDirection(e){this.element.setAttribute("data-turbo-visit-direction",e)}unmarkVisitDirection(){this.element.removeAttribute("data-turbo-visit-direction")}async renderSnapshot(e){await e.render()}finishRenderingSnapshot(e){e.finishRendering()}}class FrameView extends View{missing(){this.element.innerHTML='Content missing'}get snapshot(){return new Snapshot(this.element)}}class LinkInterceptor{constructor(e,t){this.delegate=e;this.element=t}start(){this.element.addEventListener("click",this.clickBubbled);document.addEventListener("turbo:click",this.linkClicked);document.addEventListener("turbo:before-visit",this.willVisit)}stop(){this.element.removeEventListener("click",this.clickBubbled);document.removeEventListener("turbo:click",this.linkClicked);document.removeEventListener("turbo:before-visit",this.willVisit)}clickBubbled=e=>{this.respondsToEventTarget(e.target)?this.clickEvent=e:delete this.clickEvent};linkClicked=e=>{if(this.clickEvent&&this.respondsToEventTarget(e.target)&&e.target instanceof Element&&this.delegate.shouldInterceptLinkClick(e.target,e.detail.url,e.detail.originalEvent)){this.clickEvent.preventDefault();e.preventDefault();this.delegate.linkClickIntercepted(e.target,e.detail.url,e.detail.originalEvent)}delete this.clickEvent};willVisit=e=>{delete this.clickEvent};respondsToEventTarget(e){const t=e instanceof Element?e:e instanceof Node?e.parentElement:null;return t&&t.closest("turbo-frame, html")==this.element}}class LinkClickObserver{started=false;constructor(e,t){this.delegate=e;this.eventTarget=t}start(){if(!this.started){this.eventTarget.addEventListener("click",this.clickCaptured,true);this.started=true}}stop(){if(this.started){this.eventTarget.removeEventListener("click",this.clickCaptured,true);this.started=false}}clickCaptured=()=>{this.eventTarget.removeEventListener("click",this.clickBubbled,false);this.eventTarget.addEventListener("click",this.clickBubbled,false)};clickBubbled=e=>{if(e instanceof MouseEvent&&this.clickEventIsSignificant(e)){const t=e.composedPath&&e.composedPath()[0]||e.target;const r=findLinkFromClickTarget(t);if(r&&doesNotTargetIFrame(r)){const t=getLocationForLink(r);if(this.delegate.willFollowLinkToLocation(r,t,e)){e.preventDefault();this.delegate.followedLinkToLocation(r,t)}}}};clickEventIsSignificant(e){return!(e.target&&e.target.isContentEditable||e.defaultPrevented||e.which>1||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)}}class FormLinkClickObserver{constructor(e,t){this.delegate=e;this.linkInterceptor=new LinkClickObserver(this,t)}start(){this.linkInterceptor.start()}stop(){this.linkInterceptor.stop()}canPrefetchRequestToLocation(e,t){return false}prefetchAndCacheRequestToLocation(e,t){}willFollowLinkToLocation(e,t,r){return this.delegate.willSubmitFormLinkToLocation(e,t,r)&&(e.hasAttribute("data-turbo-method")||e.hasAttribute("data-turbo-stream"))}followedLinkToLocation(e,t){const r=document.createElement("form");const s="hidden";for(const[e,i]of t.searchParams)r.append(Object.assign(document.createElement("input"),{type:s,name:e,value:i}));const i=Object.assign(t,{search:""});r.setAttribute("data-turbo","true");r.setAttribute("action",i.href);r.setAttribute("hidden","");const n=e.getAttribute("data-turbo-method");n&&r.setAttribute("method",n);const o=e.getAttribute("data-turbo-frame");o&&r.setAttribute("data-turbo-frame",o);const a=getVisitAction(e);a&&r.setAttribute("data-turbo-action",a);const l=e.getAttribute("data-turbo-confirm");l&&r.setAttribute("data-turbo-confirm",l);const c=e.hasAttribute("data-turbo-stream");c&&r.setAttribute("data-turbo-stream","");this.delegate.submittedFormLinkToLocation(e,t,r);document.body.appendChild(r);r.addEventListener("turbo:submit-end",(()=>r.remove()),{once:true});requestAnimationFrame((()=>r.requestSubmit()))}}class Bardo{static async preservingPermanentElements(e,t,r){const s=new this(e,t);s.enter();await r();s.leave()}constructor(e,t){this.delegate=e;this.permanentElementMap=t}enter(){for(const e in this.permanentElementMap){const[t,r]=this.permanentElementMap[e];this.delegate.enteringBardo(t,r);this.replaceNewPermanentElementWithPlaceholder(r)}}leave(){for(const e in this.permanentElementMap){const[t]=this.permanentElementMap[e];this.replaceCurrentPermanentElementWithClone(t);this.replacePlaceholderWithPermanentElement(t);this.delegate.leavingBardo(t)}}replaceNewPermanentElementWithPlaceholder(e){const t=createPlaceholderForPermanentElement(e);e.replaceWith(t)}replaceCurrentPermanentElementWithClone(e){const t=e.cloneNode(true);e.replaceWith(t)}replacePlaceholderWithPermanentElement(e){const t=this.getPlaceholderById(e.id);t?.replaceWith(e)}getPlaceholderById(e){return this.placeholders.find((t=>t.content==e))}get placeholders(){return[...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")]}}function createPlaceholderForPermanentElement(e){const t=document.createElement("meta");t.setAttribute("name","turbo-permanent-placeholder");t.setAttribute("content",e.id);return t}class Renderer{#a=null;constructor(e,t,r,s,i=true){this.currentSnapshot=e;this.newSnapshot=t;this.isPreview=s;this.willRender=i;this.renderElement=r;this.promise=new Promise(((e,t)=>this.resolvingFunctions={resolve:e,reject:t}))}get shouldRender(){return true}get reloadReason(){}prepareToRender(){}render(){}finishRendering(){if(this.resolvingFunctions){this.resolvingFunctions.resolve();delete this.resolvingFunctions}}async preservingPermanentElements(e){await Bardo.preservingPermanentElements(this,this.permanentElementMap,e)}focusFirstAutofocusableElement(){const e=this.connectedSnapshot.firstAutofocusableElement;e&&e.focus()}enteringBardo(e){this.#a||e.contains(this.currentSnapshot.activeElement)&&(this.#a=this.currentSnapshot.activeElement)}leavingBardo(e){if(e.contains(this.#a)&&this.#a instanceof HTMLElement){this.#a.focus();this.#a=null}}get connectedSnapshot(){return this.newSnapshot.isConnected?this.newSnapshot:this.currentSnapshot}get currentElement(){return this.currentSnapshot.element}get newElement(){return this.newSnapshot.element}get permanentElementMap(){return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot)}get renderMethod(){return"replace"}}class FrameRenderer extends Renderer{static renderElement(e,t){const r=document.createRange();r.selectNodeContents(e);r.deleteContents();const s=t;const i=s.ownerDocument?.createRange();if(i){i.selectNodeContents(s);e.appendChild(i.extractContents())}}constructor(e,t,r,s,i,n=true){super(t,r,s,i,n);this.delegate=e}get shouldRender(){return true}async render(){await nextRepaint();this.preservingPermanentElements((()=>{this.loadFrameElement()}));this.scrollFrameIntoView();await nextRepaint();this.focusFirstAutofocusableElement();await nextRepaint();this.activateScriptElements()}loadFrameElement(){this.delegate.willRenderFrame(this.currentElement,this.newElement);this.renderElement(this.currentElement,this.newElement)}scrollFrameIntoView(){if(this.currentElement.autoscroll||this.newElement.autoscroll){const e=this.currentElement.firstElementChild;const t=readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"),"end");const r=readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"),"auto");if(e){e.scrollIntoView({block:t,behavior:r});return true}}return false}activateScriptElements(){for(const e of this.newScriptElements){const t=activateScriptElement(e);e.replaceWith(t)}}get newScriptElements(){return this.currentElement.querySelectorAll("script")}}function readScrollLogicalPosition(e,t){return e=="end"||e=="start"||e=="center"||e=="nearest"?e:t}function readScrollBehavior(e,t){return e=="auto"||e=="smooth"?e:t}class ProgressBar{static animationDuration=300;static get defaultCSS(){return unindent` + .turbo-progress-bar { + position: fixed; + display: block; + top: 0; + left: 0; + height: 3px; + background: #0076ff; + z-index: 2147483647; + transition: + width ${ProgressBar.animationDuration}ms ease-out, + opacity ${ProgressBar.animationDuration/2}ms ${ProgressBar.animationDuration/2}ms ease-in; + transform: translate3d(0, 0, 0); + } + `}hiding=false;value=0;visible=false;constructor(){this.stylesheetElement=this.createStylesheetElement();this.progressElement=this.createProgressElement();this.installStylesheetElement();this.setValue(0)}show(){if(!this.visible){this.visible=true;this.installProgressElement();this.startTrickling()}}hide(){if(this.visible&&!this.hiding){this.hiding=true;this.fadeProgressElement((()=>{this.uninstallProgressElement();this.stopTrickling();this.visible=false;this.hiding=false}))}}setValue(e){this.value=e;this.refresh()}installStylesheetElement(){document.head.insertBefore(this.stylesheetElement,document.head.firstChild)}installProgressElement(){this.progressElement.style.width="0";this.progressElement.style.opacity="1";document.documentElement.insertBefore(this.progressElement,document.body);this.refresh()}fadeProgressElement(e){this.progressElement.style.opacity="0";setTimeout(e,ProgressBar.animationDuration*1.5)}uninstallProgressElement(){this.progressElement.parentNode&&document.documentElement.removeChild(this.progressElement)}startTrickling(){this.trickleInterval||(this.trickleInterval=window.setInterval(this.trickle,ProgressBar.animationDuration))}stopTrickling(){window.clearInterval(this.trickleInterval);delete this.trickleInterval}trickle=()=>{this.setValue(this.value+Math.random()/100)};refresh(){requestAnimationFrame((()=>{this.progressElement.style.width=10+this.value*90+"%"}))}createStylesheetElement(){const e=document.createElement("style");e.type="text/css";e.textContent=ProgressBar.defaultCSS;this.cspNonce&&(e.nonce=this.cspNonce);return e}createProgressElement(){const e=document.createElement("div");e.className="turbo-progress-bar";return e}get cspNonce(){return getMetaContent("csp-nonce")}}class HeadSnapshot extends Snapshot{detailsByOuterHTML=this.children.filter((e=>!elementIsNoscript(e))).map((e=>elementWithoutNonce(e))).reduce(((e,t)=>{const{outerHTML:r}=t;const s=r in e?e[r]:{type:elementType(t),tracked:elementIsTracked(t),elements:[]};return{...e,[r]:{...s,elements:[...s.elements,t]}}}),{});get trackedElementSignature(){return Object.keys(this.detailsByOuterHTML).filter((e=>this.detailsByOuterHTML[e].tracked)).join("")}getScriptElementsNotInSnapshot(e){return this.getElementsMatchingTypeNotInSnapshot("script",e)}getStylesheetElementsNotInSnapshot(e){return this.getElementsMatchingTypeNotInSnapshot("stylesheet",e)}getElementsMatchingTypeNotInSnapshot(e,t){return Object.keys(this.detailsByOuterHTML).filter((e=>!(e in t.detailsByOuterHTML))).map((e=>this.detailsByOuterHTML[e])).filter((({type:t})=>t==e)).map((({elements:[e]})=>e))}get provisionalElements(){return Object.keys(this.detailsByOuterHTML).reduce(((e,t)=>{const{type:r,tracked:s,elements:i}=this.detailsByOuterHTML[t];return r!=null||s?i.length>1?[...e,...i.slice(1)]:e:[...e,...i]}),[])}getMetaValue(e){const t=this.findMetaElementByName(e);return t?t.getAttribute("content"):null}findMetaElementByName(e){return Object.keys(this.detailsByOuterHTML).reduce(((t,r)=>{const{elements:[s]}=this.detailsByOuterHTML[r];return elementIsMetaElementWithName(s,e)?s:t}),0)}}function elementType(e){return elementIsScript(e)?"script":elementIsStylesheet(e)?"stylesheet":void 0}function elementIsTracked(e){return e.getAttribute("data-turbo-track")=="reload"}function elementIsScript(e){const t=e.localName;return t=="script"}function elementIsNoscript(e){const t=e.localName;return t=="noscript"}function elementIsStylesheet(e){const t=e.localName;return t=="style"||t=="link"&&e.getAttribute("rel")=="stylesheet"}function elementIsMetaElementWithName(e,t){const r=e.localName;return r=="meta"&&e.getAttribute("name")==t}function elementWithoutNonce(e){e.hasAttribute("nonce")&&e.setAttribute("nonce","");return e}class PageSnapshot extends Snapshot{static fromHTMLString(e=""){return this.fromDocument(parseHTMLDocument(e))}static fromElement(e){return this.fromDocument(e.ownerDocument)}static fromDocument({documentElement:e,body:t,head:r}){return new this(e,t,new HeadSnapshot(r))}constructor(e,t,r){super(t);this.documentElement=e;this.headSnapshot=r}clone(){const e=this.element.cloneNode(true);const t=this.element.querySelectorAll("select");const r=e.querySelectorAll("select");for(const[e,s]of t.entries()){const t=r[e];for(const e of t.selectedOptions)e.selected=false;for(const e of s.selectedOptions)t.options[e.index].selected=true}for(const t of e.querySelectorAll('input[type="password"]'))t.value="";return new PageSnapshot(this.documentElement,e,this.headSnapshot)}get lang(){return this.documentElement.getAttribute("lang")}get headElement(){return this.headSnapshot.element}get rootLocation(){const e=this.getSetting("root")??"/";return expandURL(e)}get cacheControlValue(){return this.getSetting("cache-control")}get isPreviewable(){return this.cacheControlValue!="no-preview"}get isCacheable(){return this.cacheControlValue!="no-cache"}get isVisitable(){return this.getSetting("visit-control")!="reload"}get prefersViewTransitions(){return this.headSnapshot.getMetaValue("view-transition")==="same-origin"}get shouldMorphPage(){return this.getSetting("refresh-method")==="morph"}get shouldPreserveScrollPosition(){return this.getSetting("refresh-scroll")==="preserve"}getSetting(e){return this.headSnapshot.getMetaValue(`turbo-${e}`)}}class ViewTransitioner{#l=false;#c=Promise.resolve();renderChange(e,t){if(e&&this.viewTransitionsAvailable&&!this.#l){this.#l=true;this.#c=this.#c.then((async()=>{await document.startViewTransition(t).finished}))}else this.#c=this.#c.then(t);return this.#c}get viewTransitionsAvailable(){return document.startViewTransition}}const h={action:"advance",historyChanged:false,visitCachedSnapshot:()=>{},willRender:true,updateHistory:true,shouldCacheSnapshot:true,acceptsStreamResponse:false};const d={visitStart:"visitStart",requestStart:"requestStart",requestEnd:"requestEnd",visitEnd:"visitEnd"};const u={initialized:"initialized",started:"started",canceled:"canceled",failed:"failed",completed:"completed"};const m={networkFailure:0,timeoutFailure:-1,contentTypeMismatch:-2};const p={advance:"forward",restore:"back",replace:"none"};class Visit{identifier=uuid();timingMetrics={};followedRedirect=false;historyChanged=false;scrolled=false;shouldCacheSnapshot=true;acceptsStreamResponse=false;snapshotCached=false;state=u.initialized;viewTransitioner=new ViewTransitioner;constructor(e,t,r,s={}){this.delegate=e;this.location=t;this.restorationIdentifier=r||uuid();const{action:i,historyChanged:n,referrer:o,snapshot:a,snapshotHTML:l,response:c,visitCachedSnapshot:d,willRender:u,updateHistory:m,shouldCacheSnapshot:f,acceptsStreamResponse:g,direction:b}={...h,...s};this.action=i;this.historyChanged=n;this.referrer=o;this.snapshot=a;this.snapshotHTML=l;this.response=c;this.isSamePage=this.delegate.locationWithActionIsSamePage(this.location,this.action);this.isPageRefresh=this.view.isPageRefresh(this);this.visitCachedSnapshot=d;this.willRender=u;this.updateHistory=m;this.scrolled=!u;this.shouldCacheSnapshot=f;this.acceptsStreamResponse=g;this.direction=b||p[i]}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get history(){return this.delegate.history}get restorationData(){return this.history.getRestorationDataForIdentifier(this.restorationIdentifier)}get silent(){return this.isSamePage}start(){if(this.state==u.initialized){this.recordTimingMetric(d.visitStart);this.state=u.started;this.adapter.visitStarted(this);this.delegate.visitStarted(this)}}cancel(){if(this.state==u.started){this.request&&this.request.cancel();this.cancelRender();this.state=u.canceled}}complete(){if(this.state==u.started){this.recordTimingMetric(d.visitEnd);this.adapter.visitCompleted(this);this.state=u.completed;this.followRedirect();this.followedRedirect||this.delegate.visitCompleted(this)}}fail(){if(this.state==u.started){this.state=u.failed;this.adapter.visitFailed(this);this.delegate.visitCompleted(this)}}changeHistory(){if(!this.historyChanged&&this.updateHistory){const e=this.location.href===this.referrer?.href?"replace":this.action;const t=getHistoryMethodForAction(e);this.history.update(t,this.location,this.restorationIdentifier);this.historyChanged=true}}issueRequest(){if(this.hasPreloadedResponse())this.simulateRequest();else if(this.shouldIssueRequest()&&!this.request){this.request=new FetchRequest(this,i.get,this.location);this.request.perform()}}simulateRequest(){if(this.response){this.startRequest();this.recordResponse();this.finishRequest()}}startRequest(){this.recordTimingMetric(d.requestStart);this.adapter.visitRequestStarted(this)}recordResponse(e=this.response){this.response=e;if(e){const{statusCode:t}=e;isSuccessful(t)?this.adapter.visitRequestCompleted(this):this.adapter.visitRequestFailedWithStatusCode(this,t)}}finishRequest(){this.recordTimingMetric(d.requestEnd);this.adapter.visitRequestFinished(this)}loadResponse(){if(this.response){const{statusCode:e,responseHTML:t}=this.response;this.render((async()=>{this.shouldCacheSnapshot&&this.cacheSnapshot();this.view.renderPromise&&await this.view.renderPromise;if(isSuccessful(e)&&t!=null){const e=PageSnapshot.fromHTMLString(t);await this.renderPageSnapshot(e,false);this.adapter.visitRendered(this);this.complete()}else{await this.view.renderError(PageSnapshot.fromHTMLString(t),this);this.adapter.visitRendered(this);this.fail()}}))}}getCachedSnapshot(){const e=this.view.getCachedSnapshotForLocation(this.location)||this.getPreloadedSnapshot();if(e&&(!getAnchor(this.location)||e.hasAnchor(getAnchor(this.location)))&&(this.action=="restore"||e.isPreviewable))return e}getPreloadedSnapshot(){if(this.snapshotHTML)return PageSnapshot.fromHTMLString(this.snapshotHTML)}hasCachedSnapshot(){return this.getCachedSnapshot()!=null}loadCachedSnapshot(){const e=this.getCachedSnapshot();if(e){const t=this.shouldIssueRequest();this.render((async()=>{this.cacheSnapshot();if(this.isSamePage||this.isPageRefresh)this.adapter.visitRendered(this);else{this.view.renderPromise&&await this.view.renderPromise;await this.renderPageSnapshot(e,t);this.adapter.visitRendered(this);t||this.complete()}}))}}followRedirect(){if(this.redirectedToLocation&&!this.followedRedirect&&this.response?.redirected){this.adapter.visitProposedToLocation(this.redirectedToLocation,{action:"replace",response:this.response,shouldCacheSnapshot:false,willRender:false});this.followedRedirect=true}}goToSamePageAnchor(){this.isSamePage&&this.render((async()=>{this.cacheSnapshot();this.performScroll();this.changeHistory();this.adapter.visitRendered(this)}))}prepareRequest(e){this.acceptsStreamResponse&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(){this.startRequest()}requestPreventedHandlingResponse(e,t){}async requestSucceededWithResponse(e,t){const r=await t.responseHTML;const{redirected:s,statusCode:i}=t;if(r==void 0)this.recordResponse({statusCode:m.contentTypeMismatch,redirected:s});else{this.redirectedToLocation=t.redirected?t.location:void 0;this.recordResponse({statusCode:i,responseHTML:r,redirected:s})}}async requestFailedWithResponse(e,t){const r=await t.responseHTML;const{redirected:s,statusCode:i}=t;r==void 0?this.recordResponse({statusCode:m.contentTypeMismatch,redirected:s}):this.recordResponse({statusCode:i,responseHTML:r,redirected:s})}requestErrored(e,t){this.recordResponse({statusCode:m.networkFailure,redirected:false})}requestFinished(){this.finishRequest()}performScroll(){if(!this.scrolled&&!this.view.forceReloaded&&!this.view.shouldPreserveScrollPosition(this)){this.action=="restore"?this.scrollToRestoredPosition()||this.scrollToAnchor()||this.view.scrollToTop():this.scrollToAnchor()||this.view.scrollToTop();this.isSamePage&&this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation,this.location);this.scrolled=true}}scrollToRestoredPosition(){const{scrollPosition:e}=this.restorationData;if(e){this.view.scrollToPosition(e);return true}}scrollToAnchor(){const e=getAnchor(this.location);if(e!=null){this.view.scrollToAnchor(e);return true}}recordTimingMetric(e){this.timingMetrics[e]=(new Date).getTime()}getTimingMetrics(){return{...this.timingMetrics}}getHistoryMethodForAction(e){switch(e){case"replace":return history.replaceState;case"advance":case"restore":return history.pushState}}hasPreloadedResponse(){return typeof this.response=="object"}shouldIssueRequest(){return!this.isSamePage&&(this.action=="restore"?!this.hasCachedSnapshot():this.willRender)}cacheSnapshot(){if(!this.snapshotCached){this.view.cacheSnapshot(this.snapshot).then((e=>e&&this.visitCachedSnapshot(e)));this.snapshotCached=true}}async render(e){this.cancelRender();this.frame=await nextRepaint();await e();delete this.frame}async renderPageSnapshot(e,t){await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(e),(async()=>{await this.view.renderPage(e,t,this.willRender,this);this.performScroll()}))}cancelRender(){if(this.frame){cancelAnimationFrame(this.frame);delete this.frame}}}function isSuccessful(e){return e>=200&&e<300}class BrowserAdapter{progressBar=new ProgressBar;constructor(e){this.session=e}visitProposedToLocation(e,t){locationIsVisitable(e,this.navigator.rootLocation)?this.navigator.startVisit(e,t?.restorationIdentifier||uuid(),t):window.location.href=e.toString()}visitStarted(e){this.location=e.location;e.loadCachedSnapshot();e.issueRequest();e.goToSamePageAnchor()}visitRequestStarted(e){this.progressBar.setValue(0);e.hasCachedSnapshot()||e.action!="restore"?this.showVisitProgressBarAfterDelay():this.showProgressBar()}visitRequestCompleted(e){e.loadResponse()}visitRequestFailedWithStatusCode(e,t){switch(t){case m.networkFailure:case m.timeoutFailure:case m.contentTypeMismatch:return this.reload({reason:"request_failed",context:{statusCode:t}});default:return e.loadResponse()}}visitRequestFinished(e){}visitCompleted(e){this.progressBar.setValue(1);this.hideVisitProgressBar()}pageInvalidated(e){this.reload(e)}visitFailed(e){this.progressBar.setValue(1);this.hideVisitProgressBar()}visitRendered(e){}formSubmissionStarted(e){this.progressBar.setValue(0);this.showFormProgressBarAfterDelay()}formSubmissionFinished(e){this.progressBar.setValue(1);this.hideFormProgressBar()}showVisitProgressBarAfterDelay(){this.visitProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay)}hideVisitProgressBar(){this.progressBar.hide();if(this.visitProgressBarTimeout!=null){window.clearTimeout(this.visitProgressBarTimeout);delete this.visitProgressBarTimeout}}showFormProgressBarAfterDelay(){this.formProgressBarTimeout==null&&(this.formProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay))}hideFormProgressBar(){this.progressBar.hide();if(this.formProgressBarTimeout!=null){window.clearTimeout(this.formProgressBarTimeout);delete this.formProgressBarTimeout}}showProgressBar=()=>{this.progressBar.show()};reload(e){dispatch("turbo:reload",{detail:e});window.location.href=this.location?.toString()||window.location.href}get navigator(){return this.session.navigator}}class CacheObserver{selector="[data-turbo-temporary]";deprecatedSelector="[data-turbo-cache=false]";started=false;start(){if(!this.started){this.started=true;addEventListener("turbo:before-cache",this.removeTemporaryElements,false)}}stop(){if(this.started){this.started=false;removeEventListener("turbo:before-cache",this.removeTemporaryElements,false)}}removeTemporaryElements=e=>{for(const e of this.temporaryElements)e.remove()};get temporaryElements(){return[...document.querySelectorAll(this.selector),...this.temporaryElementsWithDeprecation]}get temporaryElementsWithDeprecation(){const e=document.querySelectorAll(this.deprecatedSelector);e.length&&console.warn(`The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`);return[...e]}}class FrameRedirector{constructor(e,t){this.session=e;this.element=t;this.linkInterceptor=new LinkInterceptor(this,t);this.formSubmitObserver=new FormSubmitObserver(this,t)}start(){this.linkInterceptor.start();this.formSubmitObserver.start()}stop(){this.linkInterceptor.stop();this.formSubmitObserver.stop()}shouldInterceptLinkClick(e,t,r){return this.#h(e)}linkClickIntercepted(e,t,r){const s=this.#d(e);s&&s.delegate.linkClickIntercepted(e,t,r)}willSubmitForm(e,t){return e.closest("turbo-frame")==null&&this.#u(e,t)&&this.#h(e,t)}formSubmitted(e,t){const r=this.#d(e,t);r&&r.delegate.formSubmitted(e,t)}#u(e,t){const r=getAction$1(e,t);const s=this.element.ownerDocument.querySelector('meta[name="turbo-root"]');const i=expandURL(s?.content??"/");return this.#h(e,t)&&locationIsVisitable(r,i)}#h(e,t){const r=e instanceof HTMLFormElement?this.session.submissionIsNavigatable(e,t):this.session.elementIsNavigatable(e);if(r){const r=this.#d(e,t);return!!r&&r!=e.closest("turbo-frame")}return false}#d(e,t){const r=t?.getAttribute("data-turbo-frame")||e.getAttribute("data-turbo-frame");if(r&&r!="_top"){const e=this.element.querySelector(`#${r}:not([disabled])`);if(e instanceof FrameElement)return e}}}class History{location;restorationIdentifier=uuid();restorationData={};started=false;pageLoaded=false;currentIndex=0;constructor(e){this.delegate=e}start(){if(!this.started){addEventListener("popstate",this.onPopState,false);addEventListener("load",this.onPageLoad,false);this.currentIndex=history.state?.turbo?.restorationIndex||0;this.started=true;this.replace(new URL(window.location.href))}}stop(){if(this.started){removeEventListener("popstate",this.onPopState,false);removeEventListener("load",this.onPageLoad,false);this.started=false}}push(e,t){this.update(history.pushState,e,t)}replace(e,t){this.update(history.replaceState,e,t)}update(e,t,r=uuid()){e===history.pushState&&++this.currentIndex;const s={turbo:{restorationIdentifier:r,restorationIndex:this.currentIndex}};e.call(history,s,"",t.href);this.location=t;this.restorationIdentifier=r}getRestorationDataForIdentifier(e){return this.restorationData[e]||{}}updateRestorationData(e){const{restorationIdentifier:t}=this;const r=this.restorationData[t];this.restorationData[t]={...r,...e}}assumeControlOfScrollRestoration(){if(!this.previousScrollRestoration){this.previousScrollRestoration=history.scrollRestoration??"auto";history.scrollRestoration="manual"}}relinquishControlOfScrollRestoration(){if(this.previousScrollRestoration){history.scrollRestoration=this.previousScrollRestoration;delete this.previousScrollRestoration}}onPopState=e=>{if(this.shouldHandlePopState()){const{turbo:t}=e.state||{};if(t){this.location=new URL(window.location.href);const{restorationIdentifier:e,restorationIndex:r}=t;this.restorationIdentifier=e;const s=r>this.currentIndex?"forward":"back";this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location,e,s);this.currentIndex=r}}};onPageLoad=async e=>{await nextMicrotask();this.pageLoaded=true};shouldHandlePopState(){return this.pageIsLoaded()}pageIsLoaded(){return this.pageLoaded||document.readyState=="complete"}}class LinkPrefetchObserver{started=false;#m=null;constructor(e,t){this.delegate=e;this.eventTarget=t}start(){this.started||(this.eventTarget.readyState==="loading"?this.eventTarget.addEventListener("DOMContentLoaded",this.#p,{once:true}):this.#p())}stop(){if(this.started){this.eventTarget.removeEventListener("mouseenter",this.#f,{capture:true,passive:true});this.eventTarget.removeEventListener("mouseleave",this.#g,{capture:true,passive:true});this.eventTarget.removeEventListener("turbo:before-fetch-request",this.#b,true);this.started=false}}#p=()=>{this.eventTarget.addEventListener("mouseenter",this.#f,{capture:true,passive:true});this.eventTarget.addEventListener("mouseleave",this.#g,{capture:true,passive:true});this.eventTarget.addEventListener("turbo:before-fetch-request",this.#b,true);this.started=true};#f=e=>{if(getMetaContent("turbo-prefetch")==="false")return;const t=e.target;const r=t.matches&&t.matches("a[href]:not([target^=_]):not([download])");if(r&&this.#v(t)){const e=t;const r=getLocationForLink(e);if(this.delegate.canPrefetchRequestToLocation(e,r)){this.#m=e;const s=new FetchRequest(this,i.get,r,new URLSearchParams,t);l.setLater(r.toString(),s,this.#S)}}};#g=e=>{e.target===this.#m&&this.#E()};#E=()=>{l.clear();this.#m=null};#b=e=>{if(e.target.tagName!=="FORM"&&e.detail.fetchOptions.method==="get"){const t=l.get(e.detail.url.toString());t&&(e.detail.fetchRequest=t);l.clear()}};prepareRequest(e){const t=e.target;e.headers["X-Sec-Purpose"]="prefetch";const r=t.closest("turbo-frame");const s=t.getAttribute("data-turbo-frame")||r?.getAttribute("target")||r?.id;s&&s!=="_top"&&(e.headers["Turbo-Frame"]=s)}requestSucceededWithResponse(){}requestStarted(e){}requestErrored(e){}requestFinished(e){}requestPreventedHandlingResponse(e,t){}requestFailedWithResponse(e,t){}get#S(){return Number(getMetaContent("turbo-prefetch-cache-time"))||a}#v(e){const t=e.getAttribute("href");return!!t&&(!unfetchableLink(e)&&(!linkToTheSamePage(e)&&(!linkOptsOut(e)&&(!nonSafeLink(e)&&!eventPrevented(e)))))}}const unfetchableLink=e=>e.origin!==document.location.origin||!["http:","https:"].includes(e.protocol)||e.hasAttribute("target");const linkToTheSamePage=e=>e.pathname+e.search===document.location.pathname+document.location.search||e.href.startsWith("#");const linkOptsOut=e=>{if(e.getAttribute("data-turbo-prefetch")==="false")return true;if(e.getAttribute("data-turbo")==="false")return true;const t=findClosestRecursively(e,"[data-turbo-prefetch]");return!(!t||t.getAttribute("data-turbo-prefetch")!=="false")};const nonSafeLink=e=>{const t=e.getAttribute("data-turbo-method");return!(!t||t.toLowerCase()==="get")||(!!isUJS(e)||(!!e.hasAttribute("data-turbo-confirm")||!!e.hasAttribute("data-turbo-stream")))};const isUJS=e=>e.hasAttribute("data-remote")||e.hasAttribute("data-behavior")||e.hasAttribute("data-confirm")||e.hasAttribute("data-method");const eventPrevented=e=>{const t=dispatch("turbo:before-prefetch",{target:e,cancelable:true});return t.defaultPrevented};class Navigator{constructor(e){this.delegate=e}proposeVisit(e,t={}){this.delegate.allowsVisitingLocationWithAction(e,t.action)&&this.delegate.visitProposedToLocation(e,t)}startVisit(e,t,r={}){this.stop();this.currentVisit=new Visit(this,expandURL(e),t,{referrer:this.location,...r});this.currentVisit.start()}submitForm(e,t){this.stop();this.formSubmission=new FormSubmission(this,e,t,true);this.formSubmission.start()}stop(){if(this.formSubmission){this.formSubmission.stop();delete this.formSubmission}if(this.currentVisit){this.currentVisit.cancel();delete this.currentVisit}}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get rootLocation(){return this.view.snapshot.rootLocation}get history(){return this.delegate.history}formSubmissionStarted(e){typeof this.adapter.formSubmissionStarted==="function"&&this.adapter.formSubmissionStarted(e)}async formSubmissionSucceededWithResponse(e,t){if(e==this.formSubmission){const r=await t.responseHTML;if(r){const s=e.isSafe;s||this.view.clearSnapshotCache();const{statusCode:i,redirected:n}=t;const o=this.#w(e,t);const a={action:o,shouldCacheSnapshot:s,response:{statusCode:i,responseHTML:r,redirected:n}};this.proposeVisit(t.location,a)}}}async formSubmissionFailedWithResponse(e,t){const r=await t.responseHTML;if(r){const e=PageSnapshot.fromHTMLString(r);t.serverError?await this.view.renderError(e,this.currentVisit):await this.view.renderPage(e,false,true,this.currentVisit);e.shouldPreserveScrollPosition||this.view.scrollToTop();this.view.clearSnapshotCache()}}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished(e){typeof this.adapter.formSubmissionFinished==="function"&&this.adapter.formSubmissionFinished(e)}visitStarted(e){this.delegate.visitStarted(e)}visitCompleted(e){this.delegate.visitCompleted(e)}locationWithActionIsSamePage(e,t){const r=getAnchor(e);const s=getAnchor(this.view.lastRenderedLocation);const i=t==="restore"&&typeof r==="undefined";return t!=="replace"&&getRequestURL(e)===getRequestURL(this.view.lastRenderedLocation)&&(i||r!=null&&r!==s)}visitScrolledToSamePageLocation(e,t){this.delegate.visitScrolledToSamePageLocation(e,t)}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}#w(e,t){const{submitter:r,formElement:s}=e;return getVisitAction(r,s)||this.#y(t)}#y(e){const t=e.redirected&&e.location.href===this.location?.href;return t?"replace":"advance"}}const f={initial:0,loading:1,interactive:2,complete:3};class PageObserver{stage=f.initial;started=false;constructor(e){this.delegate=e}start(){if(!this.started){this.stage==f.initial&&(this.stage=f.loading);document.addEventListener("readystatechange",this.interpretReadyState,false);addEventListener("pagehide",this.pageWillUnload,false);this.started=true}}stop(){if(this.started){document.removeEventListener("readystatechange",this.interpretReadyState,false);removeEventListener("pagehide",this.pageWillUnload,false);this.started=false}}interpretReadyState=()=>{const{readyState:e}=this;e=="interactive"?this.pageIsInteractive():e=="complete"&&this.pageIsComplete()};pageIsInteractive(){if(this.stage==f.loading){this.stage=f.interactive;this.delegate.pageBecameInteractive()}}pageIsComplete(){this.pageIsInteractive();if(this.stage==f.interactive){this.stage=f.complete;this.delegate.pageLoaded()}}pageWillUnload=()=>{this.delegate.pageWillUnload()};get readyState(){return document.readyState}}class ScrollObserver{started=false;constructor(e){this.delegate=e}start(){if(!this.started){addEventListener("scroll",this.onScroll,false);this.onScroll();this.started=true}}stop(){if(this.started){removeEventListener("scroll",this.onScroll,false);this.started=false}}onScroll=()=>{this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})};updatePosition(e){this.delegate.scrollPositionChanged(e)}}class StreamMessageRenderer{render({fragment:e}){Bardo.preservingPermanentElements(this,getPermanentElementMapForFragment(e),(()=>{withAutofocusFromFragment(e,(()=>{withPreservedFocus((()=>{document.documentElement.appendChild(e)}))}))}))}enteringBardo(e,t){t.replaceWith(e.cloneNode(true))}leavingBardo(){}}function getPermanentElementMapForFragment(e){const t=queryPermanentElementsAll(document.documentElement);const r={};for(const s of t){const{id:t}=s;for(const i of e.querySelectorAll("turbo-stream")){const e=getPermanentElementById(i.templateElement.content,t);e&&(r[t]=[s,e])}}return r}async function withAutofocusFromFragment(e,t){const r=`turbo-stream-autofocus-${uuid()}`;const s=e.querySelectorAll("turbo-stream");const i=firstAutofocusableElementInStreams(s);let n=null;if(i){n=i.id?i.id:r;i.id=n}t();await nextRepaint();const o=document.activeElement==null||document.activeElement==document.body;if(o&&n){const e=document.getElementById(n);elementIsFocusable(e)&&e.focus();e&&e.id==r&&e.removeAttribute("id")}}async function withPreservedFocus(e){const[t,r]=await around(e,(()=>document.activeElement));const s=t&&t.id;if(s){const e=document.getElementById(s);elementIsFocusable(e)&&e!=r&&e.focus()}}function firstAutofocusableElementInStreams(e){for(const t of e){const e=queryAutofocusableElement(t.templateElement.content);if(e)return e}return null}class StreamObserver{sources=new Set;#R=false;constructor(e){this.delegate=e}start(){if(!this.#R){this.#R=true;addEventListener("turbo:before-fetch-response",this.inspectFetchResponse,false)}}stop(){if(this.#R){this.#R=false;removeEventListener("turbo:before-fetch-response",this.inspectFetchResponse,false)}}connectStreamSource(e){if(!this.streamSourceIsConnected(e)){this.sources.add(e);e.addEventListener("message",this.receiveMessageEvent,false)}}disconnectStreamSource(e){if(this.streamSourceIsConnected(e)){this.sources.delete(e);e.removeEventListener("message",this.receiveMessageEvent,false)}}streamSourceIsConnected(e){return this.sources.has(e)}inspectFetchResponse=e=>{const t=fetchResponseFromEvent(e);if(t&&fetchResponseIsStream(t)){e.preventDefault();this.receiveMessageResponse(t)}};receiveMessageEvent=e=>{this.#R&&typeof e.data=="string"&&this.receiveMessageHTML(e.data)};async receiveMessageResponse(e){const t=await e.responseHTML;t&&this.receiveMessageHTML(t)}receiveMessageHTML(e){this.delegate.receivedMessageFromStream(StreamMessage.wrap(e))}}function fetchResponseFromEvent(e){const t=e.detail?.fetchResponse;if(t instanceof FetchResponse)return t}function fetchResponseIsStream(e){const t=e.contentType??"";return t.startsWith(StreamMessage.contentType)}class ErrorRenderer extends Renderer{static renderElement(e,t){const{documentElement:r,body:s}=document;r.replaceChild(t,s)}async render(){this.replaceHeadAndBody();this.activateScriptElements()}replaceHeadAndBody(){const{documentElement:e,head:t}=document;e.replaceChild(this.newHead,t);this.renderElement(this.currentElement,this.newElement)}activateScriptElements(){for(const e of this.scriptElements){const t=e.parentNode;if(t){const r=activateScriptElement(e);t.replaceChild(r,e)}}}get newHead(){return this.newSnapshot.headSnapshot.element}get scriptElements(){return document.documentElement.querySelectorAll("script")}}var g=function(){let e=new Set;let t={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:noOp,afterNodeAdded:noOp,beforeNodeMorphed:noOp,afterNodeMorphed:noOp,beforeNodeRemoved:noOp,afterNodeRemoved:noOp,beforeAttributeUpdated:noOp},head:{style:"merge",shouldPreserve:function(e){return e.getAttribute("im-preserve")==="true"},shouldReAppend:function(e){return e.getAttribute("im-re-append")==="true"},shouldRemove:noOp,afterHeadMorphed:noOp}};function morph(e,t,r={}){e instanceof Document&&(e=e.documentElement);typeof t==="string"&&(t=parseContent(t));let s=normalizeContent(t);let i=createMorphContext(e,s,r);return morphNormalizedContent(e,s,i)}function morphNormalizedContent(e,t,r){if(r.head.block){let s=e.querySelector("head");let i=t.querySelector("head");if(s&&i){let n=handleHeadElement(i,s,r);Promise.all(n).then((function(){morphNormalizedContent(e,t,Object.assign(r,{head:{block:false,ignore:true}}))}));return}}if(r.morphStyle==="innerHTML"){morphChildren(t,e,r);return e.children}if(r.morphStyle==="outerHTML"||r.morphStyle==null){let s=findBestNodeMatch(t,e,r);let i=s?.previousSibling;let n=s?.nextSibling;let o=morphOldNodeTo(e,s,r);return s?insertSiblings(i,o,n):[]}throw"Do not understand how to morph style "+r.morphStyle} +/** + * @param possibleActiveElement + * @param ctx + * @returns {boolean} + */function ignoreValueOfActiveElement(e,t){return t.ignoreActiveValue&&e===document.activeElement&&e!==document.body} +/** + * @param oldNode root node to merge content into + * @param newContent new content to merge + * @param ctx the merge context + * @returns {Element} the element that ended up in the DOM + */function morphOldNodeTo(e,t,r){if(!r.ignoreActive||e!==document.activeElement){if(t==null){if(r.callbacks.beforeNodeRemoved(e)===false)return e;e.remove();r.callbacks.afterNodeRemoved(e);return null}if(isSoftMatch(e,t)){if(r.callbacks.beforeNodeMorphed(e,t)===false)return e;if(e instanceof HTMLHeadElement&&r.head.ignore);else if(e instanceof HTMLHeadElement&&r.head.style!=="morph")handleHeadElement(t,e,r);else{syncNodeFrom(t,e,r);ignoreValueOfActiveElement(e,r)||morphChildren(t,e,r)}r.callbacks.afterNodeMorphed(e,t);return e}if(r.callbacks.beforeNodeRemoved(e)===false)return e;if(r.callbacks.beforeNodeAdded(t)===false)return e;e.parentElement.replaceChild(t,e);r.callbacks.afterNodeAdded(t);r.callbacks.afterNodeRemoved(e);return t}} +/** + * This is the core algorithm for matching up children. The idea is to use id sets to try to match up + * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but + * by using id sets, we are able to better match up with content deeper in the DOM. + * + * Basic algorithm is, for each node in the new content: + * + * - if we have reached the end of the old parent, append the new content + * - if the new content has an id set match with the current insertion point, morph + * - search for an id set match + * - if id set match found, morph + * - otherwise search for a "soft" match + * - if a soft match is found, morph + * - otherwise, prepend the new node before the current insertion point + * + * The two search algorithms terminate if competing node matches appear to outweigh what can be achieved + * with the current node. See findIdSetMatch() and findSoftMatch() for details. + * + * @param {Element} newParent the parent element of the new content + * @param {Element } oldParent the old content that we are merging the new content into + * @param ctx the merge context + */function morphChildren(e,t,r){let s=e.firstChild;let i=t.firstChild;let n;while(s){n=s;s=n.nextSibling;if(i==null){if(r.callbacks.beforeNodeAdded(n)===false)return;t.appendChild(n);r.callbacks.afterNodeAdded(n);removeIdsFromConsideration(r,n);continue}if(isIdSetMatch(n,i,r)){morphOldNodeTo(i,n,r);i=i.nextSibling;removeIdsFromConsideration(r,n);continue}let o=findIdSetMatch(e,t,n,i,r);if(o){i=removeNodesBetween(i,o,r);morphOldNodeTo(o,n,r);removeIdsFromConsideration(r,n);continue}let a=findSoftMatch(e,t,n,i,r);if(a){i=removeNodesBetween(i,a,r);morphOldNodeTo(a,n,r);removeIdsFromConsideration(r,n)}else{if(r.callbacks.beforeNodeAdded(n)===false)return;t.insertBefore(n,i);r.callbacks.afterNodeAdded(n);removeIdsFromConsideration(r,n)}}while(i!==null){let e=i;i=i.nextSibling;removeNode(e,r)}} +/** + * @param attr {String} the attribute to be mutated + * @param to {Element} the element that is going to be updated + * @param updateType {("update"|"remove")} + * @param ctx the merge context + * @returns {boolean} true if the attribute should be ignored, false otherwise + */function ignoreAttribute(e,t,r,s){return!(e!=="value"||!s.ignoreActiveValue||t!==document.activeElement)||s.callbacks.beforeAttributeUpdated(e,t,r)===false} +/** + * syncs a given node with another node, copying over all attributes and + * inner element state from the 'from' node to the 'to' node + * + * @param {Element} from the element to copy attributes & state from + * @param {Element} to the element to copy attributes & state to + * @param ctx the merge context + */function syncNodeFrom(e,t,r){let s=e.nodeType;if(s===1){const s=e.attributes;const i=t.attributes;for(const e of s)ignoreAttribute(e.name,t,"update",r)||t.getAttribute(e.name)!==e.value&&t.setAttribute(e.name,e.value);for(let s=i.length-1;0<=s;s--){const n=i[s];ignoreAttribute(n.name,t,"remove",r)||(e.hasAttribute(n.name)||t.removeAttribute(n.name))}}s!==8&&s!==3||t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue);ignoreValueOfActiveElement(t,r)||syncInputValue(e,t,r)} +/** + * @param from {Element} element to sync the value from + * @param to {Element} element to sync the value to + * @param attributeName {String} the attribute name + * @param ctx the merge context + */function syncBooleanAttribute(e,t,r,s){if(e[r]!==t[r]){let i=ignoreAttribute(r,t,"update",s);i||(t[r]=e[r]);e[r]?i||t.setAttribute(r,e[r]):ignoreAttribute(r,t,"remove",s)||t.removeAttribute(r)}} +/** + * NB: many bothans died to bring us information: + * + * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js + * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113 + * + * @param from {Element} the element to sync the input value from + * @param to {Element} the element to sync the input value to + * @param ctx the merge context + */function syncInputValue(e,t,r){if(e instanceof HTMLInputElement&&t instanceof HTMLInputElement&&e.type!=="file"){let s=e.value;let i=t.value;syncBooleanAttribute(e,t,"checked",r);syncBooleanAttribute(e,t,"disabled",r);if(e.hasAttribute("value")){if(s!==i&&!ignoreAttribute("value",t,"update",r)){t.setAttribute("value",s);t.value=s}}else if(!ignoreAttribute("value",t,"remove",r)){t.value="";t.removeAttribute("value")}}else if(e instanceof HTMLOptionElement)syncBooleanAttribute(e,t,"selected",r);else if(e instanceof HTMLTextAreaElement&&t instanceof HTMLTextAreaElement){let s=e.value;let i=t.value;if(ignoreAttribute("value",t,"update",r))return;s!==i&&(t.value=s);t.firstChild&&t.firstChild.nodeValue!==s&&(t.firstChild.nodeValue=s)}}function handleHeadElement(e,t,r){let s=[];let i=[];let n=[];let o=[];let a=r.head.style;let l=new Map;for(const t of e.children)l.set(t.outerHTML,t);for(const e of t.children){let t=l.has(e.outerHTML);let s=r.head.shouldReAppend(e);let c=r.head.shouldPreserve(e);if(t||c)if(s)i.push(e);else{l.delete(e.outerHTML);n.push(e)}else if(a==="append"){if(s){i.push(e);o.push(e)}}else r.head.shouldRemove(e)!==false&&i.push(e)}o.push(...l.values());let c=[];for(const e of o){let i=document.createRange().createContextualFragment(e.outerHTML).firstChild;if(r.callbacks.beforeNodeAdded(i)!==false){if(i.href||i.src){let e=null;let t=new Promise((function(t){e=t}));i.addEventListener("load",(function(){e()}));c.push(t)}t.appendChild(i);r.callbacks.afterNodeAdded(i);s.push(i)}}for(const e of i)if(r.callbacks.beforeNodeRemoved(e)!==false){t.removeChild(e);r.callbacks.afterNodeRemoved(e)}r.head.afterHeadMorphed(t,{added:s,kept:n,removed:i});return c}function noOp(){}function mergeDefaults(e){let r={};Object.assign(r,t);Object.assign(r,e);r.callbacks={};Object.assign(r.callbacks,t.callbacks);Object.assign(r.callbacks,e.callbacks);r.head={};Object.assign(r.head,t.head);Object.assign(r.head,e.head);return r}function createMorphContext(e,t,r){r=mergeDefaults(r);return{target:e,newContent:t,config:r,morphStyle:r.morphStyle,ignoreActive:r.ignoreActive,ignoreActiveValue:r.ignoreActiveValue,idMap:createIdMap(e,t),deadIds:new Set,callbacks:r.callbacks,head:r.head}}function isIdSetMatch(e,t,r){return e!=null&&t!=null&&(e.nodeType===t.nodeType&&e.tagName===t.tagName&&(e.id!==""&&e.id===t.id||getIdIntersectionCount(r,e,t)>0))}function isSoftMatch(e,t){return e!=null&&t!=null&&(e.nodeType===t.nodeType&&e.tagName===t.tagName)}function removeNodesBetween(e,t,r){while(e!==t){let t=e;e=e.nextSibling;removeNode(t,r)}removeIdsFromConsideration(r,t);return t.nextSibling}function findIdSetMatch(e,t,r,s,i){let n=getIdIntersectionCount(i,r,t);let o=null;if(n>0){let t=s;let o=0;while(t!=null){if(isIdSetMatch(r,t,i))return t;o+=getIdIntersectionCount(i,t,e);if(o>n)return null;t=t.nextSibling}}return o}function findSoftMatch(e,t,r,s,i){let n=s;let o=r.nextSibling;let a=0;while(n!=null){if(getIdIntersectionCount(i,n,e)>0)return null;if(isSoftMatch(r,n))return n;if(isSoftMatch(o,n)){a++;o=o.nextSibling;if(a>=2)return null}n=n.nextSibling}return n}function parseContent(e){let t=new DOMParser;let r=e.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,"");if(r.match(/<\/html>/)||r.match(/<\/head>/)||r.match(/<\/body>/)){let s=t.parseFromString(e,"text/html");if(r.match(/<\/html>/)){s.generatedByIdiomorph=true;return s}{let e=s.firstChild;if(e){e.generatedByIdiomorph=true;return e}return null}}{let r=t.parseFromString("","text/html");let s=r.body.querySelector("template").content;s.generatedByIdiomorph=true;return s}}function normalizeContent(e){if(e==null){const e=document.createElement("div");return e}if(e.generatedByIdiomorph)return e;if(e instanceof Node){const t=document.createElement("div");t.append(e);return t}{const t=document.createElement("div");for(const r of[...e])t.append(r);return t}}function insertSiblings(e,t,r){let s=[];let i=[];while(e!=null){s.push(e);e=e.previousSibling}while(s.length>0){let e=s.pop();i.push(e);t.parentElement.insertBefore(e,t)}i.push(t);while(r!=null){s.push(r);i.push(r);r=r.nextSibling}while(s.length>0)t.parentElement.insertBefore(s.pop(),t.nextSibling);return i}function findBestNodeMatch(e,t,r){let s;s=e.firstChild;let i=s;let n=0;while(s){let e=scoreElement(s,t,r);if(e>n){i=s;n=e}s=s.nextSibling}return i}function scoreElement(e,t,r){return isSoftMatch(e,t)?.5+getIdIntersectionCount(r,e,t):0}function removeNode(e,t){removeIdsFromConsideration(t,e);if(t.callbacks.beforeNodeRemoved(e)!==false){e.remove();t.callbacks.afterNodeRemoved(e)}}function isIdInConsideration(e,t){return!e.deadIds.has(t)}function idIsWithinNode(t,r,s){let i=t.idMap.get(s)||e;return i.has(r)}function removeIdsFromConsideration(t,r){let s=t.idMap.get(r)||e;for(const e of s)t.deadIds.add(e)}function getIdIntersectionCount(t,r,s){let i=t.idMap.get(r)||e;let n=0;for(const e of i)isIdInConsideration(t,e)&&idIsWithinNode(t,e,s)&&++n;return n} +/** + * A bottom up algorithm that finds all elements with ids inside of the node + * argument and populates id sets for those nodes and all their parents, generating + * a set of ids contained within all nodes for the entire hierarchy in the DOM + * + * @param node {Element} + * @param {Map>} idMap + */function populateIdMapForNode(e,t){let r=e.parentElement;let s=e.querySelectorAll("[id]");for(const e of s){let s=e;while(s!==r&&s!=null){let r=t.get(s);if(r==null){r=new Set;t.set(s,r)}r.add(e.id);s=s.parentElement}}} +/** + * This function computes a map of nodes to all ids contained within that node (inclusive of the + * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows + * for a looser definition of "matching" than tradition id matching, and allows child nodes + * to contribute to a parent nodes matching. + * + * @param {Element} oldContent the old content that will be morphed + * @param {Element} newContent the new content to morph to + * @returns {Map>} a map of nodes to id sets for the + */function createIdMap(e,t){let r=new Map;populateIdMapForNode(e,r);populateIdMapForNode(t,r);return r}return{morph:morph,defaults:t}}();class PageRenderer extends Renderer{static renderElement(e,t){document.body&&t instanceof HTMLBodyElement?document.body.replaceWith(t):document.documentElement.appendChild(t)}get shouldRender(){return this.newSnapshot.isVisitable&&this.trackedElementsAreIdentical}get reloadReason(){return this.newSnapshot.isVisitable?this.trackedElementsAreIdentical?void 0:{reason:"tracked_element_mismatch"}:{reason:"turbo_visit_control_is_reload"}}async prepareToRender(){this.#A();await this.mergeHead()}async render(){this.willRender&&await this.replaceBody()}finishRendering(){super.finishRendering();this.isPreview||this.focusFirstAutofocusableElement()}get currentHeadSnapshot(){return this.currentSnapshot.headSnapshot}get newHeadSnapshot(){return this.newSnapshot.headSnapshot}get newElement(){return this.newSnapshot.element}#A(){const{documentElement:e}=this.currentSnapshot;const{lang:t}=this.newSnapshot;t?e.setAttribute("lang",t):e.removeAttribute("lang")}async mergeHead(){const e=this.mergeProvisionalElements();const t=this.copyNewHeadStylesheetElements();this.copyNewHeadScriptElements();await e;await t;this.willRender&&this.removeUnusedDynamicStylesheetElements()}async replaceBody(){await this.preservingPermanentElements((async()=>{this.activateNewBody();await this.assignNewBody()}))}get trackedElementsAreIdentical(){return this.currentHeadSnapshot.trackedElementSignature==this.newHeadSnapshot.trackedElementSignature}async copyNewHeadStylesheetElements(){const e=[];for(const t of this.newHeadStylesheetElements){e.push(waitForLoad(t));document.head.appendChild(t)}await Promise.all(e)}copyNewHeadScriptElements(){for(const e of this.newHeadScriptElements)document.head.appendChild(activateScriptElement(e))}removeUnusedDynamicStylesheetElements(){for(const e of this.unusedDynamicStylesheetElements)document.head.removeChild(e)}async mergeProvisionalElements(){const e=[...this.newHeadProvisionalElements];for(const t of this.currentHeadProvisionalElements)this.isCurrentElementInElementList(t,e)||document.head.removeChild(t);for(const t of e)document.head.appendChild(t)}isCurrentElementInElementList(e,t){for(const[r,s]of t.entries()){if(e.tagName=="TITLE"){if(s.tagName!="TITLE")continue;if(e.innerHTML==s.innerHTML){t.splice(r,1);return true}}if(s.isEqualNode(e)){t.splice(r,1);return true}}return false}removeCurrentHeadProvisionalElements(){for(const e of this.currentHeadProvisionalElements)document.head.removeChild(e)}copyNewHeadProvisionalElements(){for(const e of this.newHeadProvisionalElements)document.head.appendChild(e)}activateNewBody(){document.adoptNode(this.newElement);this.activateNewBodyScriptElements()}activateNewBodyScriptElements(){for(const e of this.newBodyScriptElements){const t=activateScriptElement(e);e.replaceWith(t)}}async assignNewBody(){await this.renderElement(this.currentElement,this.newElement)}get unusedDynamicStylesheetElements(){return this.oldHeadStylesheetElements.filter((e=>e.getAttribute("data-turbo-track")==="dynamic"))}get oldHeadStylesheetElements(){return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot)}get newHeadStylesheetElements(){return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot)}get newHeadScriptElements(){return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot)}get currentHeadProvisionalElements(){return this.currentHeadSnapshot.provisionalElements}get newHeadProvisionalElements(){return this.newHeadSnapshot.provisionalElements}get newBodyScriptElements(){return this.newElement.querySelectorAll("script")}}class MorphRenderer extends PageRenderer{async render(){this.willRender&&await this.#L()}get renderMethod(){return"morph"}async#L(){this.#C(this.currentElement,this.newElement);this.#T();dispatch("turbo:morph",{detail:{currentElement:this.currentElement,newElement:this.newElement}})}#C(e,t,r="outerHTML"){this.isMorphingTurboFrame=this.#P(e);g.morph(e,t,{ignoreActiveValue:true,morphStyle:r,callbacks:{beforeNodeAdded:this.#F,beforeNodeMorphed:this.#M,beforeAttributeUpdated:this.#I,beforeNodeRemoved:this.#k,afterNodeMorphed:this.#q}})}#F=e=>!(e.id&&e.hasAttribute("data-turbo-permanent")&&document.getElementById(e.id));#M=(e,t)=>{if(e instanceof HTMLElement){if(e.hasAttribute("data-turbo-permanent")||!this.isMorphingTurboFrame&&this.#P(e))return false;{const r=dispatch("turbo:before-morph-element",{cancelable:true,target:e,detail:{newElement:t}});return!r.defaultPrevented}}};#I=(e,t,r)=>{const s=dispatch("turbo:before-morph-attribute",{cancelable:true,target:t,detail:{attributeName:e,mutationType:r}});return!s.defaultPrevented};#q=(e,t)=>{t instanceof HTMLElement&&dispatch("turbo:morph-element",{target:e,detail:{newElement:t}})};#k=e=>this.#M(e);#T(){this.#H().forEach((e=>{if(this.#P(e)){this.#B(e);e.reload()}}))}#B(e){e.addEventListener("turbo:before-frame-render",(e=>{e.detail.render=this.#O}),{once:true})}#O=(e,t)=>{dispatch("turbo:before-frame-morph",{target:e,detail:{currentElement:e,newElement:t}});this.#C(e,t.children,"innerHTML")};#P(e){return e.src&&e.refresh==="morph"}#H(){return Array.from(document.querySelectorAll("turbo-frame[src]")).filter((e=>!e.closest("[data-turbo-permanent]")))}}class SnapshotCache{keys=[];snapshots={};constructor(e){this.size=e}has(e){return toCacheKey(e)in this.snapshots}get(e){if(this.has(e)){const t=this.read(e);this.touch(e);return t}}put(e,t){this.write(e,t);this.touch(e);return t}clear(){this.snapshots={}}read(e){return this.snapshots[toCacheKey(e)]}write(e,t){this.snapshots[toCacheKey(e)]=t}touch(e){const t=toCacheKey(e);const r=this.keys.indexOf(t);r>-1&&this.keys.splice(r,1);this.keys.unshift(t);this.trim()}trim(){for(const e of this.keys.splice(this.size))delete this.snapshots[e]}}class PageView extends View{snapshotCache=new SnapshotCache(10);lastRenderedLocation=new URL(location.href);forceReloaded=false;shouldTransitionTo(e){return this.snapshot.prefersViewTransitions&&e.prefersViewTransitions}renderPage(e,t=false,r=true,s){const i=this.isPageRefresh(s)&&this.snapshot.shouldMorphPage;const n=i?MorphRenderer:PageRenderer;const o=new n(this.snapshot,e,PageRenderer.renderElement,t,r);o.shouldRender?s?.changeHistory():this.forceReloaded=true;return this.render(o)}renderError(e,t){t?.changeHistory();const r=new ErrorRenderer(this.snapshot,e,ErrorRenderer.renderElement,false);return this.render(r)}clearSnapshotCache(){this.snapshotCache.clear()}async cacheSnapshot(e=this.snapshot){if(e.isCacheable){this.delegate.viewWillCacheSnapshot();const{lastRenderedLocation:t}=this;await nextEventLoopTick();const r=e.clone();this.snapshotCache.put(t,r);return r}}getCachedSnapshotForLocation(e){return this.snapshotCache.get(e)}isPageRefresh(e){return!e||this.lastRenderedLocation.pathname===e.location.pathname&&e.action==="replace"}shouldPreserveScrollPosition(e){return this.isPageRefresh(e)&&this.snapshot.shouldPreserveScrollPosition}get snapshot(){return PageSnapshot.fromElement(this.element)}}class Preloader{selector="a[data-turbo-preload]";constructor(e,t){this.delegate=e;this.snapshotCache=t}start(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",this.#N):this.preloadOnLoadLinksForView(document.body)}stop(){document.removeEventListener("DOMContentLoaded",this.#N)}preloadOnLoadLinksForView(e){for(const t of e.querySelectorAll(this.selector))this.delegate.shouldPreloadLink(t)&&this.preloadURL(t)}async preloadURL(e){const t=new URL(e.href);if(this.snapshotCache.has(t))return;const r=new FetchRequest(this,i.get,t,new URLSearchParams,e);await r.perform()}prepareRequest(e){e.headers["X-Sec-Purpose"]="prefetch"}async requestSucceededWithResponse(e,t){try{const r=await t.responseHTML;const s=PageSnapshot.fromHTMLString(r);this.snapshotCache.put(e.url,s)}catch(e){}}requestStarted(e){}requestErrored(e){}requestFinished(e){}requestPreventedHandlingResponse(e,t){}requestFailedWithResponse(e,t){}#N=()=>{this.preloadOnLoadLinksForView(document.body)}}class Cache{constructor(e){this.session=e}clear(){this.session.clearCache()}resetCacheControl(){this.#x("")}exemptPageFromCache(){this.#x("no-cache")}exemptPageFromPreview(){this.#x("no-preview")}#x(e){setMetaContent("turbo-cache-control",e)}}class Session{navigator=new Navigator(this);history=new History(this);view=new PageView(this,document.documentElement);adapter=new BrowserAdapter(this);pageObserver=new PageObserver(this);cacheObserver=new CacheObserver;linkPrefetchObserver=new LinkPrefetchObserver(this,document);linkClickObserver=new LinkClickObserver(this,window);formSubmitObserver=new FormSubmitObserver(this,document);scrollObserver=new ScrollObserver(this);streamObserver=new StreamObserver(this);formLinkClickObserver=new FormLinkClickObserver(this,document.documentElement);frameRedirector=new FrameRedirector(this,document.documentElement);streamMessageRenderer=new StreamMessageRenderer;cache=new Cache(this);drive=true;enabled=true;progressBarDelay=500;started=false;formMode="on";#V=150;constructor(e){this.recentRequests=e;this.preloader=new Preloader(this,this.view.snapshotCache);this.debouncedRefresh=this.refresh;this.pageRefreshDebouncePeriod=this.pageRefreshDebouncePeriod}start(){if(!this.started){this.pageObserver.start();this.cacheObserver.start();this.linkPrefetchObserver.start();this.formLinkClickObserver.start();this.linkClickObserver.start();this.formSubmitObserver.start();this.scrollObserver.start();this.streamObserver.start();this.frameRedirector.start();this.history.start();this.preloader.start();this.started=true;this.enabled=true}}disable(){this.enabled=false}stop(){if(this.started){this.pageObserver.stop();this.cacheObserver.stop();this.linkPrefetchObserver.stop();this.formLinkClickObserver.stop();this.linkClickObserver.stop();this.formSubmitObserver.stop();this.scrollObserver.stop();this.streamObserver.stop();this.frameRedirector.stop();this.history.stop();this.preloader.stop();this.started=false}}registerAdapter(e){this.adapter=e}visit(e,t={}){const r=t.frame?document.getElementById(t.frame):null;if(r instanceof FrameElement){const s=t.action||getVisitAction(r);r.delegate.proposeVisitIfNavigatedWithAction(r,s);r.src=e.toString()}else this.navigator.proposeVisit(expandURL(e),t)}refresh(e,t){const r=t&&this.recentRequests.has(t);if(!r){this.cache.exemptPageFromPreview();this.visit(e,{action:"replace"})}}connectStreamSource(e){this.streamObserver.connectStreamSource(e)}disconnectStreamSource(e){this.streamObserver.disconnectStreamSource(e)}renderStreamMessage(e){this.streamMessageRenderer.render(StreamMessage.wrap(e))}clearCache(){this.view.clearSnapshotCache()}setProgressBarDelay(e){this.progressBarDelay=e}setFormMode(e){this.formMode=e}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}get pageRefreshDebouncePeriod(){return this.#V}set pageRefreshDebouncePeriod(e){this.refresh=debounce(this.debouncedRefresh.bind(this),e);this.#V=e}shouldPreloadLink(e){const t=e.hasAttribute("data-turbo-method");const r=e.hasAttribute("data-turbo-stream");const s=e.getAttribute("data-turbo-frame");const i=s=="_top"?null:document.getElementById(s)||findClosestRecursively(e,"turbo-frame:not([disabled])");if(t||r||i instanceof FrameElement)return false;{const t=new URL(e.href);return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)}}historyPoppedToLocationWithRestorationIdentifierAndDirection(e,t,r){this.enabled?this.navigator.startVisit(e,t,{action:"restore",historyChanged:true,direction:r}):this.adapter.pageInvalidated({reason:"turbo_disabled"})}scrollPositionChanged(e){this.history.updateRestorationData({scrollPosition:e})}willSubmitFormLinkToLocation(e,t){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)}submittedFormLinkToLocation(){}canPrefetchRequestToLocation(e,t){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)}willFollowLinkToLocation(e,t,r){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)&&this.applicationAllowsFollowingLinkToLocation(e,t,r)}followedLinkToLocation(e,t){const r=this.getActionForLink(e);const s=e.hasAttribute("data-turbo-stream");this.visit(t.href,{action:r,acceptsStreamResponse:s})}allowsVisitingLocationWithAction(e,t){return this.locationWithActionIsSamePage(e,t)||this.applicationAllowsVisitingLocation(e)}visitProposedToLocation(e,t){extendURLWithDeprecatedProperties(e);this.adapter.visitProposedToLocation(e,t)}visitStarted(e){if(!e.acceptsStreamResponse){markAsBusy(document.documentElement);this.view.markVisitDirection(e.direction)}extendURLWithDeprecatedProperties(e.location);e.silent||this.notifyApplicationAfterVisitingLocation(e.location,e.action)}visitCompleted(e){this.view.unmarkVisitDirection();clearBusyState(document.documentElement);this.notifyApplicationAfterPageLoad(e.getTimingMetrics())}locationWithActionIsSamePage(e,t){return this.navigator.locationWithActionIsSamePage(e,t)}visitScrolledToSamePageLocation(e,t){this.notifyApplicationAfterVisitingSamePageLocation(e,t)}willSubmitForm(e,t){const r=getAction$1(e,t);return this.submissionIsNavigatable(e,t)&&locationIsVisitable(expandURL(r),this.snapshot.rootLocation)}formSubmitted(e,t){this.navigator.submitForm(e,t)}pageBecameInteractive(){this.view.lastRenderedLocation=this.location;this.notifyApplicationAfterPageLoad()}pageLoaded(){this.history.assumeControlOfScrollRestoration()}pageWillUnload(){this.history.relinquishControlOfScrollRestoration()}receivedMessageFromStream(e){this.renderStreamMessage(e)}viewWillCacheSnapshot(){this.navigator.currentVisit?.silent||this.notifyApplicationBeforeCachingSnapshot()}allowsImmediateRender({element:e},t){const r=this.notifyApplicationBeforeRender(e,t);const{defaultPrevented:s,detail:{render:i}}=r;this.view.renderer&&i&&(this.view.renderer.renderElement=i);return!s}viewRenderedSnapshot(e,t,r){this.view.lastRenderedLocation=this.history.location;this.notifyApplicationAfterRender(r)}preloadOnLoadLinksForView(e){this.preloader.preloadOnLoadLinksForView(e)}viewInvalidated(e){this.adapter.pageInvalidated(e)}frameLoaded(e){this.notifyApplicationAfterFrameLoad(e)}frameRendered(e,t){this.notifyApplicationAfterFrameRender(e,t)}applicationAllowsFollowingLinkToLocation(e,t,r){const s=this.notifyApplicationAfterClickingLinkToLocation(e,t,r);return!s.defaultPrevented}applicationAllowsVisitingLocation(e){const t=this.notifyApplicationBeforeVisitingLocation(e);return!t.defaultPrevented}notifyApplicationAfterClickingLinkToLocation(e,t,r){return dispatch("turbo:click",{target:e,detail:{url:t.href,originalEvent:r},cancelable:true})}notifyApplicationBeforeVisitingLocation(e){return dispatch("turbo:before-visit",{detail:{url:e.href},cancelable:true})}notifyApplicationAfterVisitingLocation(e,t){return dispatch("turbo:visit",{detail:{url:e.href,action:t}})}notifyApplicationBeforeCachingSnapshot(){return dispatch("turbo:before-cache")}notifyApplicationBeforeRender(e,t){return dispatch("turbo:before-render",{detail:{newBody:e,...t},cancelable:true})}notifyApplicationAfterRender(e){return dispatch("turbo:render",{detail:{renderMethod:e}})}notifyApplicationAfterPageLoad(e={}){return dispatch("turbo:load",{detail:{url:this.location.href,timing:e}})}notifyApplicationAfterVisitingSamePageLocation(e,t){dispatchEvent(new HashChangeEvent("hashchange",{oldURL:e.toString(),newURL:t.toString()}))}notifyApplicationAfterFrameLoad(e){return dispatch("turbo:frame-load",{target:e})}notifyApplicationAfterFrameRender(e,t){return dispatch("turbo:frame-render",{detail:{fetchResponse:e},target:t,cancelable:true})}submissionIsNavigatable(e,t){if(this.formMode=="off")return false;{const r=!t||this.elementIsNavigatable(t);return this.formMode=="optin"?r&&e.closest('[data-turbo="true"]')!=null:r&&this.elementIsNavigatable(e)}}elementIsNavigatable(e){const t=findClosestRecursively(e,"[data-turbo]");const r=findClosestRecursively(e,"turbo-frame");return this.drive||r?!t||t.getAttribute("data-turbo")!="false":!!t&&t.getAttribute("data-turbo")=="true"}getActionForLink(e){return getVisitAction(e)||"advance"}get snapshot(){return this.view.snapshot}}function extendURLWithDeprecatedProperties(e){Object.defineProperties(e,b)}const b={absoluteURL:{get(){return this.toString()}}};const v=new Session(r);const{cache:S,navigator:E}=v;function start(){v.start()} +/** + * Registers an adapter for the main session. + * + * @param adapter Adapter to register + */function registerAdapter(e){v.registerAdapter(e)} +/** + * Performs an application visit to the given location. + * + * @param location Location to visit (a URL or path) + * @param options Options to apply + * @param options.action Type of history navigation to apply ("restore", + * "replace" or "advance") + * @param options.historyChanged Specifies whether the browser history has + * already been changed for this visit or not + * @param options.referrer Specifies the referrer of this visit such that + * navigations to the same page will not result in a new history entry. + * @param options.snapshotHTML Cached snapshot to render + * @param options.response Response of the specified location + */function visit(e,t){v.visit(e,t)} +/** + * Connects a stream source to the main session. + * + * @param source Stream source to connect + */function connectStreamSource(e){v.connectStreamSource(e)} +/** + * Disconnects a stream source from the main session. + * + * @param source Stream source to disconnect + */function disconnectStreamSource(e){v.disconnectStreamSource(e)} +/** + * Renders a stream message to the main session by appending it to the + * current document. + * + * @param message Message to render + */function renderStreamMessage(e){v.renderStreamMessage(e)} +/** + * Removes all entries from the Turbo Drive page cache. + * Call this when state has changed on the server that may affect cached pages. + * + * @deprecated since version 7.2.0 in favor of `Turbo.cache.clear()` + */function clearCache(){console.warn("Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`");v.clearCache()} +/** + * Sets the delay after which the progress bar will appear during navigation. + * + * The progress bar appears after 500ms by default. + * + * Note that this method has no effect when used with the iOS or Android + * adapters. + * + * @param delay Time to delay in milliseconds + */function setProgressBarDelay(e){v.setProgressBarDelay(e)}function setConfirmMethod(e){FormSubmission.confirmMethod=e}function setFormMode(e){v.setFormMode(e)}var w=Object.freeze({__proto__:null,navigator:E,session:v,cache:S,PageRenderer:PageRenderer,PageSnapshot:PageSnapshot,FrameRenderer:FrameRenderer,fetch:fetchWithTurboHeaders,start:start,registerAdapter:registerAdapter,visit:visit,connectStreamSource:connectStreamSource,disconnectStreamSource:disconnectStreamSource,renderStreamMessage:renderStreamMessage,clearCache:clearCache,setProgressBarDelay:setProgressBarDelay,setConfirmMethod:setConfirmMethod,setFormMode:setFormMode});class TurboFrameMissingError extends Error{}class FrameController{fetchResponseLoaded=e=>Promise.resolve();#D=null;#W=()=>{};#U=false;#$=false;#z=new Set;action=null;constructor(e){this.element=e;this.view=new FrameView(this,this.element);this.appearanceObserver=new AppearanceObserver(this,this.element);this.formLinkClickObserver=new FormLinkClickObserver(this,this.element);this.linkInterceptor=new LinkInterceptor(this,this.element);this.restorationIdentifier=uuid();this.formSubmitObserver=new FormSubmitObserver(this,this.element)}connect(){if(!this.#U){this.#U=true;this.loadingStyle==t.lazy?this.appearanceObserver.start():this.#j();this.formLinkClickObserver.start();this.linkInterceptor.start();this.formSubmitObserver.start()}}disconnect(){if(this.#U){this.#U=false;this.appearanceObserver.stop();this.formLinkClickObserver.stop();this.linkInterceptor.stop();this.formSubmitObserver.stop()}}disabledChanged(){this.loadingStyle==t.eager&&this.#j()}sourceURLChanged(){if(!this.#_("src")){this.element.isConnected&&(this.complete=false);(this.loadingStyle==t.eager||this.#$)&&this.#j()}}sourceURLReloaded(){const{src:e}=this.element;this.#K("complete",(()=>{this.element.removeAttribute("complete")}));this.element.src=null;this.element.src=e;return this.element.loaded}completeChanged(){this.#_("complete")||this.#j()}loadingStyleChanged(){if(this.loadingStyle==t.lazy)this.appearanceObserver.start();else{this.appearanceObserver.stop();this.#j()}}async#j(){if(this.enabled&&this.isActive&&!this.complete&&this.sourceURL){this.element.loaded=this.#X(expandURL(this.sourceURL));this.appearanceObserver.stop();await this.element.loaded;this.#$=true}}async loadResponse(e){(e.redirected||e.succeeded&&e.isHTML)&&(this.sourceURL=e.response.url);try{const t=await e.responseHTML;if(t){const r=parseHTMLDocument(t);const s=PageSnapshot.fromDocument(r);s.isVisitable?await this.#Q(e,r):await this.#Y(e)}}finally{this.fetchResponseLoaded=()=>Promise.resolve()}}elementAppearedInViewport(e){this.proposeVisitIfNavigatedWithAction(e,getVisitAction(e));this.#j()}willSubmitFormLinkToLocation(e){return this.#J(e)}submittedFormLinkToLocation(e,t,r){const s=this.#d(e);s&&r.setAttribute("data-turbo-frame",s.id)}shouldInterceptLinkClick(e,t,r){return this.#J(e)}linkClickIntercepted(e,t){this.#G(e,t)}willSubmitForm(e,t){return e.closest("turbo-frame")==this.element&&this.#J(e,t)}formSubmitted(e,t){this.formSubmission&&this.formSubmission.stop();this.formSubmission=new FormSubmission(this,e,t);const{fetchRequest:r}=this.formSubmission;this.prepareRequest(r);this.formSubmission.start()}prepareRequest(e){e.headers["Turbo-Frame"]=this.id;this.currentNavigationElement?.hasAttribute("data-turbo-stream")&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(e){markAsBusy(this.element)}requestPreventedHandlingResponse(e,t){this.#W()}async requestSucceededWithResponse(e,t){await this.loadResponse(t);this.#W()}async requestFailedWithResponse(e,t){await this.loadResponse(t);this.#W()}requestErrored(e,t){console.error(t);this.#W()}requestFinished(e){clearBusyState(this.element)}formSubmissionStarted({formElement:e}){markAsBusy(e,this.#d(e))}formSubmissionSucceededWithResponse(e,t){const r=this.#d(e.formElement,e.submitter);r.delegate.proposeVisitIfNavigatedWithAction(r,getVisitAction(e.submitter,e.formElement,r));r.delegate.loadResponse(t);e.isSafe||v.clearCache()}formSubmissionFailedWithResponse(e,t){this.element.delegate.loadResponse(t);v.clearCache()}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished({formElement:e}){clearBusyState(e,this.#d(e))}allowsImmediateRender({element:e},t){const r=dispatch("turbo:before-frame-render",{target:this.element,detail:{newFrame:e,...t},cancelable:true});const{defaultPrevented:s,detail:{render:i}}=r;this.view.renderer&&i&&(this.view.renderer.renderElement=i);return!s}viewRenderedSnapshot(e,t,r){}preloadOnLoadLinksForView(e){v.preloadOnLoadLinksForView(e)}viewInvalidated(){}willRenderFrame(e,t){this.previousFrameElement=e.cloneNode(true)}visitCachedSnapshot=({element:e})=>{const t=e.querySelector("#"+this.element.id);t&&this.previousFrameElement&&t.replaceChildren(...this.previousFrameElement.children);delete this.previousFrameElement};async#Q(e,t){const r=await this.extractForeignFrameElement(t.body);if(r){const t=new Snapshot(r);const s=new FrameRenderer(this,this.view.snapshot,t,FrameRenderer.renderElement,false,false);this.view.renderPromise&&await this.view.renderPromise;this.changeHistory();await this.view.render(s);this.complete=true;v.frameRendered(e,this.element);v.frameLoaded(this.element);await this.fetchResponseLoaded(e)}else this.#Z(e)&&this.#ee(e)}async#X(e){const t=new FetchRequest(this,i.get,e,new URLSearchParams,this.element);this.#D?.cancel();this.#D=t;return new Promise((e=>{this.#W=()=>{this.#W=()=>{};this.#D=null;e()};t.perform()}))}#G(e,t,r){const s=this.#d(e,r);s.delegate.proposeVisitIfNavigatedWithAction(s,getVisitAction(r,e,s));this.#te(e,(()=>{s.src=t}))}proposeVisitIfNavigatedWithAction(e,t=null){this.action=t;if(this.action){const t=PageSnapshot.fromElement(e).clone();const{visitCachedSnapshot:r}=e.delegate;e.delegate.fetchResponseLoaded=async s=>{if(e.src){const{statusCode:i,redirected:n}=s;const o=await s.responseHTML;const a={statusCode:i,redirected:n,responseHTML:o};const l={response:a,visitCachedSnapshot:r,willRender:false,updateHistory:false,restorationIdentifier:this.restorationIdentifier,snapshot:t};this.action&&(l.action=this.action);v.visit(e.src,l)}}}}changeHistory(){if(this.action){const e=getHistoryMethodForAction(this.action);v.history.update(e,expandURL(this.element.src||""),this.restorationIdentifier)}}async#Y(e){console.warn(`The response (${e.statusCode}) from is performing a full page visit due to turbo-visit-control.`);await this.#re(e.response)}#Z(e){this.element.setAttribute("complete","");const t=e.response;const visit=async(e,t)=>{e instanceof Response?this.#re(e):v.visit(e,t)};const r=dispatch("turbo:frame-missing",{target:this.element,detail:{response:t,visit:visit},cancelable:true});return!r.defaultPrevented}#ee(e){this.view.missing();this.#se(e)}#se(e){const t=`The response (${e.statusCode}) did not contain the expected and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`;throw new TurboFrameMissingError(t)}async#re(e){const t=new FetchResponse(e);const r=await t.responseHTML;const{location:s,redirected:i,statusCode:n}=t;return v.visit(s,{response:{redirected:i,statusCode:n,responseHTML:r}})}#d(e,t){const r=getAttribute("data-turbo-frame",t,e)||this.element.getAttribute("target");return getFrameElementById(r)??this.element}async extractForeignFrameElement(e){let t;const r=CSS.escape(this.id);try{t=activateElement(e.querySelector(`turbo-frame#${r}`),this.sourceURL);if(t)return t;t=activateElement(e.querySelector(`turbo-frame[src][recurse~=${r}]`),this.sourceURL);if(t){await t.loaded;return await this.extractForeignFrameElement(t)}}catch(e){console.error(e);return new FrameElement}return null}#ie(e,t){const r=getAction$1(e,t);return locationIsVisitable(expandURL(r),this.rootLocation)}#J(e,t){const r=getAttribute("data-turbo-frame",t,e)||this.element.getAttribute("target");if(e instanceof HTMLFormElement&&!this.#ie(e,t))return false;if(!this.enabled||r=="_top")return false;if(r){const e=getFrameElementById(r);if(e)return!e.disabled}return!!v.elementIsNavigatable(e)&&!(t&&!v.elementIsNavigatable(t))}get id(){return this.element.id}get enabled(){return!this.element.disabled}get sourceURL(){if(this.element.src)return this.element.src}set sourceURL(e){this.#K("src",(()=>{this.element.src=e??null}))}get loadingStyle(){return this.element.loading}get isLoading(){return this.formSubmission!==void 0||this.#W()!==void 0}get complete(){return this.element.hasAttribute("complete")}set complete(e){this.#K("complete",(()=>{e?this.element.setAttribute("complete",""):this.element.removeAttribute("complete")}))}get isActive(){return this.element.isActive&&this.#U}get rootLocation(){const e=this.element.ownerDocument.querySelector('meta[name="turbo-root"]');const t=e?.content??"/";return expandURL(t)}#_(e){return this.#z.has(e)}#K(e,t){this.#z.add(e);t();this.#z.delete(e)}#te(e,t){this.currentNavigationElement=e;t();delete this.currentNavigationElement}}function getFrameElementById(e){if(e!=null){const t=document.getElementById(e);if(t instanceof FrameElement)return t}}function activateElement(e,t){if(e){const r=e.getAttribute("src");if(r!=null&&t!=null&&urlsAreEqual(r,t))throw new Error(`Matching element has a source URL which references itself`);e.ownerDocument!==document&&(e=document.importNode(e,true));if(e instanceof FrameElement){e.connectedCallback();e.disconnectedCallback();return e}}}const y={after(){this.targetElements.forEach((e=>e.parentElement?.insertBefore(this.templateContent,e.nextSibling)))},append(){this.removeDuplicateTargetChildren();this.targetElements.forEach((e=>e.append(this.templateContent)))},before(){this.targetElements.forEach((e=>e.parentElement?.insertBefore(this.templateContent,e)))},prepend(){this.removeDuplicateTargetChildren();this.targetElements.forEach((e=>e.prepend(this.templateContent)))},remove(){this.targetElements.forEach((e=>e.remove()))},replace(){this.targetElements.forEach((e=>e.replaceWith(this.templateContent)))},update(){this.targetElements.forEach((e=>{e.innerHTML="";e.append(this.templateContent)}))},refresh(){v.refresh(this.baseURI,this.requestId)}};class StreamElement extends HTMLElement{static async renderElement(e){await e.performAction()}async connectedCallback(){try{await this.render()}catch(e){console.error(e)}finally{this.disconnect()}}async render(){return this.renderPromise??=(async()=>{const e=this.beforeRenderEvent;if(this.dispatchEvent(e)){await nextRepaint();await e.detail.render(this)}})()}disconnect(){try{this.remove()}catch{}}removeDuplicateTargetChildren(){this.duplicateChildren.forEach((e=>e.remove()))}get duplicateChildren(){const e=this.targetElements.flatMap((e=>[...e.children])).filter((e=>!!e.id));const t=[...this.templateContent?.children||[]].filter((e=>!!e.id)).map((e=>e.id));return e.filter((e=>t.includes(e.id)))}get performAction(){if(this.action){const e=y[this.action];if(e)return e;this.#ne("unknown action")}this.#ne("action attribute is missing")}get targetElements(){if(this.target)return this.targetElementsById;if(this.targets)return this.targetElementsByQuery;this.#ne("target or targets attribute is missing")}get templateContent(){return this.templateElement.content.cloneNode(true)}get templateElement(){if(this.firstElementChild===null){const e=this.ownerDocument.createElement("template");this.appendChild(e);return e}if(this.firstElementChild instanceof HTMLTemplateElement)return this.firstElementChild;this.#ne("first child element must be a