create-prisma-php-app 2.1.14 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -57,7 +57,14 @@ final class Bootstrap
57
57
  ErrorHandler::registerHandlers();
58
58
 
59
59
  // Set a local store key as a cookie (before any output)
60
- setcookie("pphp_local_store_key", PrismaPHPSettings::$localStoreKey, time() + 3600, "/", "", false, false);
60
+ setcookie("pphp_local_store_key", PrismaPHPSettings::$localStoreKey, [
61
+ 'expires' => time() + 3600, // 1 hour expiration
62
+ 'path' => '/', // Cookie path
63
+ 'domain' => '', // Specify your domain
64
+ 'secure' => true, // Set to true if using HTTPS
65
+ 'httponly' => false, // Set to true to prevent JavaScript access
66
+ 'samesite' => 'Lax', // or 'Strict' depending on your requirements
67
+ ]);
61
68
 
62
69
  $contentInfo = self::determineContentToInclude();
63
70
  self::$contentToInclude = $contentInfo['path'] ?? '';
@@ -244,10 +244,10 @@ class Auth
244
244
  if (!headers_sent()) {
245
245
  setcookie(self::$cookieName, $jwt, [
246
246
  'expires' => $expirationTime,
247
- 'path' => '/',
247
+ 'path' => '/', // Set the path to '/' to make the cookie available site-wide
248
248
  'domain' => '', // Specify your domain
249
- 'secure' => true,
250
- 'httponly' => true,
249
+ 'secure' => true, // Set to true if using HTTPS
250
+ 'httponly' => true, // Prevent JavaScript access to the cookie
251
251
  'samesite' => 'Lax', // or 'Strict' depending on your requirements
252
252
  ]);
253
253
  }
@@ -51,8 +51,16 @@ class MainLayout
51
51
  */
52
52
  public static function addFooterScript(string ...$scripts): void
53
53
  {
54
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
55
+ $callerClass = $trace[1]['class'] ?? 'Unknown';
56
+
54
57
  foreach ($scripts as $script) {
55
- self::$footerScripts->add($script);
58
+ if (strpos($script, '<script') !== false) {
59
+ $taggedScript = "<!-- class:" . $callerClass . " -->\n" . $script;
60
+ self::$footerScripts->add($taggedScript);
61
+ } else {
62
+ self::$footerScripts->add($script);
63
+ }
56
64
  }
57
65
  }
58
66
 
@@ -88,7 +96,35 @@ class MainLayout
88
96
  */
89
97
  public static function outputFooterScripts(): string
90
98
  {
91
- return implode("\n", self::$footerScripts->values());
99
+ $processed = [];
100
+
101
+ foreach (self::$footerScripts->values() as $script) {
102
+ if (preg_match('/<!-- class:([^\s]+) -->/', $script, $matches)) {
103
+ $className = $matches[1];
104
+ $script = preg_replace('/<!-- class:[^\s]+ -->\s*/', '', $script, 1);
105
+
106
+ if (str_starts_with(trim($script), '<script')) {
107
+ $script = preg_replace_callback('/<script\b([^>]*)>/i', function ($m) use ($className) {
108
+ $attrs = $m[1];
109
+ $className = base64_encode($className);
110
+
111
+ if (!str_contains($attrs, 'pp-sync-script=')) {
112
+ $attrs .= " pp-sync-script=\"{$className}\"";
113
+ }
114
+
115
+ if (!preg_match('/\btype\s*=\s*/i', $attrs)) {
116
+ $attrs .= ' type="module"';
117
+ }
118
+
119
+ return "<script{$attrs}>";
120
+ }, $script, 1);
121
+ }
122
+ }
123
+
124
+ $processed[] = $script;
125
+ }
126
+
127
+ return implode("\n", $processed);
92
128
  }
93
129
 
94
130
  /**
@@ -308,6 +308,7 @@ class TemplateCompiler
308
308
  throw new RuntimeException("Class {$className} does not exist.");
309
309
  }
310
310
 
311
+ $attributes['pp-sync-script'] = base64_encode($className);
311
312
  return new $className($attributes);
312
313
  }
313
314
 
@@ -388,9 +388,11 @@ class Request
388
388
  */
389
389
  private static function getProtocol(): string
