PageSourceSearch

https://apis.oono.ai/static/embedScript.js

js oono.ai collected 2026-10-05 14:59:37 UTC 68,171 bytes, 1,837 lines download raw bytes

1(function () {
2  // Initialize global resources only once
3  if (!window._oonoInitialized) {
4    window._oonoInitialized = true;
5    
6    // Create in-memory storage fallback
7    const memoryStorage = {};
8    
9    // Storage wrapper to handle cases where localStorage is denied
10    window._oonoStorageWrapper = {
11      getItem: function(key) {
12        try {
13          return localStorage.getItem(key);
14        } catch (e) {
15          return memoryStorage[key] || null;
16        }
17      },
18      setItem: function(key, value) {
19        try {
20          localStorage.setItem(key, value);
21        } catch (error) {}
22        finally {
23          memoryStorage[key] = value;
24        }
25      },
26      removeItem: function(key) {
27        try {
28          localStorage.removeItem(key);
29        } catch (e) {
30          delete memoryStorage[key];
31        }
32      }
33    };
34    
35    // Initialize global variables
36    if (typeof window._oonoStoriesInQuestion === 'undefined') {
37      window._oonoStoriesInQuestion = [];
38    }
39
40    // Global constants
41    window._oonoIsProd = true;
42    window._oonoGetJsonCUrl = () =>
43      `https://media${window._oonoIsProd ? "-live" : ""}.oono.ai/carousal`;
44
45    // Global functions
46    window._oonoLoadSocketIO = function() {
47      return new Promise((resolve, reject) => {
48        const script = document.createElement("script");
49        script.src = "https://cdn.socket.io/4.8.1/socket.io.min.js";
50        script.onload = () => {
51          resolve();
52        };
53        script.onerror = () => {
54          reject("Failed to load Socket.IO script");
55        };
56        document.head.appendChild(script);
57      });
58    };
59
60    window._oonoInitSocketIO = async function(url) {
61      if (window._oonoSocket && window._oonoSocket.connected) {
62        return window._oonoSocket;
63      }
64
65      try {
66        await window._oonoLoadSocketIO();
67        window._oonoSocket = io(url);
68        
69        window._oonoSocket.on("connect", () => {
70          console.log("Connected to the server");
71        });
72        window._oonoSocket.on("disconnect", () => {
73          console.log("Disconnected from the server");
74        });
75        return window._oonoSocket;
76      } catch (error) {
77        console.error("Error initializing Socket.IO:", error);
78        throw error;
79      }
80    };
81
82    window._oonoEmitEvent = async function(url, event, data) {
83      try {
84        console.log("action: ", data.action)
85        const socket = await window._oonoInitSocketIO(url);
86        socket.emit(event, data);
87      } catch (error) {
88        console.error("Error emitting event:", error);
89      }
90    };
91
92    window._oonoGetCountry = async function() {
93      try {
94        const countryValue = window._oonoStorageWrapper.getItem("country");
95        if (countryValue && countryValue != "undefined") return countryValue;
96        const response = await fetch("https://ipinfo.io/json");
97        const data = await response.json();
98        window._oonoStorageWrapper.setItem("country", data.country);
99        return data.country;
100      } catch (error) {
101        console.error("Error fetching location data:", error);
102      }
103    };
104
105    window._oonoGetDeviceType = function() {
106      return /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(
107        navigator.userAgent
108      )
109        ? "mobile"
110        : "web";
111    };
112
113    window._oonoGetCollection = function(collectionId) {
114      const colData = JSON.parse(window._oonoStorageWrapper.getItem(`data_${collectionId}`)) || null;
115      return colData;
116    };
117
118    window._oonoGetCollectionId = function(collectionId) {
119      const colData = JSON.parse(window._oonoStorageWrapper.getItem(`jsonData_${collectionId}`)) || null;
120      return colData?._id;
121    };
122
123    // Helper function to get collection code and name for URL
124    window._oonoGetCollectionCodeAndName = function(collectionId) {
125      const colData = JSON.parse(window._oonoStorageWrapper.getItem(`jsonData_${collectionId}`)) || null;
126      if (colData?.code) {
127        return {
128          code: colData.code,
129          name: colData.name || ''
130        };
131      }
132      return null;
133    };
134
135    // Helper function to set URL parameters based on collection type
136    window._oonoSetCollectionUrlParams = function(url, collectionId, storyNumber = 0) {
137      const collectionData = window._oonoGetCollectionCodeAndName(collectionId);
138      
139      if (collectionData) {
140        const formattedName = collectionData.name.replace(/\s+/g, '-');
141        // Clear existing parameters first
142        url.searchParams.delete("c");
143        url.searchParams.delete("story");
144        url.searchParams.delete("oono");
145        // Set parameters in correct order: c first, then story
146        url.searchParams.set("c", `${collectionData.code}-${formattedName}`);
147        url.searchParams.set("story", storyNumber.toString());
148      } else {
149        // Old format: oono={collectionId}&story={storyNumber}
150        // Clear existing parameters first
151        url.searchParams.delete("oono");
152        url.searchParams.delete("story");
153        url.searchParams.delete("c");
154        // Set parameters in correct order: oono first, then story
155        url.searchParams.set("oono", collectionId);
156        url.searchParams.set("story", storyNumber.toString());
157      }
158    };
159
160    // Helper function to get collection ID from URL (supports both formats)
161    window._oonoGetCollectionIdFromUrl = function(url) {
162      // Check new format first
163      const newFormat = url.searchParams.get("c");
164      if (newFormat) {
165        const code = newFormat.split('-')[0]; // Extract code part
166        // Find collection by code by checking all stored collection data
167        try {
168          const allKeys = Object.keys(localStorage || {}).filter(key => key.startsWith('jsonData_'));
169          for (const key of allKeys) {
170            try {
171              const collectionId = key.replace('jsonData_', '');
172              const colData = JSON.parse(window._oonoStorageWrapper.getItem(`jsonData_${collectionId}`)) || null;
173              if (colData?.code === code) {
174                return collectionId;
175              }
176            } catch (e) {
177              // Skip invalid JSON
178            }
179          }
180        } catch (e) {
181          console.warn('Error accessing localStorage:', e);
182        }
183      }
184      
185      // Fallback to old format
186      return url.searchParams.get("oono");
187    };
188
189    // Helper function to get story number from URL
190    window._oonoGetStoryNumberFromUrl = function(url) {
191      return url.searchParams.get("story");
192    };
193  }
194
195  const storageWrapper = window._oonoStorageWrapper;
196  const isProd = window._oonoIsProd;
197  const getJsonCUrl = window._oonoGetJsonCUrl;
198  const loadSocketIO = window._oonoLoadSocketIO;
199  const initSocketIO = window._oonoInitSocketIO;
200  const EmitEvent = window._oonoEmitEvent;
201  const getCountry = window._oonoGetCountry;
202  const getDeviceType = window._oonoGetDeviceType;
203  const getCollection = window._oonoGetCollection;
204  const getCollectionId = window._oonoGetCollectionId;
205  const getCollectionCodeAndName = window._oonoGetCollectionCodeAndName;
206  const setCollectionUrlParams = window._oonoSetCollectionUrlParams;
207  const getCollectionIdFromUrl = window._oonoGetCollectionIdFromUrl;
208  const getStoryNumberFromUrl = window._oonoGetStoryNumberFromUrl;
209  window._oonoFirstClick = window._oonoFirstClick || false;
210
211  function initOonoStories() {
212    // Prevent multiple initializations especially on mobile
213    if (window._oonoStoriesInitialized) {
214      return;
215    }
216    window._oonoStoriesInitialized = true;
217    
218    const scriptTag =
219      document.currentScript ||
220      Array.from(document.getElementsByTagName("script")).pop();
221    const urlParams = new URLSearchParams(new URL(scriptTag.src).search);
222    const brandId = urlParams.get("brandId");
223    const url = new URL(window.location);
224    const collectionSlug = getCollectionIdFromUrl(url);
225    if (collectionSlug && brandId) {
226      fetch(`${getJsonCUrl()}/${brandId}.json`)
227        .then((response) => response.json())
228        .then((data) => {
229          data?.collections?.forEach((id) => {
230            if (id == collectionSlug) {
231              const newConfig = {
232                collectionId: id,
233                isProd: isProd,
234              };
235              const newDiv = document.createElement("div");
236              newDiv.id = "oono-stories-container";
237              newDiv.style.display = "flex";
238              newDiv.style.overflow = "auto";
239              initializeStories(newDiv, newConfig);
240              document.body.appendChild(newDiv);
241            }
242          });
243        });
244    }
245    document.querySelectorAll('div[id^="oono-stories"]').forEach((div) => {
246      if (!div.getAttribute("data-initialized")) {
247        div.setAttribute("data-initialized", "true");
248
249        const config = JSON.parse(div.getAttribute("data-config"));
250
251        const styleElement = document.createElement("style");
252        styleElement.textContent = `
253            @keyframes shimmer {
254              0% { background-position: -200% 0; }
255              100% { background-position: 200% 0; }
256            }
257  
258            .skeleton-loader {
259              display: block;
260              aspect-ratio: 9 / 16;
261              height: 400px;
262              background: linear-gradient(90deg, #e0e0e0 25%, #f5f5f5 50%, #e0e0e0 75%);
263              background-size: 200% 100%;
264              animation: shimmer 1.5s infinite linear;
265              border-radius: 16px;
266              margin-right: 10px;
267            }
268  
269            .skeleton-container {
270              display: flex;
271            }
272          `;
273        document.head.appendChild(styleElement);
274        const skeletonContainer = document.createElement("div");
275        skeletonContainer.className = "skeleton-container";
276        const skeletonLoader = document.createElement("div");
277        skeletonLoader.className = "skeleton-loader";
278        skeletonContainer.appendChild(skeletonLoader);
279
280        div.appendChild(skeletonContainer);
281
282        const updatedConfig = {
283          ...config,
284          isProd: isProd,
285        };
286
287        if (!config.carouselId) {
288          initializeStories(div, updatedConfig);
289        } else {
290          let isLoading = true;
291
292          const updateSkeletonVisibility = () => {
293            skeletonContainer.style.display = isLoading ? "flex" : "none";
294          };
295
296          updateSkeletonVisibility();
297
298          fetch(`${getJsonCUrl()}/${config.carouselId}.json`)
299            .then((response) => response.json())
300            .then((data) => {
301              isLoading = false;
302              updateSkeletonVisibility();
303
304              if (data?.enabled) {
305                const mainDiv = document.createElement("div");
306                mainDiv.className = "oono-carousel-container";
307                mainDiv.style.display = "flex";
308                mainDiv.style.overflow = "auto";
309
310                const styleElement = document.createElement("style");
311                styleElement.textContent = `
312                            .oono-carousel-container {
313                              overflow: auto;
314                            }
315                            .oono-carousel-container::-webkit-scrollbar { 
316                              display: none; 
317                            }
318                            .oono-carousel-container {
319                              -ms-overflow-style: none; 
320                              scrollbar-width: none; 
321                            }
322                          `;
323                document.head.appendChild(styleElement);
324                div.appendChild(mainDiv);
325
326                if (data.carousalSetting && data.carousalSetting.length > 0) {
327                  data.carousalSetting[0].collectionIds.forEach((id) => {
328                    const newDiv = document.createElement("div");
329                    newDiv.id = "oono-stories-container";
330                    const newConfig = {
331                      ...config,
332                      collectionId: id,
333                      type: "carousel",
334                      height: data.carousalSetting[0].height,
335                      brandId: data.carousalSetting[0].brandSlug,
336                      brandRealId: data.brand,
337                      isProd: isProd,
338                    };
339                    newDiv.setAttribute(
340                      "data-config",
341                      JSON.stringify(newConfig)
342                    );
343                    newDiv.setAttribute("data-initialized", "true");
344                    mainDiv.appendChild(newDiv);
345                    initializeStories(newDiv, newConfig);
346                  });
347                }
348              }
349            });
350        }
351      }
352    });
353    document.querySelectorAll("body *").forEach((el) => {
354      if (!el.childNodes) return;
355      el.childNodes.forEach((node, index) => {
356        if (node.nodeType === Node.TEXT_NODE) {
357          const matches = node.nodeValue.match(/{{oono-([a-z0-9]+)}}/gi);
358          if (matches) {
359            matches.forEach((match) => {
360              const collectionId = match.match(/{{oono-([a-z0-9]+)}}/i)[1];
361              const newConfig = {
362                collectionId: collectionId,
363                isProd: isProd,
364                type: "link",
365                text: node.nodeValue, // Keep the text so initializeStories handles it
366                index: index,
367              };
368              const newDiv = document.createElement("div");
369              newDiv.id = `oono-stories-container-${collectionId}`;
370              newDiv.style.display = "flex";
371              newDiv.style.overflow = "auto";
372              initializeStories(newDiv, newConfig);
373              const fragment = document.createDocumentFragment();
374              fragment.appendChild(newDiv);
375              el.replaceChild(fragment, node);
376            });
377          }
378        }
379      });
380    });
381
382    const anchorTags = document.querySelectorAll('a[href*="oono="], a[href*="c="]');
383    anchorTags.forEach((anchor) => {
384      const url = new URL(anchor.href);
385      const collectionId = getCollectionIdFromUrl(url);
386      if (collectionId) {
387        const wrapper = document.createElement("span");
388        wrapper.id = "wrapper";
389        document.body.appendChild(wrapper);
390        anchor.id = "anchor";
391        initializeStories(wrapper, {
392          type: "anchor",
393          collectionId,
394          isProd: isProd,
395          anchor: anchor,
396        });
397      }
398    });
399  }
400
401function initializeStories(
402  container,
403  {
404    collectionId,
405    brandId,
406    position,
407    type,
408    positionType,
409    style,
410    index,
411    height,
412    text,
413    isProd,
414    anchor,
415    brandRealId,
416  }
417) {
418  console.log("br", brandRealId);
419  if (!container.shadowRoot) {
420    const shadowRoot = container.attachShadow({ mode: "open" });
421
422    const getAWSMediaURL = (url) => {
423      return url
424        ? `https://media${isProd ? "-live" : ""}.oono.ai/uploads/` + url
425        : "";
426    };
427    const getJsonUrl = () =>
428      `https://media${isProd ? "-live" : ""}.oono.ai/meta_data`;
429    const backendUrl = isProd
430      ? "https://apis.oono.ai"
431      : "https://staging-apis-v2.oono.ai";
432    const webStoriesUrl = isProd
433      ? "https://oono.ai"
434      : "https://staging-brand.oono.ai";
435
436    const generateUniqueId = () => {
437      const uniqueId = Array(6)
438        .fill(0)
439        .map(() => Math.random().toString(36).substring(2))
440        .join("")
441        .substring(0, 36);
442      storageWrapper.setItem("uniqueId", uniqueId);
443    };
444
445    if (!storageWrapper.getItem("uniqueId")) {
446      generateUniqueId();
447    }
448
449    EmitEvent(backendUrl, "stories-stats", {
450      collectionId: getCollectionId(collectionId),
451      brandId: brandRealId,
452      identifier: storageWrapper.getItem("uniqueId"),
453      action: 8,
454    });
455
456    shadowRoot.innerHTML = `
457        <style>
458        ${
459          type === "carousel"
460            ? `
461        .oono-carousel-container {
462        display: flex;
463        overflow-x: auto;
464        scroll-behavior: smooth;
465        padding: 20px;
466        height: ${height + height * 0.1}px;
467        }
468        `
469            : ""
470        }
471        .carousel-item {
472        cursor: pointer;
473        position: relative;
474        flex-shrink: 0;
475        border-radius: 16px;
476        width: 100%;
477        height: ${height + height * 0.05}px;
478        overflow: hidden;
479        transition: transform 0.2s ease-in-out;
480        }
481        .carousel-item img {
482        box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.15);
483        object-fit: cover;
484        border-radius: 16px;
485        height: ${height}px;
486        aspect-ratio: 9/16;
487        }
488        .carousel-item:hover {
489          transform: scale(1.1);
490        }
491        
492        .link-click {
493        text-decoration: underline;
494        background-color: transparent;
495        cursor: pointer;
496        }
497         
498        .avatar-overlay {
499        position: absolute;
500        bottom: -20px;
501        right: 20px;
502        z-index: 1;
503        left: 50%;
504        transform: translateX(-50%);
505        width: 60px;
506        height: 60px;
507        border-radius: 50%;
508        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
509        }
510        #playButton {
511        z-index: 2147483647;
512        padding: 10px 20px;
513        font-size: 16px;
514        color: ${style?.labelColor ? style.labelColor : "#fff"};
515        width: ${style?.width ? style.width : "auto"};
516        height: ${style?.height ? style.height : "auto"};
517        border: ${style?.border ? style.border : "none"};
518        border-radius: ${style?.borderRadius ? style.borderRadius : "30px"};
519        cursor: pointer;
520        transition: background-color 0.3s, transform 0.3s;
521        background-color: ${style?.background ? style.background : "#007BFF"};
522        }
523        #playButton:active, #Widget:active {
524        transform: scale(0.98);
525        }
526        #storyModal {
527        z-index: -1;
528        display: flex;
529        align-items: center;
530        justify-content: center;
531        opacity: -1;
532        }
533        #Widget {
534        border: none;
535        background-color: #20E5F9;
536        cursor: pointer;
537        }
538        #oono-stories-container {
539        position: relative;
540        }
541        #imgDiv {
542        z-index: 214748;
543        background-color: white;
544        border-radius: 50%;
545        width: 65px;
546        display: flex;
547        justify-content: center;
548        align-items: center;
549        height: 65px;
550        ${position === "top-right" ? "top: 50px; right: 50px;" : ""}
551        ${position === "top-left" ? "top: 50px; left: 50px;" : ""}
552        ${position === "bottom-right" ? "bottom: 50px; right: 50px;" : ""}
553        ${position === "bottom-left" ? "bottom: 50px; left: 50px;" : ""}
554        position: ${
555          positionType === "float"
556            ? "fixed"
557            : positionType === "fixed"
558            ? "static"
559            : "absolute"
560        };
561        }
562        .lightbox {
563        z-index: 2147483647;
564        display: none;
565        position: fixed;
566        top: 0;
567        left: 0;
568        width: 100%;
569        height: 100%;
570        background-color: rgba(0, 0, 0, 0.8);
571        align-items: center;
572        justify-content: center;
573        visibility: visible;
574        opacity: 1;
575        }
576        amp-story-player.my-player {
577        height: 100vh !important;
578        width: 100vw !important;
579        overflow: hidden !important;
580        }
581        @media (max-width: 500px) {
582        amp-story-player.my-player {
583        height: 100% !important;
584        }
585        }
586        #imgDiv img {
587        cursor: pointer;
588        border-radius: 50%;
589        }
590        #ring {
591        z-index: 214748;
592        position: absolute;
593        cursor: pointer;
594        width: 70px;
595        height: 70px;
596        display: flex;
597        justify-content: center;
598        align-items: center;
599        border-radius: 50%;
600        background: conic-gradient(from 0deg, #ff8a00, #e52e71, #9b51e0, #4a00e0, #ff8a00);
601        ${position === "top-right" ? "top: 48px; right: 48px;" : ""}
602        ${position === "top-left" ? "top: 48px; left: 48px;" : ""}
603        ${position === "bottom-right" ? "bottom: 48px; right: 48px;" : ""}
604        ${position === "bottom-left" ? "bottom: 48px; left: 48px;" : ""}
605        position: ${
606          positionType === "float"
607            ? "fixed"
608            : positionType === "fixed"
609            ? "static"
610            : "absolute"
611        };
612        }
613        #playerInitialize {
614        width: ${style?.width ? style.width : "350px"};
615        height: ${style?.height ? style.height : "550px"};
616        cursor: pointer;
617        overflow: hidden;
618        position: relative;
619        z-index: 9999999 !important;
620        }
621  
622        .progress-bar-container {
623        position: absolute;
624        top: 10px;
625        left: 10px;
626        right: 10px;
627        display: flex;
628        gap: 5px;
629        }
630        .progress-bar {
631          flex: 1;
632          height: 4px;
633          background: rgba(131, 128, 128, 0.5);
634          opacity: 0.5;
635          border-radius: 4px;
636        }
637        .progress-bar1 {
638          flex: 1;
639          height: 4px;
640   box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
641          background: white;
642          border-radius: 4px;
643        }
644        .inPage-player {
645          z-index: 100;
646        }
647        #no-stories {
648          width: 100vw;
649          background-color: #f5f5f5;
650          height: 100vh;
651          overflow: hidden !important;
652          z-index: 1222221;
653          position: absolute;
654          top: 0;
655          display: none;
656          align-items: center;
657          justify-content: center;
658          flex-direction: column;
659          font-family: Arial, sans-serif;
660        }
661        .image-container {
662         position: relative;
663         width: ${style?.width ? style.width : "198px"};
664         height: ${style?.width ? style.height : "368px"};
665         aspect-ratio: 9/16;
666         display: none;
667         overflow: hidden;
668        transition: transform 0.2s ease-in-out;
669         border-radius: ${style?.borderRadius ? style.borderRadius : "8px"};
670         border: 1px solid rgb(236, 234, 234);
671        }
672  
673        .image-container:hover {
674          transform: scale(1.03);
675        }
676        
677        #collectionImage {
678          width: 100%;
679          height: 100%;
680          cursor: pointer;
681          overflow: hidden;
682          position: relative;
683        }
684       .image-container img {
685        width: 100%;
686        height: 100%;
687        object-fit: contain;
688        transition: transform 0.2s ease-in-out;
689        }
690      
691        
692        .image-container:hover #collectionImage img {
693        transform: scale(1.02);
694        }
695        #no-stories a {
696          font-family: Arial, sans-serif;
697          font-size: 20px;
698          text-decoration: none;
699        }
700        @media (max-width: 500px) {
701          #no-stories h2, #no-stories a {
702          font-size: 1.3em;
703          text-align: center;
704          }
705        }
706        #imgDivMain {
707          cursor: pointer;
708        }
709        </style>
710        ${
711          type === "button"
712            ? `<div id="playButtonDiv"><button id="playButton">${
713                style?.label ? style?.label : "Open Collection"
714              }</button></div>`
715            : ""
716        }
717        ${
718          type === "floating"
719            ? `
720        <div id="imgDivMain">
721          <div id="ring"></div>
722          <div id="imgDiv">
723          <img src="${backendUrl}/media/avatar/default.png" width="50px" height="50px" />
724          </div>
725        </div>`
726            : ""
727        }     
728        ${
729          type === "inPage"
730            ? ` 
731            <div class = "inPage-loader-container">
732            <div class="image-container">
733            <div id="collectionImage"></div>
734            <div class="progress-bar-container"></div>
735            </div>
736            </div>`
737            : ""
738        }
739        <div id="storyModal" class="lightbox"></div>
740        <div id="no-stories">
741        <img width="100px" height="100px" src="${backendUrl}/media/avatar/default.png" />
742        <h2>oono Collection is not available on the Page.</h2>
743        <a href="${webStoriesUrl}/${brandId}" target="_blank">Click here to see on oono</a>
744        </div>
745        ${type !== "link" ? `<div class="oono-carousel-container"></div> ` : ""}
746        ${
747          type === "link"
748            ? `<p id="paragraph-${index}" class="interactive-text minimalist"></p>`
749            : ""
750        }
751      `;
752
753    const ampScript = document.createElement("script");
754    ampScript.async = true;
755    ampScript.src = "https://cdn.ampproject.org/v0.js";
756    shadowRoot.appendChild(ampScript);
757
758    const ampStoryPlayerScript = document.createElement("script");
759    ampStoryPlayerScript.async = true;
760    ampStoryPlayerScript.setAttribute("custom-element", "amp-story-player");
761    ampStoryPlayerScript.src =
762      "https://cdn.ampproject.org/v0/amp-story-player-0.1.js";
763    shadowRoot.appendChild(ampStoryPlayerScript);
764
765    const ampStoryPlayerLink = document.createElement("link");
766    ampStoryPlayerLink.href =
767      "https://cdn.ampproject.org/amp-story-player-v0.css";
768    ampStoryPlayerLink.rel = "stylesheet";
769    ampStoryPlayerLink.type = "text/css";
770    shadowRoot.appendChild(ampStoryPlayerLink);
771
772    function updateStoryCount() {
773        let data = {};
774        try {
775        const stored = storageWrapper.getItem("storyClipsCount");
776        data = stored ? JSON.parse(stored) : {};
777        } catch (e) {
778        console.warn("Failed to parse storyClipsCount:", e);
779        data = {};
780        }
781
782        let seenStories = {};
783        try {
784        const getCount = storageWrapper.getItem("seenStories");
785        seenStories = getCount ? JSON.parse(getCount) : {};
786        } catch (e) {
787        console.warn("Failed to parse seenStories:", e);
788        }
789
790        const collectionCount = data[collectionId] || 0;
791        const storyCount = seenStories?.[collectionId]?.length || 0;
792        const res = storyCount > 0 ? collectionCount - storyCount : collectionCount;
793
794        const oldStyle = shadowRoot.querySelector("style[data-type='story-badge']");
795        if (oldStyle) oldStyle.remove();
796
797        const style = document.createElement("style");
798        style.setAttribute("data-type", "story-badge");
799        style.textContent = `
800        #imgDiv::after {
801            content: "${isNaN(res) || res === undefined ? 0 : Math.max(0, res)}";
802            font-size: 12px;
803            display: flex;
804            justify-content: center;
805            align-items: center;
806            color: white;
807            position: absolute;
808            top: -5px;
809            right: 0;
810            width: 20px;
811            height: 20px;
812            background-color: ${res > 0 ? "red" : "#bdbdbd"};
813            border-radius: 50%;
814        }`;
815
816        shadowRoot.appendChild(style);
817    }
818
819    const containers = shadowRoot.querySelector(".oono-carousel-container");
820
821    // function toast() {
822    //   const url = new URL(window.location);
823    //   url.searchParams.delete('oono');
824    //   url.searchParams.delete('story');
825    //   window.history.pushState({}, '', url.href);
826    //   const toast = document.createElement('div');
827    //   toast.style.position = 'fixed';
828    //   toast.style.top = '20px';
829    //   toast.style.left = '50%';
830    //   toast.style.transform = 'translateX(-50%)';
831    //   toast.style.backgroundColor = '#ff4d4d';
832    //   toast.style.color = '#fff';
833    //   toast.style.padding = '15px 30px';
834    //   toast.style.borderRadius = '8px';
835    //   toast.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.2)';
836    //   toast.style.zIndex = '2147483647';
837    //   toast.style.fontSize = '16px';
838    //   toast.style.fontWeight = 'bold';
839    //   toast.style.textAlign = 'center';
840    //   toast.innerText = 'No stories available';
841    //   document.body.appendChild(toast);
842
843    //   setTimeout(() => {
844    //     toast.style.transition = 'opacity 0.5s';
845    //     toast.style.opacity = '0';
846    //     setTimeout(() => {
847    //       document.body.removeChild(toast);
848    //     }, 500);
849    //   }, 3000);
850    // }
851
852    // Create a style element and append it to the head
853    //  if (type === "inPage") {
854
855    let brandSlug;
856    fetch(`${getJsonUrl()}/${collectionId}.json`)
857      .then((response) => response.json())
858      .then((data) => {
859        brandSlug = data?.brandSlug;
860
861        if (data?.storiesCount > 1 && type === "inPage") {
862          const progressBars = shadowRoot.querySelector(
863            ".progress-bar-container"
864          );
865
866          for (let i = 0; i < Math.min(data?.storiesCount, 10); i++) {
867            const progressBar = document.createElement("div");
868            if (i === 0) {
869              progressBar.className = "progress-bar1";
870            } else {
871              progressBar.className = "progress-bar";
872            }
873            progressBars.appendChild(progressBar);
874          }
875        }
876        if (type === "link") {
877          const paragraph = shadowRoot.querySelector(`#paragraph-${index}`);
878          let textWithLinks = text;
879          if (textWithLinks) {
880            textWithLinks = textWithLinks.replace(
881              /{{oono-([^}]+)}}/g,
882              `<span class="link-click">${data?.name}</span>`
883            );
884            paragraph.innerHTML = textWithLinks;
885          }
886        }
887
888        storageWrapper.setItem(`jsonData_${collectionId}`, JSON.stringify(data));
889        const storyModal = container.shadowRoot.querySelector("#storyModal");
890        const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
891        const lastStoryPage = lastStory[collectionId] || "page-1";
892        const storyClipsCounts =
893          JSON.parse(storageWrapper.getItem("storyClipsCount")) || {};
894        if (data) {
895          storyClipsCounts[collectionId] =
896            data.storyClipsCount || data.storiesCount || 0;
897        } else {
898          storyClipsCounts[collectionId] = 0;
899        }
900        storageWrapper.setItem(
901          "storyClipsCount",
902          JSON.stringify(storyClipsCounts)
903        );
904        updateStoryCount();
905        const url = new URL(window.location);
906        const story = getStoryNumberFromUrl(url);
907        const collection = getCollectionIdFromUrl(url);
908        let current;
909        if (collection === collectionId && story) {
910          storageWrapper.setItem(
911            "lastStory",
912            JSON.stringify({ ...lastStory, [collectionId]: `page-${story}` })
913          );
914          current = `page-${story}`;
915        } else {
916          current = lastStoryPage;
917        }
918        async function renderStoryModal(collection) {
919          if (!storyModal) return;
920          const response = await fetch(
921            `${backendUrl}/api/public/stories-collection?collectionId=${collection}`,
922            {
923              method: "GET",
924              headers: {
925                "Content-Type": "application/json",
926                "app-token":
927                  "9f8e7d6c5b4a3e2f1a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f",
928              },
929            }
930          );
931          const data = await response.json();
932          window._oonoStoriesInQuestion = data?.data[0].stories;
933          storageWrapper.setItem(
934            `data_${data?.data[0].collectionId}`,
935            JSON.stringify(data?.data[0])
936          );
937          const uniqueId = storageWrapper.getItem("uniqueId");
938
939          //   const playerInitialize = container.shadowRoot.querySelector("#playerInitialize");
940          //   if(playerInitialize){
941          //     playerInitialize.innerHTML = `
942          //    <amp-story-player class="inPage-player" height="${style?.height ? style.heigh: '550'}" width="${
943          //       style?.width ? style.width : '350'
944          //     }" layout="fixed">
945          //   ${filteredCollections
946          //     .map(
947          //       (collection) => `
948          //   <a href="${webStoriesUrl}/new-amp?brandId=${brandId}&collection=${collection._id}&brand=${collection?.brand}"></a>
949          //   `
950          //     .join("")}
951          // </amp-story-player>`;
952          //   }
953          
954          const url = new URL(window.location);
955          const currentStory = getStoryNumberFromUrl(url);
956          const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
957          const lastStoryPage = lastStory[collectionId] || "page-1";
958          
959          const storyToShow = currentStory ? `page-${currentStory}` : lastStoryPage;
960          
961          storyModal.innerHTML = `
962              <amp-story-player class="my-player" height="100vh" width="100vw" layout="fixed">
963                <script type="application/json">
964                {
965                  "controls": [
966                    {
967                      "name": "close",
968                      "position": "end"
969                    }
970                  ]
971                }
972                </script>
973                ${data?.data
974                  .map(
975                    (collection) => `
976                  <a href="${webStoriesUrl}/amp?brandId=${
977                      brandSlug || brandId
978                    }&collection=${
979                      collection._id
980                    }&embed=true&type=${type}&identifier=${uniqueId}#page=${storyToShow}"></a>
981                `
982                  )
983                  .join("")}
984              </amp-story-player>
985              `;
986        }
987
988        // renderStoryModal(data?._id);
989        updateStoryCount();
990        
991        // Preload the player for faster initial loading (with slight delay to not block initial render)
992        // On mobile, delay preloading more to prevent issues
993        const isMobile = getDeviceType() === 'mobile';
994        const preloadDelay = isMobile ? 2000 : 500;
995        
996        setTimeout(() => {
997          preloadPlayer();
998        }, preloadDelay);
999        if (type === "inPage") {
1000          function LoaderCheck() {
1001            if (!container.shadowRoot) return;
1002
1003            const styleElement = document.createElement("style");
1004            styleElement.innerHTML = `
1005              @keyframes shimmer {
1006                0% { background-position: -200px 0; }
1007                100% { background-position: 200px 0; }
1008              }
1009        
1010              .skeleton-loader {
1011                position: relative;
1012                width: ${style?.width ? style.width : "198px"};
1013                height: ${style?.height ? style.height : "368px"};
1014                aspect-ratio: 9/16;
1015                overflow: hidden;
1016                transition: transform 0.2s ease-in-out;
1017                border-radius: ${
1018                  style?.borderRadius ? style.borderRadius : "8px"
1019                };
1020                border: 1px solid rgb(236, 234, 234);
1021                background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
1022                background-size: 200% 100%;
1023                animation: shimmer 1.5s infinite linear;
1024              }
1025            `;
1026
1027            container.shadowRoot.appendChild(styleElement);
1028            const skeletonDiv = document.createElement("div");
1029            skeletonDiv.className = "skeleton-loader";
1030            skeletonDiv.id = "skeletonLoader";
1031
1032            const loaderContainer = container.shadowRoot.querySelector(
1033              ".inPage-loader-container"
1034            );
1035
1036            if (loaderContainer) {
1037              loaderContainer.appendChild(skeletonDiv);
1038            }
1039          }
1040
1041          function removeSkeletonLoader() {
1042            const skeletonDiv =
1043              container.shadowRoot.querySelector("#skeletonLoader");
1044            if (skeletonDiv) {
1045              skeletonDiv.remove();
1046            }
1047          }
1048
1049          LoaderCheck();
1050
1051          setTimeout(async () => {
1052            EmitEvent(backendUrl, "stories-stats", {
1053              collectionId: getCollectionId(collectionId),
1054              brandId: brandRealId,
1055              identifier: storageWrapper.getItem("uniqueId"),
1056              action: 10,
1057              country: await getCountry(),
1058              deviceType: getDeviceType(),
1059            });
1060            const data = JSON.parse(
1061              storageWrapper.getItem(`jsonData_${collectionId}`)
1062            );
1063            const imgDiv =
1064              container.shadowRoot.querySelector("#collectionImage");
1065            const coverUrl = getAWSMediaURL(data?.cover);
1066            const inPageDiv =
1067              container.shadowRoot.querySelector(".image-container");
1068            if (inPageDiv) {
1069              inPageDiv.addEventListener("click", async () => {
1070                await EmitEvent(backendUrl, "stories-stats", {
1071                  collectionId: getCollectionId(collectionId),
1072                  brandId: brandRealId,
1073                  identifier: storageWrapper.getItem("uniqueId"),
1074                  action: 11,
1075                });
1076                window._oonoFirstClick = true;
1077                
1078                const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1079                const lastStoryPage = lastStory[collectionId] || "page-1";
1080                const storyNumber = (parseInt(lastStoryPage.split("-")[1]) || 1).toString();
1081                
1082                const collectionData = getCollection(collectionId);
1083                const stories = collectionData?.stories;
1084                const storyId = stories?.[parseInt(storyNumber) - 1]?._id
1085
1086                await EmitEvent(backendUrl, "stories-stats", {
1087                  collectionId: getCollectionId(collectionId),
1088                  brandId: brandRealId,
1089                  identifier: storageWrapper.getItem("uniqueId"),
1090                  action: 1,
1091                  storyId,
1092                  country: await getCountry(),
1093                  deviceType: getDeviceType(),
1094                });
1095
1096                startTime = Date.now();
1097              });
1098            }
1099            if (coverUrl) {
1100              removeSkeletonLoader();
1101              inPageDiv.style.display = "block";
1102              imgDiv.innerHTML = `<img src="${coverUrl}" />`;
1103            } else {
1104              imgDiv.style.display = "none";
1105            }
1106          }, 1000);
1107        }
1108
1109        const imgDiv = shadowRoot.querySelector("#imgDiv");
1110        if (type === "button") {
1111          const playButton = shadowRoot.querySelector("#playButton");
1112          window._oonoFirstClick = true;
1113          playButton?.addEventListener("click", async () => {
1114            await EmitEvent(backendUrl, "stories-stats", {
1115              collectionId: getCollectionId(collectionId),
1116              brandId: brandRealId,
1117              identifier: storageWrapper.getItem("uniqueId"),
1118              action: 11,
1119            });
1120            
1121            const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1122            const lastStoryPage = lastStory[collectionId] || "page-1";
1123            const storyNumber = (parseInt(lastStoryPage.split("-")[1]) || 1).toString();
1124            
1125            const collectionData = getCollection(collectionId);
1126            const stories = collectionData?.stories;
1127            const storyId = stories?.[parseInt(storyNumber) - 1]?._id
1128
1129            await EmitEvent(backendUrl, "stories-stats", {
1130              collectionId: getCollectionId(collectionId),
1131              brandId: brandRealId,
1132              identifier: storageWrapper.getItem("uniqueId"),
1133              action: 1,
1134              storyId,
1135              country: await getCountry(),
1136              deviceType: getDeviceType(),
1137            });
1138
1139            startTime = Date.now();
1140          });
1141        }
1142        imgDiv?.addEventListener("click", async () => {
1143          window._oonoFirstClick = true;
1144          await EmitEvent(backendUrl, "stories-stats", {
1145            collectionId: getCollectionId(collectionId),
1146            brandId: brandRealId,
1147            identifier: storageWrapper.getItem("uniqueId"),
1148            action: 11,
1149          });
1150          
1151          const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1152          const lastStoryPage = lastStory[collectionId] || "page-1";
1153          const storyNumber = (parseInt(lastStoryPage.split("-")[1]) || 1).toString();
1154          
1155          const collectionData = getCollection(collectionId);
1156          const stories = collectionData?.stories;
1157          const storyId = stories?.[parseInt(storyNumber)]?._id
1158
1159          await EmitEvent(backendUrl, "stories-stats", {
1160            collectionId: getCollectionId(collectionId),
1161            brandId: brandRealId,
1162            identifier: storageWrapper.getItem("uniqueId"),
1163            action: 1,
1164            storyId,
1165            country: await getCountry(),
1166            deviceType: getDeviceType(),
1167          });
1168          startTime = Date.now();
1169        });
1170        let startTime = 0;
1171        let currentPageId = "";
1172
1173        const handleNavigation = async (event) => {
1174          const previousPageId = storageWrapper.getItem("currentPageId");
1175          const seenStories =
1176            JSON.parse(storageWrapper.getItem("seenStories")) || {};
1177          const collectionSeenStories = seenStories[collectionId] || [];
1178          if (!collectionSeenStories.includes(event.detail.pageId)) {
1179            collectionSeenStories.push(event.detail.pageId);
1180            seenStories[collectionId] = collectionSeenStories;
1181            storageWrapper.setItem("seenStories", JSON.stringify(seenStories));
1182          }
1183          const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1184          lastStory[collectionId] = event.detail.pageId;
1185          storageWrapper.setItem("lastStory", JSON.stringify(lastStory));
1186          const currentPageIdNumber = parseInt(
1187            event.detail.pageId.split("-")[1]
1188          );
1189          storageWrapper.setItem("currentPageId", currentPageIdNumber);
1190          const collections = JSON.parse(storageWrapper.getItem("collection"));
1191          const storyId = collections?.stories[currentPageIdNumber]?._id;
1192          storageWrapper.setItem("storyId", storyId);
1193          let timeSpent = 0;
1194          if (currentPageId !== "") {
1195            const endTime = Date.now();
1196            timeSpent = (endTime - startTime) / 1000;
1197          }
1198          const timeSpentSeconds = Math.round(timeSpent);
1199          startTime = Date.now();
1200          currentPageId = currentPageIdNumber;
1201          storageWrapper.setItem("timeSpent", timeSpentSeconds);
1202          
1203          const url = new URL(window.location);
1204          if (window._oonoFirstClick) {
1205          const storyNumber = event.detail.pageId.split("-")[1];
1206          setCollectionUrlParams(url, collectionId, storyNumber);
1207          
1208          // Prevent infinite loops by checking if URL actually changed
1209          if (window.location.href !== url.toString()) {
1210            try {
1211              window.history.replaceState({}, "", url.toString());
1212            } catch (e) {
1213              console.warn('Failed to update URL state:', e);
1214            }
1215          }
1216        }
1217          
1218          const coll = getCollectionIdFromUrl(url);
1219          if (coll === collectionId) {
1220            if (currentPageId == previousPageId) {
1221              return;
1222            }
1223            const isForward = currentPageId > previousPageId;
1224            const currentStoryNumber = parseInt(storyNumber);
1225            const collectionData = getCollection(collectionId);
1226            const stories = collectionData?.stories;
1227            const storyId = stories?.[currentStoryNumber]?._id
1228
1229            await EmitEvent(backendUrl, "stories-stats", {
1230              storyId,
1231              collectionId: getCollectionId(collectionId),
1232              brandId: brandRealId,
1233              identifier: storageWrapper.getItem("uniqueId"),
1234              action: isForward ? 3 : 4,
1235              timeSpent: timeSpentSeconds,
1236              storyId,
1237            });
1238
1239            await EmitEvent(backendUrl, "stories-stats", {
1240              collectionId: getCollectionId(collectionId),
1241              brandId: brandRealId,
1242              identifier: storageWrapper.getItem("uniqueId"),
1243              action: 1,
1244              storyId,
1245              country: await getCountry(),
1246              deviceType: getDeviceType(),
1247            });
1248          }
1249        };
1250        const intervalId = setInterval(() => {
1251          let player = shadowRoot.querySelector(".my-player");
1252          if (player) {
1253            player.addEventListener("storyNavigation", handleNavigation);
1254            clearInterval(intervalId);
1255          }
1256        }, 1000);
1257
1258        // Debounce function to prevent rapid execution
1259        let checkHashTimeout;
1260        const checkHashAndToggleModal = (item) => {
1261          clearTimeout(checkHashTimeout);
1262          checkHashTimeout = setTimeout(() => {
1263            const url = new URL(window.location);
1264            const collection = getCollectionIdFromUrl(url);
1265            const targetCollectionId = item ? item : collectionId;
1266          
1267          const isMatch = collection === targetCollectionId;
1268            let isCodeMatch = false;
1269          if (url.searchParams.get("c")) {
1270            const targetCodeData = getCollectionCodeAndName(targetCollectionId);
1271            if (targetCodeData) {
1272              const urlCode = url.searchParams.get("c").split('-')[0];
1273              isCodeMatch = urlCode === targetCodeData.code;
1274            }
1275          }
1276          
1277          if (isMatch || isCodeMatch) {
1278            const lastStory =
1279              JSON.parse(storageWrapper.getItem("lastStory")) || {};
1280            const lastStoryPage = lastStory[item ?? collectionId] || "page-1";
1281            if (lastStoryPage) {
1282              setCollectionUrlParams(url, targetCollectionId, lastStoryPage.split("-")[1]);
1283              
1284              // Prevent infinite loops by checking if URL actually changed
1285              if (window.location.href !== url.toString()) {
1286                try {
1287                  window.history.replaceState({}, "", url.toString());
1288                } catch (e) {
1289                  console.warn('Failed to update URL state:', e);
1290                }
1291              }
1292            }
1293            toggleModal(true);
1294          }
1295          // else if (window.location.hash !== `#oono-embed-${data.collectionId}` && window.location.hash.includes('#oono')) {
1296          //   const noStories = container.shadowRoot.querySelector("#no-stories");
1297          //   noStories.style.display = "flex";
1298          // }
1299          else {
1300            // const noStories = container.shadowRoot.querySelector("#no-stories");
1301            // noStories.style.display = "none";
1302            toggleModal(false);
1303          }
1304          }, 100); // 100ms debounce delay
1305        };
1306
1307        if (containers && type === "carousel") {
1308          [collectionId]?.forEach(async (item) => {
1309            const slideElement = document.createElement("div");
1310            slideElement.className = "carousel-item";
1311            const img = document.createElement("img");
1312            img.src = data?.cover
1313              ? getAWSMediaURL(data.cover)
1314              : `${backendUrl}/media/avatar/default.png`;
1315            img.alt = `Slide`;
1316            if (!data.cover) {
1317              img.style.objectFit = "contain";
1318              img.style.border = "1px solid #BFBFBF";
1319              img.style.background = "#BFBFBF";
1320            }
1321            slideElement.appendChild(img);
1322
1323            EmitEvent(backendUrl, "stories-stats", {
1324              collectionId: getCollectionId(collectionId),
1325              brandId: brandRealId,
1326              identifier: storageWrapper.getItem("uniqueId"),
1327              action: 10,
1328              country: await getCountry(),
1329              deviceType: getDeviceType(),
1330            });
1331
1332            const progressBarContainer = document.createElement("div");
1333            progressBarContainer.className = "progress-bar-container";
1334            slideElement.appendChild(progressBarContainer);
1335
1336            if (data?.storiesCount > 1) {
1337              const progressBarContainer = document.createElement("div");
1338              progressBarContainer.className = "progress-bar-container";
1339              slideElement.appendChild(progressBarContainer);
1340
1341              for (let i = 0; i < Math.min(data?.storiesCount, 10); i++) {
1342                const progressBar = document.createElement("div");
1343                if (i === 0) {
1344                  progressBar.className = "progress-bar1";
1345                } else {
1346                  progressBar.className = "progress-bar";
1347                }
1348                progressBarContainer.appendChild(progressBar);
1349              }
1350            }
1351
1352            //   const avatar = document.createElement('img');
1353            //   avatar.src = getAWSMediaURL(data.cover);
1354            //   avatar.alt = 'Avatar';
1355            //   avatar.style.width = '80px';
1356            //   avatar.style.height = '80px';
1357            //   avatar.style.borderRadius = '50%';
1358            //   avatar.style.zIndex = 6000000;
1359            //   avatar.style.position = 'absolute';
1360            //   avatar.className = 'avatar-overlay';
1361            //   slideElement.appendChild(avatar);
1362            containers.appendChild(slideElement);
1363            slideElement.addEventListener("click", async () => {
1364              await EmitEvent(backendUrl, "stories-stats", {
1365                collectionId: getCollectionId(collectionId),
1366                brandId: brandRealId,
1367                identifier: storageWrapper.getItem("uniqueId"),
1368                action: 11,
1369              });
1370                window._oonoFirstClick = true;
1371              const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1372              const lastStoryPage = lastStory[item] || "page-1";
1373              const storyNumber = (parseInt(lastStoryPage.split("-")[1]) || 1).toString();
1374
1375              const collectionData = getCollection(collectionId);
1376              const stories = collectionData?.stories;
1377              const storyId = stories?.[parseInt(storyNumber) - 1]?._id
1378
1379              await EmitEvent(backendUrl, "stories-stats", {
1380                collectionId: getCollectionId(collectionId),
1381                brandId: brandRealId,
1382                identifier: storageWrapper.getItem("uniqueId"),
1383                action: 1,
1384                storyId,
1385                country: await getCountry(),
1386                deviceType: getDeviceType(),
1387              });
1388
1389              const url = new URL(window.location);
1390              setCollectionUrlParams(url, item, storyNumber);
1391              
1392              // Prevent infinite loops by checking if URL actually changed
1393              if (window.location.href !== url.toString()) {
1394                try {
1395                  window.history.replaceState({}, "", url.toString());
1396                } catch (e) {
1397                  console.warn('Failed to update URL state:', e);
1398                }
1399              }
1400              checkHashAndToggleModal(item);
1401              startTime = Date.now();
1402            });
1403          });
1404        }
1405
1406        if (anchor) {
1407          anchor.addEventListener("click", async (event) => {
1408            event.preventDefault();
1409            if (collectionId === data.collectionId) {
1410              await EmitEvent(backendUrl, "stories-stats", {
1411                collectionId: getCollectionId(collectionId),
1412                brandId: brandRealId,
1413                identifier: storageWrapper.getItem("uniqueId"),
1414                action: 11,
1415              });
1416              window._oonoFirstClick = true;
1417
1418              const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1419              const lastStoryPage = lastStory[collectionId] || "page-1";
1420              const storyNumber = (parseInt(lastStoryPage.split("-")[1]) || 1).toString();
1421
1422              const collectionData = getCollection(collectionId);
1423              const stories = collectionData?.stories;
1424              const storyId = stories?.[parseInt(storyNumber) - 1]?._id
1425
1426              await EmitEvent(backendUrl, "stories-stats", {
1427                collectionId: getCollectionId(collectionId),
1428                brandId: brandRealId,
1429                identifier: storageWrapper.getItem("uniqueId"),
1430                action: 1,
1431                storyId,
1432                country: await getCountry(),
1433                deviceType: getDeviceType(),
1434              });
1435              const url = new URL(window.location);
1436              setCollectionUrlParams(url, collectionId, storyNumber);
1437              
1438              // Prevent infinite loops by checking if URL actually changed
1439              if (window.location.href !== url.toString()) {
1440                try {
1441                  window.history.replaceState({}, "", url.toString());
1442                } catch (e) {
1443                  console.warn('Failed to update URL state:', e);
1444                }
1445              }
1446              checkHashAndToggleModal();
1447              startTime = Date.now();
1448            }
1449          });
1450        }
1451
1452        [
1453          "#playButton",
1454          "#imgDiv",
1455          ".image-container",
1456          ".link-click",
1457          // "#playerInitialize",
1458        ].forEach((id) => {
1459          const el = shadowRoot.querySelector(id);
1460          el &&
1461            el.addEventListener("click", (event) => {
1462              event.preventDefault();
1463              if (collectionId === data.collectionId) {
1464                if (window.self !== window.top) {
1465                  toggleModal(true);
1466                } else {
1467                  const url = new URL(window.location);
1468                  const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1469                  const lastStoryPage = lastStory[collectionId] || "page-1";
1470                  const storyNumber = (parseInt(lastStoryPage.split("-")[1]) || 1).toString();
1471                  setCollectionUrlParams(url, collectionId, storyNumber);
1472                  
1473                  // Prevent infinite loops by checking if URL actually changed
1474                  if (window.location.href !== url.toString()) {
1475                    try {
1476                      window.history.replaceState({}, "", url.toString());
1477                    } catch (e) {
1478                      console.warn('Failed to update URL state:', e);
1479                    }
1480                  }
1481                  checkHashAndToggleModal();
1482                }
1483              }
1484            });
1485        });
1486
1487        // Prevent multiple event listeners
1488        if (!window._oonoHashChangeListenerAdded) {
1489          window._oonoHashChangeListenerAdded = true;
1490          window.addEventListener("hashchange", checkHashAndToggleModal);
1491        }
1492        checkHashAndToggleModal();
1493
1494        function toggleModal(show) {
1495          const storyModal = container.shadowRoot.querySelector("#storyModal");
1496          // const filter = JSON.parse(localStorage.getItem(`filterCollection-${collectionId}`));
1497          // if (filter.length > 0) {
1498          if (show) {
1499            const existingPlayer = shadowRoot.querySelector(".my-player");
1500            const isPreloaded = existingPlayer && existingPlayer.getAttribute('data-preloaded') === 'true';
1501            
1502            // Check if we need to update the story URL (for URL changes)
1503            const url = new URL(window.location);
1504            const currentStory = getStoryNumberFromUrl(url);
1505            const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1506            const lastStoryPage = lastStory[collectionId] || "page-1";
1507            const storyToShow = currentStory ? `page-${currentStory}` : lastStoryPage;
1508            
1509            // Only reset player if not preloaded or if story URL changed
1510            if (!isPreloaded || !existingPlayer || existingPlayer.querySelectorAll('a').length === 0) {
1511              resetPlayer();
1512            } else {
1513              // Update the href of existing preloaded player if story changed
1514              const existingLink = existingPlayer.querySelector('a');
1515              const uniqueId = storageWrapper.getItem("uniqueId");
1516              const data = JSON.parse(storageWrapper.getItem(`jsonData_${collectionId}`));
1517              const expectedHref = `${webStoriesUrl}/amp?brandId=${brandSlug || brandId}&collection=${data._id}&embed=true&type=${type}&identifier=${uniqueId}#page=${storyToShow}`;
1518              
1519              if (existingLink && !existingLink.href.includes(`#page=${storyToShow}`)) {
1520                existingLink.href = expectedHref;
1521              }
1522              
1523              // Preloaded player is ready to use (amp-story-player manages its own visibility)
1524            }
1525            
1526            storyModal.style.zIndex = "21474836472222";
1527            storyModal.style.opacity = "1";
1528            document.documentElement.style.overflow = "hidden";
1529            const allElements = document.querySelectorAll(
1530              "body *:not(#oono-stories-container):not(#oono-stories-container *)"
1531            );
1532            allElements.forEach((el) => {
1533              el.style.visibility = "hidden";
1534            });
1535            // localStorage.setItem("scrollPosition", window.scrollY);
1536            setTimeout(() => {
1537              playPlayer();
1538            }, isPreloaded ? 0 : 100); // Immediate for preloaded, slight delay for new players
1539          } else {
1540            storyModal.style.zIndex = "-1";
1541            storyModal.style.opacity = "0";
1542            document.documentElement.style.overflow = "auto";
1543            const allElements = document.querySelectorAll(
1544              "body *:not(#oono-stories-container):not(#oono-stories-container *)"
1545            );
1546            allElements.forEach((el) => {
1547              el.style.visibility = "visible";
1548            });
1549            // window.scrollTo(0, localStorage.getItem("scrollPosition"));
1550            
1551            // Pause the player (amp-story-player manages its own visibility)
1552            const player = shadowRoot.querySelector(".my-player");
1553            if (player) {
1554              player.pause();
1555            }
1556          }
1557          // } else {
1558          //   // toast()
1559          // }
1560        }
1561
1562        if (positionType === "float") {
1563          window.addEventListener("scroll", () => {
1564            imgDiv.style.position = "fixed";
1565          });
1566        } else if (positionType === "fixed") {
1567          imgDiv.style.position = "absolute";
1568        }
1569
1570        function preloadPlayer() {
1571          // Prevent multiple preloads for the same collection
1572          if (window[`_oonoPreloaded_${collectionId}`]) {
1573            return;
1574          }
1575          window[`_oonoPreloaded_${collectionId}`] = true;
1576          
1577          const uniqueId = storageWrapper.getItem("uniqueId");
1578          const data = JSON.parse(
1579            storageWrapper.getItem(`jsonData_${collectionId}`)
1580          );
1581          const storyModal = shadowRoot.querySelector("#storyModal");
1582          
1583          if (storyModal && !shadowRoot.querySelector(".my-player") && data) {
1584            const url = new URL(window.location);
1585            const currentStory = getStoryNumberFromUrl(url);
1586            const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1587            const lastStoryPage = lastStory[collectionId] || "page-1";
1588            
1589            const storyToShow = currentStory ? `page-${currentStory}` : lastStoryPage;
1590            
1591            console.log('Preloading amp-story-player for collection:', collectionId);
1592            
1593            // Create the player (amp-story-player manages its own visibility)
1594            storyModal.innerHTML = `
1595                <amp-story-player class="my-player" height="100vh" width="100vw" layout="fixed">
1596                    <script type="application/json">
1597                {
1598                  "controls": [
1599                    {
1600                      "name": "close",
1601                      "position": "end"
1602                    }
1603                  ]
1604                }
1605                </script>
1606                <a href="${webStoriesUrl}/amp?brandId=${brandSlug || brandId}&collection=${data._id}&embed=true&type=${type}&identifier=${uniqueId}#page=${storyToShow}"></a>
1607              </amp-story-player>`;
1608              
1609            // Wait for amp scripts to load and mark as preloaded
1610            const checkPlayerReady = () => {
1611              const player = shadowRoot.querySelector(".my-player");
1612              if (player) {
1613                // Try to initialize the player to preload content
1614                try {
1615                  // Mark as preloaded after a reasonable time for amp initialization
1616                  setTimeout(() => {
1617                    player.setAttribute('data-preloaded', 'true');
1618                    console.log('amp-story-player preloaded successfully for collection:', collectionId);
1619                  }, 2000);
1620                } catch (e) {
1621                  console.log('Player preload initialization completed for collection:', collectionId);
1622                  player.setAttribute('data-preloaded', 'true');
1623                }
1624              }
1625            };
1626            
1627            // Check immediately and also after a delay
1628            setTimeout(checkPlayerReady, 100);
1629          }
1630        }
1631
1632        function resetPlayer() {
1633          const uniqueId = storageWrapper.getItem("uniqueId");
1634          const data = JSON.parse(
1635            storageWrapper.getItem(`jsonData_${collectionId}`)
1636          );
1637          const storyModal = shadowRoot.querySelector("#storyModal");
1638          if (storyModal) {
1639            const url = new URL(window.location);
1640            const currentStory = getStoryNumberFromUrl(url);
1641            const lastStory = JSON.parse(storageWrapper.getItem("lastStory")) || {};
1642            const lastStoryPage = lastStory[collectionId] || "page-1";
1643            
1644            const storyToShow = currentStory ? `page-${currentStory}` : lastStoryPage;
1645            
1646            storyModal.innerHTML = `
1647                <amp-story-player class="my-player" height="100vh" width="100vw" layout="fixed">
1648                    <script type="application/json">
1649                {
1650                  "controls": [
1651                    {
1652                      "name": "close",
1653                      "position": "end"
1654                    }
1655                  ]
1656                }
1657                </script>
1658                <a href="${webStoriesUrl}/amp?brandId=${brandSlug || brandId}&collection=${data._id}&embed=true&type=${type}&identifier=${uniqueId}#page=${storyToShow}"></a>
1659              </amp-story-player>`;
1660          }
1661        }
1662        
1663     function closeAllOonoModals() {
1664        document.querySelectorAll('div[id^="oono-stories-container"]').forEach(div => {
1665        if (div.shadowRoot) {
1666      const storyModal = div.shadowRoot.querySelector("#storyModal");
1667      if (storyModal) {
1668        storyModal.style.opacity = "0";
1669        storyModal.style.zIndex = "-1";
1670      }
1671    }
1672  });
1673}
1674
1675        const handleClose = async () => {
1676          const storyModal = container.shadowRoot.querySelector("#storyModal");
1677          updateStoryCount();
1678          closeAllOonoModals();
1679          storyModal.style.opacity = "0";
1680          storyModal.style.zIndex = "-1";
1681          document.documentElement.style.overflow = "auto";
1682          const allElements = document.querySelectorAll(
1683            "body *:not(#oono-stories-container):not(#oono-stories-container *)"
1684          );
1685          allElements.forEach((el) => {
1686            el.style.visibility = "visible";
1687          });
1688
1689          // find current storyNumber 
1690          const url = new URL(window.location);
1691          const storyNumber = parseInt(getStoryNumberFromUrl(url) || 0);
1692
1693          const collectionData = getCollection(collectionId);
1694          const stories = collectionData?.stories;
1695          const storyId = stories?.[storyNumber]?._id
1696          window._oonoFirstClick = false;
1697
1698          // calculate the timeSpent
1699          const endTime = Date.now();
1700          const timeSpent = (endTime - startTime) / 1000;
1701          const timeSpentSeconds = Math.round(timeSpent);
1702
1703          await EmitEvent(backendUrl, "stories-stats", {
1704            collectionId: getCollectionId(collectionId),
1705            brandId: brandRealId,
1706            identifier: storageWrapper.getItem("uniqueId"),
1707            action: 5,
1708            storyId,
1709            timeSpent: timeSpentSeconds,
1710          });
1711
1712          // Just pause the player instead of trying to remove it
1713          const player = shadowRoot.querySelector(".my-player");
1714          if (player) {
1715            player.pause();
1716          }
1717          
1718          storageWrapper.removeItem("storyId");
1719          storageWrapper.removeItem("timeSpent");
1720          
1721          // Clear URL parameters based on collection type
1722          const collectionCodeData = getCollectionCodeAndName(collectionId);
1723          if (collectionCodeData) {
1724            url.searchParams.delete("c");
1725            url.searchParams.delete("story");
1726          } else {
1727            url.searchParams.delete("oono");
1728            url.searchParams.delete("story");
1729          }
1730          
1731          // Prevent infinite loops by checking if URL actually changed
1732          if (window.location.href !== url.href) {
1733            try {
1734              window.history.pushState({}, "", url.href);
1735            } catch (e) {
1736              console.warn('Failed to update URL state:', e);
1737            }
1738          }
1739        };
1740        window.addEventListener("popstate", () => {
1741          handleClose();
1742        });
1743
1744        function playPlayer() {
1745          const tryPlayPlayer = () => {
1746            const player = shadowRoot.querySelector(".my-player");
1747            if (player) {
1748              const isPreloaded = player.getAttribute('data-preloaded') === 'true';
1749              
1750              if (!isPreloaded && (player.readyState === 0 || player.querySelectorAll('a').length === 0)) {
1751                resetPlayer();
1752                return;
1753              }
1754              
1755              // Remove existing event listener to prevent duplicates
1756              player.removeEventListener("amp-story-player-close", handleClose);
1757              player.addEventListener("amp-story-player-close", handleClose);
1758              player.show();
1759              player.play();
1760            } else {
1761              const intervalId = setInterval(() => {
1762                const player = shadowRoot.querySelector(".my-player");
1763
1764                if (player) {
1765                  clearInterval(intervalId);
1766                  player.removeEventListener("amp-story-player-close", handleClose);
1767                  player.addEventListener(
1768                    "amp-story-player-close",
1769                    handleClose
1770                  );
1771                  player.show();
1772                  player.play();
1773                }
1774              }, 1000);
1775            }
1776          };
1777          tryPlayPlayer();
1778        }
1779
1780        window.addEventListener("message", (event) => {
1781          if (event.data.openCollection) {
1782            // Don't reset player, just close the current modal
1783            handleClose();
1784          }
1785          const handlePlayerAction = () => {
1786            const player = shadowRoot.querySelector(".my-player");
1787            if (player) {
1788              if (event.data.action === "pause") {
1789                player.pause();
1790              } else if (event.data.action === "play") {
1791                player.play();
1792              }
1793            } else {
1794              const intervalId = setInterval(() => {
1795                handlePlayerAction();
1796                clearInterval(intervalId);
1797              }, 1000);
1798            }
1799          };
1800
1801          if (event.data.moveTo) {
1802            const player = shadowRoot.querySelector(".my-player");
1803            if (player) {
1804              const negativeMoveTo = -Math.abs(parseInt(event.data.moveTo, 10));
1805              player.go(0, negativeMoveTo);
1806            }
1807          }
1808
1809          handlePlayerAction();
1810          if (event.origin === webStoriesUrl) {
1811            if (event.data.collection) {
1812              storageWrapper.setItem(
1813                "collection",
1814                JSON.stringify(event.data.collection)
1815              );
1816            }
1817            if (event.data.story) {
1818              handleClose();
1819            }
1820          }
1821        });
1822      })
1823      .catch((error) => {
1824        // if (error) {
1825        //   ["#playButton", "#imgDiv", "#collectionImage",".carousel-item"]?.forEach(id => {
1826        //     const el = shadowRoot.querySelector(id);
1827        //     el && el.addEventListener("click", () => {
1828        //       // toast()
1829        //     });
1830        //   });
1831        // }
1832      });
1833  }
1834}
1835
1836  initOonoStories();
1837})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.