create-prisma-php-app 1.20.2 → 1.20.3

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.
@@ -1,1631 +1 @@
1
- var eventAttributesB6B56 = [
2
- "onclick",
3
- "ondblclick",
4
- "onmousedown",
5
- "onmouseup",
6
- "onmouseover",
7
- "onmousemove",
8
- "onmouseout",
9
- "onwheel",
10
- "onkeypress",
11
- "onkeydown",
12
- "onkeyup",
13
- "onfocus",
14
- "onblur",
15
- "onchange",
16
- "oninput",
17
- "onselect",
18
- "onsubmit",
19
- "onreset",
20
- "onresize",
21
- "onscroll",
22
- "onload",
23
- "onunload",
24
- "onabort",
25
- "onerror",
26
- "onbeforeunload",
27
- "oncopy",
28
- "oncut",
29
- "onpaste",
30
- "ondrag",
31
- "ondragstart",
32
- "ondragend",
33
- "ondragover",
34
- "ondragenter",
35
- "ondragleave",
36
- "ondrop",
37
- "oncontextmenu",
38
- "ontouchstart",
39
- "ontouchmove",
40
- "ontouchend",
41
- "ontouchcancel",
42
- "onpointerdown",
43
- "onpointerup",
44
- "onpointermove",
45
- "onpointerover",
46
- "onpointerout",
47
- "onpointerenter",
48
- "onpointerleave",
49
- "onpointercancel",
50
- ];
51
- var stateA129A = {
52
- checkedElements: new Set(),
53
- };
54
- var responseDataDEAC2 = null;
55
- var store = null;
56
- var isNavigatingA12E1 = false;
57
- var redirectRegex3AE99 = /redirect_7F834\s*=\s*(\/[^\s]+)/;
58
- (() => {
59
- // Save a reference to the original addEventListener function
60
- const originalAddEventListener = EventTarget.prototype.addEventListener;
61
- // Create a Map to store the event listeners
62
- const listeners = new Map();
63
- // Override the addEventListener method
64
- EventTarget.prototype.addEventListener = function (type, listener, options) {
65
- // Ensure that the listeners map has a Map for this EventTarget instance
66
- if (!listeners.has(this)) {
67
- listeners.set(this, new Map());
68
- }
69
- const typeListeners = listeners.get(this).get(type) || new Set();
70
- typeListeners.add(listener);
71
- // Store the listener
72
- listeners.get(this).set(type, typeListeners);
73
- // Call the original addEventListener function
74
- originalAddEventListener.call(this, type, listener, options);
75
- };
76
- // Add a method to remove all event listeners of a specific type
77
- EventTarget.prototype.removeAllEventListeners = function (type) {
78
- if (listeners.has(this) && listeners.get(this).has(type)) {
79
- // Remove each listener of the specified type
80
- listeners
81
- .get(this)
82
- .get(type)
83
- .forEach((listener) => {
84
- this.removeEventListener(type, listener);
85
- });
86
- // Remove the type map after all listeners are removed
87
- listeners.get(this).delete(type);
88
- }
89
- };
90
- })();
91
- ((history) => {
92
- const pushState = history.pushState;
93
- const replaceState = history.replaceState;
94
- history.pushState = function (state, title, url) {
95
- const result = pushState.apply(history, arguments);
96
- window.dispatchEvent(new Event("urlchange"));
97
- return result;
98
- };
99
- history.replaceState = function (state, title, url) {
100
- const result = replaceState.apply(history, arguments);
101
- window.dispatchEvent(new Event("urlchange"));
102
- return result;
103
- };
104
- })(window.history);
105
- document.addEventListener("DOMContentLoaded", attachWireFunctionEvents);
106
- function attachWireFunctionEvents() {
107
- handleHiddenAttribute();
108
- const interactiveElements = document.querySelectorAll(
109
- "button, input, select, textarea, a, form, label, div, span"
110
- );
111
- interactiveElements.forEach((element) => {
112
- handleAnchorTag(element);
113
- eventAttributesB6B56.forEach((attr) => {
114
- const originalHandler = element.getAttribute(attr);
115
- const eventType = attr.slice(2); // Get the event type (e.g., "click" from "onclick")
116
- if (originalHandler) {
117
- element.removeAttribute(attr);
118
- handleDebounce(element, eventType, originalHandler);
119
- }
120
- });
121
- // Special handling for form submit
122
- if (element instanceof HTMLFormElement) {
123
- const submitHandler = element.getAttribute("onsubmit");
124
- if (submitHandler) {
125
- element.removeAttribute("onsubmit");
126
- handleDebounce(element, "submit", submitHandler);
127
- }
128
- }
129
- });
130
- initializePpOnListeners();
131
- }
132
- // Function to check if an element has any pp-on attribute
133
- function hasPpOnAttribute(element) {
134
- const attributes = element.attributes;
135
- if (!attributes) return false;
136
- for (let i = 0; i < attributes.length; i++) {
137
- const name = attributes[i].name;
138
- if (
139
- name.startsWith("pp-on:") ||
140
- name.startsWith("data-pp-on:") ||
141
- name.startsWith("pp-on-") ||
142
- name.startsWith("data-pp-on-")
143
- ) {
144
- return true;
145
- }
146
- }
147
- return false;
148
- }
149
- // Function to find all elements with any pp-on attribute within a given context
150
- function findAllPpOnElements(context) {
151
- const result = [];
152
- if (hasPpOnAttribute(context)) {
153
- result.push(context);
154
- }
155
- if (document.evaluate) {
156
- const xpathResult = document.evaluate(
157
- './/*[@*[starts-with(name(), "pp-on:") or starts-with(name(), "data-pp-on:") or' +
158
- ' starts-with(name(), "pp-on-") or starts-with(name(), "data-pp-on-")]]',
159
- context,
160
- null,
161
- XPathResult.ORDERED_NODE_ITERATOR_TYPE,
162
- null
163
- );
164
- let node = xpathResult.iterateNext();
165
- while (node) {
166
- result.push(node);
167
- node = xpathResult.iterateNext();
168
- }
169
- } else if (typeof context.getElementsByTagName === "function") {
170
- const elements = context.getElementsByTagName("*");
171
- for (let i = 0; i < elements.length; i++) {
172
- if (hasPpOnAttribute(elements[i])) {
173
- result.push(elements[i]);
174
- }
175
- }
176
- }
177
- return result;
178
- }
179
- // Function to initialize pp-on event listeners
180
- function initializePpOnListeners() {
181
- const elements = findAllPpOnElements(document);
182
- elements.forEach((element) => {
183
- Array.from(element.attributes).forEach((attr) => {
184
- if (attr.name.startsWith("pp-on:")) {
185
- const eventName = attr.name.split(":")[1];
186
- const handler = attr.value;
187
- if (handler) {
188
- element.addEventListener(eventName, (event) => {
189
- try {
190
- new Function("event", handler).call(element, event);
191
- } catch (error) {
192
- console.error("Error executing handler:", error);
193
- }
194
- });
195
- // Optionally, remove the attribute after adding the event listener
196
- // element.removeAttribute(attr.name);
197
- }
198
- }
199
- });
200
- });
201
- }
202
- function handleHiddenAttribute() {
203
- const visibilityElements = document.querySelectorAll("[pp-visibility]");
204
- const displayNoneElements = document.querySelectorAll("[pp-display]");
205
- visibilityElements.forEach((element) =>
206
- handleVisibilityElementAttribute(
207
- element,
208
- "pp-visibility",
209
- handleElementVisibility
210
- )
211
- );
212
- displayNoneElements.forEach((element) =>
213
- handleVisibilityElementAttribute(
214
- element,
215
- "pp-display",
216
- handleElementDisplay
217
- )
218
- );
219
- }
220
- function handleVisibilityElementAttribute(element, attributeName, handler) {
221
- const attributeValue = element.getAttribute(attributeName);
222
- if (!attributeValue) return;
223
- if (isJsonLike(attributeValue)) {
224
- const config = parseJson(attributeValue);
225
- handler(element, config);
226
- } else {
227
- const timeout = parseTime(attributeValue);
228
- if (timeout > 0) {
229
- // Map attribute names to style properties
230
- const styleProperty =
231
- attributeName === "pp-visibility" ? "visibility" : "display";
232
- const hiddenValue = styleProperty === "visibility" ? "hidden" : "none";
233
- scheduleChange(element, timeout, styleProperty, hiddenValue);
234
- }
235
- }
236
- }
237
- // Function to determine if a string is JSON-like
238
- function isJsonLike(str) {
239
- // Ensure the input is a string
240
- if (typeof str !== "string") return false;
241
- // Trim the string and check if it looks like JSON
242
- str = str.trim();
243
- return (
244
- (str.startsWith("{") && str.endsWith("}")) ||
245
- (str.startsWith("[") && str.endsWith("]"))
246
- );
247
- }
248
- // Function to handle visibility changes based on config
249
- function handleElementVisibility(element, config) {
250
- handleElementChange(element, config, "visibility", "hidden", "visible");
251
- }
252
- // Function to handle display changes based on config
253
- function handleElementDisplay(element, config) {
254
- handleElementChange(element, config, "display", "none", "block");
255
- }
256
- function handleElementChange(
257
- element,
258
- config,
259
- styleProperty,
260
- hiddenValue,
261
- visibleValue
262
- ) {
263
- const startTimeout = config.start ? parseTime(config.start) : 0;
264
- const endTimeout = config.end ? parseTime(config.end) : 0;
265
- if (startTimeout > 0) {
266
- element.style[styleProperty] = hiddenValue;
267
- scheduleChange(element, startTimeout, styleProperty, visibleValue);
268
- if (endTimeout > 0) {
269
- scheduleChange(
270
- element,
271
- startTimeout + endTimeout,
272
- styleProperty,
273
- hiddenValue
274
- );
275
- }
276
- } else if (endTimeout > 0) {
277
- scheduleChange(element, endTimeout, styleProperty, hiddenValue);
278
- }
279
- }
280
- // Function to schedule visibility or display changes using requestAnimationFrame
281
- function scheduleChange(element, timeout, styleProperty, value) {
282
- setTimeout(() => {
283
- requestAnimationFrame(() => {
284
- element.style[styleProperty] = value;
285
- });
286
- }, timeout);
287
- }
288
- // Function to parse time strings into milliseconds
289
- function parseTime(time) {
290
- if (typeof time === "number") {
291
- return time;
292
- }
293
- const match = time.match(/^(\d+)(ms|s|m)?$/);
294
- if (match) {
295
- const value = parseInt(match[1], 10);
296
- const unit = match[2] || "ms"; // Default to milliseconds if no unit specified
297
- switch (unit) {
298
- case "ms":
299
- return value;
300
- case "s":
301
- return value * 1000;
302
- case "m":
303
- return value * 60 * 1000;
304
- default:
305
- return value; // Default to milliseconds
306
- }
307
- }
308
- return 0; // Default to 0 if parsing fails
309
- }
310
- async function handleDebounce(element, eventType, originalHandler) {
311
- const debounceTime = element.getAttribute("pp-debounce") || "";
312
- const executeBeforeRequest = element.getAttribute("pp-before-request") || "";
313
- const executeAfterRequest = element.getAttribute("pp-after-request") || "";
314
- const combinedHandler = async (event) => {
315
- event.preventDefault();
316
- try {
317
- if (executeBeforeRequest)
318
- await invokeHandler(element, executeBeforeRequest, event);
319
- await invokeHandler(element, originalHandler, event);
320
- if (executeAfterRequest && executeAfterRequest !== "@close")
321
- await invokeHandler(element, executeAfterRequest, event);
322
- handlerAutofocusAttribute();
323
- } catch (error) {
324
- console.error("Error in debounced handler:", error);
325
- }
326
- };
327
- if (debounceTime) {
328
- const wait = parseTime(debounceTime);
329
- const debouncedHandler = debounce(combinedHandler, wait);
330
- if (element instanceof HTMLFormElement && eventType === "submit") {
331
- element.addEventListener(eventType, (event) => {
332
- event.preventDefault();
333
- debouncedHandler(event);
334
- });
335
- } else {
336
- element.addEventListener(eventType, debouncedHandler);
337
- }
338
- } else {
339
- element.addEventListener(eventType, combinedHandler);
340
- }
341
- }
342
- function handlerAutofocusAttribute() {
343
- const ppAutofocusElements = document.querySelectorAll("[pp-autofocus]");
344
- let hasFocusedElement = false;
345
- ppAutofocusElements.forEach((el) => {
346
- if (hasFocusedElement) return;
347
- const ppAutofocusAttribute = el.getAttribute("pp-autofocus");
348
- if (!ppAutofocusAttribute || !isJsonLike(ppAutofocusAttribute)) return;
349
- const ppAutofocusConfig = parseJson(ppAutofocusAttribute);
350
- if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
351
- if (el.type === "number" && el instanceof HTMLInputElement) {
352
- el.type = "text";
353
- const length = el.value.length || 0;
354
- el.setSelectionRange(length, length);
355
- el.type = "number";
356
- } else {
357
- if (ppAutofocusConfig.start) {
358
- el.setSelectionRange(0, 0);
359
- } else if (ppAutofocusConfig.end) {
360
- const currentAutofocusLength = el.value.length || 0;
361
- el.setSelectionRange(currentAutofocusLength, currentAutofocusLength);
362
- } else if (ppAutofocusConfig.length) {
363
- const length = parseInt(ppAutofocusConfig.length, 10) || 0;
364
- el.setSelectionRange(length, length);
365
- }
366
- }
367
- }
368
- el.focus();
369
- hasFocusedElement = true;
370
- });
371
- }
372
- async function invokeHandler(element, handler, event) {
373
- try {
374
- // Extract method details from the handler string
375
- const methodMatch = handler.match(/^(\w+(\.\w+)*)\((.*)\)$/);
376
- if (methodMatch) {
377
- const fullMethodName = methodMatch[1];
378
- const methodParts = fullMethodName.split(".");
379
- const { context, methodName } = resolveContext(methodParts);
380
- if (typeof context[methodName] === "function") {
381
- new Function("event", handler).call(element, event);
382
- } else {
383
- await handleParsedCallback(element, handler);
384
- }
385
- } else {
386
- await handleParsedCallback(element, handler);
387
- }
388
- } catch (error) {
389
- console.error(`Error executing handler ${handler}:`, error);
390
- }
391
- }
392
- /**
393
- * Resolve the context and method name for nested methods.
394
- * @param methodParts - Array of method parts split by dots.
395
- * @returns Object containing the resolved context and method name.
396
- */
397
- function resolveContext(methodParts) {
398
- let context = window;
399
- for (let i = 0; i < methodParts.length - 1; i++) {
400
- context = context[methodParts[i]];
401
- if (!context) {
402
- throw new Error(`Cannot find object ${methodParts[i]} in the context.`);
403
- }
404
- }
405
- return { context, methodName: methodParts[methodParts.length - 1] };
406
- }
407
- /**
408
- * Handle parsing and executing the callback from the element's handler.
409
- * @param element - HTML element that initiated the handler.
410
- * @param handler - Handler string to be parsed and executed.
411
- */
412
- async function handleParsedCallback(element, handler) {
413
- const { funcName, data } = parseCallback(element, handler);
414
- if (!funcName) return;
415
- const func = window[funcName];
416
- if (typeof func === "function") {
417
- const isAfterRequest = element.hasAttribute("pp-after-request");
418
- const args = Array.isArray(data.args) ? data.args : [];
419
- const response = responseDataDEAC2
420
- ? parseJson(responseDataDEAC2)
421
- : { response: responseDataDEAC2 };
422
- let params = {
423
- args,
424
- element,
425
- data,
426
- };
427
- if (isAfterRequest) {
428
- params = {
429
- ...params,
430
- ...response,
431
- };
432
- }
433
- await func(params);
434
- } else {
435
- responseDataDEAC2 = null;
436
- responseDataDEAC2 = await handleUndefinedFunction(element, funcName, data);
437
- }
438
- }
439
- function handleAnchorTag(element) {
440
- if (!(element instanceof HTMLAnchorElement)) return;
441
- element.addEventListener("click", async (event) => {
442
- const anchor = event.currentTarget;
443
- const href = anchor.getAttribute("href");
444
- const target = anchor.getAttribute("target");
445
- // Allow default behavior for special cases
446
- if (!href || target === "_blank" || event.metaKey || event.ctrlKey) {
447
- return;
448
- }
449
- event.preventDefault(); // Prevent the default navigation
450
- if (isNavigatingA12E1) return; // Prevent multiple navigations
451
- isNavigatingA12E1 = true;
452
- try {
453
- const isExternal =
454
- /^(https?:)?\/\//i.test(href) &&
455
- !href.startsWith(window.location.origin);
456
- if (isExternal) {
457
- window.location.href = href;
458
- } else {
459
- const anchorPpAppendParams = anchor.getAttribute("pp-append-params");
460
- if (href.startsWith("?") && anchorPpAppendParams === "true") {
461
- const url = new URL(window.location.href);
462
- // Handle query parameter updates
463
- const params = new URLSearchParams(url.search); // Retain existing parameters
464
- // Extract the hash if it exists
465
- let hash = "";
466
- const [queryPart, hashPart] = href.split("#");
467
- if (hashPart) {
468
- hash = `#${hashPart}`;
469
- }
470
- // Get new parameters from the href and update/add them
471
- const newParams = new URLSearchParams(queryPart.split("?")[1]);
472
- newParams.forEach((value, key) => {
473
- params.set(key, value);
474
- });
475
- // Construct the new URL with merged parameters
476
- const newUrl = `${url.pathname}?${params.toString()}${hash}`;
477
- history.pushState(null, "", newUrl);
478
- } else {
479
- // Handle path navigation and retain hash
480
- const [path, hash] = href.split("#");
481
- const newUrl = `${path}${hash ? `#${hash}` : ""}`;
482
- history.pushState(null, "", newUrl);
483
- }
484
- const hashIndex = href.indexOf("#");
485
- if (hashIndex !== -1) {
486
- const hash = href.slice(hashIndex + 1);
487
- const targetElement = document.getElementById(hash);
488
- if (targetElement) {
489
- targetElement.scrollIntoView({ behavior: "smooth" });
490
- } else {
491
- await handleNavigation();
492
- const newTargetElement = document.getElementById(hash);
493
- if (newTargetElement) {
494
- newTargetElement.scrollIntoView({ behavior: "smooth" });
495
- }
496
- }
497
- } else {
498
- await handleNavigation();
499
- }
500
- }
501
- } catch (error) {
502
- console.error("Anchor click error:", error);
503
- } finally {
504
- isNavigatingA12E1 = false;
505
- }
506
- });
507
- }
508
- // Handle browser's back/forward navigation
509
- window.addEventListener("popstate", async () => {
510
- await handleNavigation();
511
- });
512
- async function handleNavigation() {
513
- try {
514
- const parseTransition = (element) => {
515
- const getTransitionAttrFromElement = element.querySelector(
516
- "[pp-loading-transition]"
517
- );
518
- const transitionAttr = getTransitionAttrFromElement?.getAttribute(
519
- "pp-loading-transition"
520
- );
521
- let fadeIn = 250;
522
- let fadeOut = 250;
523
- if (transitionAttr) {
524
- try {
525
- const transitionConfig = parseJson(transitionAttr);
526
- fadeIn = parseTime(transitionConfig.fadeIn || fadeIn);
527
- fadeOut = parseTime(transitionConfig.fadeOut || fadeOut);
528
- } catch (error) {
529
- console.error(
530
- "Failed to parse pp-loading-transition attribute:",
531
- error
532
- );
533
- }
534
- }
535
- return { fadeIn, fadeOut };
536
- };
537
- const fadeOut = (element, duration) => {
538
- return new Promise((resolve) => {
539
- element.style.transition = `opacity ${duration}ms ease-out`;
540
- element.style.opacity = "0";
541
- setTimeout(() => {
542
- element.style.transition = "";
543
- resolve();
544
- }, duration);
545
- });
546
- };
547
- const fadeIn = (element, duration) => {
548
- element.style.transition = `opacity ${duration}ms ease-in`;
549
- element.style.opacity = "1";
550
- setTimeout(() => {
551
- element.style.transition = "";
552
- }, duration);
553
- };
554
- const updateContent = async (loadingElement) => {
555
- const pageContent =
556
- document.querySelector("[pp-loading-content='true']") || document.body;
557
- if (pageContent) {
558
- const { fadeIn: fadeInDuration, fadeOut: fadeOutDuration } =
559
- parseTransition(loadingElement);
560
- await fadeOut(pageContent, fadeOutDuration);
561
- pageContent.innerHTML = loadingElement.innerHTML;
562
- fadeIn(pageContent, fadeInDuration);
563
- }
564
- };
565
- const dynamicPart = window.location.pathname;
566
- const parentElement = document.getElementById("loading-file-1B87E");
567
- if (parentElement) {
568
- let loadingElement = parentElement.querySelector(
569
- `div[pp-loading-url='${dynamicPart}']`
570
- );
571
- if (!loadingElement) {
572
- loadingElement = parentElement.querySelector("div[pp-loading-url='/']");
573
- }
574
- if (loadingElement) {
575
- await updateContent(loadingElement);
576
- }
577
- }
578
- const data = await pphpFetch(window.location.href);
579
- const match = data.match(redirectRegex3AE99);
580
- if (match && match[1]) {
581
- const url = match[1];
582
- await handleRedirect(url);
583
- } else {
584
- updateDocumentContent(data);
585
- }
586
- } catch (error) {
587
- console.error("Navigation error:", error);
588
- }
589
- }
590
- window.addEventListener("urlchange", () => {
591
- // console.log("URL changed:", window.location.href);
592
- // Call your function here
593
- // onUrlChange();
594
- });
595
- function onUrlChange() {
596
- // console.log("Handling URL change");
597
- // Add your code to handle the URL change here
598
- }
599
- function updateDocumentContent(data) {
600
- const scrollPositions = saveScrollPositions();
601
- document.removeAllEventListeners("DOMContentLoaded");
602
- if (data.includes("<!DOCTYPE html>")) {
603
- const newDoc = new DOMParser().parseFromString(data, "text/html");
604
- const replaceDocumentContent = (newDoc) => {
605
- Array.from(newDoc.head.children).forEach((newHeadChild) => {
606
- const tagName = newHeadChild.tagName;
607
- if (tagName === "META") {
608
- // Exclude specific meta tags like <meta charset="UTF-8">
609
- if (
610
- newHeadChild.getAttribute("charset") ||
611
- newHeadChild.getAttribute("name") === "viewport"
612
- ) {
613
- return;
614
- }
615
- // Check if the meta tag already exists
616
- const nameAttr = newHeadChild.name;
617
- const propertyAttr = newHeadChild.getAttribute("property");
618
- const existingMeta = document.head.querySelector(
619
- nameAttr
620
- ? `meta[name="${nameAttr}"]`
621
- : `meta[property="${propertyAttr}"]`
622
- );
623
- // If the meta tag doesn't exist, add it
624
- if (existingMeta) {
625
- document.head.replaceChild(
626
- newHeadChild.cloneNode(true),
627
- existingMeta
628
- );
629
- } else {
630
- document.head.appendChild(newHeadChild.cloneNode(true));
631
- }
632
- } else if (tagName === "TITLE") {
633
- // Check if the title tag already exists
634
- const existingTitle = document.head.querySelector("title");
635
- if (existingTitle) {
636
- document.head.replaceChild(
637
- newHeadChild.cloneNode(true),
638
- existingTitle
639
- );
640
- } else {
641
- document.head.appendChild(newHeadChild.cloneNode(true));
642
- }
643
- } else if (tagName === "LINK") {
644
- const updateFavicon = (newFaviconHref) => {
645
- const existingLink =
646
- document.head.querySelector('link[rel="icon"]');
647
- if (existingLink) {
648
- document.head.replaceChild(
649
- newHeadChild.cloneNode(true),
650
- existingLink
651
- );
652
- } else {
653
- const newLink = document.createElement("link");
654
- newLink.rel = "icon";
655
- newLink.href = newFaviconHref;
656
- document.head.appendChild(newLink);
657
- }
658
- };
659
- if (newHeadChild.getAttribute("rel") === "icon") {
660
- const newFaviconHref = newHeadChild.href;
661
- updateFavicon(newFaviconHref);
662
- }
663
- }
664
- });
665
- loadAndValidateContent(newDoc);
666
- };
667
- // Replace the document content keeping positions of scripts and styles
668
- replaceDocumentContent(newDoc);
669
- } else {
670
- saveState();
671
- const newDoc = new DOMParser().parseFromString(data, "text/html");
672
- loadAndValidateContent(newDoc);
673
- restoreState();
674
- }
675
- restoreScrollPositions(scrollPositions);
676
- attachWireFunctionEvents();
677
- document.dispatchEvent(new Event("DOMContentLoaded"));
678
- }
679
- function loadAndValidateContent(newDoc) {
680
- const elementStore = new Map();
681
- const documentFragment = document.createDocumentFragment();
682
- function processElement(element, parentClone) {
683
- let newElement = null;
684
- if (element.tagName === "SCRIPT") {
685
- const newScript = document.createElement("script");
686
- const scriptElement = element;
687
- if (scriptElement.src) {
688
- newScript.src = scriptElement.src;
689
- newScript.async = false; // Ensure scripts execute in order
690
- } else {
691
- newScript.textContent = scriptElement.textContent;
692
- }
693
- newElement = newScript;
694
- } else {
695
- newElement = element.cloneNode(false);
696
- elementStore.set(element, newElement);
697
- Array.from(element.childNodes).forEach((childNode) => {
698
- if (childNode.nodeType === Node.TEXT_NODE) {
699
- newElement.appendChild(
700
- document.createTextNode(childNode.textContent || "")
701
- );
702
- } else if (childNode.nodeType === Node.ELEMENT_NODE) {
703
- processElement(childNode, newElement);
704
- }
705
- });
706
- }
707
- parentClone.appendChild(newElement);
708
- }
709
- Array.from(newDoc.body.children).forEach((newBodyChild) => {
710
- processElement(newBodyChild, documentFragment);
711
- });
712
- document.body.innerHTML = "";
713
- document.body.appendChild(documentFragment);
714
- }
715
- function saveState() {
716
- const focusElement = document.activeElement;
717
- stateA129A.focusId = focusElement?.id || focusElement?.name;
718
- stateA129A.focusValue = focusElement?.value;
719
- stateA129A.focusChecked = focusElement?.checked;
720
- stateA129A.focusType = focusElement?.type;
721
- stateA129A.focusSelectionStart = focusElement?.selectionStart;
722
- stateA129A.focusSelectionEnd = focusElement?.selectionEnd;
723
- stateA129A.isSuspense = focusElement.hasAttribute("pp-suspense");
724
- stateA129A.checkedElements.clear();
725
- document.querySelectorAll('input[type="checkbox"]:checked').forEach((el) => {
726
- stateA129A.checkedElements.add(el.id || el.name);
727
- });
728
- document.querySelectorAll('input[type="radio"]:checked').forEach((el) => {
729
- stateA129A.checkedElements.add(el.id || el.name);
730
- });
731
- }
732
- function restoreState() {
733
- if (stateA129A.focusId) {
734
- const newFocusElement =
735
- document.getElementById(stateA129A.focusId) ||
736
- document.querySelector(`[name="${stateA129A.focusId}"]`);
737
- if (newFocusElement instanceof HTMLInputElement) {
738
- const length = newFocusElement.value.length || 0;
739
- if (
740
- stateA129A.focusSelectionStart !== undefined &&
741
- stateA129A.focusSelectionEnd !== null
742
- ) {
743
- newFocusElement.setSelectionRange(length, length);
744
- }
745
- if (stateA129A.focusValue) {
746
- if (
747
- newFocusElement.type === "checkbox" ||
748
- newFocusElement.type === "radio"
749
- ) {
750
- newFocusElement.checked = !!stateA129A.focusChecked;
751
- } else if (newFocusElement.type === "number") {
752
- newFocusElement.type = "text";
753
- newFocusElement.setSelectionRange(length, length);
754
- newFocusElement.type = "number";
755
- } else {
756
- if (newFocusElement.value !== "")
757
- newFocusElement.value = stateA129A.focusValue;
758
- }
759
- }
760
- newFocusElement.focus();
761
- } else if (newFocusElement instanceof HTMLTextAreaElement) {
762
- const length = newFocusElement.value.length || 0;
763
- if (
764
- stateA129A.focusSelectionStart !== undefined &&
765
- stateA129A.focusSelectionEnd !== null
766
- ) {
767
- newFocusElement.setSelectionRange(length, length);
768
- }
769
- if (stateA129A.focusValue) {
770
- if (newFocusElement.value !== "")
771
- newFocusElement.value = stateA129A.focusValue;
772
- }
773
- newFocusElement.focus();
774
- } else if (newFocusElement instanceof HTMLSelectElement) {
775
- if (stateA129A.focusValue) {
776
- if (newFocusElement.value !== "")
777
- newFocusElement.value = stateA129A.focusValue;
778
- }
779
- newFocusElement.focus();
780
- }
781
- }
782
- stateA129A.checkedElements.forEach((id) => {
783
- const checkbox = document.getElementById(id);
784
- if (checkbox) {
785
- checkbox.checked = true;
786
- }
787
- });
788
- }
789
- function saveScrollPositions() {
790
- const scrollPositions = {};
791
- document.querySelectorAll("*").forEach((el) => {
792
- if (el.scrollTop || el.scrollLeft) {
793
- scrollPositions[getElementKey(el)] = {
794
- scrollTop: el.scrollTop,
795
- scrollLeft: el.scrollLeft,
796
- };
797
- }
798
- });
799
- return scrollPositions;
800
- }
801
- function restoreScrollPositions(scrollPositions) {
802
- document.querySelectorAll("*").forEach((el) => {
803
- const key = getElementKey(el);
804
- if (scrollPositions[key]) {
805
- el.scrollTop = scrollPositions[key].scrollTop;
806
- el.scrollLeft = scrollPositions[key].scrollLeft;
807
- }
808
- });
809
- }
810
- function getElementKey(el) {
811
- return el.id || el.className || el.tagName;
812
- }
813
- async function pphpFetch(url, options) {
814
- const data = await fetch(url, {
815
- ...options,
816
- headers: {
817
- ...options?.headers,
818
- "X-Requested-With": "XMLHttpRequest",
819
- },
820
- });
821
- return await data.text();
822
- }
823
- function parseCallback(element, callback) {
824
- let data = {};
825
- // Check if the element is inside a form
826
- const form = element.closest("form");
827
- if (form) {
828
- // Serialize the form data
829
- const formData = new FormData(form);
830
- formData.forEach((value, key) => {
831
- if (data[key]) {
832
- // Handle multiple values
833
- if (Array.isArray(data[key])) {
834
- data[key].push(value);
835
- } else {
836
- data[key] = [data[key], value];
837
- }
838
- } else {
839
- data[key] = value;
840
- }
841
- });
842
- } else {
843
- // Handle single input element
844
- if (element instanceof HTMLInputElement) {
845
- data = handleInputElement(element);
846
- } else if (element instanceof HTMLSelectElement) {
847
- data[element.name] = element.value;
848
- } else if (element instanceof HTMLTextAreaElement) {
849
- data[element.name] = element.value;
850
- }
851
- }
852
- // Parse function name and arguments from the callback string
853
- const match = callback.match(/(\w+)\((.*)\)/);
854
- if (match) {
855
- const funcName = match[1];
856
- let rawArgs = match[2].trim();
857
- if (rawArgs.startsWith("{") && rawArgs.endsWith("}")) {
858
- try {
859
- const parsedArg = parseJson(rawArgs);
860
- if (typeof parsedArg === "object" && parsedArg !== null) {
861
- data = { ...data, ...parsedArg };
862
- }
863
- } catch (e) {
864
- console.error("Error parsing JSON:", e);
865
- }
866
- } else {
867
- const args = rawArgs
868
- .split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/)
869
- .map((arg) => arg.trim().replace(/^['"]|['"]$/g, ""));
870
- data.args = args;
871
- }
872
- return { funcName, data };
873
- }
874
- return { funcName: callback, data };
875
- }
876
- function handleInputElement(element) {
877
- let data = {};
878
- // Only proceed if the element has a name
879
- if (element.name) {
880
- // Handle checkboxes
881
- if (element.type === "checkbox") {
882
- data[element.name] = {
883
- value: element.value,
884
- checked: element.checked,
885
- };
886
- } else if (element.type === "radio") {
887
- // Handle radio buttons
888
- const checkedRadio = document.querySelector(
889
- `input[name="${element.name}"]:checked`
890
- );
891
- data[element.name] = checkedRadio ? checkedRadio.value : null;
892
- } else {
893
- // Handle other input types
894
- data[element.name] = element.value;
895
- }
896
- } else {
897
- // Handle cases where the element does not have a name
898
- if (element.type === "checkbox" || element.type === "radio") {
899
- data.value = element.checked;
900
- } else {
901
- data.value = element.value;
902
- }
903
- }
904
- return data;
905
- }
906
- function updateElementAttributes(element, data) {
907
- for (const key in data) {
908
- if (!data.hasOwnProperty(key)) continue;
909
- switch (key) {
910
- case "innerHTML":
911
- case "outerHTML":
912
- case "textContent":
913
- case "innerText":
914
- element[key] = decodeHTML(data[key]);
915
- break;
916
- case "insertAdjacentHTML":
917
- element.insertAdjacentHTML(
918
- data.position || "beforeend",
919
- decodeHTML(data[key].html)
920
- );
921
- break;
922
- case "insertAdjacentText":
923
- element.insertAdjacentText(
924
- data.position || "beforeend",
925
- decodeHTML(data[key].text)
926
- );
927
- break;
928
- case "setAttribute":
929
- element.setAttribute(data.attrName, decodeHTML(data[key]));
930
- break;
931
- case "removeAttribute":
932
- element.removeAttribute(data[key]);
933
- break;
934
- case "className":
935
- element.className = decodeHTML(data[key]);
936
- break;
937
- case "classList.add":
938
- element.classList.add(...decodeHTML(data[key]).split(","));
939
- break;
940
- case "classList.remove":
941
- element.classList.remove(...decodeHTML(data[key]).split(","));
942
- break;
943
- case "classList.toggle":
944
- element.classList.toggle(decodeHTML(data[key]));
945
- break;
946
- case "classList.replace":
947
- const [oldClass, newClass] = decodeHTML(data[key]).split(",");
948
- element.classList.replace(oldClass, newClass);
949
- break;
950
- case "dataset":
951
- element.dataset[data.attrName] = decodeHTML(data[key]);
952
- break;
953
- case "style":
954
- Object.assign(element.style, data[key]);
955
- break;
956
- case "value":
957
- element.value = decodeHTML(data[key]);
958
- break;
959
- case "checked":
960
- element.checked = data[key];
961
- break;
962
- default:
963
- element.setAttribute(key, decodeHTML(data[key]));
964
- }
965
- }
966
- }
967
- function decodeHTML(html) {
968
- const txt = document.createElement("textarea");
969
- txt.innerHTML = html;
970
- return txt.value;
971
- }
972
- function saveElementOriginalState(element) {
973
- if (
974
- element.hasAttribute("pp-suspense") &&
975
- !element.hasAttribute("pp-original-state")
976
- ) {
977
- const originalState = {};
978
- // Save text content if the element has it
979
- if (element.textContent) {
980
- originalState.textContent = element.textContent.trim();
981
- }
982
- // Save innerHTML if the element has it
983
- if (element.innerHTML) {
984
- originalState.innerHTML = element.innerHTML.trim();
985
- }
986
- // Save value for input, textarea, and select elements
987
- if (
988
- element instanceof HTMLInputElement ||
989
- element instanceof HTMLTextAreaElement ||
990
- element instanceof HTMLSelectElement
991
- ) {
992
- originalState.value = element.value;
993
- }
994
- // Save other attributes if necessary
995
- for (let i = 0; i < element.attributes.length; i++) {
996
- const attr = element.attributes[i];
997
- originalState[attr.name] = attr.value;
998
- }
999
- // Save the original state as a JSON string in a custom attribute
1000
- element.setAttribute("pp-original-state", JSON.stringify(originalState));
1001
- }
1002
- // Save the state of child elements with pp-suspense attribute
1003
- const childrenWithSuspense = element.querySelectorAll("[pp-suspense]");
1004
- childrenWithSuspense.forEach((child) => saveElementOriginalState(child));
1005
- }
1006
- async function handleSuspenseElement(element) {
1007
- let suspenseElement = element.getAttribute("pp-suspense") || "";
1008
- const handleFormElement = (form, data) => {
1009
- for (const key in data) {
1010
- if (!data.hasOwnProperty(key)) continue;
1011
- for (const formElement of form.elements) {
1012
- if (
1013
- formElement instanceof HTMLInputElement ||
1014
- formElement instanceof HTMLButtonElement ||
1015
- formElement instanceof HTMLTextAreaElement ||
1016
- formElement instanceof HTMLSelectElement
1017
- ) {
1018
- const suspenseElement = formElement.getAttribute("pp-suspense") || "";
1019
- if (suspenseElement) {
1020
- if (isJsonLike(suspenseElement)) {
1021
- const suspenseData = parseJson(suspenseElement);
1022
- if (suspenseData.onsubmit !== "disabled") {
1023
- updateElementAttributes(formElement, suspenseData);
1024
- }
1025
- if (suspenseData.targets) {
1026
- suspenseData.targets.forEach((target) => {
1027
- const { id, ...rest } = target;
1028
- const targetElement = document.querySelector(id);
1029
- if (targetElement) {
1030
- handleTargetElement(targetElement, rest);
1031
- }
1032
- });
1033
- }
1034
- } else {
1035
- updateElementTextContent(formElement, suspenseElement);
1036
- }
1037
- }
1038
- }
1039
- }
1040
- }
1041
- };
1042
- const updateElementTextContent = (element, data) => {
1043
- if (element instanceof HTMLInputElement) {
1044
- element.value = data;
1045
- } else {
1046
- element.textContent = data;
1047
- }
1048
- };
1049
- const handleTargetElement = (element, data) => {
1050
- if (element instanceof HTMLFormElement) {
1051
- handleFormElement(element, data);
1052
- } else {
1053
- updateElementAttributes(element, data);
1054
- }
1055
- };
1056
- try {
1057
- if (suspenseElement && isJsonLike(suspenseElement)) {
1058
- const data = parseJson(suspenseElement);
1059
- if (data) {
1060
- if (element instanceof HTMLFormElement) {
1061
- const formData = new FormData(element);
1062
- const formDataToProcess = {};
1063
- formData.forEach((value, key) => {
1064
- formDataToProcess[key] = value;
1065
- });
1066
- if (data.disabled) {
1067
- toggleFormElements(element, true);
1068
- }
1069
- const { disabled, ...restData } = data;
1070
- updateElementAttributes(element, restData);
1071
- handleFormElement(element, formDataToProcess);
1072
- } else if (data.targets) {
1073
- data.targets.forEach((target) => {
1074
- const { id, ...rest } = target;
1075
- const targetElement = document.querySelector(id);
1076
- if (targetElement) {
1077
- handleTargetElement(targetElement, rest);
1078
- }
1079
- });
1080
- const { targets, ...restData } = data;
1081
- updateElementAttributes(element, restData);
1082
- } else {
1083
- if (data.empty === "disabled" && element.value === "") return;
1084
- const { empty, ...restData } = data;
1085
- updateElementAttributes(element, restData);
1086
- }
1087
- }
1088
- } else if (suspenseElement) {
1089
- updateElementTextContent(element, suspenseElement);
1090
- } else {
1091
- if (element instanceof HTMLFormElement) {
1092
- const formData = new FormData(element);
1093
- const formDataToProcess = {};
1094
- formData.forEach((value, key) => {
1095
- formDataToProcess[key] = value;
1096
- });
1097
- handleFormElement(element, formDataToProcess);
1098
- }
1099
- }
1100
- } catch (error) {
1101
- console.error("🚀 ~ handleSuspenseElement ~ JSON parse error:", error);
1102
- }
1103
- }
1104
- // Function to restore the original state of an element
1105
- function restoreSuspenseElement(element) {
1106
- const originalStateAttribute = element.getAttribute("pp-original-state");
1107
- if (element.hasAttribute("pp-suspense") && originalStateAttribute) {
1108
- const restoreElement = (element, data) => {
1109
- // Restore attributes and properties
1110
- for (const key in data) {
1111
- if (data.hasOwnProperty(key)) {
1112
- if (key === "textContent") {
1113
- element.textContent = data[key];
1114
- } else if (key === "innerHTML") {
1115
- element.innerHTML = data[key];
1116
- } else if (key === "disabled") {
1117
- if (data[key] === true) {
1118
- element.setAttribute("disabled", "true");
1119
- } else {
1120
- element.removeAttribute("disabled");
1121
- }
1122
- } else {
1123
- element.setAttribute(key, data[key]);
1124
- }
1125
- }
1126
- }
1127
- // Remove any attributes that were in the original element but not in the restored state
1128
- for (const attr of Array.from(element.attributes)) {
1129
- if (!data.hasOwnProperty(attr.name)) {
1130
- element.removeAttribute(attr.name);
1131
- }
1132
- }
1133
- };
1134
- const restoreFormElement = (form, data) => {
1135
- for (const key in data) {
1136
- if (!data.hasOwnProperty(key)) continue;
1137
- for (const formElement of Array.from(form.elements)) {
1138
- if (
1139
- formElement instanceof HTMLInputElement ||
1140
- formElement instanceof HTMLButtonElement ||
1141
- formElement instanceof HTMLTextAreaElement ||
1142
- formElement instanceof HTMLSelectElement
1143
- ) {
1144
- const originalStateAttribute =
1145
- formElement.getAttribute("pp-original-state") || "";
1146
- if (originalStateAttribute) {
1147
- if (isJsonLike(originalStateAttribute)) {
1148
- const originalData = parseJson(originalStateAttribute);
1149
- restoreElement(formElement, originalData);
1150
- } else {
1151
- restoreElementTextContent(formElement, originalStateAttribute);
1152
- }
1153
- formElement.removeAttribute("pp-original-state");
1154
- }
1155
- }
1156
- }
1157
- }
1158
- };
1159
- const restoreElementTextContent = (element, data) => {
1160
- if (element instanceof HTMLInputElement) {
1161
- element.value = data;
1162
- } else {
1163
- element.textContent = data;
1164
- }
1165
- };
1166
- const restoreTargetElement = (element, data) => {
1167
- if (element instanceof HTMLFormElement) {
1168
- restoreFormElement(element, data);
1169
- } else {
1170
- restoreElement(element, data);
1171
- }
1172
- };
1173
- try {
1174
- const data = JSON.parse(originalStateAttribute);
1175
- if (data) {
1176
- if (element instanceof HTMLFormElement) {
1177
- const formData = new FormData(element);
1178
- const formDataToProcess = {};
1179
- formData.forEach((value, key) => {
1180
- formDataToProcess[key] = value;
1181
- });
1182
- restoreFormElement(element, formDataToProcess);
1183
- if (element.hasAttribute("pp-suspense")) {
1184
- const suspenseDataAttribute =
1185
- element.getAttribute("pp-suspense") || "";
1186
- const suspenseData = parseJson(suspenseDataAttribute);
1187
- if (suspenseData.disabled) {
1188
- for (const formElement of Array.from(element.elements)) {
1189
- if (
1190
- formElement instanceof HTMLInputElement ||
1191
- formElement instanceof HTMLButtonElement ||
1192
- formElement instanceof HTMLTextAreaElement ||
1193
- formElement instanceof HTMLSelectElement
1194
- ) {
1195
- formElement.removeAttribute("disabled");
1196
- }
1197
- }
1198
- }
1199
- }
1200
- } else if (data.targets) {
1201
- data.targets.forEach((target) => {
1202
- const { id, ...rest } = target;
1203
- const targetElement = document.querySelector(id);
1204
- if (targetElement) {
1205
- restoreTargetElement(targetElement, rest);
1206
- }
1207
- });
1208
- const { targets, ...restData } = data;
1209
- restoreElement(element, restData);
1210
- } else {
1211
- const { empty, ...restData } = data;
1212
- restoreElement(element, restData);
1213
- }
1214
- }
1215
- } catch (error) {
1216
- console.error("🚀 ~ restoreSuspenseElement ~ JSON parse error:", error);
1217
- }
1218
- }
1219
- // Restore the state of child elements with pp-suspense attribute
1220
- const childrenWithSuspense = element.querySelectorAll("[pp-suspense]");
1221
- childrenWithSuspense.forEach((child) => restoreSuspenseElement(child));
1222
- // Clean up the saved state after restoration
1223
- element.removeAttribute("pp-original-state");
1224
- }
1225
- function parseJson(jsonString) {
1226
- try {
1227
- // Handle cases where the JSON string uses incorrect quotes
1228
- if (!isJsonLike(jsonString)) return null;
1229
- // Normalize quotes: replace single quotes with double quotes, except for those within strings
1230
- jsonString = jsonString.replace(/\\'/g, "'"); // Handle escaped single quotes
1231
- jsonString = jsonString.replace(/(?<!\\)'/g, '"'); // Replace unescaped single quotes with double quotes
1232
- // Fix common issues with curly quotes and other non-standard quotes
1233
- jsonString = jsonString
1234
- .replace(/[\u2018\u2019]/g, "'")
1235
- .replace(/[\u201C\u201D]/g, '"');
1236
- // Replace invalid JSON syntax (e.g., `name"s` -> `name's`, `I"m` -> `I'm`)
1237
- jsonString = jsonString.replace(/(\w)"s/g, "$1's");
1238
- jsonString = jsonString.replace(/(\w)"(\w)/g, "$1'$2");
1239
- // Handle cases where colons are missing (e.g., {"key" "value"})
1240
- jsonString = jsonString.replace(/"(\w+)"\s*([\[\{])/g, '"$1": $2');
1241
- jsonString = jsonString.replace(/(\w+)\s*([\[\{])/g, '"$1": $2'); // Non-quoted keys
1242
- // Handle improperly escaped characters
1243
- jsonString = jsonString.replace(/\\([^"\\/bfnrtu])/g, "\\\\$1"); // Escape special characters correctly
1244
- // Attempt to parse the JSON string
1245
- return JSON.parse(jsonString);
1246
- } catch (error) {
1247
- // Log detailed error information for debugging
1248
- const errorMessage = error.message;
1249
- const positionMatch = errorMessage.match(/position (\d+)/);
1250
- const errorPosition = positionMatch ? parseInt(positionMatch[1]) : null;
1251
- if (errorPosition !== null) {
1252
- console.error(
1253
- "Error parsing JSON at position:",
1254
- errorPosition,
1255
- "\nContext around error:",
1256
- jsonString.slice(Math.max(0, errorPosition - 50), errorPosition + 50)
1257
- );
1258
- } else {
1259
- console.error("Error parsing JSON:", errorMessage);
1260
- }
1261
- return null;
1262
- }
1263
- }
1264
- function toggleFormElements(form, disable) {
1265
- Array.from(form.elements).forEach((element) => {
1266
- if (
1267
- element instanceof HTMLInputElement ||
1268
- element instanceof HTMLButtonElement ||
1269
- element instanceof HTMLSelectElement ||
1270
- element instanceof HTMLTextAreaElement
1271
- ) {
1272
- element.disabled = disable;
1273
- }
1274
- });
1275
- }
1276
- async function pphpFetchFile(url, functionName, fileInput) {
1277
- const formData = new FormData();
1278
- const files = fileInput.files;
1279
- if (files) {
1280
- for (let i = 0; i < files.length; i++) {
1281
- formData.append("file[]", files[i]);
1282
- }
1283
- }
1284
- formData.append("callback", functionName);
1285
- const response = await fetch(url, {
1286
- method: "POST",
1287
- headers: {
1288
- HTTP_PPHP_WIRE_REQUEST: "true",
1289
- },
1290
- body: formData,
1291
- });
1292
- return await response.text();
1293
- }
1294
- async function handleUndefinedFunction(element, funcName, data) {
1295
- const body = { callback: funcName, ...data };
1296
- const firstFetchOptions = createFetchOptions(body);
1297
- const secondFetchOptions = createFetchOptions({ secondRequestC69CD: true });
1298
- try {
1299
- saveElementOriginalState(element);
1300
- handleSuspenseElement(element);
1301
- const url = window.location.pathname;
1302
- let firstResponseText = "";
1303
- let firstResponseJSON = "";
1304
- let jsonResponse = { success: false };
1305
- const fileUpload = element.querySelector("input[type='file']");
1306
- if (fileUpload) {
1307
- firstResponseText = await pphpFetchFile(url, funcName, fileUpload);
1308
- firstResponseJSON = extractJson(firstResponseText) || "";
1309
- if (firstResponseJSON) {
1310
- try {
1311
- jsonResponse = JSON.parse(firstResponseJSON);
1312
- } catch (error) {
1313
- console.error("Error parsing JSON:", error);
1314
- }
1315
- }
1316
- } else {
1317
- firstResponseText = await pphpFetch(url, firstFetchOptions);
1318
- firstResponseJSON = extractJson(firstResponseText) || "";
1319
- if (firstResponseJSON) {
1320
- try {
1321
- jsonResponse = JSON.parse(firstResponseJSON);
1322
- } catch (error) {
1323
- console.error("Error parsing JSON:", error);
1324
- }
1325
- }
1326
- }
1327
- const isPpOnAttribute = hasPpOnAttribute(element);
1328
- const beforeRequestAttribute =
1329
- element.getAttribute("pp-before-request") || "";
1330
- const afterRequestAttribute =
1331
- element.getAttribute("pp-after-request") || "";
1332
- if (
1333
- isPpOnAttribute ||
1334
- beforeRequestAttribute ||
1335
- (afterRequestAttribute && jsonResponse.success)
1336
- )
1337
- restoreSuspenseElement(element);
1338
- if (isPpOnAttribute || beforeRequestAttribute || afterRequestAttribute) {
1339
- let contentToAppend = "";
1340
- if (jsonResponse.success) {
1341
- const remainder = firstResponseText.replace(firstResponseJSON, "");
1342
- contentToAppend = remainder;
1343
- } else {
1344
- contentToAppend = firstResponseText;
1345
- }
1346
- appendAfterbegin(contentToAppend);
1347
- if (!afterRequestAttribute && !jsonResponse.success) return;
1348
- }
1349
- if (afterRequestAttribute && jsonResponse.success) {
1350
- handleAfterRequest(afterRequestAttribute, firstResponseJSON);
1351
- const remainder = firstResponseText.replace(firstResponseJSON, "");
1352
- appendAfterbegin(remainder);
1353
- return firstResponseJSON;
1354
- }
1355
- const secondResponseText = await pphpFetch(url, secondFetchOptions);
1356
- await handleResponseRedirectOrUpdate(
1357
- firstResponseText,
1358
- secondResponseText,
1359
- firstResponseJSON,
1360
- jsonResponse
1361
- );
1362
- } catch (error) {
1363
- console.error("Error handling undefined function:", error);
1364
- }
1365
- }
1366
- function createFetchOptions(body) {
1367
- return {
1368
- method: "POST",
1369
- headers: {
1370
- "Content-Type": "application/json",
1371
- HTTP_PPHP_WIRE_REQUEST: "true",
1372
- },
1373
- body: JSON.stringify(body),
1374
- };
1375
- }
1376
- async function handleResponseRedirectOrUpdate(
1377
- firstResponseText,
1378
- secondResponseText,
1379
- firstResponseJSON,
1380
- jsonResponse
1381
- ) {
1382
- const match = firstResponseText.match(redirectRegex3AE99);
1383
- if (match && match[1]) {
1384
- await handleRedirect(match[1]);
1385
- } else {
1386
- const doc = new DOMParser().parseFromString(
1387
- secondResponseText,
1388
- "text/html"
1389
- );
1390
- let combinedHTML = document.createElement("div");
1391
- combinedHTML.id = "afterbegin-8D95D";
1392
- if (firstResponseJSON) {
1393
- if (jsonResponse.success) {
1394
- const remainder = firstResponseText.replace(firstResponseJSON, "");
1395
- combinedHTML.innerHTML = remainder;
1396
- } else {
1397
- combinedHTML.innerHTML = firstResponseText;
1398
- }
1399
- } else {
1400
- combinedHTML.innerHTML = firstResponseText;
1401
- }
1402
- if (combinedHTML.innerHTML) {
1403
- doc.body.insertAdjacentElement("afterbegin", combinedHTML);
1404
- }
1405
- updateDocumentContent(doc.body.outerHTML);
1406
- }
1407
- }
1408
- function appendAfterbegin(content) {
1409
- if (!content) return;
1410
- const contentId = "afterbegin-8D95D";
1411
- let afterBeginNode = document.getElementById(contentId);
1412
- if (afterBeginNode) {
1413
- afterBeginNode.innerHTML = content;
1414
- document.body.insertAdjacentElement("afterbegin", afterBeginNode);
1415
- } else {
1416
- afterBeginNode = document.createElement("div");
1417
- afterBeginNode.id = contentId;
1418
- afterBeginNode.innerHTML = content;
1419
- document.body.insertAdjacentElement("afterbegin", afterBeginNode);
1420
- }
1421
- }
1422
- function extractJson(responseText) {
1423
- const jsonMatch = responseText?.match(/\{[\s\S]*\}/);
1424
- return jsonMatch ? jsonMatch[0] : null;
1425
- }
1426
- function handleAfterRequest(functionOnlyAttribute, firstResponseText) {
1427
- if (!isJsonLike(functionOnlyAttribute)) return;
1428
- const functionOnlyData = parseJson(functionOnlyAttribute);
1429
- const responseData = firstResponseText ? parseJson(firstResponseText) : null;
1430
- const targets = functionOnlyData.targets; // Assuming targets is an array of objects
1431
- if (Array.isArray(targets)) {
1432
- targets.forEach((targetData) => {
1433
- const { id, ...restData } = targetData;
1434
- const targetToProcess = document.querySelector(id);
1435
- let targetAttributes = {};
1436
- if (responseData) {
1437
- for (const key in restData) {
1438
- if (restData.hasOwnProperty(key)) {
1439
- switch (key) {
1440
- case "innerHTML":
1441
- case "outerHTML":
1442
- case "textContent":
1443
- case "innerText":
1444
- if (restData[key] === "response") {
1445
- targetAttributes[key] = targetData.responseKey
1446
- ? responseData[targetData.responseKey]
1447
- : responseData.response;
1448
- }
1449
- break;
1450
- default:
1451
- targetAttributes[key] = restData[key];
1452
- break;
1453
- }
1454
- }
1455
- }
1456
- } else {
1457
- targetAttributes = restData;
1458
- }
1459
- if (targetToProcess) {
1460
- updateElementAttributes(targetToProcess, targetAttributes);
1461
- }
1462
- });
1463
- }
1464
- }
1465
- // Function to handle redirection without a full page reload
1466
- async function handleRedirect(url) {
1467
- if (!url) return;
1468
- try {
1469
- const fullUrl = new URL(url, window.location.origin);
1470
- const isExternal = fullUrl.origin !== window.location.origin;
1471
- if (isExternal) {
1472
- window.location.href = url;
1473
- } else {
1474
- history.pushState(null, "", url);
1475
- await handleNavigation();
1476
- }
1477
- } catch (error) {
1478
- console.error("Redirect error:", error);
1479
- }
1480
- }
1481
- /**
1482
- * Debounces a function to limit the rate at which it is called.
1483
- *
1484
- * The debounced function will postpone its execution until after the specified wait time
1485
- * has elapsed since the last time it was invoked. If `immediate` is `true`, the function
1486
- * will be called at the beginning of the wait period instead of at the end.
1487
- *
1488
- * @param {Function} func - The function to debounce.
1489
- * @param {number} [wait=300] - The number of milliseconds to wait before invoking the function.
1490
- * @param {boolean} [immediate=false] - If `true`, the function is invoked immediately on the leading edge.
1491
- * @returns {Function} - Returns the debounced version of the original function.
1492
- */
1493
- function debounce(func, wait = 300, immediate = false) {
1494
- let timeout;
1495
- return function (...args) {
1496
- const context = this;
1497
- if (timeout) clearTimeout(timeout);
1498
- timeout = setTimeout(() => {
1499
- timeout = null;
1500
- if (!immediate) func.apply(context, args);
1501
- }, wait);
1502
- if (immediate && !timeout) {
1503
- func.apply(context, args);
1504
- }
1505
- };
1506
- }
1507
- /**
1508
- * Copies code to the clipboard and updates the button icon.
1509
- *
1510
- * @param {HTMLElement} btnElement - The button element that triggered the copy action.
1511
- * @param {string} containerClass - The class of the container element that contains the code block.
1512
- * @param {string} initialIconClass - The initial class for the icon.
1513
- * @param {string} successIconClass - The class for the icon after a successful copy.
1514
- * @param {number} [timeout=2000] - The time in milliseconds to revert to the initial icon class.
1515
- */
1516
- function copyCode(
1517
- btnElement,
1518
- containerClass,
1519
- initialIconClass,
1520
- successIconClass,
1521
- timeout = 2000
1522
- ) {
1523
- // Ensure btnElement is an instance of HTMLElement
1524
- if (!(btnElement instanceof HTMLElement)) return;
1525
- // Find the closest container with the specified class relative to the button
1526
- const codeBlock = btnElement
1527
- .closest(`.${containerClass}`)
1528
- ?.querySelector("pre code");
1529
- const textToCopy = codeBlock?.textContent?.trim() || ""; // Get the text content of the code block and trim whitespace
1530
- if (textToCopy) {
1531
- navigator.clipboard.writeText(textToCopy).then(
1532
- () => {
1533
- // Clipboard successfully set
1534
- const icon = btnElement.querySelector("i");
1535
- if (icon) {
1536
- icon.className = successIconClass; // Change to success icon
1537
- }
1538
- // Set a timeout to change the icon back to initial after the specified timeout
1539
- setTimeout(() => {
1540
- if (icon) {
1541
- icon.className = initialIconClass; // Change back to initial icon
1542
- }
1543
- }, timeout); // Timeout delay
1544
- },
1545
- () => {
1546
- // Clipboard write failed
1547
- alert("Failed to copy command to clipboard");
1548
- }
1549
- );
1550
- } else {
1551
- alert("Failed to find the code block to copy");
1552
- }
1553
- }
1554
- if (store === null) {
1555
- class StateManager {
1556
- static instance = null;
1557
- state;
1558
- listeners;
1559
- /**
1560
- * Creates a new StateManager instance.
1561
- *
1562
- * @param {State} [initialState={}] - The initial state.
1563
- */
1564
- constructor(initialState = {}) {
1565
- this.state = initialState;
1566
- this.listeners = [];
1567
- }
1568
- /**
1569
- * Gets the singleton instance of StateManager.
1570
- *
1571
- * @param {State} [initialState={}] - The initial state.
1572
- * @returns {StateManager} - The StateManager instance.
1573
- */
1574
- static getInstance(initialState = {}) {
1575
- if (!StateManager.instance) {
1576
- StateManager.instance = new StateManager(initialState);
1577
- StateManager.instance.loadState(); // Load state immediately after instance creation
1578
- }
1579
- return StateManager.instance;
1580
- }
1581
- /**
1582
- * Sets the state.
1583
- *
1584
- * @param {Partial<State>} update - The state update.
1585
- */
1586
- setState(update) {
1587
- this.state = { ...this.state, ...update };
1588
- this.listeners.forEach((listener) => listener(this.state));
1589
- this.saveState();
1590
- }
1591
- /**
1592
- * Subscribes to state changes.
1593
- *
1594
- * @param {(state: State) => void} listener - The listener function.
1595
- * @returns {() => void} - A function to unsubscribe the listener.
1596
- */
1597
- subscribe(listener) {
1598
- this.listeners.push(listener);
1599
- listener(this.state); // Immediately invoke the listener with the current state
1600
- return () => {
1601
- this.listeners = this.listeners.filter((l) => l !== listener);
1602
- };
1603
- }
1604
- /**
1605
- * Saves the state to localStorage.
1606
- */
1607
- saveState() {
1608
- localStorage.setItem("appState_59E13", JSON.stringify(this.state));
1609
- }
1610
- /**
1611
- * Loads the state from localStorage.
1612
- */
1613
- loadState() {
1614
- const state = localStorage.getItem("appState_59E13");
1615
- if (state) {
1616
- this.state = JSON.parse(state);
1617
- this.listeners.forEach((listener) => listener(this.state));
1618
- }
1619
- }
1620
- /**
1621
- * Resets the state to its initial value.
1622
- * This will also clear the state from localStorage.
1623
- */
1624
- resetState() {
1625
- this.state = {}; // Reset the state to an empty object or a default state if you prefer
1626
- this.listeners.forEach((listener) => listener(this.state));
1627
- localStorage.removeItem("appState_59E13"); // Clear the state from localStorage
1628
- }
1629
- }
1630
- store = StateManager.getInstance();
1631
- }
1
+ var eventAttributesB6B56=["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"],stateA129A={checkedElements:new Set},responseDataDEAC2=null,store=null,isNavigatingA12E1=!1,redirectRegex3AE99=/redirect_7F834\s*=\s*(\/[^\s]+)/;function attachWireFunctionEvents(){handleHiddenAttribute();document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((e=>{if(handleAnchorTag(e),eventAttributesB6B56.forEach((t=>{const n=e.getAttribute(t),s=t.slice(2);n&&(e.removeAttribute(t),handleDebounce(e,s,n))})),e instanceof HTMLFormElement){const t=e.getAttribute("onsubmit");t&&(e.removeAttribute("onsubmit"),handleDebounce(e,"submit",t))}})),initializePpOnListeners()}function hasPpOnAttribute(e){const t=e.attributes;if(!t)return!1;for(let e=0;e<t.length;e++){const n=t[e].name;if(n.startsWith("pp-on:")||n.startsWith("data-pp-on:")||n.startsWith("pp-on-")||n.startsWith("data-pp-on-"))return!0}return!1}function findAllPpOnElements(e){const t=[];if(hasPpOnAttribute(e)&&t.push(e),document.evaluate){const n=document.evaluate('.//*[@*[starts-with(name(), "pp-on:") or starts-with(name(), "data-pp-on:") or starts-with(name(), "pp-on-") or starts-with(name(), "data-pp-on-")]]',e,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);let s=n.iterateNext();for(;s;)t.push(s),s=n.iterateNext()}else if("function"==typeof e.getElementsByTagName){const n=e.getElementsByTagName("*");for(let e=0;e<n.length;e++)hasPpOnAttribute(n[e])&&t.push(n[e])}return t}function initializePpOnListeners(){findAllPpOnElements(document).forEach((e=>{Array.from(e.attributes).forEach((t=>{if(t.name.startsWith("pp-on:")){const n=t.name.split(":")[1],s=t.value;s&&e.addEventListener(n,(t=>{try{new Function("event",s).call(e,t)}catch(e){}}))}}))}))}function handleHiddenAttribute(){const e=document.querySelectorAll("[pp-visibility]"),t=document.querySelectorAll("[pp-display]");e.forEach((e=>handleVisibilityElementAttribute(e,"pp-visibility",handleElementVisibility))),t.forEach((e=>handleVisibilityElementAttribute(e,"pp-display",handleElementDisplay)))}function handleVisibilityElementAttribute(e,t,n){const s=e.getAttribute(t);if(s)if(isJsonLike(s)){n(e,parseJson(s))}else{const n=parseTime(s);if(n>0){const s="pp-visibility"===t?"visibility":"display";scheduleChange(e,n,s,"visibility"===s?"hidden":"none")}}}function isJsonLike(e){return"string"==typeof e&&((e=e.trim()).startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))}function handleElementVisibility(e,t){handleElementChange(e,t,"visibility","hidden","visible")}function handleElementDisplay(e,t){handleElementChange(e,t,"display","none","block")}function handleElementChange(e,t,n,s,a){const o=t.start?parseTime(t.start):0,i=t.end?parseTime(t.end):0;o>0?(e.style[n]=s,scheduleChange(e,o,n,a),i>0&&scheduleChange(e,o+i,n,s)):i>0&&scheduleChange(e,i,n,s)}function scheduleChange(e,t,n,s){setTimeout((()=>{requestAnimationFrame((()=>{e.style[n]=s}))}),t)}function 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}async function handleDebounce(e,t,n){const s=e.getAttribute("pp-debounce")||"",a=e.getAttribute("pp-before-request")||"",o=e.getAttribute("pp-after-request")||"",i=async t=>{t.preventDefault();try{a&&await invokeHandler(e,a,t),await invokeHandler(e,n,t),o&&"@close"!==o&&await invokeHandler(e,o,t),handlerAutofocusAttribute()}catch(e){}};if(s){const n=debounce(i,parseTime(s));e instanceof HTMLFormElement&&"submit"===t?e.addEventListener(t,(e=>{e.preventDefault(),n(e)})):e.addEventListener(t,n)}else e.addEventListener(t,i)}function handlerAutofocusAttribute(){const e=document.querySelectorAll("[pp-autofocus]");let t=!1;e.forEach((e=>{if(t)return;const n=e.getAttribute("pp-autofocus");if(!n||!isJsonLike(n))return;const s=parseJson(n);if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)if("number"===e.type&&e instanceof HTMLInputElement){e.type="text";const t=e.value.length||0;e.setSelectionRange(t,t),e.type="number"}else if(s.start)e.setSelectionRange(0,0);else if(s.end){const t=e.value.length||0;e.setSelectionRange(t,t)}else if(s.length){const t=parseInt(s.length,10)||0;e.setSelectionRange(t,t)}e.focus(),t=!0}))}async function invokeHandler(e,t,n){try{const s=t.match(/^(\w+(\.\w+)*)\((.*)\)$/);if(s){const a=s[1].split("."),{context:o,methodName:i}=resolveContext(a);"function"==typeof o[i]?new Function("event",t).call(e,n):await handleParsedCallback(e,t)}else await handleParsedCallback(e,t)}catch(e){}}function 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]}}async function handleParsedCallback(e,t){const{funcName:n,data:s}=parseCallback(e,t);if(!n)return;const a=window[n];if("function"==typeof a){const t=e.hasAttribute("pp-after-request"),n=Array.isArray(s.args)?s.args:[],o=responseDataDEAC2?parseJson(responseDataDEAC2):{response:responseDataDEAC2};let i={args:n,element:e,data:s};t&&(i={...i,...o}),await a(i)}else responseDataDEAC2=null,responseDataDEAC2=await handleUndefinedFunction(e,n,s)}function 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(),!isNavigatingA12E1)){isNavigatingA12E1=!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[a,o]=n.split("#");o&&(s=`#${o}`);new URLSearchParams(a.split("?")[1]).forEach(((e,n)=>{t.set(n,e)}));const i=`${e.pathname}?${t.toString()}${s}`;history.pushState(null,"",i)}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 handleNavigation();const t=document.getElementById(e);t&&t.scrollIntoView({behavior:"smooth"})}}else await handleNavigation()}}catch(e){}finally{isNavigatingA12E1=!1}}}))}async function handleNavigation(){try{const e=e=>{const t=e.querySelector("[pp-loading-transition]")?.getAttribute("pp-loading-transition");let n=250,s=250;if(t)try{const e=parseJson(t);n=parseTime(e.fadeIn||n),s=parseTime(e.fadeOut||s)}catch(e){}return{fadeIn:n,fadeOut:s}},t=(e,t)=>new Promise((n=>{e.style.transition=`opacity ${t}ms ease-out`,e.style.opacity="0",setTimeout((()=>{e.style.transition="",n()}),t)})),n=(e,t)=>{e.style.transition=`opacity ${t}ms ease-in`,e.style.opacity="1",setTimeout((()=>{e.style.transition=""}),t)},s=async s=>{const a=document.querySelector("[pp-loading-content='true']")||document.body;if(a){const{fadeIn:o,fadeOut:i}=e(s);await t(a,i),a.innerHTML=s.innerHTML,n(a,o)}},a=window.location.pathname,o=document.getElementById("loading-file-1B87E");if(o){let e=o.querySelector(`div[pp-loading-url='${a}']`);e||(e=o.querySelector("div[pp-loading-url='/']")),e&&await s(e)}const i=await pphpFetch(window.location.href),r=i.match(redirectRegex3AE99);if(r&&r[1]){const e=r[1];await handleRedirect(e)}else updateDocumentContent(i)}catch(e){}}function onUrlChange(){}function updateDocumentContent(e){const t=saveScrollPositions();if(document.removeAllEventListeners("DOMContentLoaded"),e.includes("<!DOCTYPE html>")){const t=e=>{Array.from(e.head.children).forEach((e=>{const t=e.tagName;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}"]`);s?document.head.replaceChild(e.cloneNode(!0),s):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)}}})),loadAndValidateContent(e)};t((new DOMParser).parseFromString(e,"text/html"))}else{saveState();loadAndValidateContent((new DOMParser).parseFromString(e,"text/html")),restoreState()}restoreScrollPositions(t),attachWireFunctionEvents(),document.dispatchEvent(new Event("DOMContentLoaded"))}function loadAndValidateContent(e){const t=new Map,n=document.createDocumentFragment();function s(e,n){let a=null;if("SCRIPT"===e.tagName){const t=document.createElement("script"),n=e;n.src?(t.src=n.src,t.async=!1):t.textContent=n.textContent,a=t}else a=e.cloneNode(!1),t.set(e,a),Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.TEXT_NODE?a.appendChild(document.createTextNode(e.textContent||"")):e.nodeType===Node.ELEMENT_NODE&&s(e,a)}));n.appendChild(a)}Array.from(e.body.children).forEach((e=>{s(e,n)})),document.body.innerHTML="",document.body.appendChild(n)}function saveState(){const e=document.activeElement;stateA129A.focusId=e?.id||e?.name,stateA129A.focusValue=e?.value,stateA129A.focusChecked=e?.checked,stateA129A.focusType=e?.type,stateA129A.focusSelectionStart=e?.selectionStart,stateA129A.focusSelectionEnd=e?.selectionEnd,stateA129A.isSuspense=e.hasAttribute("pp-suspense"),stateA129A.checkedElements.clear(),document.querySelectorAll('input[type="checkbox"]:checked').forEach((e=>{stateA129A.checkedElements.add(e.id||e.name)})),document.querySelectorAll('input[type="radio"]:checked').forEach((e=>{stateA129A.checkedElements.add(e.id||e.name)}))}function restoreState(){if(stateA129A.focusId){const e=document.getElementById(stateA129A.focusId)||document.querySelector(`[name="${stateA129A.focusId}"]`);if(e instanceof HTMLInputElement){const t=e.value.length||0;void 0!==stateA129A.focusSelectionStart&&null!==stateA129A.focusSelectionEnd&&e.setSelectionRange(t,t),stateA129A.focusValue&&("checkbox"===e.type||"radio"===e.type?e.checked=!!stateA129A.focusChecked:"number"===e.type?(e.type="text",e.setSelectionRange(t,t),e.type="number"):""!==e.value&&(e.value=stateA129A.focusValue)),e.focus()}else if(e instanceof HTMLTextAreaElement){const t=e.value.length||0;void 0!==stateA129A.focusSelectionStart&&null!==stateA129A.focusSelectionEnd&&e.setSelectionRange(t,t),stateA129A.focusValue&&""!==e.value&&(e.value=stateA129A.focusValue),e.focus()}else e instanceof HTMLSelectElement&&(stateA129A.focusValue&&""!==e.value&&(e.value=stateA129A.focusValue),e.focus())}stateA129A.checkedElements.forEach((e=>{const t=document.getElementById(e);t&&(t.checked=!0)}))}function saveScrollPositions(){const e={};return document.querySelectorAll("*").forEach((t=>{(t.scrollTop||t.scrollLeft)&&(e[getElementKey(t)]={scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})})),e}function restoreScrollPositions(e){document.querySelectorAll("*").forEach((t=>{const n=getElementKey(t);e[n]&&(t.scrollTop=e[n].scrollTop,t.scrollLeft=e[n].scrollLeft)}))}function getElementKey(e){return e.id||e.className||e.tagName}async function pphpFetch(e,t){const n=await fetch(e,{...t,headers:{...t?.headers,"X-Requested-With":"XMLHttpRequest"}});return await n.text()}function 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=handleInputElement(e):(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(n[e.name]=e.value);const a=t.match(/(\w+)\((.*)\)/);if(a){const e=a[1];let t=a[2].trim();if(t.startsWith("{")&&t.endsWith("}"))try{const e=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}}function 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}function updateElementAttributes(e,t){for(const n in t)if(t.hasOwnProperty(n))switch(n){case"innerHTML":case"outerHTML":case"textContent":case"innerText":e[n]=decodeHTML(t[n]);break;case"insertAdjacentHTML":e.insertAdjacentHTML(t.position||"beforeend",decodeHTML(t[n].html));break;case"insertAdjacentText":e.insertAdjacentText(t.position||"beforeend",decodeHTML(t[n].text));break;case"setAttribute":e.setAttribute(t.attrName,decodeHTML(t[n]));break;case"removeAttribute":e.removeAttribute(t[n]);break;case"className":e.className=decodeHTML(t[n]);break;case"classList.add":e.classList.add(...decodeHTML(t[n]).split(","));break;case"classList.remove":e.classList.remove(...decodeHTML(t[n]).split(","));break;case"classList.toggle":e.classList.toggle(decodeHTML(t[n]));break;case"classList.replace":const[s,a]=decodeHTML(t[n]).split(",");e.classList.replace(s,a);break;case"dataset":e.dataset[t.attrName]=decodeHTML(t[n]);break;case"style":Object.assign(e.style,t[n]);break;case"value":e.value=decodeHTML(t[n]);break;case"checked":e.checked=t[n];break;default:e.setAttribute(n,decodeHTML(t[n]))}}function decodeHTML(e){const t=document.createElement("textarea");return t.innerHTML=e,t.value}function 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))}e.querySelectorAll("[pp-suspense]").forEach((e=>saveElementOriginalState(e)))}async function 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(isJsonLike(e)){const n=parseJson(e);"disabled"!==n.onsubmit&&updateElementAttributes(t,n),n.targets&&n.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&a(s,n)}))}else s(t,e)}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},a=(e,t)=>{e instanceof HTMLFormElement?n(e,t):updateElementAttributes(e,t)};try{if(t&&isJsonLike(t)){const s=parseJson(t);if(s)if(e instanceof HTMLFormElement){const t=new FormData(e),a={};t.forEach(((e,t)=>{a[t]=e})),s.disabled&&toggleFormElements(e,!0);const{disabled:o,...i}=s;updateElementAttributes(e,i),n(e,a)}else if(s.targets){s.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&a(s,n)}));const{targets:t,...n}=s;updateElementAttributes(e,n)}else{if("disabled"===s.empty&&""===e.value)return;const{empty:t,...n}=s;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){}}function 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(isJsonLike(e)){const s=parseJson(e);n(t,s)}else a(t,e);t.removeAttribute("pp-original-state")}}},a=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},o=(e,t)=>{e instanceof HTMLFormElement?s(e,t):n(e,t)};try{const a=JSON.parse(t);if(a)if(e instanceof HTMLFormElement){const t=new FormData(e),n={};if(t.forEach(((e,t)=>{n[t]=e})),s(e,n),e.hasAttribute("pp-suspense")){const t=e.getAttribute("pp-suspense")||"";if(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(a.targets){a.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&o(s,n)}));const{targets:t,...s}=a;n(e,s)}else{const{empty:t,...s}=a;n(e,s)}}catch(e){}}e.querySelectorAll("[pp-suspense]").forEach((e=>restoreSuspenseElement(e))),e.removeAttribute("pp-original-state")}function parseJson(e){try{return isJsonLike(e)?(e=(e=(e=(e=(e=(e=(e=(e=e.replace(/\\'/g,"'")).replace(/(?<!\\)'/g,'"')).replace(/[\u2018\u2019]/g,"'").replace(/[\u201C\u201D]/g,'"')).replace(/(\w)"s/g,"$1's")).replace(/(\w)"(\w)/g,"$1'$2")).replace(/"(\w+)"\s*([\[\{])/g,'"$1": $2')).replace(/(\w+)\s*([\[\{])/g,'"$1": $2')).replace(/\\([^"\\/bfnrtu])/g,"\\\\$1"),JSON.parse(e)):null}catch(e){const t=e.message.match(/position (\d+)/);t&&parseInt(t[1]);return null}}function toggleFormElements(e,t){Array.from(e.elements).forEach((e=>{(e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(e.disabled=t)}))}async function pphpFetchFile(e,t,n){const s=new FormData,a=n.files;if(a)for(let e=0;e<a.length;e++)s.append("file[]",a[e]);s.append("callback",t);const o=await fetch(e,{method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:s});return await o.text()}async function handleUndefinedFunction(e,t,n){const s=createFetchOptions({callback:t,...n}),a=createFetchOptions({secondRequestC69CD:!0});try{saveElementOriginalState(e),handleSuspenseElement(e);const n=window.location.pathname;let o="",i="",r={success:!1};const c=e.querySelector("input[type='file']");if(c){if(o=await pphpFetchFile(n,t,c),i=extractJson(o)||"",i)try{r=JSON.parse(i)}catch(e){}}else if(o=await pphpFetch(n,s),i=extractJson(o)||"",i)try{r=JSON.parse(i)}catch(e){}const l=hasPpOnAttribute(e),u=e.getAttribute("pp-before-request")||"",d=e.getAttribute("pp-after-request")||"";if((l||u||d&&r.success)&&restoreSuspenseElement(e),l||u||d){let e="";if(r.success){e=o.replace(i,"")}else e=o;if(appendAfterbegin(e),!d&&!r.success)return}if(d&&r.success){handleAfterRequest(d,i);return appendAfterbegin(o.replace(i,"")),i}const p=await pphpFetch(n,a);await handleResponseRedirectOrUpdate(o,p,i,r)}catch(e){}}function createFetchOptions(e){return{method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(e)}}async function handleResponseRedirectOrUpdate(e,t,n,s){const a=e.match(redirectRegex3AE99);if(a&&a[1])await handleRedirect(a[1]);else{const a=(new DOMParser).parseFromString(t,"text/html");let o=document.createElement("div");if(o.id="afterbegin-8D95D",n)if(s.success){const t=e.replace(n,"");o.innerHTML=t}else o.innerHTML=e;else o.innerHTML=e;o.innerHTML&&a.body.insertAdjacentElement("afterbegin",o),updateDocumentContent(a.body.outerHTML)}}function 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))}function extractJson(e){const t=e?.match(/\{[\s\S]*\}/);return t?t[0]:null}function handleAfterRequest(e,t){if(!isJsonLike(e))return;const n=parseJson(e),s=t?parseJson(t):null,a=n.targets;Array.isArray(a)&&a.forEach((e=>{const{id:t,...n}=e,a=document.querySelector(t);let o={};if(s){for(const t in n)if(n.hasOwnProperty(t))switch(t){case"innerHTML":case"outerHTML":case"textContent":case"innerText":"response"===n[t]&&(o[t]=e.responseKey?s[e.responseKey]:s.response);break;default:o[t]=n[t];break}}else o=n;a&&updateElementAttributes(a,o)}))}async function handleRedirect(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 handleNavigation())}catch(e){}}function debounce(e,t=300,n=!1){let s;return function(...a){const o=this;s&&clearTimeout(s),s=setTimeout((()=>{s=null,n||e.apply(o,a)}),t),n&&!s&&e.apply(o,a)}}function copyCode(e,t,n,s,a=2e3){if(!(e instanceof HTMLElement))return;const o=e.closest(`.${t}`)?.querySelector("pre code"),i=o?.textContent?.trim()||"";i?navigator.clipboard.writeText(i).then((()=>{const t=e.querySelector("i");t&&(t.className=s),setTimeout((()=>{t&&(t.className=n)}),a)}),(()=>{alert("Failed to copy command to clipboard")})):alert("Failed to find the code block to copy")}if((()=>{const e=EventTarget.prototype.addEventListener,t=new Map;EventTarget.prototype.addEventListener=function(n,s,a){t.has(this)||t.set(this,new Map);const o=t.get(this).get(n)||new Set;o.add(s),t.get(this).set(n,o),e.call(this,n,s,a)},EventTarget.prototype.removeAllEventListeners=function(e){t.has(this)&&t.get(this).has(e)&&(t.get(this).get(e).forEach((t=>{this.removeEventListener(e,t)})),t.get(this).delete(e))}})(),(e=>{const t=e.pushState,n=e.replaceState;e.pushState=function(n,s,a){const o=t.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),o},e.replaceState=function(t,s,a){const o=n.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),o}})(window.history),document.addEventListener("DOMContentLoaded",attachWireFunctionEvents),window.addEventListener("popstate",(async()=>{await handleNavigation()})),window.addEventListener("urlchange",(()=>{})),null===store){class e{static instance=null;state;listeners;constructor(e={}){this.state=e,this.listeners=[]}static getInstance(t={}){return e.instance||(e.instance=new e(t),e.instance.loadState()),e.instance}setState(e){this.state={...this.state,...e},this.listeners.forEach((e=>e(this.state))),this.saveState()}subscribe(e){return this.listeners.push(e),e(this.state),()=>{this.listeners=this.listeners.filter((t=>t!==e))}}saveState(){localStorage.setItem("appState_59E13",JSON.stringify(this.state))}loadState(){const e=localStorage.getItem("appState_59E13");e&&(this.state=JSON.parse(e),this.listeners.forEach((e=>e(this.state))))}resetState(){this.state={},this.listeners.forEach((e=>e(this.state))),localStorage.removeItem("appState_59E13")}}store=e.getInstance()}