390
390
  {
391
- return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ||
391
+ return (
392
+ (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ||
392
393
  (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') ||
393
- $_SERVER['SERVER_PORT'] == 443 ? "https://" : "http://";
394
+ ($_SERVER['SERVER_PORT'] == 443)
395
+ ) ? "https://" : "http://";
394
396
  }
395
397
 
396
398
  /**
@@ -1,12 +1,7 @@
1
- (()=>{const e=EventTarget.prototype.addEventListener,t=EventTarget.prototype.removeEventListener,n=new Map;EventTarget.prototype.addEventListener=function(t,s,i){n.has(this)||n.set(this,new Map);const a=n.get(this).get(t)||new Set;a.add(s),n.get(this).set(t,a),e.call(this,t,s,i)},EventTarget.prototype.removeEventListener=function(e,s,i){if(n.has(this)&&n.get(this).has(e)){const t=n.get(this).get(e);t&&(t.delete(s),0===t.size&&n.get(this).delete(e))}t.call(this,e,s,i)},EventTarget.prototype.removeAllEventListeners=function(e){if(n.has(this)&&n.get(this).has(e)){const s=n.get(this).get(e);s&&(s.forEach((n=>{t.call(this,e,n)})),n.get(this).delete(e))}}})();class PPHP{props={};static _instance;isNavigating=!1;responseData=null;activeAbortController=null;rawProps={};bindings=[];state={checkedElements:new Set};builtInProps;eventHandlers;redirectRegex=/redirect_7F834\s*=\s*(\/[^\s]*)/;constructor(){this.eventHandlers=new Set(["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onwheel","onkeypress","onkeydown","onkeyup","onfocus","onblur","onchange","oninput","onselect","onsubmit","onreset","onresize","onscroll","onload","onunload","onabort","onerror","onbeforeunload","oncopy","oncut","onpaste","ondrag","ondragstart","ondragend","ondragover","ondragenter","ondragleave","ondrop","oncontextmenu","ontouchstart","ontouchmove","ontouchend","ontouchcancel","onpointerdown","onpointerup","onpointermove","onpointerover","onpointerout","onpointerenter","onpointerleave","onpointercancel"]),this.builtInProps=new Set(["length","charAt","charCodeAt","codePointAt","concat","includes","endsWith","indexOf","lastIndexOf","localeCompare","match","matchAll","normalize","padEnd","padStart","repeat","replace","replaceAll","search","slice","split","substring","substr","startsWith","toLocaleLowerCase","toLocaleUpperCase","toLowerCase","toString","toUpperCase","trim","trimEnd","trimStart","valueOf"]),this.handlePopState(),this.props=this.makeReactive(this.rawProps)}static get instance(){return PPHP._instance||(PPHP._instance=new PPHP),PPHP._instance}extractDependencies(e){return new Set(e.match(/\b[a-zA-Z_][a-zA-Z0-9_]*\b/g)||[])}formatValue(e){return"boolean"==typeof e?e?"true":"false":e&&"object"==typeof e?Object.keys(e).length>0?JSON.stringify(e,null,2):"":e?.toString()||""}registerBinding(e,t,n="text",s){const i=this.extractDependencies(t),a=this.makeSafeEvaluator(t);if(/^\s*[\w\.]+\s*=(?!=)/.test(t))return;if("value"===s||"checked"===s){const t=()=>{try{const t=a(this.props),n=this.formatValue(t);"value"===s?e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement?e.value=n:e.setAttribute("value",n):"checked"===s&&(e instanceof HTMLInputElement?e.checked="true"===n:e.setAttribute("checked",n))}catch(e){}};return void this.bindings.push({dependencies:i,update:t})}this.bindings.push({dependencies:i,update:()=>{try{if(s){const t="__static_"+s;let n=e[t];if(void 0===n){n=e.getAttribute(s)||"",e[t]=n;(n.match(/\{\{\s*([\s\S]+?)\s*\}\}/gu)||[]).forEach((e=>{const t=e.replace(/\{\{\s*|\}\}/gu,"").trim();this.extractDependencies(t).forEach((e=>i.add(e)))}))}const a=n.replace(/\{\{\s*([\s\S]+?)\s*\}\}/gu,((e,t)=>{try{const e=this.makeSafeEvaluator(t)(this.props);return this.formatValue(e)}catch(e){return""}}));e.setAttribute(s,a)}else{const t=a(this.props),s=this.formatValue(t);switch(n){case"value":e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement?e.value=s:e.setAttribute("value",s);break;case"checked":e instanceof HTMLInputElement?e.checked="true"===s:e.setAttribute("checked",s);break;case"text":default:e.textContent=s;break}}}catch(e){}}})}initBindings(){this.bindings=[],document.querySelectorAll("[pp-bind]").forEach((e=>{const t=e.getAttribute("pp-bind");t&&this.registerBinding(e,t,"text")})),document.querySelectorAll("[pp-bind-expr]").forEach((e=>{const t=e.getAttribute("pp-bind-expr");t&&this.registerBinding(e,t,"text")})),document.body.querySelectorAll("*").forEach((e=>{Array.from(e.attributes).forEach((t=>{if(!t.name.startsWith("pp-bind-"))return;let n=t.value.replace(/&quot;/g,'"').replace(/&#039;/g,"'").replace(/&amp;/g,"&").replace(/^{{\s*|\s*}}$/g,"");const s=t.name.replace(/^(pp-bind-)+/,"");let i="text";"value"===s&&(i="value"),"checked"===s&&(i="checked"),this.registerBinding(e,n,i,s)}))}))}safeNull=new Proxy((()=>""),{get:(e,t)=>"toString"===t||"valueOf"===t?()=>"":this.safeNull,apply:()=>""});safeTag=(e,...t)=>e.reduce(((e,n,s)=>{const i=t[s];return e+n+(null==i||"object"==typeof i?"":i)}),"");makeSafeEvaluator(e){const t=e.trim();if(t.startsWith("`")&&t.endsWith("`")){const e=t.slice(1,-1),n=/\$\{\s*([^}]+?)\s*\}/g,s=new Set;let i;for(;i=n.exec(e);){const e=i[1];this.extractDependencies(e).forEach((e=>s.add(e)))}const a=Array.from(s),o=new Function(...a,"safeTag",`return safeTag\`${e}\``);return e=>{const t=a.map((t=>void 0===e[t]?this.safeNull:e[t]));return o(...t,this.safeTag.bind(this))}}const n=e.replace(/(["'])(?:(?=(\\?))\2.)*?\1/g,""),s=new Set(n.match(/\b[a-zA-Z_][a-zA-Z0-9_]*\b/g)||[]);s.delete("safeTag");const i=Array.from(s).map((t=>`\n const ${t} = ctx["${t}"] !== undefined \n ? ctx["${t}"] \n : (typeof window !== "undefined" && window["${t}"] !== undefined \n ? window["${t}"] \n : ${new RegExp(`\\b${t}\\.`).test(e)?"{}":"void 0"});\n if (typeof window !== "undefined" && window["${t}"] !== ${t}) {\n window["${t}"] = ${t};\n }\n `)).join("\n"),a=/^\s*[\w\.]+\s*=(?!=)/.test(e),o=new Function("ctx","safeTag",`\n "use strict";\n ${i}\n try {\n ${a?e+"; return '';":"const result = "+e+"; return result === undefined || result === null ? '' : result;"}\n } catch (e) {\n return "";\n }\n `);return e=>o(e,this.safeTag.bind(this))}makeReactive(e,t=[]){const n=this;if(e instanceof Map||e instanceof Set)return e;const s=new Proxy(e,{get(e,s){const i=e[s];return"object"==typeof i&&null!==i?n.makeReactive(i,[...t,s.toString()]):i},set:(e,t,s)=>(e[t]=s,n.bindings.forEach((e=>{e.dependencies.has(t)&&e.update()})),!0)});return"loading"===document.readyState&&document.addEventListener("DOMContentLoaded",(()=>{this.initBindings(),this.bindings.forEach((e=>e.update())),this.initializeAllReferencedProps()})),s}handlePopState(){window.addEventListener("popstate",(async()=>{await this.handleNavigation()}))}attachWireFunctionEvents(){this.handleHiddenAttribute();document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((e=>{if(this.handleAnchorTag(e),Array.from(e.attributes).filter((e=>this.eventHandlers.has(e.name))).forEach((t=>{const n=t.name.slice(2),s=t.value;e instanceof HTMLInputElement&&this.handleInputAppendParams(e,n),s&&(e.removeAttribute(t.name),this.handleDebounce(e,n,s))})),e instanceof HTMLFormElement){const t=e.getAttribute("onsubmit");t&&(e.removeAttribute("onsubmit"),this.handleDebounce(e,"submit",t))}}))}async handleDebounce(e,t,n){e.removeEventListener(t,(()=>{}));const s=e.getAttribute("pp-debounce")||"",i=e.getAttribute("pp-before-request")||"",a=e.getAttribute("pp-after-request")||"",o=async t=>{t.preventDefault();try{i&&await this.invokeHandler(e,i,t),await this.invokeHandler(e,n,t),a&&"@close"!==a&&await this.invokeHandler(e,a,t),this.handlerAutofocusAttribute()}catch(e){}};if(s){const n=this.parseTime(s),i=this.debounce(o,n);e instanceof HTMLFormElement&&"submit"===t?e.addEventListener(t,(e=>{e.preventDefault(),i(e)})):e.addEventListener(t,i)}else e.addEventListener(t,o)}debounce(e,t=300,n=!1){let s;return function(...i){const a=this;s&&clearTimeout(s),s=setTimeout((()=>{s=null,n||e.apply(a,i)}),t),n&&!s&&e.apply(a,i)}}handlerAutofocusAttribute(){const e=document.activeElement;if(e&&e!==document.body)return;const t=this.state?.focusId;if(!t)return;const n=document.querySelectorAll("[pp-autofocus]");let s=!1;n.forEach((e=>{if(s)return;const t=e.getAttribute("pp-autofocus");if(!t||!this.isJsonLike(t))return;const n=this.parseJson(t);if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){const t=["text","search","tel","url","password"];if(e instanceof HTMLInputElement)if(t.includes(e.type))if("number"===e.type){e.type="text";const t=e.value.length||0;e.setSelectionRange(t,t),e.type="number"}else this.setCursorPosition(e,n);else;else e instanceof HTMLTextAreaElement&&this.setCursorPosition(e,n)}e.focus(),s=!0}))}initializeAllReferencedProps(){const e=/\b([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)\b/g,t=new Set;document.body.querySelectorAll("*").forEach((n=>{for(const s of Array.from(n.attributes)){if(!s.name.startsWith("pp-bind"))continue;const n=s.value.replace(/&quot;/g,'"').replace(/&#039;/g,"'").replace(/&amp;/g,"&").replace(/^{{\s*|\s*}}$/g,"");let i;for(;i=e.exec(n);){const e=i[1];if(e.indexOf(".")<0)continue;const[n]=e.split(".");this.builtInProps.has(n)||t.add(e)}}}));for(const e of t){const t=e.split(".");let n=this.props;for(let e=0;e<t.length;e++){const s=t[e],i=e===t.length-1;if(this.builtInProps.has(s))break;s in n||(n[s]=i?void 0:{}),n=n[s]}}}async invokeHandler(e,t,n){try{const s=t.match(/^(\w+(\.\w+)*)\((.*)\)$/);if(s){const i=s[1],a=s[3],o=i.split("."),{context:r,methodName:c}=this.resolveContext(o);if("function"==typeof r[c])if(this.isJsonLike(a)){const t=this.parseJson(a);t.element=e,t.event=n;const s=[t];await r[c](...s)}else new Function("event",t).call(e,n);else await this.handleParsedCallback(e,t)}else if(t.includes("=")){const s=t.match(/^\s*([\w\.]+)\s*=/);if(s){const e=s[1];if(e.includes(".")){const t=e.split(".");let n=pphp.props;for(let e=0;e<t.length-1;e++)t[e]in n||(n[t[e]]={}),n=n[t[e]]}else e in pphp.props||(pphp.props[e]=void 0)}new Function("event","props",`\n with (new Proxy(props, {\n get(target, key) {\n return key in target ? target[key] : undefined;\n },\n set(target, key, value) {\n target[key] = value;\n return true;\n }\n })) {\n ${t}\n }\n `).call(e,n,pphp.props)}else await this.handleParsedCallback(e,t)}catch(e){}}async handleParsedCallback(e,t){const{funcName:n,data:s}=this.parseCallback(e,t);if(!n)return;const i=this[n],a=window[n];let o;if("function"==typeof i?o=i:"function"==typeof a&&(o=a),"function"==typeof o){const t=e.hasAttribute("pp-after-request"),n=Array.isArray(s.args)?s.args:[],i=this.responseData?this.parseJson(this.responseData):{response:this.responseData};let a={args:n,element:e,data:s};t&&(a={...a,...i}),await o.call(this,a)}else this.responseData=null,this.responseData=await this.handleUndefinedFunction(e,n,s)}async handleUndefinedFunction(e,t,n){const s={callback:t,...n},i=this.createFetchOptions(s),a=this.createFetchOptions({secondRequestC69CD:!0,...this.getUrlParams()});try{this.saveElementOriginalState(e),this.handleSuspenseElement(e);const s=new URL(window.location.href);let o="",r="",c={success:!1};const l=e.querySelector("input[type='file']");if(l){if(o=await this.fetchFileWithData(s.href,t,l,n),r=this.extractJson(o)||"",r)try{c=this.parseJson(r)}catch(e){}}else{const e=await this.fetch(s.href,i);if(o=await e.text(),this.getRedirectUrl(o))return void await this.redirect(this.getRedirectUrl(o)||"");if(r=this.extractJson(o)||"",r)try{c=this.parseJson(r)}catch(e){}}const h=e.getAttribute("pp-before-request")||"",d=e.getAttribute("pp-after-request")||"";if((h||d&&c.success)&&this.restoreSuspenseElement(e),h||d){let e="";if(c.success){e=o.replace(r,"")}else e=o;if(this.appendAfterbegin(e),!d&&!c.success)return}if(d&&c.success){this.handleAfterRequest(d,r);const e=o.replace(r,"");return this.appendAfterbegin(e),r}if("@close"===d)return c.success?r:void 0;const u=await this.fetch(s.href,a),p=await u.text();if(this.getRedirectUrl(p))return void await this.redirect(this.getRedirectUrl(p)||"");await this.handleResponseRedirectOrUpdate(o,p,r,c)}catch(e){}}handleAfterRequest(e,t){if(!this.isJsonLike(e))return;const n=this.parseJson(e),s=t?this.parseJson(t):null,i=n.targets;Array.isArray(i)&&i.forEach((e=>{const{id:t,...n}=e,i=document.querySelector(t);let a={};if(s){for(const t in n)if(n.hasOwnProperty(t))switch(t){case"innerHTML":case"outerHTML":case"textContent":case"innerText":"response"===n[t]&&(a[t]=e.responseKey?s[e.responseKey]:s.response);break;default:a[t]=n[t];break}}else a=n;i&&this.updateElementAttributes(i,a)}))}async handleResponseRedirectOrUpdate(e,t,n,s){const i=this.getUpdatedHTMLContent(e,n,s),a=(new DOMParser).parseFromString(t,"text/html");i&&a.body.insertAdjacentElement("afterbegin",i),this.updateBodyContent(a.body.outerHTML)}getUpdatedHTMLContent(e,t,n){const s=document.createElement("div");if(s.id="afterbegin-8D95D",n&&t?.success){const t=e.replace(n,"");s.innerHTML=t}else s.innerHTML=e;return s.innerHTML?s:null}async updateBodyContent(e){const t=this.saveScrollPositions();this.saveState();const n=(new DOMParser).parseFromString(e,"text/html");document.removeAllEventListeners("PPBodyLoaded"),await this.appendCallbackResponse(n),this.restoreState(),this.restoreScrollPositions(t),this.attachWireFunctionEvents(),document.dispatchEvent(new Event("PPBodyLoaded"))}restoreState(){if(this.state.focusId){const e=document.getElementById(this.state.focusId)||document.querySelector(`[name="${this.state.focusId}"]`);if(e instanceof HTMLInputElement){const t=e.value.length||0;void 0!==this.state.focusSelectionStart&&null!==this.state.focusSelectionEnd&&e.setSelectionRange(t,t),this.state.focusValue&&("checkbox"===e.type||"radio"===e.type?e.checked=!!this.state.focusChecked:"number"===e.type||"email"===e.type?(e.type="text",e.setSelectionRange(t,t),e.type="number"===e.type?"number":"email"):"date"===e.type||"month"===e.type||"week"===e.type||"time"===e.type||"datetime-local"===e.type||"color"===e.type||"file"===e.type||""!==e.value&&(e.value=this.state.focusValue)),e.focus()}else if(e instanceof HTMLTextAreaElement){const t=e.value.length||0;void 0!==this.state.focusSelectionStart&&null!==this.state.focusSelectionEnd&&e.setSelectionRange(t,t),this.state.focusValue&&""!==e.value&&(e.value=this.state.focusValue),e.focus()}else e instanceof HTMLSelectElement&&(this.state.focusValue&&""!==e.value&&(e.value=this.state.focusValue),e.focus())}this.state.checkedElements.forEach((e=>{const t=document.getElementById(e);t&&(t.checked=!0)}))}async appendCallbackResponse(e){const t=e.getElementById("afterbegin-8D95D");if(t){const e=document.getElementById("afterbegin-8D95D");e?e.innerHTML=t.innerHTML:document.body.insertAdjacentHTML("afterbegin",t.outerHTML)}await this.populateDocumentBody(e)}saveState(){const e=document.activeElement;this.state.focusId=e?.id||e?.name,this.state.focusValue=e?.value,this.state.focusChecked=e?.checked,this.state.focusType=e?.type,this.state.focusSelectionStart=e?.selectionStart,this.state.focusSelectionEnd=e?.selectionEnd,this.state.isSuspense=e.hasAttribute("pp-suspense"),this.state.checkedElements.clear(),document.querySelectorAll('input[type="checkbox"]:checked').forEach((e=>{this.state.checkedElements.add(e.id||e.name)})),document.querySelectorAll('input[type="radio"]:checked').forEach((e=>{this.state.checkedElements.add(e.id||e.name)}))}updateElementAttributes(e,t){for(const n in t)if(t.hasOwnProperty(n))switch(n){case"innerHTML":case"outerHTML":case"textContent":case"innerText":e[n]=this.decodeHTML(t[n]);break;case"insertAdjacentHTML":e.insertAdjacentHTML(t.position||"beforeend",this.decodeHTML(t[n].html));break;case"insertAdjacentText":e.insertAdjacentText(t.position||"beforeend",this.decodeHTML(t[n].text));break;case"setAttribute":e.setAttribute(t.attrName,this.decodeHTML(t[n]));break;case"removeAttribute":e.removeAttribute(t[n]);break;case"className":e.className=this.decodeHTML(t[n]);break;case"classList.add":e.classList.add(...this.decodeHTML(t[n]).split(","));break;case"classList.remove":e.classList.remove(...this.decodeHTML(t[n]).split(","));break;case"classList.toggle":e.classList.toggle(this.decodeHTML(t[n]));break;case"classList.replace":const[s,i]=this.decodeHTML(t[n]).split(",");e.classList.replace(s,i);break;case"dataset":e.dataset[t.attrName]=this.decodeHTML(t[n]);break;case"style":Object.assign(e.style,t[n]);break;case"value":e.value=this.decodeHTML(t[n]);break;case"checked":e.checked=t[n];break;default:e.setAttribute(n,this.decodeHTML(t[n]))}}decodeHTML(e){const t=document.createElement("textarea");return t.innerHTML=e,t.value}appendAfterbegin(e){if(!e)return;const t="afterbegin-8D95D";let n=document.getElementById(t);n?(n.innerHTML=e,document.body.insertAdjacentElement("afterbegin",n)):(n=document.createElement("div"),n.id=t,n.innerHTML=e,document.body.insertAdjacentElement("afterbegin",n))}restoreSuspenseElement(e){const t=e.getAttribute("pp-original-state");if(e.hasAttribute("pp-suspense")&&t){const n=(e,t)=>{for(const n in t)t.hasOwnProperty(n)&&("textContent"===n?e.textContent=t[n]:"innerHTML"===n?e.innerHTML=t[n]:"disabled"===n?!0===t[n]?e.setAttribute("disabled","true"):e.removeAttribute("disabled"):e.setAttribute(n,t[n]));for(const n of Array.from(e.attributes))t.hasOwnProperty(n.name)||e.removeAttribute(n.name)},s=(e,t)=>{for(const s in t)if(t.hasOwnProperty(s))for(const t of Array.from(e.elements))if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-original-state")||"";if(e){if(this.isJsonLike(e)){const s=this.parseJson(e);n(t,s)}else i(t,e);t.removeAttribute("pp-original-state")}}},i=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},a=(e,t)=>{e instanceof HTMLFormElement?s(e,t):n(e,t)};try{const i=this.parseJson(t);if(i)if(e instanceof HTMLFormElement){const t=e.id;if(t){const e=document.querySelector(`[form="${t}"]`);if(e){const t=e.getAttribute("pp-original-state");if(t&&this.isJsonLike(t)){const s=this.parseJson(t);n(e,s)}}}const i=new FormData(e),a={};if(i.forEach(((e,t)=>{a[t]=e})),s(e,a),e.hasAttribute("pp-suspense")){const t=e.getAttribute("pp-suspense")||"";if(this.parseJson(t).disabled)for(const t of Array.from(e.elements))(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement)&&t.removeAttribute("disabled")}}else if(i.targets){i.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&a(s,n)}));const{targets:t,...s}=i;n(e,s)}else{const{empty:t,...s}=i;n(e,s)}}catch(e){}}e.querySelectorAll("[pp-suspense]").forEach((e=>this.restoreSuspenseElement(e))),e.removeAttribute("pp-original-state")}extractJson(e){const t=e?.match(/\{[\s\S]*\}/);return t?t[0]:null}getRedirectUrl(e){const t=e.match(this.redirectRegex);return t?t[1]:null}async fetchFileWithData(e,t,n,s={}){const i=new FormData,a=n.files;if(a)for(let e=0;e<a.length;e++)i.append("file[]",a[e]);i.append("callback",t);for(const e in s)s.hasOwnProperty(e)&&i.append(e,s[e]);const o=await this.fetch(e,{method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:i});return await o.text()}async handleSuspenseElement(e){let t=e.getAttribute("pp-suspense")||"";const n=(e,t)=>{for(const n in t)if(t.hasOwnProperty(n))for(const t of e.elements)if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-suspense")||"";if(e)if(this.isJsonLike(e)){const n=this.parseJson(e);"disabled"!==n.onsubmit&&this.updateElementAttributes(t,n),n.targets&&n.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&i(s,n)}))}else s(t,e)}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},i=(e,t)=>{e instanceof HTMLFormElement?n(e,t):this.updateElementAttributes(e,t)};try{if(t&&this.isJsonLike(t)){const s=this.parseJson(t);if(s)if(e instanceof HTMLFormElement){const t=new FormData(e),i={};t.forEach(((e,t)=>{i[t]=e})),s.disabled&&this.toggleFormElements(e,!0);const{disabled:a,...o}=s;this.updateElementAttributes(e,o),n(e,i)}else if(s.targets){s.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&i(s,n)}));const{targets:t,...n}=s;this.updateElementAttributes(e,n)}else{if("disabled"===s.empty&&""===e.value)return;const{empty:t,...n}=s;this.updateElementAttributes(e,n)}}else if(t)s(e,t);else if(e instanceof HTMLFormElement){const t=new FormData(e),s={};t.forEach(((e,t)=>{s[t]=e})),n(e,s)}}catch(e){}}toggleFormElements(e,t){Array.from(e.elements).forEach((e=>{(e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(e.disabled=t)}))}saveElementOriginalState(e){if(e.hasAttribute("pp-suspense")&&!e.hasAttribute("pp-original-state")){const t={};e.textContent&&(t.textContent=e.textContent.trim()),e.innerHTML&&(t.innerHTML=e.innerHTML.trim()),(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)&&(t.value=e.value);for(let n=0;n<e.attributes.length;n++){const s=e.attributes[n];t[s.name]=s.value}e.setAttribute("pp-original-state",JSON.stringify(t))}if(e instanceof HTMLFormElement){let t=null;const n=e.id;n&&(t=document.querySelector(`[form="${n}"]`)),n&&t||(t=Array.from(e.elements).find((e=>e instanceof HTMLButtonElement||e instanceof HTMLInputElement))),t&&(t.hasAttribute("pp-original-state")||this.saveElementOriginalState(t))}e.querySelectorAll("[pp-suspense]").forEach((e=>this.saveElementOriginalState(e)))}getUrlParams(){const e={};return new URLSearchParams(window.location.search).forEach(((t,n)=>{e[n]=t})),e}createFetchOptions(e){return{method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(e)}}parseCallback(e,t){let n={};const s=e.closest("form");if(s){new FormData(s).forEach(((e,t)=>{n[t]?Array.isArray(n[t])?n[t].push(e):n[t]=[n[t],e]:n[t]=e}))}else e instanceof HTMLInputElement?n=this.handleInputElement(e):(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(n[e.name]=e.value);const i=t.match(/(\w+)\((.*)\)/);if(i){const e=i[1];let t=i[2].trim();if(t.startsWith("{")&&t.endsWith("}"))try{const e=this.parseJson(t);"object"==typeof e&&null!==e&&(n={...n,...e})}catch(e){}else{const e=t.split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/).map((e=>e.trim().replace(/^['"]|['"]$/g,"")));n.args=e}return{funcName:e,data:n}}return{funcName:t,data:n}}handleInputElement(e){let t={};if(e.name)if("checkbox"===e.type)t[e.name]={value:e.value,checked:e.checked};else if("radio"===e.type){const n=document.querySelector(`input[name="${e.name}"]:checked`);t[e.name]=n?n.value:null}else t[e.name]=e.value;else"checkbox"===e.type||"radio"===e.type?t.value=e.checked:t.value=e.value;return t}resolveContext(e){let t=window;for(let n=0;n<e.length-1;n++)if(t=t[e[n]],!t)throw new Error(`Cannot find object ${e[n]} in the context.`);return{context:t,methodName:e[e.length-1]}}setCursorPosition(e,t){if(t.start)e.setSelectionRange(0,0);else if(t.end){const t=e.value.length||0;e.setSelectionRange(t,t)}else if(t.length){const n=parseInt(t.length,10)||0;e.setSelectionRange(n,n)}}handleInputAppendParams(e,t){const n=e.getAttribute("pp-append-params"),s=e.getAttribute("pp-append-params-sync");if("true"===n){if("true"===s){const t=e.name||e.id;if(t){const n=new URL(window.location.href),s=new URLSearchParams(n.search);s.has(t)&&(e.value=s.get(t)||"")}}e.addEventListener(t,(e=>{const t=e.currentTarget,n=t.value,s=new URL(window.location.href),i=new URLSearchParams(s.search),a=t.name||t.id;if(a){n?i.set(a,n):i.delete(a);const e=i.toString()?`${s.pathname}?${i.toString()}`:s.pathname;history.replaceState(null,"",e)}}))}}handleHiddenAttribute(){const e=document.querySelectorAll("[pp-visibility]"),t=document.querySelectorAll("[pp-display]");e.forEach((e=>this.handleVisibilityElementAttribute(e,"pp-visibility",this.handleElementVisibility))),t.forEach((e=>this.handleVisibilityElementAttribute(e,"pp-display",this.handleElementDisplay)))}handleVisibilityElementAttribute(e,t,n){const s=e.getAttribute(t);if(s)if(this.isJsonLike(s)){n(e,this.parseJson(s))}else{const n=this.parseTime(s);if(n>0){const s="pp-visibility"===t?"visibility":"display",i="visibility"===s?"hidden":"none";this.scheduleChange(e,n,s,i)}}}handleElementVisibility(e,t){this.handleElementChange(e,t,"visibility","hidden","visible")}handleElementDisplay(e,t){this.handleElementChange(e,t,"display","none","block")}handleElementChange(e,t,n,s,i){const a=t.start?this.parseTime(t.start):0,o=t.end?this.parseTime(t.end):0;a>0?(e.style[n]=s,this.scheduleChange(e,a,n,i),o>0&&this.scheduleChange(e,a+o,n,s)):o>0&&this.scheduleChange(e,o,n,s)}handleAnchorTag(e){e instanceof HTMLAnchorElement&&e.addEventListener("click",(async e=>{const t=e.currentTarget,n=t.getAttribute("href"),s=t.getAttribute("target");if(n&&"_blank"!==s&&!e.metaKey&&!e.ctrlKey&&(e.preventDefault(),!this.isNavigating)){this.isNavigating=!0;try{if(/^(https?:)?\/\//i.test(n)&&!n.startsWith(window.location.origin))window.location.href=n;else{const e=t.getAttribute("pp-append-params");if(n.startsWith("?")&&"true"===e){const e=new URL(window.location.href),t=new URLSearchParams(e.search);let s="";const[i,a]=n.split("#");a&&(s=`#${a}`);new URLSearchParams(i.split("?")[1]).forEach(((e,n)=>{t.set(n,e)}));const o=`${e.pathname}?${t.toString()}${s}`;history.pushState(null,"",o)}else{const[e,t]=n.split("#"),s=`${e}${t?`#${t}`:""}`;history.pushState(null,"",s)}const s=n.indexOf("#");if(-1!==s){const e=n.slice(s+1),t=document.getElementById(e);if(t)t.scrollIntoView({behavior:"smooth"});else{await this.handleNavigation();const t=document.getElementById(e);t&&t.scrollIntoView({behavior:"smooth"})}}else await this.handleNavigation()}}catch(e){}finally{this.isNavigating=!1}}}))}async handleNavigation(){try{const e=document.getElementById("loading-file-1B87E");if(e){const t=this.findLoadingElement(e,window.location.pathname);t&&await this.updateContentWithTransition(t)}const t=await this.fetch(window.location.href);if(!t.ok)return;const n=await t.text(),s=n.match(this.redirectRegex);if(s&&s[1])return void await this.redirect(s[1]);await this.updateDocumentContent(n)}catch(e){}}findLoadingElement(e,t){let n=t;for(;;){const t=e.querySelector(`div[pp-loading-url='${n}']`);if(t)return t;if("/"===n)break;const s=n.lastIndexOf("/");n=s<=0?"/":n.substring(0,s)}return e.querySelector("div[pp-loading-url='/' ]")}async updateContentWithTransition(e){const t=document.querySelector("[pp-loading-content='true']")||document.body;if(!t)return;const{fadeIn:n,fadeOut:s}=this.parseTransition(e);await this.fadeOut(t,s),t.innerHTML=e.innerHTML,this.fadeIn(t,n)}parseTransition(e){let t=250,n=250;const s=e.querySelector("[pp-loading-transition]")?.getAttribute("pp-loading-transition");if(s)try{const e=this.parseJson(s);t=this.parseTime(e.fadeIn??t),n=this.parseTime(e.fadeOut??n)}catch(e){}return{fadeIn:t,fadeOut:n}}fadeOut(e,t){return new Promise((n=>{e.style.transition=`opacity ${t}ms ease-out`,e.style.opacity="0",setTimeout((()=>{e.style.transition="",n()}),t)}))}fadeIn(e,t){e.style.transition=`opacity ${t}ms ease-in`,e.style.opacity="1",setTimeout((()=>{e.style.transition=""}),t)}async updateDocumentContent(e){const t=this.saveScrollPositions(),n=(new DOMParser).parseFromString(e,"text/html"),s="pp-dynamic-script",i="pp-dynamic-link";document.head.querySelectorAll("[pp-dynamic-meta]").forEach((e=>e.remove()));document.head.querySelectorAll("[pp-dynamic-link]").forEach((e=>e.remove()));document.head.querySelectorAll("[pp-dynamic-script]").forEach((e=>e.remove()));document.removeAllEventListeners("PPBodyLoaded"),await(async e=>{Array.from(e.head.children).forEach((e=>{const t=e.tagName;if("SCRIPT"===t&&e.hasAttribute(s)){const t=document.createElement("script");Array.from(e.attributes).forEach((e=>t.setAttribute(e.name,e.value))),e.textContent&&(t.textContent=e.textContent),document.head.appendChild(t)}else if("META"===t){if(e.getAttribute("charset")||"viewport"===e.getAttribute("name"))return;const t=e.name,n=e.getAttribute("property"),s=document.head.querySelector(t?`meta[name="${t}"]`:`meta[property="${n}"]`),i=document.head.querySelector("title");s?document.head.replaceChild(e.cloneNode(!0),s):i?.nextSibling?document.head.insertBefore(e.cloneNode(!0),i.nextSibling):document.head.appendChild(e.cloneNode(!0))}else if("TITLE"===t){const t=document.head.querySelector("title");t?document.head.replaceChild(e.cloneNode(!0),t):document.head.appendChild(e.cloneNode(!0))}else if("LINK"===t){const t=t=>{const n=document.head.querySelector('link[rel="icon"]');if(n)document.head.replaceChild(e.cloneNode(!0),n);else{const e=document.createElement("link");e.rel="icon",e.href=t,document.head.appendChild(e)}};if("icon"===e.getAttribute("rel")){t(e.href)}else if(e.hasAttribute(i)){const t=e.cloneNode(!0);document.head.appendChild(t)}}})),await this.populateDocumentBody(e)})(n),this.restoreScrollPositions(t),this.initBindings(),this.bindings.forEach((e=>e.update())),this.initializeAllReferencedProps(),this.attachWireFunctionEvents(),document.dispatchEvent(new Event("PPBodyLoaded"))}restoreScrollPositions(e){requestAnimationFrame((()=>{const t=e.window;t&&window.scrollTo(t.scrollLeft,t.scrollTop),document.querySelectorAll("*").forEach((t=>{const n=this.getElementKey(t);e[n]&&(t.scrollTop=e[n].scrollTop,t.scrollLeft=e[n].scrollLeft)}))}))}async populateDocumentBody(e){try{const t=e.body.cloneNode(!0);this.manageScriptTags(t),document.body.replaceWith(t)}catch(e){}}manageScriptTags(e,t){const n=e.querySelectorAll("script"),s=t?.querySelectorAll("script")||n;n.forEach(((e,t)=>{const n=document.createElement("script"),i=s[t]||e;Array.from(i.attributes).forEach((e=>{n.setAttribute(e.name,e.value)})),i.hasAttribute("src")||(n.textContent=i.textContent),e.parentNode?.replaceChild(n,e)}))}saveScrollPositions(){const e={window:{scrollTop:window.scrollY||document.documentElement.scrollTop,scrollLeft:window.scrollX||document.documentElement.scrollLeft}};return document.querySelectorAll("*").forEach((t=>{(t.scrollTop||t.scrollLeft)&&(e[this.getElementKey(t)]={scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})})),e}getElementKey(e){return e.id||e.className||e.tagName}async redirect(e){if(e)try{const t=new URL(e,window.location.origin);t.origin!==window.location.origin?window.location.href=e:(history.pushState(null,"",e),await this.handleNavigation())}catch(e){}}abortActiveRequest(){this.activeAbortController&&this.activeAbortController.abort()}async fetch(e,t,n=!1){let s;return n?(this.activeAbortController&&this.activeAbortController.abort(),this.activeAbortController=new AbortController,s=this.activeAbortController):s=new AbortController,fetch(e,{...t,signal:s.signal,headers:{...t?.headers,"X-Requested-With":"XMLHttpRequest"}})}isJsonLike(e){return"string"==typeof e&&((e=e.trim()).startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))}parseJson(e){try{return JSON5.parse(e)}catch(e){return null}}parseTime(e){if("number"==typeof e)return e;const t=e.match(/^(\d+)(ms|s|m)?$/);if(t){const e=parseInt(t[1],10);switch(t[2]||"ms"){case"ms":return e;case"s":return 1e3*e;case"m":return 60*e*1e3;default:return e}}return 0}scheduleChange(e,t,n,s){setTimeout((()=>{requestAnimationFrame((()=>{e.style[n]=s}))}),t)}observeDOMChanges(){new MutationObserver((e=>{for(const t of e)"childList"===t.type&&t.addedNodes.length>0&&this.attachWireFunctionEvents()})).observe(document.body,{childList:!0,subtree:!0})}async fetchFunction(e,t={},n=!1){try{const s={callback:e,...t},i=window.location.href;let a;if(Object.keys(s).some((e=>{const t=s[e];return t instanceof File||t instanceof FileList&&t.length>0}))){const e=new FormData;Object.keys(s).forEach((t=>{const n=s[t];n instanceof File?e.append(t,n):n instanceof FileList?Array.from(n).forEach((n=>e.append(t,n))):e.append(t,n)})),a={method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:e}}else a=this.createFetchOptions(s);const o=await this.fetch(i,a,n);if(!o.ok)throw new Error(`Fetch failed with status: ${o.status} ${o.statusText}`);const r=await o.text();try{return JSON.parse(r)}catch{return r}}catch(e){throw new Error("Failed to fetch data.")}}async sync(...e){try{const t=this.saveScrollPositions();this.saveState();const n=e.length>0?e.map((e=>`pp-sync="${e}"`)):['pp-sync="true"'],s=this.createFetchOptions({secondRequestC69CD:!0,...this.getUrlParams()}),i=await this.fetch(window.location.href,s),a=await i.text(),o=(new DOMParser).parseFromString(a,"text/html");n.forEach((e=>{const t=document.querySelectorAll(`[${e}]`),n=o.body.querySelectorAll(`[${e}]`);t.forEach(((e,t)=>{const s=n[t];s&&(e.innerHTML=s.innerHTML,this.reRunScripts(e))}))})),this.restoreState(),this.restoreScrollPositions(t)}catch(e){}}async fetchAndUpdateBodyContent(){const e=this.createFetchOptions({secondRequestC69CD:!0,...this.getUrlParams()});this.abortActiveRequest();const t=await this.fetch(window.location.href,e,!0),n=await t.text();await this.updateBodyContent(n)}reRunScripts(e){e.querySelectorAll("script").forEach((e=>{const t=document.createElement("script");Array.from(e.attributes).forEach((e=>{t.setAttribute(e.name,e.value)})),e.hasAttribute("src")||(t.textContent=e.textContent),e.parentNode?.replaceChild(t,e)}))}copyCode(e,t,n,s,i="img",a=2e3){if(!(e instanceof HTMLElement))return;const o=e.closest(`.${t}`)?.querySelector("pre code"),r=o?.textContent?.trim()||"";r?navigator.clipboard.writeText(r).then((()=>{const t=e.querySelector(i);if(t)for(const[e,n]of Object.entries(s))e in t?t[e]=n:t.setAttribute(e,n);setTimeout((()=>{if(t)for(const[e,s]of Object.entries(n))e in t?t[e]=s:t.setAttribute(e,s)}),a)}),(()=>{alert("Failed to copy command to clipboard")})):alert("Failed to find the code block to copy")}getCookie(e){return document.cookie.split("; ").find((t=>t.startsWith(e+"=")))?.split("=")[1]||null}}class PPHPLocalStore{static instance=null;state;listeners;pphp;STORAGE_KEY;constructor(e={}){this.state=e,this.listeners=[],this.pphp=PPHP.instance,this.STORAGE_KEY=this.pphp.getCookie("pphp_local_store_key")||"pphp_local_store_59e13",this.loadState()}static getInstance(e={}){return PPHPLocalStore.instance||(PPHPLocalStore.instance=new PPHPLocalStore(e)),PPHPLocalStore.instance}setState(e,t=!1){if(this.state={...this.state,...e},this.listeners.forEach((e=>e(this.state))),this.saveState(),t){const e=localStorage.getItem(this.STORAGE_KEY);e&&this.pphp.fetchFunction(this.STORAGE_KEY,{[this.STORAGE_KEY]:e})}}saveState(){localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.state))}loadState(){const e=localStorage.getItem(this.STORAGE_KEY);e&&(this.state=this.pphp.parseJson(e),this.listeners.forEach((e=>e(this.state))))}resetState(e,t=!1){if(e?(delete this.state[e],this.saveState()):(this.state={},localStorage.removeItem(this.STORAGE_KEY)),this.listeners.forEach((e=>e(this.state))),t){const t=e?localStorage.getItem(this.STORAGE_KEY):null;this.pphp.fetchFunction(this.STORAGE_KEY,{[this.STORAGE_KEY]:t})}}}
2
- // Initialize the PPHP instance
3
- document.addEventListener("PPBodyLoaded", () => {
4
- PPHP.instance.attachWireFunctionEvents();
5
- PPHP.instance.observeDOMChanges();
6
- });
7
- // Dispatch the PPBodyLoaded event when the DOM is fully loaded
1
+ (()=>{const e=EventTarget.prototype.addEventListener,t=EventTarget.prototype.removeEventListener,n=new Map;EventTarget.prototype.addEventListener=function(t,s,i){n.has(this)||n.set(this,new Map);const a=n.get(this).get(t)||new Set;a.add(s),n.get(this).set(t,a),e.call(this,t,s,i)},EventTarget.prototype.removeEventListener=function(e,s,i){if(n.has(this)&&n.get(this).has(e)){const t=n.get(this).get(e);t&&(t.delete(s),0===t.size&&n.get(this).delete(e))}t.call(this,e,s,i)},EventTarget.prototype.removeAllEventListeners=function(e){if(n.has(this)&&n.get(this).has(e)){const s=n.get(this).get(e);s&&(s.forEach((n=>{t.call(this,e,n)})),n.get(this).delete(e))}}})();class PPHP{props={};static _instance;isNavigating=!1;responseData=null;activeAbortController=null;rawProps={};bindings=[];state={checkedElements:new Set};builtInProps;eventHandlers;redirectRegex=/redirect_7F834\s*=\s*(\/[^\s]*)/;constructor(){this.eventHandlers=new Set(["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onwheel","onkeypress","onkeydown","onkeyup","onfocus","onblur","onchange","oninput","onselect","onsubmit","onreset","onresize","onscroll","onload","onunload","onabort","onerror","onbeforeunload","oncopy","oncut","onpaste","ondrag","ondragstart","ondragend","ondragover","ondragenter","ondragleave","ondrop","oncontextmenu","ontouchstart","ontouchmove","ontouchend","ontouchcancel","onpointerdown","onpointerup","onpointermove","onpointerover","onpointerout","onpointerenter","onpointerleave","onpointercancel"]),this.builtInProps=new Set(["length","charAt","charCodeAt","codePointAt","concat","includes","endsWith","indexOf","lastIndexOf","localeCompare","match","matchAll","normalize","padEnd","padStart","repeat","replace","replaceAll","search","slice","split","substring","substr","startsWith","toLocaleLowerCase","toLocaleUpperCase","toLowerCase","toString","toUpperCase","trim","trimEnd","trimStart","valueOf"]),this.handlePopState(),this.props=this.makeReactive(this.rawProps)}static get instance(){return PPHP._instance||(PPHP._instance=new PPHP),PPHP._instance}extractDependencies(e){return new Set(e.match(/\b[a-zA-Z_][a-zA-Z0-9_]*\b/g)||[])}formatValue(e){return"boolean"==typeof e?e?"true":"false":e&&"object"==typeof e?Object.keys(e).length>0?JSON.stringify(e,null,2):"":e?.toString()||""}registerBinding(e,t,n="text",s){const i=this.extractDependencies(t),a=this.makeSafeEvaluator(t);if(/^\s*[\w\.]+\s*=(?!=)/.test(t))return;if("value"===s||"checked"===s){const t=()=>{try{const t=a(this.props),n=this.formatValue(t);"value"===s?e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement?e.value=n:e.setAttribute("value",n):"checked"===s&&(e instanceof HTMLInputElement?e.checked="true"===n:e.setAttribute("checked",n))}catch(e){}};return void this.bindings.push({dependencies:i,update:t})}this.bindings.push({dependencies:i,update:()=>{try{if(s){const t="__static_"+s;let n=e[t];if(void 0===n){n=e.getAttribute(s)||"",e[t]=n;(n.match(/\{\{\s*([\s\S]+?)\s*\}\}/gu)||[]).forEach((e=>{const t=e.replace(/\{\{\s*|\}\}/gu,"").trim();this.extractDependencies(t).forEach((e=>i.add(e)))}))}const a=n.replace(/\{\{\s*([\s\S]+?)\s*\}\}/gu,((e,t)=>{try{const e=this.makeSafeEvaluator(t)(this.props);return this.formatValue(e)}catch(e){return""}}));e.setAttribute(s,a)}else{const t=a(this.props),s=this.formatValue(t);switch(n){case"value":e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement?e.value=s:e.setAttribute("value",s);break;case"checked":e instanceof HTMLInputElement?e.checked="true"===s:e.setAttribute("checked",s);break;case"text":default:e.textContent=s;break}}}catch(e){}}})}initBindings(){this.bindings=[],document.querySelectorAll("[pp-bind]").forEach((e=>{const t=e.getAttribute("pp-bind");t&&this.registerBinding(e,t,"text")})),document.querySelectorAll("[pp-bind-expr]").forEach((e=>{const t=e.getAttribute("pp-bind-expr");t&&this.registerBinding(e,t,"text")})),document.body.querySelectorAll("*").forEach((e=>{Array.from(e.attributes).forEach((t=>{if(!t.name.startsWith("pp-bind-"))return;let n=t.value.replace(/&quot;/g,'"').replace(/&#039;/g,"'").replace(/&amp;/g,"&").replace(/^{{\s*|\s*}}$/g,"");const s=t.name.replace(/^(pp-bind-)+/,"");let i="text";"value"===s&&(i="value"),"checked"===s&&(i="checked"),this.registerBinding(e,n,i,s)}))}))}safeNull=new Proxy((()=>""),{get:(e,t)=>"toString"===t||"valueOf"===t?()=>"":this.safeNull,apply:()=>""});safeTag=(e,...t)=>e.reduce(((e,n,s)=>{const i=t[s];return e+n+(null==i||"object"==typeof i?"":i)}),"");makeSafeEvaluator(e){const t=e.trim();if(t.startsWith("`")&&t.endsWith("`")){const e=t.slice(1,-1),n=/\$\{\s*([^}]+?)\s*\}/g,s=new Set;let i;for(;i=n.exec(e);){const e=i[1];this.extractDependencies(e).forEach((e=>s.add(e)))}const a=Array.from(s),o=new Function(...a,"safeTag",`return safeTag\`${e}\``);return e=>{const t=a.map((t=>void 0===e[t]?this.safeNull:e[t]));return o(...t,this.safeTag.bind(this))}}const n=e.replace(/(["'])(?:(?=(\\?))\2.)*?\1/g,""),s=new Set(n.match(/\b[a-zA-Z_][a-zA-Z0-9_]*\b/g)||[]);s.delete("safeTag");const i=Array.from(s).map((t=>`\n const ${t} = ctx["${t}"] !== undefined \n ? ctx["${t}"] \n : (typeof window !== "undefined" && window["${t}"] !== undefined \n ? window["${t}"] \n : ${new RegExp(`\\b${t}\\.`).test(e)?"{}":"void 0"});\n if (typeof window !== "undefined" && window["${t}"] !== ${t}) {\n window["${t}"] = ${t};\n }\n `)).join("\n"),a=/^\s*[\w\.]+\s*=(?!=)/.test(e),o=new Function("ctx","safeTag",`\n "use strict";\n ${i}\n try {\n ${a?e+"; return '';":"const result = "+e+"; return result === undefined || result === null ? '' : result;"}\n } catch (e) {\n return "";\n }\n `);return e=>o(e,this.safeTag.bind(this))}makeReactive(e,t=[]){const n=this;if(e instanceof Map||e instanceof Set)return e;const s=new Proxy(e,{get(e,s){const i=e[s];return"object"==typeof i&&null!==i?n.makeReactive(i,[...t,s.toString()]):i},set:(e,t,s)=>(e[t]=s,n.bindings.forEach((e=>{e.dependencies.has(t)&&e.update()})),!0)});return"loading"===document.readyState&&document.addEventListener("DOMContentLoaded",(()=>{this.initBindings(),this.bindings.forEach((e=>e.update())),this.initializeAllReferencedProps()})),s}handlePopState(){window.addEventListener("popstate",(async()=>{await this.handleNavigation()}))}attachWireFunctionEvents(){this.handleHiddenAttribute();document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((e=>{if(this.handleAnchorTag(e),Array.from(e.attributes).filter((e=>this.eventHandlers.has(e.name))).forEach((t=>{const n=t.name.slice(2),s=t.value;e instanceof HTMLInputElement&&this.handleInputAppendParams(e,n),s&&(e.removeAttribute(t.name),this.handleDebounce(e,n,s))})),e instanceof HTMLFormElement){const t=e.getAttribute("onsubmit");t&&(e.removeAttribute("onsubmit"),this.handleDebounce(e,"submit",t))}}))}async handleDebounce(e,t,n){e.removeEventListener(t,(()=>{}));const s=e.getAttribute("pp-debounce")||"",i=e.getAttribute("pp-before-request")||"",a=e.getAttribute("pp-after-request")||"",o=async t=>{t.preventDefault();try{i&&await this.invokeHandler(e,i,t),await this.invokeHandler(e,n,t),a&&"@close"!==a&&await this.invokeHandler(e,a,t),this.handlerAutofocusAttribute()}catch(e){}};if(s){const n=this.parseTime(s),i=this.debounce(o,n);e instanceof HTMLFormElement&&"submit"===t?e.addEventListener(t,(e=>{e.preventDefault(),i(e)})):e.addEventListener(t,i)}else e.addEventListener(t,o)}debounce(e,t=300,n=!1){let s;return function(...i){const a=this;s&&clearTimeout(s),s=setTimeout((()=>{s=null,n||e.apply(a,i)}),t),n&&!s&&e.apply(a,i)}}handlerAutofocusAttribute(){const e=document.activeElement;if(e&&e!==document.body)return;const t=this.state?.focusId;if(!t)return;const n=document.querySelectorAll("[pp-autofocus]");let s=!1;n.forEach((e=>{if(s)return;const t=e.getAttribute("pp-autofocus");if(!t||!this.isJsonLike(t))return;const n=this.parseJson(t);if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){const t=["text","search","tel","url","password"];if(e instanceof HTMLInputElement)if(t.includes(e.type))if("number"===e.type){e.type="text";const t=e.value.length||0;e.setSelectionRange(t,t),e.type="number"}else this.setCursorPosition(e,n);else;else e instanceof HTMLTextAreaElement&&this.setCursorPosition(e,n)}e.focus(),s=!0}))}initializeAllReferencedProps(){const e=/\b([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)\b/g,t=new Set;document.body.querySelectorAll("*").forEach((n=>{for(const s of Array.from(n.attributes)){if(!s.name.startsWith("pp-bind"))continue;const n=s.value.replace(/&quot;/g,'"').replace(/&#039;/g,"'").replace(/&amp;/g,"&").replace(/^{{\s*|\s*}}$/g,"");let i;for(;i=e.exec(n);){const e=i[1];if(e.indexOf(".")<0)continue;const[n]=e.split(".");this.builtInProps.has(n)||t.add(e)}}}));for(const e of t){const t=e.split(".");let n=this.props;for(let e=0;e<t.length;e++){const s=t[e],i=e===t.length-1;if(this.builtInProps.has(s))break;s in n||(n[s]=i?void 0:{}),n=n[s]}}}async invokeHandler(e,t,n){try{const s=t.match(/^(\w+(\.\w+)*)\((.*)\)$/);if(s){const i=s[1],a=s[3],o=i.split("."),{context:r,methodName:c}=this.resolveContext(o);if("function"==typeof r[c])if(this.isJsonLike(a)){const t=this.parseJson(a);t.element=e,t.event=n;const s=[t];await r[c](...s)}else new Function("event",t).call(e,n);else await this.handleParsedCallback(e,t)}else if(t.includes("=")){const s=t.match(/^\s*([\w\.]+)\s*=/);if(s){const e=s[1];if(e.includes(".")){const t=e.split(".");let n=pphp.props;for(let e=0;e<t.length-1;e++)t[e]in n||(n[t[e]]={}),n=n[t[e]]}else e in pphp.props||(pphp.props[e]=void 0)}new Function("event","props",`\n with (new Proxy(props, {\n get(target, key) {\n return key in target ? target[key] : undefined;\n },\n set(target, key, value) {\n target[key] = value;\n return true;\n }\n })) {\n ${t}\n }\n `).call(e,n,pphp.props)}else await this.handleParsedCallback(e,t)}catch(e){}}async handleParsedCallback(e,t){const{funcName:n,data:s}=this.parseCallback(e,t);if(!n)return;const i=this[n],a=window[n];let o;if("function"==typeof i?o=i:"function"==typeof a&&(o=a),"function"==typeof o){const t=e.hasAttribute("pp-after-request"),n=Array.isArray(s.args)?s.args:[],i=this.responseData?this.parseJson(this.responseData):{response:this.responseData};let a={args:n,element:e,data:s};t&&(a={...a,...i}),await o.call(this,a)}else this.responseData=null,this.responseData=await this.handleUndefinedFunction(e,n,s)}async handleUndefinedFunction(e,t,n){const s={callback:t,...n},i=this.createFetchOptions(s),a=this.createFetchOptions({secondRequestC69CD:!0,...this.getUrlParams()});try{this.saveElementOriginalState(e),this.handleSuspenseElement(e);const s=new URL(window.location.href);let o="",r="",c={success:!1};const l=e.querySelector("input[type='file']");if(l){if(o=await this.fetchFileWithData(s.href,t,l,n),r=this.extractJson(o)||"",r)try{c=this.parseJson(r)}catch(e){}}else{const e=await this.fetch(s.href,i);if(o=await e.text(),this.getRedirectUrl(o))return void await this.redirect(this.getRedirectUrl(o)||"");if(r=this.extractJson(o)||"",r)try{c=this.parseJson(r)}catch(e){}}const h=e.getAttribute("pp-before-request")||"",u=e.getAttribute("pp-after-request")||"";if((h||u&&c.success)&&this.restoreSuspenseElement(e),h||u){let e="";if(c.success){e=o.replace(r,"")}else e=o;if(this.appendAfterbegin(e),!u&&!c.success)return}if(u&&c.success){this.handleAfterRequest(u,r);const e=o.replace(r,"");return this.appendAfterbegin(e),r}if("@close"===u)return c.success?r:void 0;const d=await this.fetch(s.href,a),p=await d.text();if(this.getRedirectUrl(p))return void await this.redirect(this.getRedirectUrl(p)||"");await this.handleResponseRedirectOrUpdate(o,p,r,c)}catch(e){}}handleAfterRequest(e,t){if(!this.isJsonLike(e))return;const n=this.parseJson(e),s=t?this.parseJson(t):null,i=n.targets;Array.isArray(i)&&i.forEach((e=>{const{id:t,...n}=e,i=document.querySelector(t);let a={};if(s){for(const t in n)if(n.hasOwnProperty(t))switch(t){case"innerHTML":case"outerHTML":case"textContent":case"innerText":"response"===n[t]&&(a[t]=e.responseKey?s[e.responseKey]:s.response);break;default:a[t]=n[t];break}}else a=n;i&&this.updateElementAttributes(i,a)}))}async handleResponseRedirectOrUpdate(e,t,n,s){const i=this.getUpdatedHTMLContent(e,n,s),a=(new DOMParser).parseFromString(t,"text/html");i&&a.body.insertAdjacentElement("afterbegin",i),this.updateBodyContent(a.body.outerHTML)}getUpdatedHTMLContent(e,t,n){const s=document.createElement("div");if(s.id="afterbegin-8D95D",n&&t?.success){const t=e.replace(n,"");s.innerHTML=t}else s.innerHTML=e;return s.innerHTML?s:null}async updateBodyContent(e){const t=this.saveScrollPositions();this.saveState();const n=(new DOMParser).parseFromString(e,"text/html");await this.appendCallbackResponse(n),this.restoreState(),this.restoreScrollPositions(t),this.attachWireFunctionEvents()}restoreState(){if(this.state.focusId){const e=document.getElementById(this.state.focusId)||document.querySelector(`[name="${this.state.focusId}"]`);if(e instanceof HTMLInputElement){const t=e.value.length||0;void 0!==this.state.focusSelectionStart&&null!==this.state.focusSelectionEnd&&e.setSelectionRange(t,t),this.state.focusValue&&("checkbox"===e.type||"radio"===e.type?e.checked=!!this.state.focusChecked:"number"===e.type||"email"===e.type?(e.type="text",e.setSelectionRange(t,t),e.type="number"===e.type?"number":"email"):"date"===e.type||"month"===e.type||"week"===e.type||"time"===e.type||"datetime-local"===e.type||"color"===e.type||"file"===e.type||""!==e.value&&(e.value=this.state.focusValue)),e.focus()}else if(e instanceof HTMLTextAreaElement){const t=e.value.length||0;void 0!==this.state.focusSelectionStart&&null!==this.state.focusSelectionEnd&&e.setSelectionRange(t,t),this.state.focusValue&&""!==e.value&&(e.value=this.state.focusValue),e.focus()}else e instanceof HTMLSelectElement&&(this.state.focusValue&&""!==e.value&&(e.value=this.state.focusValue),e.focus())}this.state.checkedElements.forEach((e=>{const t=document.getElementById(e);t&&(t.checked=!0)}))}async appendCallbackResponse(e){const t=e.getElementById("afterbegin-8D95D");if(t){const e=document.getElementById("afterbegin-8D95D");e?e.innerHTML=t.innerHTML:document.body.insertAdjacentHTML("afterbegin",t.outerHTML)}await this.populateDocumentBody(e)}saveState(){const e=document.activeElement;this.state.focusId=e?.id||e?.name,this.state.focusValue=e?.value,this.state.focusChecked=e?.checked,this.state.focusType=e?.type,this.state.focusSelectionStart=e?.selectionStart,this.state.focusSelectionEnd=e?.selectionEnd,this.state.isSuspense=e.hasAttribute("pp-suspense"),this.state.checkedElements.clear(),document.querySelectorAll('input[type="checkbox"]:checked').forEach((e=>{this.state.checkedElements.add(e.id||e.name)})),document.querySelectorAll('input[type="radio"]:checked').forEach((e=>{this.state.checkedElements.add(e.id||e.name)}))}updateElementAttributes(e,t){for(const n in t)if(t.hasOwnProperty(n))switch(n){case"innerHTML":case"outerHTML":case"textContent":case"innerText":e[n]=this.decodeHTML(t[n]);break;case"insertAdjacentHTML":e.insertAdjacentHTML(t.position||"beforeend",this.decodeHTML(t[n].html));break;case"insertAdjacentText":e.insertAdjacentText(t.position||"beforeend",this.decodeHTML(t[n].text));break;case"setAttribute":e.setAttribute(t.attrName,this.decodeHTML(t[n]));break;case"removeAttribute":e.removeAttribute(t[n]);break;case"className":e.className=this.decodeHTML(t[n]);break;case"classList.add":e.classList.add(...this.decodeHTML(t[n]).split(","));break;case"classList.remove":e.classList.remove(...this.decodeHTML(t[n]).split(","));break;case"classList.toggle":e.classList.toggle(this.decodeHTML(t[n]));break;case"classList.replace":const[s,i]=this.decodeHTML(t[n]).split(",");e.classList.replace(s,i);break;case"dataset":e.dataset[t.attrName]=this.decodeHTML(t[n]);break;case"style":Object.assign(e.style,t[n]);break;case"value":e.value=this.decodeHTML(t[n]);break;case"checked":e.checked=t[n];break;default:e.setAttribute(n,this.decodeHTML(t[n]))}}decodeHTML(e){const t=document.createElement("textarea");return t.innerHTML=e,t.value}appendAfterbegin(e){if(!e)return;const t="afterbegin-8D95D";let n=document.getElementById(t);n?(n.innerHTML=e,document.body.insertAdjacentElement("afterbegin",n)):(n=document.createElement("div"),n.id=t,n.innerHTML=e,document.body.insertAdjacentElement("afterbegin",n))}restoreSuspenseElement(e){const t=e.getAttribute("pp-original-state");if(e.hasAttribute("pp-suspense")&&t){const n=(e,t)=>{for(const n in t)t.hasOwnProperty(n)&&("textContent"===n?e.textContent=t[n]:"innerHTML"===n?e.innerHTML=t[n]:"disabled"===n?!0===t[n]?e.setAttribute("disabled","true"):e.removeAttribute("disabled"):e.setAttribute(n,t[n]));for(const n of Array.from(e.attributes))t.hasOwnProperty(n.name)||e.removeAttribute(n.name)},s=(e,t)=>{for(const s in t)if(t.hasOwnProperty(s))for(const t of Array.from(e.elements))if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-original-state")||"";if(e){if(this.isJsonLike(e)){const s=this.parseJson(e);n(t,s)}else i(t,e);t.removeAttribute("pp-original-state")}}},i=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},a=(e,t)=>{e instanceof HTMLFormElement?s(e,t):n(e,t)};try{const i=this.parseJson(t);if(i)if(e instanceof HTMLFormElement){const t=e.id;if(t){const e=document.querySelector(`[form="${t}"]`);if(e){const t=e.getAttribute("pp-original-state");if(t&&this.isJsonLike(t)){const s=this.parseJson(t);n(e,s)}}}const i=new FormData(e),a={};if(i.forEach(((e,t)=>{a[t]=e})),s(e,a),e.hasAttribute("pp-suspense")){const t=e.getAttribute("pp-suspense")||"";if(this.parseJson(t).disabled)for(const t of Array.from(e.elements))(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement)&&t.removeAttribute("disabled")}}else if(i.targets){i.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&a(s,n)}));const{targets:t,...s}=i;n(e,s)}else{const{empty:t,...s}=i;n(e,s)}}catch(e){}}e.querySelectorAll("[pp-suspense]").forEach((e=>this.restoreSuspenseElement(e))),e.removeAttribute("pp-original-state")}extractJson(e){const t=e?.match(/\{[\s\S]*\}/);return t?t[0]:null}getRedirectUrl(e){const t=e.match(this.redirectRegex);return t?t[1]:null}async fetchFileWithData(e,t,n,s={}){const i=new FormData,a=n.files;if(a)for(let e=0;e<a.length;e++)i.append("file[]",a[e]);i.append("callback",t);for(const e in s)s.hasOwnProperty(e)&&i.append(e,s[e]);const o=await this.fetch(e,{method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:i});return await o.text()}async handleSuspenseElement(e){let t=e.getAttribute("pp-suspense")||"";const n=(e,t)=>{for(const n in t)if(t.hasOwnProperty(n))for(const t of e.elements)if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-suspense")||"";if(e)if(this.isJsonLike(e)){const n=this.parseJson(e);"disabled"!==n.onsubmit&&this.updateElementAttributes(t,n),n.targets&&n.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&i(s,n)}))}else s(t,e)}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},i=(e,t)=>{e instanceof HTMLFormElement?n(e,t):this.updateElementAttributes(e,t)};try{if(t&&this.isJsonLike(t)){const s=this.parseJson(t);if(s)if(e instanceof HTMLFormElement){const t=new FormData(e),i={};t.forEach(((e,t)=>{i[t]=e})),s.disabled&&this.toggleFormElements(e,!0);const{disabled:a,...o}=s;this.updateElementAttributes(e,o),n(e,i)}else if(s.targets){s.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&i(s,n)}));const{targets:t,...n}=s;this.updateElementAttributes(e,n)}else{if("disabled"===s.empty&&""===e.value)return;const{empty:t,...n}=s;this.updateElementAttributes(e,n)}}else if(t)s(e,t);else if(e instanceof HTMLFormElement){const t=new FormData(e),s={};t.forEach(((e,t)=>{s[t]=e})),n(e,s)}}catch(e){}}toggleFormElements(e,t){Array.from(e.elements).forEach((e=>{(e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(e.disabled=t)}))}saveElementOriginalState(e){if(e.hasAttribute("pp-suspense")&&!e.hasAttribute("pp-original-state")){const t={};e.textContent&&(t.textContent=e.textContent.trim()),e.innerHTML&&(t.innerHTML=e.innerHTML.trim()),(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)&&(t.value=e.value);for(let n=0;n<e.attributes.length;n++){const s=e.attributes[n];t[s.name]=s.value}e.setAttribute("pp-original-state",JSON.stringify(t))}if(e instanceof HTMLFormElement){let t=null;const n=e.id;n&&(t=document.querySelector(`[form="${n}"]`)),n&&t||(t=Array.from(e.elements).find((e=>e instanceof HTMLButtonElement||e instanceof HTMLInputElement))),t&&(t.hasAttribute("pp-original-state")||this.saveElementOriginalState(t))}e.querySelectorAll("[pp-suspense]").forEach((e=>this.saveElementOriginalState(e)))}getUrlParams(){const e={};return new URLSearchParams(window.location.search).forEach(((t,n)=>{e[n]=t})),e}createFetchOptions(e){return{method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(e)}}parseCallback(e,t){let n={};const s=e.closest("form");if(s){new FormData(s).forEach(((e,t)=>{n[t]?Array.isArray(n[t])?n[t].push(e):n[t]=[n[t],e]:n[t]=e}))}else e instanceof HTMLInputElement?n=this.handleInputElement(e):(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(n[e.name]=e.value);const i=t.match(/(\w+)\((.*)\)/);if(i){const e=i[1];let t=i[2].trim();if(t.startsWith("{")&&t.endsWith("}"))try{const e=this.parseJson(t);"object"==typeof e&&null!==e&&(n={...n,...e})}catch(e){}else{const e=t.split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/).map((e=>e.trim().replace(/^['"]|['"]$/g,"")));n.args=e}return{funcName:e,data:n}}return{funcName:t,data:n}}handleInputElement(e){let t={};if(e.name)if("checkbox"===e.type)t[e.name]={value:e.value,checked:e.checked};else if("radio"===e.type){const n=document.querySelector(`input[name="${e.name}"]:checked`);t[e.name]=n?n.value:null}else t[e.name]=e.value;else"checkbox"===e.type||"radio"===e.type?t.value=e.checked:t.value=e.value;return t}resolveContext(e){let t=window;for(let n=0;n<e.length-1;n++)if(t=t[e[n]],!t)throw new Error(`Cannot find object ${e[n]} in the context.`);return{context:t,methodName:e[e.length-1]}}setCursorPosition(e,t){if(t.start)e.setSelectionRange(0,0);else if(t.end){const t=e.value.length||0;e.setSelectionRange(t,t)}else if(t.length){const n=parseInt(t.length,10)||0;e.setSelectionRange(n,n)}}handleInputAppendParams(e,t){const n=e.getAttribute("pp-append-params"),s=e.getAttribute("pp-append-params-sync");if("true"===n){if("true"===s){const t=e.name||e.id;if(t){const n=new URL(window.location.href),s=new URLSearchParams(n.search);s.has(t)&&(e.value=s.get(t)||"")}}e.addEventListener(t,(e=>{const t=e.currentTarget,n=t.value,s=new URL(window.location.href),i=new URLSearchParams(s.search),a=t.name||t.id;if(a){n?i.set(a,n):i.delete(a);const e=i.toString()?`${s.pathname}?${i.toString()}`:s.pathname;history.replaceState(null,"",e)}}))}}handleHiddenAttribute(){const e=document.querySelectorAll("[pp-visibility]"),t=document.querySelectorAll("[pp-display]");e.forEach((e=>this.handleVisibilityElementAttribute(e,"pp-visibility",this.handleElementVisibility))),t.forEach((e=>this.handleVisibilityElementAttribute(e,"pp-display",this.handleElementDisplay)))}handleVisibilityElementAttribute(e,t,n){const s=e.getAttribute(t);if(s)if(this.isJsonLike(s)){n(e,this.parseJson(s))}else{const n=this.parseTime(s);if(n>0){const s="pp-visibility"===t?"visibility":"display",i="visibility"===s?"hidden":"none";this.scheduleChange(e,n,s,i)}}}handleElementVisibility(e,t){this.handleElementChange(e,t,"visibility","hidden","visible")}handleElementDisplay(e,t){this.handleElementChange(e,t,"display","none","block")}handleElementChange(e,t,n,s,i){const a=t.start?this.parseTime(t.start):0,o=t.end?this.parseTime(t.end):0;a>0?(e.style[n]=s,this.scheduleChange(e,a,n,i),o>0&&this.scheduleChange(e,a+o,n,s)):o>0&&this.scheduleChange(e,o,n,s)}handleAnchorTag(e){e instanceof HTMLAnchorElement&&e.addEventListener("click",(async e=>{const t=e.currentTarget,n=t.getAttribute("href"),s=t.getAttribute("target");if(n&&"_blank"!==s&&!e.metaKey&&!e.ctrlKey&&(e.preventDefault(),!this.isNavigating)){this.isNavigating=!0;try{if(/^(https?:)?\/\//i.test(n)&&!n.startsWith(window.location.origin))window.location.href=n;else{const e=t.getAttribute("pp-append-params");if(n.startsWith("?")&&"true"===e){const e=new URL(window.location.href),t=new URLSearchParams(e.search);let s="";const[i,a]=n.split("#");a&&(s=`#${a}`);new URLSearchParams(i.split("?")[1]).forEach(((e,n)=>{t.set(n,e)}));const o=`${e.pathname}?${t.toString()}${s}`;history.pushState(null,"",o)}else{const[e,t]=n.split("#"),s=`${e}${t?`#${t}`:""}`;history.pushState(null,"",s)}const s=n.indexOf("#");if(-1!==s){const e=n.slice(s+1),t=document.getElementById(e);if(t)t.scrollIntoView({behavior:"smooth"});else{await this.handleNavigation();const t=document.getElementById(e);t&&t.scrollIntoView({behavior:"smooth"})}}else await this.handleNavigation()}}catch(e){}finally{this.isNavigating=!1}}}))}async handleNavigation(){try{const e=document.getElementById("loading-file-1B87E");if(e){const t=this.findLoadingElement(e,window.location.pathname);t&&await this.updateContentWithTransition(t)}const t=await this.fetch(window.location.href);if(!t.ok)return;const n=await t.text(),s=n.match(this.redirectRegex);if(s&&s[1])return void await this.redirect(s[1]);await this.updateDocumentContent(n)}catch(e){}}findLoadingElement(e,t){let n=t;for(;;){const t=e.querySelector(`div[pp-loading-url='${n}']`);if(t)return t;if("/"===n)break;const s=n.lastIndexOf("/");n=s<=0?"/":n.substring(0,s)}return e.querySelector("div[pp-loading-url='/' ]")}async updateContentWithTransition(e){const t=document.querySelector("[pp-loading-content='true']")||document.body;if(!t)return;const{fadeIn:n,fadeOut:s}=this.parseTransition(e);await this.fadeOut(t,s),t.innerHTML=e.innerHTML,this.fadeIn(t,n)}parseTransition(e){let t=250,n=250;const s=e.querySelector("[pp-loading-transition]")?.getAttribute("pp-loading-transition");if(s)try{const e=this.parseJson(s);t=this.parseTime(e.fadeIn??t),n=this.parseTime(e.fadeOut??n)}catch(e){}return{fadeIn:t,fadeOut:n}}fadeOut(e,t){return new Promise((n=>{e.style.transition=`opacity ${t}ms ease-out`,e.style.opacity="0",setTimeout((()=>{e.style.transition="",n()}),t)}))}fadeIn(e,t){e.style.transition=`opacity ${t}ms ease-in`,e.style.opacity="1",setTimeout((()=>{e.style.transition=""}),t)}async updateDocumentContent(e){const t=this.saveScrollPositions(),n=(new DOMParser).parseFromString(e,"text/html"),s="pp-dynamic-script",i="pp-dynamic-link";document.head.querySelectorAll("[pp-dynamic-meta]").forEach((e=>e.remove()));document.head.querySelectorAll("[pp-dynamic-link]").forEach((e=>e.remove()));document.head.querySelectorAll("[pp-dynamic-script]").forEach((e=>e.remove()));await(async e=>{Array.from(e.head.children).forEach((e=>{const t=e.tagName;if("SCRIPT"===t&&e.hasAttribute(s)){const t=document.createElement("script");Array.from(e.attributes).forEach((e=>t.setAttribute(e.name,e.value))),e.textContent&&(t.textContent=e.textContent),document.head.appendChild(t)}else if("META"===t){if(e.getAttribute("charset")||"viewport"===e.getAttribute("name"))return;const t=e.name,n=e.getAttribute("property"),s=document.head.querySelector(t?`meta[name="${t}"]`:`meta[property="${n}"]`),i=document.head.querySelector("title");s?document.head.replaceChild(e.cloneNode(!0),s):i?.nextSibling?document.head.insertBefore(e.cloneNode(!0),i.nextSibling):document.head.appendChild(e.cloneNode(!0))}else if("TITLE"===t){const t=document.head.querySelector("title");t?document.head.replaceChild(e.cloneNode(!0),t):document.head.appendChild(e.cloneNode(!0))}else if("LINK"===t){const t=t=>{const n=document.head.querySelector('link[rel="icon"]');if(n)document.head.replaceChild(e.cloneNode(!0),n);else{const e=document.createElement("link");e.rel="icon",e.href=t,document.head.appendChild(e)}};if("icon"===e.getAttribute("rel")){t(e.href)}else if(e.hasAttribute(i)){const t=e.cloneNode(!0);document.head.appendChild(t)}}})),await this.populateDocumentBody(e)})(n),this.restoreScrollPositions(t),this.initBindings(),this.bindings.forEach((e=>e.update())),this.initializeAllReferencedProps(),this.attachWireFunctionEvents()}restoreScrollPositions(e){requestAnimationFrame((()=>{const t=e.window;t&&window.scrollTo(t.scrollLeft,t.scrollTop),document.querySelectorAll("*").forEach((t=>{const n=this.getElementKey(t);e[n]&&(t.scrollTop=e[n].scrollTop,t.scrollLeft=e[n].scrollLeft)}))}))}async populateDocumentBody(e){try{const t=e.body.cloneNode(!0);this.manageScriptTags(t),document.body.replaceWith(t)}catch(e){}}manageScriptTags(e,t){const n=e.querySelectorAll("script"),s=t?.querySelectorAll("script")||n;n.forEach(((e,t)=>{const n=document.createElement("script"),i=s[t]||e;Array.from(i.attributes).forEach((e=>{n.setAttribute(e.name,e.value)})),i.hasAttribute("src")||(n.textContent=i.textContent),e.parentNode?.replaceChild(n,e)}))}saveScrollPositions(){const e={window:{scrollTop:window.scrollY||document.documentElement.scrollTop,scrollLeft:window.scrollX||document.documentElement.scrollLeft}};return document.querySelectorAll("*").forEach((t=>{(t.scrollTop||t.scrollLeft)&&(e[this.getElementKey(t)]={scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})})),e}getElementKey(e){return e.id||e.className||e.tagName}async redirect(e){if(e)try{const t=new URL(e,window.location.origin);t.origin!==window.location.origin?window.location.href=e:(history.pushState(null,"",e),await this.handleNavigation())}catch(e){}}abortActiveRequest(){this.activeAbortController&&this.activeAbortController.abort()}async fetch(e,t,n=!1){let s;return n?(this.activeAbortController&&this.activeAbortController.abort(),this.activeAbortController=new AbortController,s=this.activeAbortController):s=new AbortController,fetch(e,{...t,signal:s.signal,headers:{...t?.headers,"X-Requested-With":"XMLHttpRequest"}})}isJsonLike(e){return"string"==typeof e&&((e=e.trim()).startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))}parseJson(e){try{return JSON5.parse(e)}catch(e){return null}}parseTime(e){if("number"==typeof e)return e;const t=e.match(/^(\d+)(ms|s|m)?$/);if(t){const e=parseInt(t[1],10);switch(t[2]||"ms"){case"ms":return e;case"s":return 1e3*e;case"m":return 60*e*1e3;default:return e}}return 0}scheduleChange(e,t,n,s){setTimeout((()=>{requestAnimationFrame((()=>{e.style[n]=s}))}),t)}observeDOMChanges(){new MutationObserver((e=>{for(const t of e)"childList"===t.type&&t.addedNodes.length>0&&this.attachWireFunctionEvents()})).observe(document.body,{childList:!0,subtree:!0})}async fetchFunction(e,t={},n=!1){try{const s={callback:e,...t},i=window.location.href;let a;if(Object.keys(s).some((e=>{const t=s[e];return t instanceof File||t instanceof FileList&&t.length>0}))){const e=new FormData;Object.keys(s).forEach((t=>{const n=s[t];n instanceof File?e.append(t,n):n instanceof FileList?Array.from(n).forEach((n=>e.append(t,n))):e.append(t,n)})),a={method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:e}}else a=this.createFetchOptions(s);const o=await this.fetch(i,a,n);if(!o.ok)throw new Error(`Fetch failed with status: ${o.status} ${o.statusText}`);const r=await o.text();try{return JSON.parse(r)}catch{return r}}catch(e){throw new Error("Failed to fetch data.")}}processSyncScripts(e){e.forEach((e=>{const t=`script[pp-sync-script="${CSS.escape(e)}"]`,n=document.querySelector(t);if(n){n.remove();const e=document.createElement("script");Array.from(n.attributes).forEach((t=>{e.setAttribute(t.name,t.value)})),n.src?e.src=n.src:e.textContent=n.textContent,e.type=n.type||"module",document.body.appendChild(e)}}))}async sync(...e){try{const t=this.saveScrollPositions();this.saveState();const n=e.length>0?e.map((e=>`pp-sync="${e}"`)):['pp-sync="true"'],s=this.createFetchOptions({secondRequestC69CD:!0,...this.getUrlParams()}),i=await this.fetch(window.location.href,s),a=await i.text(),o=(new DOMParser).parseFromString(a,"text/html"),r=new Set;n.forEach((e=>{const t=document.querySelectorAll(`[${e}]`),n=o.body.querySelectorAll(`[${e}]`);t.forEach(((e,t)=>{const s=n[t];if(s){if(s.hasAttribute("pp-sync-script")){const e=s.getAttribute("pp-sync-script")||"";e&&r.add(e)}s.querySelectorAll("[pp-sync-script]").forEach((e=>{const t=e.getAttribute("pp-sync-script")||"";t&&r.add(t)})),e.innerHTML=s.innerHTML,this.reRunScripts(e)}}))})),this.processSyncScripts(r),this.restoreState(),this.restoreScrollPositions(t),this.attachWireFunctionEvents()}catch(e){}}async fetchAndUpdateBodyContent(){const e=this.createFetchOptions({secondRequestC69CD:!0,...this.getUrlParams()});this.abortActiveRequest();const t=await this.fetch(window.location.href,e,!0),n=await t.text();await this.updateBodyContent(n)}reRunScripts(e){e.querySelectorAll("script").forEach((e=>{const t=document.createElement("script");Array.from(e.attributes).forEach((e=>{t.setAttribute(e.name,e.value)})),e.hasAttribute("src")||(t.textContent=e.textContent),e.parentNode?.replaceChild(t,e)}))}copyCode(e,t,n,s,i="img",a=2e3){if(!(e instanceof HTMLElement))return;const o=e.closest(`.${t}`)?.querySelector("pre code"),r=o?.textContent?.trim()||"";r?navigator.clipboard.writeText(r).then((()=>{const t=e.querySelector(i);if(t)for(const[e,n]of Object.entries(s))e in t?t[e]=n:t.setAttribute(e,n);setTimeout((()=>{if(t)for(const[e,s]of Object.entries(n))e in t?t[e]=s:t.setAttribute(e,s)}),a)}),(()=>{alert("Failed to copy command to clipboard")})):alert("Failed to find the code block to copy")}getCookie(e){return document.cookie.split("; ").find((t=>t.startsWith(e+"=")))?.split("=")[1]||null}}class PPHPLocalStore{static instance=null;state;listeners;pphp;STORAGE_KEY;constructor(e={}){this.state=e,this.listeners=[],this.pphp=PPHP.instance,this.STORAGE_KEY=this.pphp.getCookie("pphp_local_store_key")||"pphp_local_store_59e13",this.loadState()}static getInstance(e={}){return PPHPLocalStore.instance||(PPHPLocalStore.instance=new PPHPLocalStore(e)),PPHPLocalStore.instance}setState(e,t=!1){if(this.state={...this.state,...e},this.listeners.forEach((e=>e(this.state))),this.saveState(),t){const e=localStorage.getItem(this.STORAGE_KEY);e&&this.pphp.fetchFunction(this.STORAGE_KEY,{[this.STORAGE_KEY]:e})}}saveState(){localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.state))}loadState(){const e=localStorage.getItem(this.STORAGE_KEY);e&&(this.state=this.pphp.parseJson(e),this.listeners.forEach((e=>e(this.state))))}resetState(e,t=!1){if(e?(delete this.state[e],this.saveState()):(this.state={},localStorage.removeItem(this.STORAGE_KEY)),this.listeners.forEach((e=>e(this.state))),t){const t=e?localStorage.getItem(this.STORAGE_KEY):null;this.pphp.fetchFunction(this.STORAGE_KEY,{[this.STORAGE_KEY]:t})}}}
2
+ // Initialize the PPHP instance and observe DOM changes
8
3
  document.addEventListener("DOMContentLoaded", () => {
9
- document.dispatchEvent(new Event("PPBodyLoaded"));
4
+ PPHP.instance.observeDOMChanges();
10
5
  });
11
6
  var pphp = PPHP.instance;
12
7
  var store = PPHPLocalStore.getInstance();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma-php-app",
3
- "version": "2.1.14",
3
+ "version": "2.2.1",
4
4
  "description": "Prisma-PHP: A Revolutionary Library Bridging PHP with Prisma ORM",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",