diff --git a/WHATSNEW.md b/WHATSNEW.md index 534385a..fd96f4c 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -1,5 +1,39 @@ ## What's New +### Support the _mounted_ function when starting a component manually + +> Dec, 8, 2023 + +When using a component in JSX, AppRun always invokes the the _mounted_ lifecycle function each time the component is loaded. + +```js +class ComponentClass extends Component { + mounted = () => console.log('mounted is called'); +} +app.render(document.body, ); +``` + +However, the _mounted_ function is not called when you start the component manully in the previous versions. + +```js +class ComponentClass extends Component { + mounted = () => console.log('mounted is called'); // not called in previous versions +} +new ComponentClass().start(document.body); +``` + +Now, the _mounted_ function is called when the component is started. + +```js +class ComponentClass extends Component { + mounted = () => console.log('mounted is called'); // called in this version +} +new ComponentClass().start(document.body); +``` + +This change make the _mounted_ funciton compatible in JSX and in manual start. + + ### Support View Transition API > September, 27, 2023 diff --git a/demo/app.js b/demo/app.js index 5af988a..9598df8 100644 --- a/demo/app.js +++ b/demo/app.js @@ -1,5 +1,5 @@ /*! For license information please see app.js.LICENSE.txt */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.apprun=e():t.apprun=e()}(this,(()=>(()=>{"use strict";var __webpack_modules__={740:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{__webpack_require__.d(__webpack_exports__,{Z:()=>__WEBPACK_DEFAULT_EXPORT__});var _src_apprun__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(37),_state_machine__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(863);const state={_state:"START",display:"0",arg1:0,arg2:0,op:"",stack:[]},view=({_state:t,op:e,arg1:n,arg2:o,display:s,stack:i})=>_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h(_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.Fragment,null,_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("style",null," ","\n .calculator { width: 200px; }\n .buttons {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n grid-gap: 2px;\n }\n button { padding: 10px; width:100%; }\n button:nth-of-type(1) {\n grid-column: span 2;\n }\n button:nth-of-type(16) {\n grid-column: span 2;\n }\n "),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("div",{class:"calculator"},_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("h1",null,s),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("div",{class:"buttons",$onclick:button_click},_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"CE"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"+/-"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"/"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"7"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"8"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"9"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"*"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"4"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"5"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"6"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"-"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"1"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"2"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"3"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"+"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"0"),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"."),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("button",null,"=")),_src_apprun__WEBPACK_IMPORTED_MODULE_0__.default.h("small",null,i.length>0&&`${i[0][0]} ${i[0][1]} `,t.startsWith("FIRST_")&&`${s}`,"OP"===t&&`${n} ${e}`,t.startsWith("SECOND_")&&`${n} ${e} ${s}`,"EQ"===t&&`${n} ${e} ${o} = ${s}`))),button_click=(state,e)=>{var _a;const priority={"*":2,"/":2,"+":1,"-":1},getEvent=t=>{switch(t){case"+/-":return"+/-";case"CE":return"CE";case".":return"DOT";case"=":return"EQ";default:return/\d/.test(t)?"NUM":"OP"}},key=(null===(_a=e.target)||void 0===_a?void 0:_a.textContent)||e,event=getEvent(key);let{_state,op,arg1,arg2,display,stack}=state;const clear=()=>{display="0",arg1=arg2=0,op="",stack.length=0},negative=()=>{display=display.startsWith("-")?display.substring(1):"-"+display},calc=()=>{display=eval(`${arg1}${op}${arg2}`).toString()},op1=()=>{op=key,arg1=parseFloat(display)},op2=()=>{if(priority[key]===priority[op])arg2=parseFloat(display),calc(),op=key,arg1=parseFloat(display);else if(priority[key]{arg1=parseFloat(display),calc()},eq2=()=>{if(arg2=parseFloat(display),calc(),stack.length){arg2=parseFloat(display);const f=stack.pop();display=eval(`${f[0]}${f[1]}${display}`).toString(),arg1=f[0],op=f[1]}},state_machine={START:[["NUM","FIRST_ARG",()=>display=key],["DOT","FIRST_ARG_FLOAT",()=>display="0."]],FIRST_ARG:[["+/-","FIRST_ARG",negative],["NUM","FIRST_ARG",()=>display+=key],["DOT","FIRST_ARG_FLOAT",()=>display+=key],["OP","OP",op1],["CE","START",clear]],FIRST_ARG_FLOAT:[["+/-","FIRST_ARG_FLOAT",negative],["NUM","FIRST_ARG_FLOAT",()=>display+=key],["OP","OP",op1],["CE","START",clear]],OP:[["NUM","SECOND_ARG",()=>display=key],["DOT","SECOND_ARG",()=>display="0."],["OP","OP",()=>op=key],["CE","START",clear]],SECOND_ARG:[["+/-","SECOND_ARG",negative],["NUM","SECOND_ARG",()=>display+=key],["DOT","SECOND_ARG_FLOAT",()=>display+=key],["EQ","EQ",eq2],["OP","OP",op2],["CE","OP",()=>display="0"]],SECOND_ARG_FLOAT:[["+/-","SECOND_ARG_FLOAT",negative],["NUM","SECOND_ARG_FLOAT",()=>display+=key],["EQ","EQ",eq2],["OP","OP",op2],["CE","OP",()=>display="0"]],EQ:[["+/-","FIRST_ARG",negative],["NUM","FIRST_ARG",()=>display=key],["DOT","FIRST_ARG_FLOAT",()=>display="0."],["EQ","EQ",eq0],["OP","OP",op1],["CE","START",clear]]},{next_state,transition}=(0,_state_machine__WEBPACK_IMPORTED_MODULE_1__.k)(state_machine,_state,event);return _state=next_state||_state,transition&&transition(),{_state,op,arg1,arg2,display,stack}},update={"#calculator":t=>t},__WEBPACK_DEFAULT_EXPORT__=t=>new _src_apprun__WEBPACK_IMPORTED_MODULE_0__.Component(state,view,update).mount(t)},863:(t,e,n)=>{n.d(e,{k:()=>o});const o=(t,e,n)=>{const o=t[e];if(!o)throw new Error(`No state: ${o} found in state machine`);const s=o.find((t=>t[0]===n));return s?{next_state:s[1],transition:s[2]}:{}}},752:(t,e,n)=>{n.d(e,{Z:()=>a,g:()=>o});class o{constructor(){this._events={}}on(t,e,n={}){this._events[t]=this._events[t]||[],this._events[t].push({fn:e,options:n})}off(t,e){const n=this._events[t]||[];this._events[t]=n.filter((t=>t.fn!==e))}find(t){return this._events[t]}run(t,...e){const n=this.getSubscribers(t,this._events);return console.assert(n&&n.length>0,"No subscriber for event: "+t),n.forEach((n=>{const{fn:o,options:s}=n;return s.delay?this.delay(t,o,e,s):Object.keys(s).length>0?o.apply(this,[...e,s]):o.apply(this,e),!n.options.once})),n.length}once(t,e,n={}){this.on(t,e,Object.assign(Object.assign({},n),{once:!0}))}delay(t,e,n,o){o._t&&clearTimeout(o._t),o._t=setTimeout((()=>{clearTimeout(o._t),Object.keys(o).length>0?e.apply(this,[...n,o]):e.apply(this,n)}),o.delay)}query(t,...e){const n=this.getSubscribers(t,this._events);console.assert(n&&n.length>0,"No subscriber for event: "+t);const o=n.map((t=>{const{fn:n,options:o}=t;return Object.keys(o).length>0?n.apply(this,[...e,o]):n.apply(this,e)}));return Promise.all(o)}getSubscribers(t,e){const n=e[t]||[];return e[t]=n.filter((t=>!t.options.once)),Object.keys(e).filter((e=>e.endsWith("*")&&t.startsWith(e.replace("*","")))).sort(((t,e)=>e.length-t.length)).forEach((o=>n.push(...e[o].map((e=>Object.assign(Object.assign({},e),{options:Object.assign(Object.assign({},e.options),{event:t})})))))),n}}let s;const i="object"==typeof self&&self.self===self&&self||"object"==typeof n.g&&n.g.global===n.g&&n.g;i.app&&i._AppRunVersions?s=i.app:(s=new o,i.app=s,i._AppRunVersions="AppRun-3");const a=s},570:(t,e,n)=>{var o=n(752);function s(t){return t.map((t=>a(t))).join("")}function i(t){for(var e in t)null==t[e]?delete t[e]:"object"==typeof t[e]&&i(t[e])}function a(t){if(!t)return"";if("_$litType$"in t)return t.toString();if(i(t),Array.isArray(t))return s(t);if("string"==typeof t)return t.startsWith("_html:")?t.substring(6):t;if(t.tag){const e=t.props?function(t){return Object.keys(t).map((e=>{return` ${"className"===e?"class":e}="${n=t[e],"object"==typeof n?Object.keys(n).map((t=>`${t}:${n[t]}`)).join(";"):n.toString()}"`;var n})).join("")}(t.props):"",n=t.children?s(t.children):"";return`<${t.tag}${e}>${n}`}return"object"==typeof t?JSON.stringify(t):void 0}const r=a;let l;function c(t){l=window.open("",t),l.document.write(`\n AppRun Analyzer | ${document.location.href}\n \n
`)}function d(t){l.document.write(t+"\n")}function u(){l.document.write("
\n \n "),l.document.close()}app.debug=!0;const p=t=>{d(`import ${t.constructor.name} from '../src/${t.constructor.name}'`),d(`describe('${t.constructor.name}', ()=>{`),t._actions.forEach((e=>{"."!==e.name&&(d(` it ('should handle event: ${e.name}', (done)=>{`),d(` const component = new ${t.constructor.name}().mount();`),d(` component.run('${e.name}');`),d(" setTimeout(() => {"),d(" //expect(?).toHaveBeenCalled();"),d(" //expect(component.state).toBe(?);"),d(" done();"),d(" })"))})),d("});")};let h=!1,m=[];app.on("debug",(t=>{h&&t.vdom&&(m.push(t),console.log(`* ${m.length} state(s) recorded.`))}));var _;function f(t){const e=window.open("","_apprun_debug","toolbar=0");e.document.write(`\n AppRun Analyzer | ${document.location.href}\n \n \n
${t}
\n <\/script>\n \n `),e.document.close()}o.Z.debug=!0,window["_apprun-help"]=["",()=>{Object.keys(window).forEach((t=>{t.startsWith("_apprun-")&&("_apprun-help"===t?console.log("AppRun Commands:"):console.log(`* ${t.substring(8)}: ${window[t][0]}`))}))}];const v=()=>{const t={components:{}};o.Z.run("get-components",t);const{components:e}=t;return e};let b=Number(null===(_=null===window||void 0===window?void 0:window.localStorage)||void 0===_?void 0:_.getItem("__apprun_debugging__"))||0;if(o.Z.on("debug",(t=>{1&b&&t.event&&console.log(t),2&b&&t.vdom&&console.log(t)})),window["_apprun-components"]=["components [print]",t=>{(t=>{const e=v(),n=[];if(e instanceof Map)for(let[t,o]of e){const e="string"==typeof t?document.getElementById(t)||document.querySelector(t):t;n.push({element:e,comps:o})}else Object.keys(e).forEach((t=>{const o="string"==typeof t?document.getElementById(t)||document.querySelector(t):t;n.push({element:o,comps:e[t]})}));if(t){const t=(t=>{const e=({events:t})=>o.Z.h("ul",null,t&&t.filter((t=>"."!==t.name)).map((t=>o.Z.h("li",null,t.name)))),n=({components:t})=>o.Z.h("ul",null,t.map((t=>o.Z.h("li",null,o.Z.h("div",null,t.constructor.name),o.Z.h(e,{events:t._actions})))));return o.Z.h("ul",null,t.map((({element:t,comps:e})=>o.Z.h("li",null,o.Z.h("div",null,(t=>o.Z.h("div",null,t.tagName.toLowerCase(),t.id?"#"+t.id:""," ",t.className&&t.className.split(" ").map((t=>"."+t)).join()))(t)),o.Z.h(n,{components:e})))))})(n);f(r(t))}else n.forEach((({element:t,comps:e})=>console.log(t,e)))})("print"===t)}],window["_apprun-events"]=["events [print]",t=>{(t=>{const e=o.Z._events,n={},s=v(),i=t=>t._actions.forEach((e=>{n[e.name]=n[e.name]||[],n[e.name].push(t)}));if(s instanceof Map)for(let[t,e]of s)e.forEach(i);else Object.keys(s).forEach((t=>s[t].forEach(i)));const a=[];if(Object.keys(n).forEach((t=>{a.push({event:t,components:n[t],global:!!e[t]})})),a.sort(((t,e)=>t.event>e.event?1:-1)).map((t=>t.event)),t){const t=(t=>{const e=({components:t})=>o.Z.h("ul",null,t.map((t=>o.Z.h("li",null,o.Z.h("div",null,t.constructor.name))))),n=({events:t,global:n})=>o.Z.h("ul",null,t&&t.filter((t=>t.global===n&&"."!==t.event)).map((({event:t,components:n})=>o.Z.h("li",null,o.Z.h("div",null,t),o.Z.h(e,{components:n})))));return o.Z.h("div",null,o.Z.h("div",null,"GLOBAL EVENTS"),o.Z.h(n,{events:t,global:!0}),o.Z.h("div",null,"LOCAL EVENTS"),o.Z.h(n,{events:t,global:!1}))})(a);f(r(t))}else console.log("=== GLOBAL EVENTS ==="),a.filter((t=>t.global&&"."!==t.event)).forEach((({event:t,components:e})=>console.log({event:t},e))),console.log("=== LOCAL EVENTS ==="),a.filter((t=>!t.global&&"."!==t.event)).forEach((({event:t,components:e})=>console.log({event:t},e)))})("print"===t)}],window["_apprun-log"]=["log [event|view] on|off",(t,e)=>{var n;"on"===t?b=3:"off"===t?b=0:"event"===t?"on"===e?b|=1:"off"===e&&(b&=-2):"view"===t&&("on"===e?b|=2:"off"===e&&(b&=-3)),console.log(`* log ${t} ${e||""}`),null===(n=null===window||void 0===window?void 0:window.localStorage)||void 0===n||n.setItem("__apprun_debugging__",`${b}`)}],window["_apprun-create-event-tests"]=["create-event-tests",()=>(()=>{const t={components:{}};app.run("get-components",t);const{components:e}=t;if(c(""),e instanceof Map)for(let[t,n]of e)n.forEach(p);else Object.keys(e).forEach((t=>{e[t].forEach(p)}));u()})()],window["_apprun-create-state-tests"]=["create-state-tests ",t=>{var e;"start"===(e=t)?(m=[],h=!0,console.log("* State logging started.")):"stop"===e?(0!==m.length?(c(""),m.forEach(((t,e)=>{d(` it ('view snapshot: #${e+1}', ()=>{`),d(` const component = new ${t.component.constructor.name}()`),d(` const state = ${JSON.stringify(t.state,void 0,2)};`),d(" const vdom = component['view'](state);"),d(" expect(JSON.stringify(vdom)).toMatchSnapshot();"),d(" })")})),u()):console.log("* No state recorded."),h=!1,m=[],console.log("* State logging stopped.")):console.log("create-state-tests ")}],window._apprun=t=>{const[e,...n]=t[0].split(" ").filter((t=>!!t)),o=window[`_apprun-${e}`];o?o[1](...n):window["_apprun-help"][1]()},console.info('AppRun DevTools 2.27: type "_apprun `help`" to list all available commands.'),window.__REDUX_DEVTOOLS_EXTENSION__){let t=!1;const e=window.__REDUX_DEVTOOLS_EXTENSION__.connect();if(e){const n=location.hash||"#";e.send(n,"");const s=[{component:null,state:""}];console.info("Connected to the Redux DevTools"),e.subscribe((e=>{if("START"===e.type)t=!0;else if("STOP"===e.type)t=!1;else if("DISPATCH"===e.type){const t=e.payload.index;if(0===t)o.Z.run(n);else{const{component:e,state:n}=s[t];null==e||e.setState(n)}}}));const i=(t,n,o)=>{null!=o&&(s.push({component:t,state:o}),e.send(n,o))};o.Z.on("debug",(e=>{if(t&&e.event){const t=e.newState,n={type:e.event,payload:e.p},o=e.component;t instanceof Promise?t.then((t=>i(o,n,t))):i(o,n,t)}}))}}},705:(t,e,n)=>{n.d(e,{Component:()=>o.Component,html:()=>i.dy,run:()=>d,svg:()=>i.YP});var o=n(37),s=n(559),i=n(692),a=n(875);class r extends a.Xe{constructor(t){if(super(t),this.it=i.Ld,t.type!==a.pX.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(t){if(t===i.Ld||null==t)return this.ft=void 0,this.it=t;if(t===i.Jb)return t;if("string"!=typeof t)throw Error(this.constructor.directiveName+"() called with a non-string value");if(t===this.it)return this.ft;this.it=t;const e=[t];return e.raw=e,this.ft={_$litType$:this.constructor.resultType,strings:e,values:[]}}}r.directiveName="unsafeHTML",r.resultType=1;const l=(0,a.XM)(r);class c extends a.Xe{constructor(t){if(super(t),t.type!==a.pX.EVENT)throw new Error("${run} can only be used in event handlers")}update(t,e){let{element:n,name:s}=t;const i=()=>{let t=n._component;for(;!t&&n;)n=n.parentElement,t=n&&n._component;return console.assert(!!t,"Component not found."),t},[a,...r]=e;return"string"==typeof a?n[`on${s}`]=t=>{const e=i();e?e.run(a,...r,t):o.default.run(a,...r,t)}:"function"==typeof a&&(n[`on${s}`]=t=>i().setState(a(i().state,...r,t))),this.render()}render(){return i.Jb}}const d=(0,a.XM)(c);o.default.createElement=s.az,o.default.render=function(t,e,n){e&&("string"==typeof e?(t._$litPart$||t.replaceChildren(),(0,i.sY)(i.dy`${l(e)}`,t)):"_$litType$"in e?(t._$litPart$||t.replaceChildren(),(0,i.sY)(e,t)):((0,s.yj)(t,e,n),t._$litPart$=void 0))},o.default.Fragment=s.HY,"object"==typeof window&&(window.React=window._React||o.default,window.html=i.dy,window.svg=i.YP,window.run=d)},607:(t,e,n)=>{var o=n(37);const s=(t,e,n,o)=>{if(!e||!n)return;const s=t=>{var n,o;const s=e.cloneNode();null===(n=e.parentNode)||void 0===n||n.replaceChild(s,e);const i=null===(o=(e=s).contentWindow)||void 0===o?void 0:o.document;i&&(i.open(),t.indexOf("=0?i.write(t):i.write((t=>`\n\n\n \n \n \n \n \n `);\n win.document.close();\n}\n\nconst get_components = () => {\n const o = { components: {} };\n app.run('get-components', o);\n const { components } = o;\n return components;\n}\nconst viewElement = element =>
\n {element.tagName.toLowerCase()}{element.id ? '#' + element.id : ''}\n {' '}\n {element.className && element.className.split(' ').map(c => '.' + c).join() }\n
;\n\nconst viewComponents = state => {\n\n const Events = ({ events }) =>
    \n {events && events.filter(event => event.name !== '.').map(event =>
  • \n {event.name}\n
  • )}\n
;\n\n const Components = ({ components }) =>
    \n {components.map(component =>
  • \n
    {component.constructor.name}
    \n \n
  • )}\n
;\n\n return
    \n {state.map(({ element, comps}) =>
  • \n
    {viewElement(element)}
    \n \n
  • )}\n
\n}\n\nconst viewEvents = state => {\n\n const Components = ({ components }) =>
    \n {components.map(component =>
  • \n
    {component.constructor.name}
    \n
  • )}\n
;\n\n const Events = ({ events, global }) =>
    \n {events && events\n .filter(event =>\n event.global === global && event.event !== '.')\n .map(({ event, components }) =>
  • \n
    {event}
    \n \n
  • )}\n
;\n\n return
\n
GLOBAL EVENTS
\n \n
LOCAL EVENTS
\n \n
\n}\n\nconst _events = (print?) => {\n const global_events = app['_events']\n const events = {};\n const cache = get_components();\n\n const add_component = component => component['_actions'].forEach(event => {\n events[event.name] = events[event.name] || [];\n events[event.name].push(component);\n });\n\n if (cache instanceof Map) {\n for (let [key, comps] of cache) {\n comps.forEach(add_component);\n }\n } else {\n Object.keys(cache).forEach(el =>\n cache[el].forEach(add_component)\n );\n }\n const data = [];\n Object.keys(events).forEach(event => {\n data.push({ event, components: events[event], global: global_events[event] ? true : false });\n });\n\n data.sort(((a, b) => a.event > b.event ? 1 : -1)).map(e => e.event);\n\n if (print) {\n const vdom = viewEvents(data);\n newWin(toHTML(vdom));\n } else {\n console.log('=== GLOBAL EVENTS ===')\n data.filter(event => event.global && event.event !== '.')\n .forEach(({ event, components }) => console.log({ event }, components));\n console.log('=== LOCAL EVENTS ===')\n data.filter(event => !event.global && event.event !== '.')\n .forEach(({ event, components }) => console.log({ event }, components));\n }\n}\n\nconst _components = (print?) => {\n const components = get_components();\n const data = [];\n\n if (components instanceof Map) {\n for (let [key, comps] of components) {\n const element = typeof key === 'string' ? document.getElementById(key) || document.querySelector(key): key;\n data.push({ element, comps });\n }\n } else {\n Object.keys(components).forEach(el => {\n const element = typeof el === 'string' ? document.getElementById(el) || document.querySelector(el): el;\n data.push({ element, comps: components[el] });\n });\n }\n if (print) {\n const vdom = viewComponents(data);\n newWin(toHTML(vdom));\n } else {\n data.forEach(({ element, comps }) => console.log(element, comps));\n }\n}\n\nlet debugging = Number(window?.localStorage?.getItem('__apprun_debugging__')) || 0;\napp.on('debug', p => {\n if (debugging & 1 && p.event) console.log(p);\n if (debugging & 2 && p.vdom) console.log(p);\n});\n\nwindow['_apprun-components'] = ['components [print]', (p) => {\n _components(p === 'print');\n}]\n\nwindow['_apprun-events'] = ['events [print]', (p) => {\n _events(p === 'print');\n}]\n\nwindow['_apprun-log'] = ['log [event|view] on|off', (a1?, a2?) => {\n if (a1 === 'on') {\n debugging = 3;\n } else if (a1 === 'off') {\n debugging = 0;\n } else if (a1 === 'event') {\n if (a2 === 'on') {\n debugging |= 1;\n } else if (a2 === 'off') {\n debugging &= ~1;\n }\n } else if (a1 === 'view') {\n if (a2 === 'on') {\n debugging |= 2;\n } else if (a2 === 'off') {\n debugging &= ~2;\n }\n }\n console.log(`* log ${a1} ${a2 || ''}`);\n window?.localStorage?.setItem('__apprun_debugging__', `${debugging}`)\n}];\n\nwindow['_apprun-create-event-tests'] = ['create-event-tests',\n () => _createEventTests()\n]\n\nwindow['_apprun-create-state-tests'] = ['create-state-tests ',\n (p?) => _createStateTests(p)\n]\n\nwindow['_apprun'] = (strings) => {\n const [cmd, ...p] = strings[0].split(' ').filter(c => !!c);\n const command = window[`_apprun-${cmd}`];\n if (command) command[1](...p);\n else window['_apprun-help'][1]();\n}\n\nconsole.info('AppRun DevTools 2.27: type \"_apprun `help`\" to list all available commands.');\n\nconst reduxExt = window['__REDUX_DEVTOOLS_EXTENSION__'];\nif (reduxExt) {\n let devTools_running = false;\n const devTools = window['__REDUX_DEVTOOLS_EXTENSION__'].connect();\n if (devTools) {\n const hash = location.hash || '#';\n devTools.send(hash, '' );\n const buf = [{ component:null, state:''}];\n console.info('Connected to the Redux DevTools');\n devTools.subscribe((message) => {\n if (message.type === 'START') devTools_running = true;\n else if (message.type === 'STOP') devTools_running = false;\n else if (message.type === 'DISPATCH') {\n // console.log('From Redux DevTools: ', message);\n const idx = message.payload.index;\n if (idx === 0) { app.run(hash) }\n else {\n const { component, state } = buf[idx];\n component?.setState(state);\n }\n }\n });\n\n const send = (component, action, state) => {\n if (state == null) return;\n buf.push({ component, state });\n devTools.send(action, state);\n }\n\n app.on('debug', p => {\n if (devTools_running && p.event) {\n const state = p.newState;\n const type = p.event;\n const payload = p.p;\n const action = { type, payload };\n const component = p.component;\n if (state instanceof Promise) {\n state.then(s => send(component, action, s));\n } else {\n send(component, action, state);\n }\n }\n });\n }\n}\n","import{nothing as t,noChange as i}from\"../lit-html.js\";import{Directive as r,PartType as s,directive as n}from\"../directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */class e extends r{constructor(i){if(super(i),this.it=t,i.type!==s.CHILD)throw Error(this.constructor.directiveName+\"() can only be used in child bindings\")}render(r){if(r===t||null==r)return this.ft=void 0,this.it=r;if(r===i)return r;if(\"string\"!=typeof r)throw Error(this.constructor.directiveName+\"() called with a non-string value\");if(r===this.it)return this.ft;this.it=r;const s=[r];return s.raw=s,this.ft={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName=\"unsafeHTML\",e.resultType=1;const o=n(e);export{e as UnsafeHTMLDirective,o as unsafeHTML};\n//# sourceMappingURL=unsafe-html.js.map\n","import { createElement, updateElement, Fragment } from './vdom-my';\n\n\nimport { render, svg, html, noChange, nothing } from 'lit-html';\nimport { directive, Directive, Part, PartInfo, PartType, EventPart } from 'lit-html/directive.js';\nimport { unsafeHTML } from 'lit-html/directives/unsafe-html.js';\nimport app from './apprun';\n\nfunction _render(element, vdom, parent?) {\n if (!vdom) return;\n if (typeof vdom === 'string') {\n if (!element['_$litPart$']) element.replaceChildren();\n render(html`${unsafeHTML(vdom)}`, element);\n } else if ('_$litType$' in vdom) {\n if (!element['_$litPart$']) element.replaceChildren();\n render(vdom, element);\n } else {\n updateElement(element, vdom, parent);\n element['_$litPart$'] = undefined;\n }\n}\n\nexport class RunDirective extends Directive {\n // State stored in class field\n value: number | undefined;\n constructor(partInfo: PartInfo) {\n super(partInfo);\n // When necessary, validate part in constructor using `part.type`\n if (partInfo.type !== PartType.EVENT) {\n throw new Error('${run} can only be used in event handlers');\n }\n }\n // Optional: override update to perform any direct DOM manipulation\n update(part: Part, params) {\n /* Any imperative updates to DOM/parts would go here */\n\n let { element, name } = part as EventPart;\n const getComponent = () => {\n let component = element['_component'];\n while (!component && element) {\n element = element.parentElement;\n component = element && element['_component'];\n }\n console.assert(!!component, 'Component not found.');\n return component;\n }\n const [event, ...args] = params;\n if (typeof event === 'string') {\n element[`on${name}`] = e => {\n const component = getComponent();\n component ? component.run(event, ...args, e) : app.run(event, ...args, e)\n }\n } else if (typeof event === 'function') {\n element[`on${name}`] = e => getComponent().setState(event(getComponent().state, ...args, e));\n }\n return this.render();\n }\n render() {\n return noChange;\n }\n}\n\nconst run = directive(RunDirective) as any;\nexport { createElement, Fragment, html, svg, _render as render, run };\n\n","import app from './apprun'\nexport {\n app, Component, View, Action, Update, on, update, event, EventOptions,\n customElement, CustomElementOptions,\n ROUTER_404_EVENT, ROUTER_EVENT, safeHTML\n} from './apprun'\nimport { createElement, render, Fragment, html, svg, run } from './vdom-lit-html';\nexport { html, svg, render, run }\n\napp.createElement = createElement;\napp.render = render;\napp.Fragment = Fragment;\n\nexport default app;\n\nif (typeof window === 'object') {\n window['React'] = window['_React'] || app;\n window['html'] = html;\n window['svg'] = svg;\n window['run'] = run;\n}\n","import { app, Component } from './apprun';\n\nconst popup_div = `
\n\n\n\t
\n\t\t×\n\t\t
\n\t\t\t
\n \n
\n
\n