Duda Collections Are Powerful, But Why Don't We Make Them Look Better?


Agency Genius • 15 July 2025

5 MINUITE READ

Right, cards on the table. I was late to the party with Duda collections. Really late. And you know why? Because I'm a bit of a design snob. There, I said it.

Don't get me wrong – I've seen some decent collection implementations. But most of the examples I came across were... functional. And functional is great! But I've always believed that functional and beautiful aren't mutually exclusive. We can have both, yeah?

Collections are incredibly powerful – they pull dynamic data, update automatically, and save hours of manual work. But for the longest time, I struggled to make them match the design standards I wanted for my sites. Maybe you've been there too?

The Creative AI Revolution (Yes, I Said Creative)

When I started Agency Genius, the mission was simple: get more people using AI in their creative workflows. And yes, I said creative. Because AI is creative when the person behind the prompt gives it the right direction. But that's a discussion for another day.

What I want to share today is a workflow that's completely changed how I approach Duda collections. It's the perfect marriage of Duda's powerful data handling and AI's ability to create stunning designs.

The Free Tool That Changes Everything

I'm making a tool available to everyone – publicly, ungated, no login required. Use it to your heart's content. It's called the JS API Explorer, and when you combine it with Claude AI, something special happens.

Let me walk you through creating a "Meet the Team" component that'll make you proud to show it off.

Step 1: Plan Your Component

First, map out what you want. For our team component, let's go with:

  • Person's name
  • Their position
  • A professional headshot
  • A short bio about them

Pretty standard stuff, right? But here's where we can elevate it beyond the usual grid layout.

Step 2: Create Your Collection in Duda

Head into Duda and create a new collection. Call it something sensible like "Team Members" (we've all been guilty of "test123" at some point, haven't we?).

Add some dummy data:

  • Name: Sarah Chen
  • Position: Creative Director
  • Image: Upload a headshot
  • Bio : "Sarah brings 15 years of experience in transforming brands..."

Add a few more team members, then publish the collection . This bit's crucial – if you don't publish it, the magic won't happen.

Step 3: The JS API Explorer Magic

Now here's where it gets interesting. If you're a Pro member of AgencyGenius, you can request this as a Duda widget and just drag-and-drop it in. But if you're not (yet), you'll need to add the code directly... scroll down to find:

  • If you have the Duda Widget drag in the JS API Explorer widget

Alternatively, if you're not yet a Pro member:


  • Copy the 'Combined' tab
  • Paste it into an HTML widget on your Duda site
Code
Html
Css
Javascript
Combined
 <!-- 
 Enhanced Duda JS API Explorer Widget 
 This is a self-contained HTML widget that provides a comprehensive interface 
 for exploring the full Duda JS API including Collections, Store API, Dynamic 
 Pages, Content Library and core API methods. 
 Created: May 2025 
 --> 
 <div id="aog-enhanced-js-explorer-widget"> 
 <!-- Widget Button --> 
 <button id="aog-js-explorer-button" class="aog-js-explorer-button" type="button"> 
 <span class="aog-js-explorer-icon">🔍</span> 
 <span class="aog-js-explorer-text">JS API Explorer</span> 
 </button> 
  
 <!-- Widget Panel --> 
 <div id="aog-js-explorer-panel" class="aog-js-explorer-panel"> 
 <div class="aog-js-explorer-header"> 
 <div class="aog-js-logo-container"> 
 <img src="https://irp.cdn-website.com/a778beb9/dms3rep/multi/Group+206.svg" alt="Agents of Genius" class="aog-js-logo"> 
 </div> 
 <h5 class="aog-js-title">JS API Explorer</h5> 
 <div class="aog-js-explorer-controls"> 
 <button id="aog-js-explorer-close" class="aog-js-explorer-close" type="button">×</button> 
 </div> 
 </div> 
  
 <div class="aog-js-explorer-content"> 
 <div id="aog-js-explorer-loading" class="aog-js-explorer-loading"> 
 <div class="aog-js-spinner"></div> 
 <div>Initializing API...</div> 
 </div> 
  
 <div id="aog-js-explorer-error" class="aog-js-explorer-error"> 
 <div class="aog-js-error-icon">⚠️</div> 
 <div> 
 <strong>Error retrieving data</strong> 
 <p id="aog-js-error-message">Could not load API data. Please try again.</p> 
 </div> 
 </div> 
  
 <div id="aog-js-explorer-data"> 
 <!-- Tabs Navigation --> 
 <div class="aog-js-explorer-tabs"> 
 <button class="aog-js-tab-button active" data-tab="api-discovery" type="button">API Discovery</button> 
 <button class="aog-js-tab-button" data-tab="collections" type="button">Collections</button> 
 <button class="aog-js-tab-button" data-tab="content-library" type="button">Content Library</button> 
 <button class="aog-js-tab-button" data-tab="store" type="button">Store</button> 
 <button class="aog-js-tab-button" data-tab="dynamic-pages" type="button">Dynamic Pages</button> 
 <button class="aog-js-tab-button" data-tab="members" type="button">Members</button> 
 <button class="aog-js-tab-button" data-tab="sitemap" type="button">Sitemap</button> 
 <button class="aog-js-tab-button" data-tab="core-methods" type="button">Core Methods</button> 
 <button class="aog-js-tab-button" data-tab="raw-json" type="button">Raw JSON</button> 
 <button class="aog-js-tab-button" data-tab="api-settings" type="button">Settings</button> 
 </div> 
  
 <!-- Tab Content --> 
 <div class="aog-js-explorer-tab-content"> 
 <!-- API Discovery Tab --> 
 <div id="api-discovery-tab" class="aog-js-tab-pane active"> 
 <h5 class="aog-js-section-title">API Discovery</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Scan this Duda site to discover available API features and data sources.</p> 
 <p>This will check for Collections, Content Library data, Store information, Dynamic Pages, and Members API.</p> 
 </div> 
 <button id="aog-js-discover-all" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">🔍</span> 
 Discover Available APIs 
 </button> 
 <div id="aog-js-discovery-results" class="aog-js-discovery-results"> 
 <div class="aog-js-api-section" data-section="core"> 
 <h5 class="aog-js-api-section-title">Core API</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="collections"> 
 <h5 class="aog-js-api-section-title">Collections</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="contentLibrary"> 
 <h5 class="aog-js-api-section-title">Content Library</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="store"> 
 <h5 class="aog-js-api-section-title">Store API</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="dynamicPages"> 
 <h5 class="aog-js-api-section-title">Dynamic Pages</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="members"> 
 <h5 class="aog-js-api-section-title">Members API</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="sitemap"> 
 <h5 class="aog-js-api-section-title">Sitemap</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Collections Tab --> 
 <div id="collections-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Collection Explorer</h5> 
 <div class="aog-js-input-container"> 
 <div class="aog-js-collection-actions"> 
 <button id="aog-js-find-all-btn" class="aog-js-primary-button aog-js-secondary-button"> 
 <span class="aog-js-button-icon">🔍</span> 
 Find All Collections 
 </button> 
 <div class="aog-js-specific-collection"> 
 <label for="aog-js-collection-input" class="aog-js-label">Specific Collection Name/ID:</label> 
 <div class="aog-js-input-group"> 
 <input id="aog-js-collection-input" type="text" placeholder="Enter collection name or ID" class="aog-js-input"> 
 <button id="aog-js-find-btn" class="aog-js-action-button">Find</button> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <div id="aog-js-collections-status" class="aog-js-status"></div> 
  
 <div id="aog-js-discovered-collections" class="aog-js-discovered-collections"> 
 <div class="aog-js-collections-header"> 
 <div class="aog-js-section-subtitle">Discovered Collections</div> 
 <div class="aog-js-discovery-count">0 found</div> 
 </div> 
 <div id="aog-js-collections-list" class="aog-js-collections-list"> 
 <!-- Collections will be populated here --> 
 <div class="aog-js-empty-state">No collections discovered yet. Use "API Discovery" to scan the page.</div> 
 </div> 
 </div> 
  
 <div class="aog-js-filter-section"> 
 <div class="aog-js-section-subtitle">Filtering &amp; Sorting (Optional)</div> 
 <div class="aog-js-filter-inputs"> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-filter-field" class="aog-js-label">Field:</label> 
 <input id="aog-js-filter-field" type="text" placeholder="Field name" class="aog-js-input"> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-filter-operator" class="aog-js-label">Operator:</label> 
 <select id="aog-js-filter-operator" class="aog-js-input"> 
 <option value="EQ">Equal to (EQ)</option> 
 <option value="NE">Not equal to (NE)</option> 
 <option value="GT">Greater than (GT)</option> 
 <option value="GTE">Greater than or equal (GTE)</option> 
 <option value="LT">Less than (LT)</option> 
 <option value="LTE">Less than or equal (LTE)</option> 
 <option value="IN">In array (IN)</option> 
 <option value="NIN">Not in array (NIN)</option> 
 <option value="BTWN">Between (BTWN)</option> 
 </select> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-filter-value" class="aog-js-label">Value:</label> 
 <input id="aog-js-filter-value" type="text" placeholder="Value or comma-separated values for IN/BTWN" class="aog-js-input"> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-sort-field" class="aog-js-label">Sort by:</label> 
 <input id="aog-js-sort-field" type="text" placeholder="Field name (optional)" class="aog-js-input"> 
 <select id="aog-js-sort-direction" class="aog-js-input aog-js-small-input"> 
 <option value="asc">Ascending</option> 
 <option value="desc">Descending</option> 
 </select> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-page-size" class="aog-js-label">Page size:</label> 
 <input id="aog-js-page-size" type="number" value="50" min="1" max="100" class="aog-js-input aog-js-small-input"> 
 <label for="aog-js-page-number" class="aog-js-label aog-js-inline-label">Page:</label> 
 <input id="aog-js-page-number" type="number" value="0" min="0" class="aog-js-input aog-js-small-input"> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Content Library Tab --> 
 <div id="content-library-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Content Library Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Explore site's business info, text and images from the Content Library API.</p> 
 </div> 
 <button id="aog-js-load-content-library" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">📚</span> 
 Load Content Library 
 </button> 
 <div id="aog-js-content-lib-status" class="aog-js-status"></div> 
 <div id="aog-js-content-sections" class="aog-js-content-sections"> 
 <div class="aog-js-content-section-list"> 
 <div class="aog-js-content-section" data-section="business_data"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Business Data</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 <div class="aog-js-content-section" data-section="location_data"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Location Data</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 <div class="aog-js-content-section" data-section="additional_locations"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Additional Locations</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 <div class="aog-js-content-section" data-section="site_texts"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Site Texts</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 <div class="aog-js-content-section" data-section="site_images"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Site Images</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Store Tab --> 
 <div id="store-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Store API Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Explore the Store API to access product catalog and categories.</p> 
 </div> 
 <div class="aog-js-store-actions"> 
 <button id="aog-js-load-catalog" class="aog-js-action-button aog-js-wide-button"> 
 <span class="aog-js-button-icon">🛒</span> 
 Load Product Catalog 
 </button> 
 <button id="aog-js-load-categories" class="aog-js-action-button aog-js-wide-button"> 
 <span class="aog-js-button-icon">📁</span> 
 Load Product Categories 
 </button> 
 </div> 
 <div id="aog-js-store-status" class="aog-js-status"></div> 
 <div class="aog-js-filter-section"> 
 <div class="aog-js-section-subtitle">Filtering &amp; Sorting (Optional)</div> 
 <div class="aog-js-filter-inputs"> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-store-filter-field" class="aog-js-label">Field:</label> 
 <input id="aog-js-store-filter-field" type="text" placeholder="Field name" class="aog-js-input"> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-store-filter-operator" class="aog-js-label">Operator:</label> 
 <select id="aog-js-store-filter-operator" class="aog-js-input"> 
 <option value="EQ">Equal to (EQ)</option> 
 <option value="NE">Not equal to (NE)</option> 
 <option value="GT">Greater than (GT)</option> 
 <option value="GTE">Greater than or equal (GTE)</option> 
 <option value="LT">Less than (LT)</option> 
 <option value="LTE">Less than or equal (LTE)</option> 
 <option value="IN">In array (IN)</option> 
 <option value="NIN">Not in array (NIN)</option> 
 <option value="BTWN">Between (BTWN)</option> 
 </select> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-store-filter-value" class="aog-js-label">Value:</label> 
 <input id="aog-js-store-filter-value" type="text" placeholder="Value or comma-separated values for IN/BTWN" class="aog-js-input"> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-store-sort-field" class="aog-js-label">Sort by:</label> 
 <input id="aog-js-store-sort-field" type="text" placeholder="Field name (optional)" class="aog-js-input"> 
 <select id="aog-js-store-sort-direction" class="aog-js-input aog-js-small-input"> 
 <option value="asc">Ascending</option> 
 <option value="desc">Descending</option> 
 </select> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Dynamic Pages Tab --> 
 <div id="dynamic-pages-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Dynamic Pages Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Check if the current page is a dynamic page and explore its data.</p> 
 </div> 
 <button id="aog-js-check-dynamic-page" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">📄</span> 
 Check Current Page 
 </button> 
 <div id="aog-js-dynamic-page-status" class="aog-js-status"></div> 
 <div id="aog-js-dynamic-page-info" class="aog-js-dynamic-page-info"> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Is Dynamic Page:</div> 
 <div id="aog-js-is-dynamic" class="aog-js-info-value">Unknown</div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Core Methods Tab --> 
 <div id="core-methods-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Core API Methods</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Access core API methods to get site information, navigation items, and more.</p> 
 </div> 
 <div class="aog-js-method-group"> 
 <h3 class="aog-js-method-group-title">Site Information</h3> 
 <div class="aog-js-method-buttons"> 
 <button class="aog-js-method-button" data-method="getSiteName">getSiteName</button> 
 <button class="aog-js-method-button" data-method="getSiteExternalId">getSiteExternalId</button> 
 <button class="aog-js-method-button" data-method="getSitePlanID">getSitePlanID</button> 
 <button class="aog-js-method-button" data-method="getCurrentDeviceType">getCurrentDeviceType</button> 
 <button class="aog-js-method-button" data-method="getCurrentEnvironment">getCurrentEnvironment</button> 
 </div> 
 </div> 
 <div class="aog-js-method-group"> 
 <h3 class="aog-js-method-group-title">Navigation</h3> 
 <div class="aog-js-method-buttons"> 
 <button class="aog-js-method-button" data-method="getNavItemsAsync">getNavItemsAsync</button> 
 </div> 
 </div> 
 <div id="aog-js-method-result-container" class="aog-js-method-result-container"> 
 <div class="aog-js-section-subtitle">Method Result</div> 
 <pre id="aog-js-method-result" class="aog-js-method-result">Click a method button to see its result</pre> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Raw JSON Tab --> 
 <div id="raw-json-tab" class="aog-js-tab-pane"> 
 <div class="aog-js-code-controls"> 
 <button id="aog-js-copy-json" class="aog-js-control-button" type="button">Copy JSON</button> 
 <button id="aog-js-format-json" class="aog-js-control-button" type="button">Format JSON</button> 
 </div> 
 <pre id="aog-js-raw-json" class="aog-js-json-display">No data available. Use the other tabs to fetch data first.</pre> 
 </div> 
  
 <!-- Members API Tab --> 
 <div id="members-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Members API Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Check for logged-in members and access member data.</p> 
 </div> 
 <button id="aog-js-check-member" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">👤</span> 
 Check Logged-in Member 
 </button> 
 <div id="aog-js-member-status" class="aog-js-status"></div> 
 <div id="aog-js-member-info" class="aog-js-member-info"> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Login Status:</div> 
 <div id="aog-js-is-logged-in" class="aog-js-info-value">Unknown</div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Sitemap Tab --> 
 <div id="sitemap-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Sitemap Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Fetch and explore the site's sitemap.xml file.</p> 
 </div> 
 <button id="aog-js-fetch-sitemap" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">🗺️</span> 
 Fetch Sitemap 
 </button> 
 <div id="aog-js-sitemap-status" class="aog-js-status"></div> 
 <div id="aog-js-sitemap-stats" class="aog-js-sitemap-stats" style="display: none;"> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Total URLs:</div> 
 <div id="aog-js-sitemap-count" class="aog-js-info-value">0</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Last Updated:</div> 
 <div id="aog-js-sitemap-updated" class="aog-js-info-value">Unknown</div> 
 </div> 
 </div> 
 <div id="aog-js-sitemap-container" class="aog-js-sitemap-container" style="display: none;"> 
 <h5 class="aog-js-section-subtitle">Sitemap URLs</h5> 
 <div id="aog-js-sitemap-urls" class="aog-js-sitemap-urls"></div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- API Settings Tab --> 
 <div id="api-settings-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">API Configuration</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Initialize the APIs to explore available data on this page.</p> 
 </div> 
 <button id="aog-js-init-all-btn" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">⚡</span> 
 Initialize All APIs 
 </button> 
 <div class="aog-js-api-info"> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Collections API:</div> 
 <div id="aog-js-collections-api-status" class="aog-js-info-value">Not initialized</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Content Library:</div> 
 <div id="aog-js-content-api-status" class="aog-js-info-value">Not initialized</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Dynamic Pages API:</div> 
 <div id="aog-js-dynamic-api-status" class="aog-js-info-value">Not initialized</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Members API:</div> 
 <div id="aog-js-members-api-status" class="aog-js-info-value">Not initialized</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Core dmAPI:</div> 
 <div id="aog-js-core-api-status" class="aog-js-info-value"> 
 <span id="aog-js-core-api-available">Checking...</span> 
 </div> 
 </div> 
 </div> 
 <div class="aog-js-debug-section"> 
 <div class="aog-js-section-subtitle">Debug Settings</div> 
 <div class="aog-js-debug-toggle"> 
 <label class="aog-js-switch"> 
 <input type="checkbox" id="aog-js-debug-toggle"> 
 <span class="aog-js-slider"></span> 
 </label> 
 <span class="aog-js-debug-label">Enable debug mode</span> 
 </div> 
 <p class="aog-js-debug-description"> 
 When debug mode is enabled, detailed logs will be output to the browser console. 
 This helps troubleshoot issues with API connections and data retrieval. 
 </p> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 /* 
 * Enhanced Duda JS API Explorer Widget - Styles 
 * Uses Inter font family and adaptive colors 
 */ 
  
 /* Import Inter font */ 
 @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); 
  
 /* Define nav display styles */ 
 .aog-js-nav-display { 
 background-color: #f8f9fa; 
 border-radius: 6px; 
 padding: 12px; 
 margin-bottom: 15px; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-nav-heading { 
 font-weight: bold; 
 margin-bottom: 10px; 
 font-size: 15px; 
 color: #1A1B4B; 
 } 
  
 .aog-js-nav-item { 
 padding: 6px 0; 
 border-bottom: 1px solid #eee; 
 } 
  
 .aog-js-nav-title { 
 font-weight: 500; 
 color: #1A1B4B; 
 } 
  
 .aog-js-nav-path { 
 color: #666; 
 font-size: 13px; 
 } 
  
 .aog-js-raw-link-container { 
 text-align: right; 
 padding-top: 10px; 
 } 
  
 .aog-js-show-raw { 
 font-size: 13px; 
 color: #6B46C1; 
 text-decoration: none; 
 } 
  
 .aog-js-show-raw:hover { 
 text-decoration: underline; 
 } 
  
 /* Widget Container */ 
 #aog-enhanced-js-explorer-widget { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 14px; 
 line-height: 1.5; 
 color: #333; 
 position: relative; 
 z-index: 999999; 
 } 
  
 /* Button Styles */ 
 .aog-js-explorer-button { 
 position: fixed; 
 bottom: 20px; 
 left: 20px; 
 background-color: #ad24a6; /* Agents of Genius CTA color */ 
 color: white; 
 border: none; 
 border-radius: 50px; 
 padding: 12px 20px; 
 font-size: 14px; 
 font-weight: 500; 
 cursor: pointer; 
 display: flex; 
 align-items: center; 
 box-shadow: 0 2px 10px rgba(0,0,0,0.2); 
 transition: all 0.3s ease; 
 z-index: 999999; 
 } 
  
 .aog-js-explorer-button:hover { 
 background-color: #851c83; /* Agents of Genius CTA hover color */ 
 box-shadow: 0 4px 12px rgba(0,0,0,0.3); 
 } 
  
 .aog-js-explorer-icon { 
 margin-right: 8px; 
 font-weight: bold; 
 font-size: 16px; 
 } 
  
 /* Panel Styles */ 
 .aog-js-explorer-panel { 
 position: fixed; 
 bottom: 90px; 
 left: 20px; 
 width: 800px; 
 height: 80vh; 
 max-height: 800px; 
 background-color: white; 
 border-radius: 10px; /* Changed to 10px as requested */ 
 box-shadow: 0 5px 25px rgba(0,0,0,0.3); 
 display: none; 
 flex-direction: column; 
 z-index: 999998; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-explorer-header { 
 background-color: #ad24a6; /* Agents of Genius CTA color */ 
 padding: 15px 20px; 
 border-bottom: 1px solid rgba(255,255,255,0.2); 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 border-top-left-radius: 10px; 
 border-top-right-radius: 10px; 
 } 
  
 .aog-js-logo-container { 
 display: flex; 
 align-items: center; 
 height: 32px; 
 } 
  
 .aog-js-logo { 
 height: 100%; 
 max-width: 150px; 
 } 
  
 .aog-js-title { 
 margin: 0; 
 font-size: 16px; 
 font-weight: 600; 
 color: white !important; /* White text for better contrast */ 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-explorer-controls { 
 display: flex; 
 align-items: center; 
 } 
  
 .aog-js-explorer-close { 
 background: none; 
 border: none; 
 font-size: 24px; 
 color: white; 
 cursor: pointer; 
 padding: 0 5px; 
 line-height: 1; 
 } 
  
 .aog-js-explorer-content { 
 padding: 0; 
 overflow-y: auto; 
 flex-grow: 1; 
 position: relative; 
 } 
  
 /* Loading state */ 
 .aog-js-explorer-loading { 
 display: none; 
 flex-direction: column; 
 justify-content: center; 
 align-items: center; 
 height: 100%; 
 padding: 30px; 
 text-align: center; 
 color: #666; 
 } 
  
 .aog-js-spinner { 
 width: 40px; 
 height: 40px; 
 border: 3px solid #f3f3f3; 
 border-top: 3px solid #ad24a6; /* Agents of Genius CTA color */ 
 border-radius: 50%; 
 animation: spin 1s linear infinite; 
 margin-bottom: 15px; 
 } 
  
 @keyframes spin { 
 0% { transform: rotate(0deg); } 
 100% { transform: rotate(360deg); } 
 } 
  
 /* Error state */ 
 .aog-js-explorer-error { 
 display: none; 
 padding: 30px; 
 text-align: center; 
 color: #e74c3c; 
 flex-direction: column; 
 align-items: center; 
 justify-content: center; 
 height: 100%; 
 } 
  
 .aog-js-error-icon { 
 font-size: 40px; 
 margin-bottom: 15px; 
 } 
  
 /* Tab navigation */ 
 .aog-js-explorer-tabs { 
 display: flex; 
 border-bottom: 1px solid #E5E9F2; 
 background-color: #F5F7FB; 
 overflow-x: auto; 
 white-space: nowrap; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-tab-button { 
 padding: 12px 15px; 
 background: none; 
 border: none; 
 border-bottom: 2px solid transparent; 
 cursor: pointer; 
 font-size: 14px; 
 font-weight: 500; 
 color: #666; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-tab-button:hover { 
 color: #ad24a6; /* Agents of Genius CTA color */ 
 } 
  
 .aog-js-tab-button.active { 
 color: #ad24a6; /* Agents of Genius CTA color */ 
 border-bottom-color: #ad24a6; /* Agents of Genius CTA color */ 
 } 
  
 /* Tab content */ 
 .aog-js-explorer-tab-content { 
 padding: 20px; 
 } 
  
 .aog-js-tab-pane { 
 display: none; 
 } 
  
 .aog-js-tab-pane.active { 
 display: block; 
 } 
  
 /* General data styles */ 
 .aog-js-section-title { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 22px; 
 font-weight: 600; 
 margin-bottom: 20px; 
 color: #1A1B4B; 
 } 
  
 .aog-js-section-subtitle { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 18px; 
 font-weight: 600; 
 color: #1A1B4B; 
 margin-bottom: 12px; 
 margin-top: 20px; 
 } 
  
 .aog-js-notice { 
 padding: 10px; 
 background-color: #f8f9fa; 
 border-left: 4px solid #ad24a6; /* Agents of Genius CTA color */ 
 margin-bottom: 15px; 
 font-size: 13px; 
 color: #666; 
 } 
  
 .aog-js-notice p { 
 margin: 5px 0; 
 } 
  
 /* Input styles */ 
 .aog-js-input-container { 
 margin-bottom: 20px; 
 } 
  
 .aog-js-label { 
 display: block; 
 margin-bottom: 8px; 
 font-weight: 500; 
 color: #444; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-inline-label { 
 display: inline-block; 
 margin: 0 10px 0 15px; 
 } 
  
 .aog-js-input-group { 
 display: flex; 
 gap: 8px; 
 } 
  
 .aog-js-input { 
 flex-grow: 1; 
 padding: 10px 12px; 
 border: 1px solid #ddd; 
 border-radius: 6px; 
 font-size: 14px; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-small-input { 
 flex-grow: 0; 
 width: 100px; 
 } 
  
 .aog-js-input:focus { 
 outline: none; 
 border-color: #ad24a6; 
 } 
  
 .aog-js-input-row { 
 margin-bottom: 12px; 
 display: flex; 
 align-items: center; 
 } 
  
 .aog-js-filter-section { 
 margin-top: 20px; 
 border-top: 1px solid #eee; 
 padding-top: 20px; 
 } 
  
 .aog-js-filter-inputs { 
 background-color: #f8f9fa; 
 padding: 15px; 
 border-radius: 6px; 
 } 
  
 .aog-js-action-button { 
 background-color: #333; 
 color: white; 
 border: none; 
 border-radius: 6px; 
 padding: 0 15px; 
 font-weight: 500; 
 cursor: pointer; 
 transition: all 0.2s; 
 height: 38px; 
 display: flex; 
 align-items: center; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-action-button:hover { 
 background-color: #222; 
 } 
  
 .aog-js-wide-button { 
 padding: 10px 20px; 
 margin-right: 10px; 
 margin-bottom: 10px; 
 } 
  
 .aog-js-store-actions { 
 display: flex; 
 flex-wrap: wrap; 
 } 
  
 /* Status indicator */ 
 .aog-js-status { 
 margin-bottom: 20px; 
 padding: 12px 15px; 
 border-radius: 6px; 
 font-size: 14px; 
 line-height: 1.4; 
 display: none; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-status.success { 
 background-color: #f0fff4; 
 border-left: 3px solid #38a169; 
 color: #2f855a; 
 } 
  
 .aog-js-status.error { 
 background-color: #fff5f5; 
 border-left: 3px solid #e53e3e; 
 color: #c53030; 
 } 
  
 .aog-js-status.info { 
 background-color: #f8f9fa; 
 border-left: 3px solid #4299e1; 
 color: #2b6cb0; 
 } 
  
 /* Discovered collections */ 
 .aog-js-discovered-collections { 
 margin-bottom: 20px; 
 } 
  
 .aog-js-collections-header { 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 margin-bottom: 10px; 
 } 
  
 .aog-js-discovery-count { 
 font-size: 13px; 
 color: #666; 
 background-color: #f0f0f0; 
 padding: 4px 8px; 
 border-radius: 12px; 
 } 
  
 .aog-js-collections-list { 
 background-color: #f8f9fa; 
 border-radius: 6px; 
 padding: 15px; 
 max-height: 200px; 
 overflow-y: auto; 
 } 
  
 .aog-js-collection-item { 
 padding: 10px; 
 background-color: white; 
 border-radius: 4px; 
 margin-bottom: 8px; 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 cursor: pointer; 
 transition: all 0.2s; 
 } 
  
 .aog-js-collection-item:hover { 
 box-shadow: 0 2px 8px rgba(0,0,0,0.1); 
 } 
  
 .aog-js-collection-id { 
 font-weight: 500; 
 color: #333; 
 } 
  
 .aog-js-collection-load { 
 color: #ad24a6; 
 font-size: 13px; 
 font-weight: 500; 
 } 
  
 .aog-js-empty-state { 
 padding: 20px; 
 text-align: center; 
 color: #888; 
 font-style: italic; 
 } 
  
 /* Card styles */ 
 .aog-js-card { 
 background-color: #ffffff; 
 border-radius: 8px; 
 margin-bottom: 20px; 
 overflow: hidden; 
 box-shadow: 0 2px 10px rgba(0,0,0,0.05); 
 border: 1px solid #E5E9F2; 
 } 
  
 .aog-js-card-body { 
 padding: 20px; 
 } 
  
 /* Button styles */ 
 .aog-js-primary-button { 
 background-color: #ad24a6; 
 color: white; 
 border: none; 
 border-radius: 6px; 
 padding: 12px 20px; 
 font-weight: 500; 
 cursor: pointer; 
 display: flex; 
 align-items: center; 
 justify-content: center; 
 width: 100%; 
 margin-bottom: 15px; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-primary-button:hover { 
 background-color: #851c83; 
 } 
  
 .aog-js-button-icon { 
 margin-right: 8px; 
 } 
  
 /* API Info */ 
 .aog-js-api-info { 
 margin-top: 20px; 
 border-top: 1px solid #eee; 
 padding-top: 15px; 
 } 
  
 .aog-js-info-item { 
 display: flex; 
 margin-bottom: 10px; 
 border-bottom: 1px solid #eee; 
 padding-bottom: 10px; 
 } 
  
 .aog-js-info-label { 
 width: 120px; 
 font-weight: 500; 
 color: #444; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-info-value { 
 flex-grow: 1; 
 color: #666; 
 } 
  
 /* JSON display */ 
 .aog-js-json-display { 
 background-color: #f8f9fa; 
 padding: 15px; 
 border-radius: 6px; 
 overflow: auto; 
 font-family: Monaco, Menlo, Consolas, "Courier New", monospace; 
 font-size: 13px; 
 line-height: 1.5; 
 color: #333; 
 white-space: pre-wrap; 
 max-height: 600px; 
 } 
  
 .aog-js-code-controls { 
 margin-bottom: 10px; 
 display: flex; 
 gap: 8px; 
 } 
  
 .aog-js-control-button { 
 background-color: #f1f3f5; 
 border: 1px solid #dee2e6; 
 border-radius: 4px; 
 padding: 6px 12px; 
 font-size: 13px; 
 cursor: pointer; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-control-button:hover { 
 background-color: #e9ecef; 
 } 
  
 /* Copied notification */ 
 .aog-js-copied-notification { 
 position: fixed; 
 top: 20px; 
 right: 20px; 
 background-color: #ad24a6; 
 color: white; 
 padding: 12px 20px; 
 border-radius: 4px; 
 box-shadow: 0 2px 10px rgba(0,0,0,0.2); 
 opacity: 0; 
 transform: translateY(-10px); 
 transition: all 0.3s ease; 
 pointer-events: none; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-copied-notification.show { 
 opacity: 1; 
 transform: translateY(0); 
 } 
  
 /* Core Methods */ 
 .aog-js-method-group { 
 margin-bottom: 20px; 
 } 
  
 .aog-js-method-group-title { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 18px; 
 margin-bottom: 10px; 
 color: #1A1B4B; 
 } 
  
 .aog-js-method-buttons { 
 display: flex; 
 flex-wrap: wrap; 
 gap: 8px; 
 } 
  
 .aog-js-method-button { 
 background-color: #f1f3f5; 
 border: 1px solid #dee2e6; 
 border-radius: 4px; 
 padding: 8px 12px; 
 font-size: 13px; 
 cursor: pointer; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-method-button:hover { 
 background-color: #e9ecef; 
 } 
  
 .aog-js-method-result-container { 
 margin-top: 20px; 
 border-top: 1px solid #eee; 
 padding-top: 15px; 
 } 
  
 .aog-js-method-result { 
 background-color: #f8f9fa; 
 padding: 15px; 
 border-radius: 6px; 
 overflow: auto; 
 font-family: Monaco, Menlo, Consolas, "Courier New", monospace; 
 font-size: 13px; 
 line-height: 1.5; 
 color: #666; 
 white-space: pre-wrap; 
 max-height: 200px; 
 } 
  
 /* API Discovery Results */ 
 .aog-js-discovery-results { 
 margin-top: 20px; 
 } 
  
 .aog-js-api-section { 
 border: 1px solid #e5e9f2; 
 border-radius: 6px; 
 margin-bottom: 15px; 
 overflow: hidden; 
 } 
  
 .aog-js-api-section-title { 
 margin: 0; 
 font-size: 15px; 
 font-weight: 500; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-api-section h5 { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 18px; 
 background-color: #f5f7fb; 
 padding: 10px 15px; 
 border-bottom: 1px solid #e5e9f2; 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 margin: 0; 
 color: #1A1B4B; 
 } 
  
 .aog-js-api-section-status { 
 font-size: 13px; 
 color: #666; 
 font-weight: normal; 
 } 
  
 .aog-js-api-section-results { 
 padding: 15px; 
 max-height: 200px; 
 overflow-y: auto; 
 } 
  
 /* Content Library */ 
 .aog-js-content-sections { 
 margin-top: 20px; 
 } 
  
 .aog-js-content-section { 
 border: 1px solid #e5e9f2; 
 border-radius: 6px; 
 margin-bottom: 10px; 
 overflow: hidden; 
 } 
  
 /* Collection actions */ 
 .aog-js-collection-actions { 
 display: flex; 
 flex-direction: column; 
 gap: 15px; 
 width: 100%; 
 } 
  
 .aog-js-secondary-button { 
 background-color: #6B46C1; 
 margin-bottom: 5px; 
 } 
  
 .aog-js-secondary-button:hover { 
 background-color: #553C9A; 
 } 
  
 .aog-js-specific-collection { 
 width: 100%; 
 } 
  
 .aog-js-content-section-header { 
 background-color: #f5f7fb; 
 padding: 10px 15px; 
 cursor: pointer; 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 } 
  
 .aog-js-content-section-title { 
 font-weight: 500; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-content-section-body { 
 padding: 0; 
 max-height: 0; 
 overflow: hidden; 
 transition: all 0.3s ease; 
 } 
  
 .aog-js-content-section.expanded .aog-js-content-section-body { 
 padding: 15px; 
 max-height: 500px; 
 overflow-y: auto; 
 } 
  
 .aog-js-content-section.expanded .aog-js-content-section-toggle { 
 transform: rotate(90deg); 
 } 
  
 .aog-js-content-section-toggle { 
 transition: transform 0.3s ease; 
 } 
  
 /* Debug Toggle */ 
 .aog-js-debug-section { 
 margin-top: 20px; 
 border-top: 1px solid #eee; 
 padding-top: 15px; 
 } 
  
 .aog-js-debug-toggle { 
 display: flex; 
 align-items: center; 
 } 
  
 .aog-js-switch { 
 position: relative; 
 display: inline-block; 
 width: 50px; 
 height: 24px; 
 margin-right: 10px; 
 } 
  
 .aog-js-switch input { 
 opacity: 0; 
 width: 0; 
 height: 0; 
 } 
  
 .aog-js-slider { 
 position: absolute; 
 cursor: pointer; 
 top: 0; 
 left: 0; 
 right: 0; 
 bottom: 0; 
 background-color: #ccc; 
 transition: .4s; 
 border-radius: 34px; 
 } 
  
 .aog-js-slider:before { 
 position: absolute; 
 content: ""; 
 height: 16px; 
 width: 16px; 
 left: 4px; 
 bottom: 4px; 
 background-color: white; 
 transition: .4s; 
 border-radius: 50%; 
 } 
  
 input:checked + .aog-js-slider { 
 background-color: #ad24a6; 
 } 
  
 input:checked + .aog-js-slider:before { 
 transform: translateX(26px); 
 } 
  
 .aog-js-debug-label { 
 font-size: 14px; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-debug-description { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 13px; 
 color: #666; 
 line-height: 1.5; 
 } 
  
 /* Mobile responsiveness */ 
 @media (max-width: 992px) { 
 .aog-js-explorer-panel { 
 width: calc(100% - 40px); 
 height: 80vh; 
 bottom: 80px; 
 } 
  
 .aog-js-explorer-tabs { 
 overflow-x: auto; 
 white-space: nowrap; 
 } 
  
 .aog-js-input-row { 
 flex-direction: column; 
 align-items: flex-start; 
 } 
  
 .aog-js-inline-label { 
 margin: 8px 0; 
 } 
  
 .aog-js-store-actions { 
 flex-direction: column; 
 } 
  
 .aog-js-wide-button { 
 width: 100%; 
 margin-right: 0; 
 } 
 } 
  
 @media (max-width: 480px) { 
 .aog-js-method-buttons { 
 flex-direction: column; 
 } 
  
 .aog-js-method-button { 
 width: 100%; 
 } 
 } 
  
 /* Sitemap Styles */ 
 .aog-js-sitemap-url-list { 
 list-style: none; 
 padding: 0; 
 margin: 0; 
 } 
  
 .aog-js-sitemap-url-item { 
 padding: 8px 0; 
 border-bottom: 1px solid #eee; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-sitemap-url-item a { 
 color: #4a5568; 
 text-decoration: none; 
 } 
  
 .aog-js-sitemap-url-item a:hover { 
 color: #ad24a6; 
 text-decoration: underline; 
 } 
  
 .aog-js-sitemap-lastmod { 
 font-size: 12px; 
 color: #718096; 
 margin-left: 8px; 
 } 
 // Enhanced JS API Explorer Widget - Agents of Genius Branded JavaScript 
 // IIFE to avoid polluting global scope 
 (function() { 
 // Debug flag - can be toggled via UI 
 let DEBUG = false; 
  
 // Debug logging function 
 function debug(message, data) { 
 if (DEBUG) { 
 console.log(`[AOGJS Debug] ${message}`, data || ''); 
 } 
 } 
  
 // Initialize immediately 
 debug('Script loaded, initializing...'); 
 document.addEventListener('DOMContentLoaded', initEnhancedJSAPIExplorer); 
  
 // Main initialization function 
 function initEnhancedJSAPIExplorer() { 
 // API State 
 let apiState = { 
 collectionsAPI: null, 
 contentLibraryAPI: null, 
 dynamicPagesAPI: null, 
 currentData: null, 
 discoveredCollections: [], 
 isDudaSite: false 
 }; 
  
 // DOM Elements 
 const explorerButton = document.getElementById('aog-js-explorer-button'); 
 const explorerPanel = document.getElementById('aog-js-explorer-panel'); 
 const closeButton = document.getElementById('aog-js-explorer-close'); 
 const loadingEl = document.getElementById('aog-js-explorer-loading'); 
 const errorEl = document.getElementById('aog-js-explorer-error'); 
 const errorMessage = document.getElementById('aog-js-error-message'); 
 const dataEl = document.getElementById('aog-js-explorer-data'); 
  
 // Settings Elements 
 const initAllBtn = document.getElementById('aog-js-init-all-btn'); 
 const collectionsApiStatusEl = document.getElementById('aog-js-collections-api-status'); 
 const contentApiStatusEl = document.getElementById('aog-js-content-api-status'); 
 const dynamicApiStatusEl = document.getElementById('aog-js-dynamic-api-status'); 
 const coreApiAvailableEl = document.getElementById('aog-js-core-api-available'); 
 const debugToggle = document.getElementById('aog-js-debug-toggle'); 
  
 // Collections Tab Elements 
 const findBtn = document.getElementById('aog-js-find-btn'); 
 // Removed findAllBtn reference since we're removing that button 
 const collectionInput = document.getElementById('aog-js-collection-input'); 
 const collectionsStatusEl = document.getElementById('aog-js-collections-status'); 
 const collectionsListEl = document.getElementById('aog-js-collections-list'); 
 const discoveryCountEl = document.querySelector('.aog-js-discovery-count'); 
  
 // Filter Elements 
 const filterFieldEl = document.getElementById('aog-js-filter-field'); 
 const filterOperatorEl = document.getElementById('aog-js-filter-operator'); 
 const filterValueEl = document.getElementById('aog-js-filter-value'); 
 const sortFieldEl = document.getElementById('aog-js-sort-field'); 
 const sortDirectionEl = document.getElementById('aog-js-sort-direction'); 
 const pageSizeEl = document.getElementById('aog-js-page-size'); 
 const pageNumberEl = document.getElementById('aog-js-page-number'); 
  
 // Store Tab Elements 
 const loadCatalogBtn = document.getElementById('aog-js-load-catalog'); 
 const loadCategoriesBtn = document.getElementById('aog-js-load-categories'); 
 const storeStatusEl = document.getElementById('aog-js-store-status'); 
 const storeFilterFieldEl = document.getElementById('aog-js-store-filter-field'); 
 const storeFilterOperatorEl = document.getElementById('aog-js-store-filter-operator'); 
 const storeFilterValueEl = document.getElementById('aog-js-store-filter-value'); 
 const storeSortFieldEl = document.getElementById('aog-js-store-sort-field'); 
 const storeSortDirectionEl = document.getElementById('aog-js-store-sort-direction'); 
  
 // Content Library Tab Elements 
 const loadContentLibraryBtn = document.getElementById('aog-js-load-content-library'); 
 const contentLibStatusEl = document.getElementById('aog-js-content-lib-status'); 
 const contentSectionElements = document.querySelectorAll('.aog-js-content-section'); 
  
 // Dynamic Pages Tab Elements 
 const checkDynamicPageBtn = document.getElementById('aog-js-check-dynamic-page'); 
 const dynamicPageStatusEl = document.getElementById('aog-js-dynamic-page-status'); 
 const isDynamicEl = document.getElementById('aog-js-is-dynamic'); 
  
 // Core Methods Tab Elements 
 const methodButtons = document.querySelectorAll('.aog-js-method-button'); 
 const methodResultEl = document.getElementById('aog-js-method-result'); 
  
 // API Discovery Tab Elements 
 const discoverAllBtn = document.getElementById('aog-js-discover-all'); 
 const apiSections = document.querySelectorAll('.aog-js-api-section'); 
  
 // Raw JSON Tab Elements 
 const rawJsonEl = document.getElementById('aog-js-raw-json'); 
 const copyJsonBtn = document.getElementById('aog-js-copy-json'); 
 const formatJsonBtn = document.getElementById('aog-js-format-json'); 
  
 // Tab Elements 
 const tabButtons = document.querySelectorAll('.aog-js-tab-button'); 
 const tabPanes = document.querySelectorAll('.aog-js-tab-pane'); 
  
 // UI State 
 let isOpen = false; 
  
 // Apply style updates 
 function applyStyleUpdates() { 
 // 1. Reduce size of section titles in API discovery and other tabs 
 const sectionTitles = document.querySelectorAll('.aog-js-section-title'); 
 sectionTitles.forEach(title => { 
 title.style.fontSize = '16px'; 
 title.style.fontWeight = '600'; 
 }); 
  
 // 2. Reduce size of section subtitles 
 const sectionSubtitles = document.querySelectorAll('.aog-js-section-subtitle'); 
 sectionSubtitles.forEach(subtitle => { 
 subtitle.style.fontSize = '14px'; 
 subtitle.style.fontWeight = '600'; 
 }); 
  
 // 3. Make all CTA buttons the same color (#ad24a6 - purple) 
 const ctaButtons = document.querySelectorAll('.aog-js-primary-button'); 
 ctaButtons.forEach(button => { 
 button.style.backgroundColor = '#ad24a6'; 
 button.style.color = 'white'; 
 }); 
  
 // 4. Remove the main JS API Explorer title from header 
 const headerTitle = document.querySelector('.aog-js-explorer-header h2'); 
 if (headerTitle) { 
 headerTitle.style.display = 'none'; 
 } 
  
 // 5. Remove "Find All Collections" button if it exists 
 const findAllBtn = document.getElementById('aog-js-find-all-btn'); 
 if (findAllBtn) { 
 findAllBtn.style.display = 'none'; 
 } 
  
 // 6. Update the collections tab description 
 const collectionsDesc = document.querySelector('.aog-js-collections-description'); 
 if (collectionsDesc) { 
 collectionsDesc.textContent = 'Enter a collection name or ID to retrieve data. Use filters and sorting options below for more specific queries.'; 
 } 
  
 // 7. Update the API discovery tab description 
 const apiDiscoveryDesc = document.querySelector('.aog-js-api-discovery-description'); 
 if (apiDiscoveryDesc) { 
 apiDiscoveryDesc.textContent = 'Discover available APIs on this site. To search for collections, go to the Collections tab and enter a collection name.'; 
 } 
 } 
  
 // Check if running on a Duda site 
 function checkDudaEnvironment() { 
 const isDudaSite = typeof window.dmAPI !== 'undefined'; 
 debug('Checking Duda environment', { isDudaSite }); 
 apiState.isDudaSite = isDudaSite; 
  
 if (isDudaSite) { 
 coreApiAvailableEl.textContent = 'Available ✓'; 
 coreApiAvailableEl.style.color = '#38a169'; 
 } else { 
 coreApiAvailableEl.textContent = 'Not detected'; 
 coreApiAvailableEl.style.color = '#e53e3e'; 
 // Show warning in API discovery tab 
 showStatus('Warning: dmAPI not detected. Are you on a Duda site?', 'error', 'api-discovery-tab'); 
 } 
  
 return isDudaSite; 
 } 
  
 // Tab switching 
 function switchTab(event) { 
 const tabId = event.target.getAttribute('data-tab'); 
 debug('Tab switch to:', tabId); 
  
 // Update active tab button 
 tabButtons.forEach(button => { 
 button.classList.remove('active'); 
 }); 
 event.target.classList.add('active'); 
  
 // Update active tab pane 
 tabPanes.forEach(pane => { 
 pane.classList.remove('active'); 
 }); 
 document.getElementById(`${tabId}-tab`).classList.add('active'); 
 } 
  
 // Toggle panel 
 function togglePanel() { 
 debug('Toggle panel called, current state:', isOpen); 
 if (isOpen) { 
 explorerPanel.style.display = 'none'; 
 } else { 
 explorerPanel.style.display = 'flex'; 
 // Check if running on a Duda site 
 checkDudaEnvironment(); 
 // Apply style updates 
 applyStyleUpdates(); 
 } 
 isOpen = !isOpen; 
 } 
  
 // Close panel 
 function closePanel() { 
 debug('Close panel called'); 
 explorerPanel.style.display = 'none'; 
 isOpen = false; 
 } 
  
 // Show status message in a specific tab 
 function showStatus(message, type = 'info', tabId = null) { 
 debug(`Status: ${message} (${type}) in tab: ${tabId || 'current'}`); 
 let statusEl; 
  
 // Determine which status element to use 
 if (tabId === 'collections-tab') { 
 statusEl = collectionsStatusEl; 
 } else if (tabId === 'store-tab') { 
 statusEl = storeStatusEl; 
 } else if (tabId === 'content-library-tab') { 
 statusEl = contentLibStatusEl; 
 } else if (tabId === 'dynamic-pages-tab') { 
 statusEl = dynamicPageStatusEl; 
 } else if (tabId === 'api-discovery-tab') { 
 // For discovery tab, show in all status elements 
 const discoveryStatusEl = document.querySelector('#aog-js-discovery-results .aog-js-status'); 
 if (discoveryStatusEl) { 
 discoveryStatusEl.textContent = message; 
 discoveryStatusEl.className = 'aog-js-status'; 
 discoveryStatusEl.classList.add(type); 
 discoveryStatusEl.style.display = 'block'; 
 } 
 return; 
 } else { 
 // Default to collections status 
 statusEl = collectionsStatusEl; 
 } 
  
 statusEl.textContent = message; 
 statusEl.className = 'aog-js-status'; // Reset classes 
 statusEl.classList.add(type); 
 statusEl.style.display = 'block'; 
  
 // Auto-hide success messages after 5 seconds 
 if (type === 'success') { 
 setTimeout(() => { 
 statusEl.style.display = 'none'; 
 }, 5000); 
 } 
 } 
  
 // Create collection item (for when collection is added to discovered collections) 
 function createCollectionItem(id) { 
 const item = document.createElement('div'); 
 item.className = 'aog-js-collection-item'; 
  
 const idEl = document.createElement('div'); 
 idEl.className = 'aog-js-collection-id'; 
 idEl.textContent = id; 
  
 const loadEl = document.createElement('div'); 
 loadEl.className = 'aog-js-collection-load'; 
 loadEl.textContent = 'Load →'; 
  
 item.appendChild(idEl); 
 item.appendChild(loadEl); 
  
 // Add click event to load this collection 
 item.addEventListener('click', () => { 
 collectionInput.value = id; 
 findCollection(id); 
 }); 
  
 return item; 
 } 
  
 // Initialize all APIs 
 async function initAllAPIs() { 
 debug('Initializing all APIs...'); 
  
 if (!apiState.isDudaSite) { 
 showAllErrors('dmAPI not detected. Cannot initialize APIs.'); 
 return; 
 } 
  
 // Show loading state 
 dataEl.style.display = 'none'; 
 loadingEl.style.display = 'flex'; 
  
 try { 
 // Initialize Collections API 
 try { 
 apiState.collectionsAPI = await window.dmAPI.loadCollectionsAPI(); 
 collectionsApiStatusEl.textContent = 'Initialized ✓'; 
 collectionsApiStatusEl.style.color = '#38a169'; 
 } catch (error) { 
 debug('Error initializing Collections API:', error); 
 collectionsApiStatusEl.textContent = 'Failed: ' + error.message; 
 collectionsApiStatusEl.style.color = '#e53e3e'; 
 } 
  
 // Initialize Content Library API 
 try { 
 apiState.contentLibraryAPI = await window.dmAPI.loadContentLibrary(); 
 contentApiStatusEl.textContent = 'Initialized ✓'; 
 contentApiStatusEl.style.color = '#38a169'; 
 } catch (error) { 
 debug('Error initializing Content Library API:', error); 
 contentApiStatusEl.textContent = 'Failed: ' + error.message; 
 contentApiStatusEl.style.color = '#e53e3e'; 
 } 
  
 // Initialize Dynamic Pages API 
 try { 
 apiState.dynamicPagesAPI = window.dmAPI.dynamicPageApi(); 
 dynamicApiStatusEl.textContent = 'Initialized ✓'; 
 dynamicApiStatusEl.style.color = '#38a169'; 
 } catch (error) { 
 debug('Error initializing Dynamic Pages API:', error); 
 dynamicApiStatusEl.textContent = 'Failed: ' + error.message; 
 dynamicApiStatusEl.style.color = '#e53e3e'; 
 } 
  
 // Check Members API 
 const membersApiStatusEl = document.getElementById('aog-js-members-api-status'); 
 try { 
 if (typeof window.dmAPI.getLoggedInMember === 'function') { 
 membersApiStatusEl.textContent = 'Available ✓'; 
 membersApiStatusEl.style.color = '#38a169'; 
 } else { 
 membersApiStatusEl.textContent = 'Not Available'; 
 membersApiStatusEl.style.color = '#dd6b20'; 
 } 
 } catch (error) { 
 debug('Error checking Members API:', error); 
 membersApiStatusEl.textContent = 'Failed: ' + error.message; 
 membersApiStatusEl.style.color = '#e53e3e'; 
 } 
  
 // Show data section 
 loadingEl.style.display = 'none'; 
 dataEl.style.display = 'block'; 
  
 showStatus('✅ APIs initialized successfully!', 'success', 'api-settings-tab'); 
 } catch (error) { 
 loadingEl.style.display = 'none'; 
 dataEl.style.display = 'block'; 
 showStatus(`❌ Error initializing APIs: ${error.message}`, 'error', 'api-settings-tab'); 
 debug('Full initialization error:', error); 
 } 
 } 
  
 // Show error in all status elements 
 function showAllErrors(errorMsg) { 
 showStatus(errorMsg, 'error', 'collections-tab'); 
 showStatus(errorMsg, 'error', 'content-library-tab'); 
 showStatus(errorMsg, 'error', 'store-tab'); 
 showStatus(errorMsg, 'error', 'dynamic-pages-tab'); 
 showStatus(errorMsg, 'error', 'api-discovery-tab'); 
 showStatus(errorMsg, 'error', 'api-settings-tab'); 
 } 
  
 // Find collection with filters and also display in collections tab 
 async function findCollection(collectionId) { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot find collection: dmAPI not detected', 'error', 'collections-tab'); 
 return; 
 } 
  
 if (!apiState.collectionsAPI) { 
 showStatus('Collections API not initialized. Click "Initialize All APIs" in Settings tab first.', 'error', 'collections-tab'); 
 return; 
 } 
  
 if (!collectionId) { 
 collectionId = collectionInput.value.trim(); 
 } 
  
 if (!collectionId) { 
 showStatus('Please enter a collection name or ID', 'error', 'collections-tab'); 
 return; 
 } 
  
 debug(`Finding collection: ${collectionId}`); 
 showStatus(`Searching for collection: ${collectionId}...`, 'info', 'collections-tab'); 
  
 try { 
 // Build query with filters if provided 
 let query = apiState.collectionsAPI.data(collectionId); 
  
 // Add where clause if field is provided 
 const filterField = filterFieldEl.value.trim(); 
 const filterOperator = filterOperatorEl.value; 
 const filterValue = filterValueEl.value.trim(); 
  
 if (filterField && filterValue) { 
 // Handle array operators (IN, NIN, BTWN) 
 if (['IN', 'NIN', 'BTWN'].includes(filterOperator)) { 
 const valueArray = filterValue.split(',').map(v => v.trim()); 
 query = query.where(filterField, filterOperator, valueArray); 
 } else { 
 // Convert to number if it looks like one 
 const value = !isNaN(filterValue) ? parseFloat(filterValue) : filterValue; 
 query = query.where(filterField, filterOperator, value); 
 } 
 } 
  
 // Add sort if field is provided 
 const sortField = sortFieldEl.value.trim(); 
 const sortDirection = sortDirectionEl.value; 
  
 if (sortField) { 
 query = query.orderBy(sortField, sortDirection); 
 } 
  
 // Add pagination 
 const pageSize = parseInt(pageSizeEl.value) || 50; 
 const pageNumber = parseInt(pageNumberEl.value) || 0; 
  
 query = query.pageSize(pageSize).pageNumber(pageNumber); 
  
 // Execute query 
 const data = await query.get(); 
  
 // Check if the response is actually an error 
 if (isErrorResponse(data)) { 
 showStatus(`❌ Error: ${data.message || 'Collection not found'}`, 'error', 'collections-tab'); 
 showResults(data); 
 return; 
 } 
  
 // Check if the response is valid and contains data 
 if (data) { 
 let itemCount = 0; 
 let dataType = 'unknown'; 
  
 // For array responses 
 if (Array.isArray(data)) { 
 itemCount = data.length; 
 dataType = 'array'; 
  
 if (data.length > 0) { 
 showStatus(`✅ Successfully retrieved collection: ${collectionId} (${data.length} items)`, 'success', 'collections-tab'); 
 } else { 
 showStatus('⚠️ Collection found but contains no items.', 'info', 'collections-tab'); 
 } 
 } 
 // For object responses like the one with values property 
 else if (data.values && Array.isArray(data.values)) { 
 itemCount = data.values.length; 
 dataType = 'object with values array'; 
  
 if (data.values.length > 0) { 
 showStatus(`✅ Successfully retrieved collection: ${collectionId} (${data.values.length} items)`, 'success', 'collections-tab'); 
 } else { 
 showStatus('⚠️ Collection found but contains no items.', 'info', 'collections-tab'); 
 } 
 } 
 // For other types of responses 
 else if (typeof data === 'object' && Object.keys(data).length > 0) { 
 itemCount = Object.keys(data).length; 
 dataType = 'object'; 
 showStatus(`✅ Successfully retrieved data for: ${collectionId}`, 'success', 'collections-tab'); 
 } else { 
 showStatus('⚠️ Response received but with unexpected format.', 'info', 'collections-tab'); 
 } 
  
 // Add the collection to discovered collections if not already there 
 if (!apiState.discoveredCollections.includes(collectionId)) { 
 apiState.discoveredCollections.push(collectionId); 
 updateDiscoveredCollections(); 
 } 
  
 // Display in Raw JSON tab 
 showResults(data); 
  
 // Also display in collections tab 
 displayCollectionData(collectionId, data, itemCount, dataType); 
 } else { 
 showStatus('⚠️ Received empty response.', 'error', 'collections-tab'); 
 showResults({}); 
 } 
 } catch (error) { 
 showStatus(`❌ Error finding collection: ${error.message}`, 'error', 'collections-tab'); 
 showResults({ error: error.message }); 
  
 // Try alternative methods if API call fails 
 tryAlternativeMethods(collectionId); 
 } 
 } 
  
 // Display collection data in the collections tab 
 function displayCollectionData(collectionId, data, itemCount, dataType) { 
 // Check if collection details section exists, create if not 
 let collectionDetailsEl = document.getElementById('aog-js-collection-details'); 
 if (!collectionDetailsEl) { 
 collectionDetailsEl = document.createElement('div'); 
 collectionDetailsEl.id = 'aog-js-collection-details'; 
 collectionDetailsEl.className = 'aog-js-collection-details'; 
  
 // Find where to insert it (after the discovered collections) 
 const insertAfter = document.getElementById('aog-js-discovered-collections'); 
 if (insertAfter && insertAfter.parentNode) { 
 insertAfter.parentNode.insertBefore(collectionDetailsEl, insertAfter.nextSibling); 
 } else { 
 // Fallback - try to insert before the filter section 
 const filterSection = document.querySelector('.aog-js-filter-section'); 
 if (filterSection && filterSection.parentNode) { 
 filterSection.parentNode.insertBefore(collectionDetailsEl, filterSection); 
 } 
 } 
 } 
  
 // Create the preview content 
 collectionDetailsEl.innerHTML = ''; 
  
 // Create the header 
 const headerEl = document.createElement('div'); 
 headerEl.className = 'aog-js-section-subtitle'; 
 headerEl.textContent = 'Collection Preview'; 
 collectionDetailsEl.appendChild(headerEl); 
  
 // Create the details container 
 const detailsContainer = document.createElement('div'); 
 detailsContainer.className = 'aog-js-card'; 
  
 const detailsBody = document.createElement('div'); 
 detailsBody.className = 'aog-js-card-body'; 
  
 // Create collection info 
 const infoEl = document.createElement('div'); 
 infoEl.className = 'aog-js-collection-info'; 
 infoEl.innerHTML = ` 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Collection Name:</div> 
 <div class="aog-js-info-value">${collectionId}</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Items Count:</div> 
 <div class="aog-js-info-value">${itemCount}</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Data Type:</div> 
 <div class="aog-js-info-value">${dataType}</div> 
 </div> 
 `; 
  
 detailsBody.appendChild(infoEl); 
  
 // Create data preview 
 const previewTitle = document.createElement('div'); 
 previewTitle.className = 'aog-js-section-subtitle'; 
 previewTitle.textContent = 'Data Preview'; 
 previewTitle.style.marginTop = '20px'; 
 detailsBody.appendChild(previewTitle); 
  
 // Format the data for display 
 let previewContent = ''; 
  
 try { 
 // Show a truncated version (first item if array, or first few properties if object) 
 if (Array.isArray(data) && data.length > 0) { 
 previewContent = JSON.stringify(data[0], null, 2); 
 if (data.length > 1) { 
 previewContent += `\n\n// ... and ${data.length - 1} more items`; 
 } 
 } else if (data.values && Array.isArray(data.values) && data.values.length > 0) { 
 previewContent = JSON.stringify(data.values[0], null, 2); 
 if (data.values.length > 1) { 
 previewContent += `\n\n// ... and ${data.values.length - 1} more items`; 
 } 
 } else { 
 // For objects, limit the preview 
 const fullJson = JSON.stringify(data, null, 2); 
 previewContent = fullJson.length > 1000 ? fullJson.substring(0, 1000) + '...' : fullJson; 
 } 
 } catch (error) { 
 previewContent = 'Error formatting data preview: ' + error.message; 
 } 
  
 const previewEl = document.createElement('pre'); 
 previewEl.className = 'aog-js-collection-preview'; 
 previewEl.textContent = previewContent; 
 detailsBody.appendChild(previewEl); 
  
 // Add view in raw JSON link 
 const viewRawLink = document.createElement('button'); 
 viewRawLink.className = 'aog-js-primary-button'; 
 viewRawLink.style.marginTop = '15px'; 
 viewRawLink.style.backgroundColor = '#ad24a6'; // Consistent purple color 
 viewRawLink.textContent = 'View Full Data in Raw JSON Tab'; 
 viewRawLink.addEventListener('click', () => { 
 // Switch to raw JSON tab 
 switchToTab('raw-json'); 
 }); 
  
 detailsBody.appendChild(viewRawLink); 
 detailsContainer.appendChild(detailsBody); 
 collectionDetailsEl.appendChild(detailsContainer); 
  
 // Make sure the details are visible 
 collectionDetailsEl.style.display = 'block'; 
 } 
  
 // Update discovered collections UI 
 function updateDiscoveredCollections() { 
 if (!collectionsListEl) return; 
  
 collectionsListEl.innerHTML = ''; 
  
 if (apiState.discoveredCollections.length === 0) { 
 const emptyState = document.createElement('div'); 
 emptyState.className = 'aog-js-empty-state'; 
 emptyState.textContent = 'No discovered collections yet. Search for a collection by name in the field above.'; 
 collectionsListEl.appendChild(emptyState); 
 return; 
 } 
  
 // Update count if element exists 
 if (discoveryCountEl) { 
 discoveryCountEl.textContent = `${apiState.discoveredCollections.length} found`; 
 } 
  
 // Add each collection to the list 
 apiState.discoveredCollections.forEach(id => { 
 collectionsListEl.appendChild(createCollectionItem(id)); 
 }); 
 } 
  
 // Try alternative methods to find collection 
 async function tryAlternativeMethods(identifier) { 
 debug('Trying alternative methods for: ' + identifier); 
 showStatus('Trying alternative lookup methods...', 'info', 'collections-tab'); 
  
 let found = false; 
  
 // Method 1: Try to access using external data source if available 
 if (typeof window.dm !== 'undefined' && typeof window.dm.getExternalDataSource === 'function') { 
 try { 
 const externalDataId = isNaN(identifier) ? identifier : parseInt(identifier); 
 const externalData = await window.dm.getExternalDataSource(externalDataId); 
  
 if (externalData && externalData.items) { 
 showStatus(`✅ Found collection using dm.getExternalDataSource`, 'success', 'collections-tab'); 
 showResults(externalData.items); 
 // Also display in collections tab 
 displayCollectionData(identifier, externalData.items, externalData.items.length, 'external data array'); 
 found = true; 
  
 // Add to discovered collections if not already there 
 if (!apiState.discoveredCollections.includes(identifier)) { 
 apiState.discoveredCollections.push(identifier); 
 updateDiscoveredCollections(); 
 } 
 } 
 } catch (error) { 
 debug('Error using getExternalDataSource:', error.message); 
 } 
 } 
  
 // Method 2: Try to look for global collections variable 
 if (!found && (window.collectionsData || window.collections)) { 
 const collections = window.collectionsData || window.collections; 
 if (collections && collections[identifier]) { 
 showStatus(`✅ Found collection in global variables`, 'success', 'collections-tab'); 
 showResults(collections[identifier]); 
 // Also display in collections tab 
 displayCollectionData(identifier, collections[identifier], 
 Array.isArray(collections[identifier]) ? collections[identifier].length : 1, 
 'global collection'); 
 found = true; 
  
 // Add to discovered collections if not already there 
 if (!apiState.discoveredCollections.includes(identifier)) { 
 apiState.discoveredCollections.push(identifier); 
 updateDiscoveredCollections(); 
 } 
 } 
 } 
  
 if (!found) { 
 showStatus(`Could not find collection "${identifier}" using any method.`, 'error', 'collections-tab'); 
 } 
 } 
  
 // Discover APIs - Modified to not search for collections 
 async function discoverAPIs() { 
 if (!apiState.isDudaSite) { 
 updateApiSectionStatus('core', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('collections', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('contentLibrary', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('store', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('dynamicPages', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('members', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('sitemap', 'Error', 'dmAPI not detected'); 
 return; 
 } 
  
 debug('Discovering APIs...'); 
 showStatus('Scanning site for available APIs...', 'info', 'api-discovery-tab'); 
  
 // Initialize APIs if needed 
 if (!apiState.collectionsAPI || !apiState.contentLibraryAPI || !apiState.dynamicPagesAPI) { 
 await initAllAPIs(); 
 } 
  
 // Check core API methods 
 discoverCoreAPI(); 
  
 // Check if collections API is available (but don't search for collections) 
 checkCollectionsAPIAvailability(); 
  
 // Check content library 
 discoverContentLibrary(); 
  
 // Check store API 
 discoverStoreAPI(); 
  
 // Check dynamic pages 
 discoverDynamicPages(); 
  
 // Check members API 
 discoverMembersAPI(); 
  
 // Check sitemap 
 discoverSitemap(); 
 } 
  
 // Check if Collections API is available without searching for collections 
 async function checkCollectionsAPIAvailability() { 
 updateApiSectionStatus('collections', 'Checking...'); 
  
 try { 
 if (!apiState.collectionsAPI) { 
 try { 
 apiState.collectionsAPI = await window.dmAPI.loadCollectionsAPI(); 
 } catch (error) { 
 updateApiSectionStatus('collections', 'Not Available', error.message); 
 return; 
 } 
 } 
  
 // If we get here, the API is available 
 updateApiSectionStatus('collections', 'Available', 'Use Collections tab to search for collections'); 
  
 // Display guidance in the results section 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="collections"] .aog-js-api-section-results'); 
 if (resultsEl) { 
 resultsEl.innerHTML = '<div class="aog-js-guidance">Collections API is available. Go to the Collections tab to search for specific collections by name.</div>'; 
 } 
  
 } catch (error) { 
 updateApiSectionStatus('collections', 'Error', error.message); 
 } 
 } 
  
 // Find store catalog or categories 
 async function findStoreData(type) { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot access store data: dmAPI not detected', 'error', 'store-tab'); 
 return; 
 } 
  
 if (!apiState.collectionsAPI) { 
 showStatus('Collections API not initialized. Click "Initialize All APIs" in Settings tab first.', 'error', 'store-tab'); 
 return; 
 } 
  
 const storeType = type === 'catalog' ? 'catalog_product' : 'catalog_category'; 
 debug(`Finding store ${type}`); 
 showStatus(`Searching for store ${type}...`, 'info', 'store-tab'); 
  
 try { 
 // Build query with filters if provided 
 let query = apiState.collectionsAPI.storeData(storeType); 
  
 // Add where clause if field is provided 
 const filterField = storeFilterFieldEl.value.trim(); 
 const filterOperator = storeFilterOperatorEl.value; 
 const filterValue = storeFilterValueEl.value.trim(); 
  
 if (filterField && filterValue) { 
 // Handle array operators (IN, NIN, BTWN) 
 if (['IN', 'NIN', 'BTWN'].includes(filterOperator)) { 
 const valueArray = filterValue.split(',').map(v => v.trim()); 
 query = query.where(filterField, filterOperator, valueArray); 
 } else { 
 // Convert to number if it looks like one 
 const value = !isNaN(filterValue) ? parseFloat(filterValue) : filterValue; 
 query = query.where(filterField, filterOperator, value); 
 } 
 } 
  
 // Add sort if field is provided 
 const sortField = storeSortFieldEl.value.trim(); 
 const sortDirection = storeSortDirectionEl.value; 
  
 if (sortField) { 
 query = query.orderBy(sortField, sortDirection); 
 } 
  
 // Execute query 
 const data = await query.get(); 
  
 // Check response 
 if (isErrorResponse(data)) { 
 showStatus(`❌ Error: ${data.message || 'Store data not found'}`, 'error', 'store-tab'); 
 showResults(data); 
 return; 
 } 
  
 if (data) { 
 if (Array.isArray(data)) { 
 if (data.length > 0) { 
 showStatus(`✅ Successfully retrieved store ${type}: (${data.length} items)`, 'success', 'store-tab'); 
 } else { 
 showStatus(`⚠️ Store ${type} found but contains no items.`, 'info', 'store-tab'); 
 } 
 } else if (typeof data === 'object' && Object.keys(data).length > 0) { 
 showStatus(`✅ Successfully retrieved store ${type} data`, 'success', 'store-tab'); 
 } else { 
 showStatus('⚠️ Response received but with unexpected format.', 'info', 'store-tab'); 
 } 
  
 showResults(data); 
 } else { 
 showStatus('⚠️ Received empty response.', 'error', 'store-tab'); 
 showResults({}); 
 } 
 } catch (error) { 
 showStatus(`❌ Error finding store ${type}: ${error.message}`, 'error', 'store-tab'); 
 showResults({ error: error.message }); 
 } 
 } 
  
 // Load content library 
 async function loadContentLibrary() { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot access content library: dmAPI not detected', 'error', 'content-library-tab'); 
 return; 
 } 
  
 if (!apiState.contentLibraryAPI) { 
 try { 
 showStatus('Initializing Content Library API...', 'info', 'content-library-tab'); 
 apiState.contentLibraryAPI = await window.dmAPI.loadContentLibrary(); 
 } catch (error) { 
 showStatus(`❌ Error initializing Content Library API: ${error.message}`, 'error', 'content-library-tab'); 
 return; 
 } 
 } 
  
 debug('Loading content library'); 
  
 try { 
 const data = apiState.contentLibraryAPI; 
  
 if (!data) { 
 showStatus('❌ Content Library returned no data', 'error', 'content-library-tab'); 
 return; 
 } 
  
 // Display the data in each section 
 displayContentLibraryData(data); 
  
 showStatus('✅ Successfully loaded Content Library data', 'success', 'content-library-tab'); 
 showResults(data); 
 } catch (error) { 
 showStatus(`❌ Error loading Content Library: ${error.message}`, 'error', 'content-library-tab'); 
 showResults({ error: error.message }); 
 } 
 } 
  
 // Display content library data in sections 
 function displayContentLibraryData(data) { 
 // Helper to create a simple key-value display 
 function createDataDisplay(obj, depth = 0) { 
 if (!obj || typeof obj !== 'object') { 
 return document.createTextNode(obj === null ? 'null' : obj === undefined ? 'undefined' : String(obj)); 
 } 
  
 const container = document.createElement('div'); 
 container.style.paddingLeft = depth > 0 ? '15px' : '0'; 
  
 // Handle arrays 
 if (Array.isArray(obj)) { 
 if (obj.length === 0) { 
 const emptyMsg = document.createElement('div'); 
 emptyMsg.textContent = '(empty array)'; 
 emptyMsg.style.fontStyle = 'italic'; 
 emptyMsg.style.color = '#888'; 
 container.appendChild(emptyMsg); 
 } else { 
 obj.forEach((item, index) => { 
 const itemContainer = document.createElement('div'); 
 itemContainer.style.marginBottom = '8px'; 
  
 const indexEl = document.createElement('div'); 
 indexEl.textContent = `[${index}]:`; 
 indexEl.style.fontWeight = 'bold'; 
  
 itemContainer.appendChild(indexEl); 
 itemContainer.appendChild(createDataDisplay(item, depth + 1)); 
 container.appendChild(itemContainer); 
 }); 
 } 
  
 return container; 
 } 
  
 // Handle objects 
 const keys = Object.keys(obj); 
  
 if (keys.length === 0) { 
 const emptyMsg = document.createElement('div'); 
 emptyMsg.textContent = '(empty object)'; 
 emptyMsg.style.fontStyle = 'italic'; 
 emptyMsg.style.color = '#888'; 
 container.appendChild(emptyMsg); 
 } else { 
 keys.forEach(key => { 
 const row = document.createElement('div'); 
 row.style.marginBottom = '8px'; 
  
 const keyEl = document.createElement('div'); 
 keyEl.textContent = `${key}:`; 
 keyEl.style.fontWeight = 'bold'; 
  
 row.appendChild(keyEl); 
  
 const valueContainer = document.createElement('div'); 
 valueContainer.style.marginLeft = '15px'; 
 valueContainer.appendChild(createDataDisplay(obj[key], depth + 1)); 
  
 row.appendChild(valueContainer); 
 container.appendChild(row); 
 }); 
 } 
  
 return container; 
 } 
  
 // Update each section 
 document.querySelectorAll('.aog-js-content-section').forEach(section => { 
 const sectionName = section.getAttribute('data-section'); 
 const bodyEl = section.querySelector('.aog-js-content-section-body'); 
  
 // Clear previous content 
 bodyEl.innerHTML = ''; 
  
 // Add new content 
 if (data && data[sectionName]) { 
 bodyEl.appendChild(createDataDisplay(data[sectionName])); 
 } else { 
 const notFoundEl = document.createElement('div'); 
 notFoundEl.textContent = 'No data found for this section'; 
 notFoundEl.style.fontStyle = 'italic'; 
 notFoundEl.style.color = '#888'; 
 notFoundEl.style.padding = '10px'; 
 bodyEl.appendChild(notFoundEl); 
 } 
 }); 
 } 
  
 // Toggle content section 
 function toggleContentSection(event) { 
 const section = event.currentTarget.closest('.aog-js-content-section'); 
 section.classList.toggle('expanded'); 
 } 
  
 // Check if current page is a dynamic page 
 async function checkDynamicPage() { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot check dynamic page: dmAPI not detected', 'error', 'dynamic-pages-tab'); 
 return; 
 } 
  
 try { 
 if (!apiState.dynamicPagesAPI) { 
 apiState.dynamicPagesAPI = window.dmAPI.dynamicPageApi(); 
 } 
  
 const isDynamic = apiState.dynamicPagesAPI.isDynamicPage(); 
 isDynamicEl.textContent = isDynamic ? 'Yes ✓' : 'No'; 
 isDynamicEl.style.color = isDynamic ? '#38a169' : '#666'; 
  
 if (isDynamic) { 
 showStatus('✅ This is a dynamic page. Loading page data...', 'success', 'dynamic-pages-tab'); 
  
 try { 
 const pageData = await apiState.dynamicPagesAPI.pageData(); 
  
 showStatus('✅ Successfully loaded dynamic page data', 'success', 'dynamic-pages-tab'); 
 showResults(pageData); 
  
 // Display dynamic page info 
 const infoEl = document.getElementById('aog-js-dynamic-page-info'); 
  
 // Clear existing items except the first one 
 const items = infoEl.querySelectorAll('.aog-js-info-item'); 
 for (let i = 1; i < items.length; i++) { 
 items[i].remove(); 
 } 
  
 // Add new info items 
 if (pageData) { 
 for (const key in pageData) { 
 if (key !== 'data') { // Skip the data property, show it in raw JSON instead 
 const item = document.createElement('div'); 
 item.className = 'aog-js-info-item'; 
  
 const label = document.createElement('div'); 
 label.className = 'aog-js-info-label'; 
 label.textContent = formatLabel(key) + ':'; 
  
 const value = document.createElement('div'); 
 value.className = 'aog-js-info-value'; 
 value.textContent = typeof pageData[key] === 'object' 
 ? JSON.stringify(pageData[key]).substring(0, 50) + '...' 
 : pageData[key]; 
  
 item.appendChild(label); 
 item.appendChild(value); 
 infoEl.appendChild(item); 
 } 
 } 
 } 
 } catch (error) { 
 showStatus(`❌ Error loading dynamic page data: ${error.message}`, 'error', 'dynamic-pages-tab'); 
 showResults({ error: error.message }); 
 } 
 } else { 
 showStatus('❌ This is not a dynamic page', 'error', 'dynamic-pages-tab'); 
 } 
 } catch (error) { 
 showStatus(`❌ Error checking dynamic page: ${error.message}`, 'error', 'dynamic-pages-tab'); 
 isDynamicEl.textContent = 'Error'; 
 isDynamicEl.style.color = '#e53e3e'; 
 } 
 } 
  
 // Format label for display 
 function formatLabel(str) { 
 return str 
 .replace(/_/g, ' ') 
 .replace(/\w\S*/g, txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()); 
 } 
  
 // Call core API method 
 async function callCoreMethod(methodName) { 
 if (!apiState.isDudaSite) { 
 methodResultEl.textContent = 'Error: dmAPI not detected'; 
 return; 
 } 
  
 debug(`Calling core method: ${methodName}`); 
  
 try { 
 let result; 
  
 // Handle async methods differently 
 if (methodName === 'getNavItemsAsync') { 
 result = await window.dmAPI[methodName](); 
  
 // Special handling for navigation data to make it more readable 
 if (result) { 
 methodResultEl.innerHTML = ''; 
  
 // Create a formatted navigation display 
 const navContainer = document.createElement('div'); 
 navContainer.className = 'aog-js-nav-display'; 
  
 function addNavItem(item, level = 0) { 
 const itemEl = document.createElement('div'); 
 itemEl.className = 'aog-js-nav-item'; 
 itemEl.style.paddingLeft = `${level * 20}px`; 
  
 const titleEl = document.createElement('span'); 
 titleEl.className = 'aog-js-nav-title'; 
 titleEl.textContent = item.title; 
  
 const pathEl = document.createElement('span'); 
 pathEl.className = 'aog-js-nav-path'; 
 pathEl.textContent = ` (${item.path})`; 
  
 const visibleEl = document.createElement('span'); 
 visibleEl.className = 'aog-js-nav-visible'; 
 visibleEl.textContent = item.visible ? ' - Visible' : ' - Hidden'; 
 visibleEl.style.color = item.visible ? '#38a169' : '#e53e3e'; 
  
 itemEl.appendChild(titleEl); 
 itemEl.appendChild(pathEl); 
 itemEl.appendChild(visibleEl); 
  
 navContainer.appendChild(itemEl); 
  
 // Add subnav items if any 
 if (item.subNav && item.subNav.length > 0) { 
 item.subNav.forEach(subItem => { 
 addNavItem(subItem, level + 1); 
 }); 
 } 
 } 
  
 // Add heading 
 const headingEl = document.createElement('div'); 
 headingEl.className = 'aog-js-nav-heading'; 
 headingEl.textContent = 'Navigation Structure:'; 
 navContainer.appendChild(headingEl); 
  
 // Process all nav items 
 result.forEach(item => { 
 addNavItem(item); 
 }); 
  
 methodResultEl.appendChild(navContainer); 
  
 // Add link to raw JSON 
 const rawLink = document.createElement('a'); 
 rawLink.href = '#'; 
 rawLink.textContent = 'Show raw JSON'; 
 rawLink.className = 'aog-js-show-raw'; 
 rawLink.addEventListener('click', (e) => { 
 e.preventDefault(); 
 methodResultEl.textContent = JSON.stringify(result, null, 2); 
 }); 
  
 const rawLinkContainer = document.createElement('div'); 
 rawLinkContainer.className = 'aog-js-raw-link-container'; 
 rawLinkContainer.appendChild(rawLink); 
  
 methodResultEl.appendChild(rawLinkContainer); 
 } else { 
 methodResultEl.textContent = 'No navigation data returned'; 
 } 
 } else { 
 // Call the method directly for non-async methods 
 result = window.dmAPI[methodName](); 
  
 // Format and display the result 
 methodResultEl.textContent = typeof result === 'object' 
 ? JSON.stringify(result, null, 2) 
 : result; 
 } 
  
 // Also show in Raw JSON tab 
 showResults(result); 
 } catch (error) { 
 methodResultEl.textContent = `Error: ${error.message}`; 
 } 
 } 
  
 // Check if response contains an error message 
 function isErrorResponse(data) { 
 // Check for common error patterns in responses 
 if (data && typeof data === 'object') { 
 // Check for error message property 
 if (data.message && typeof data.message === 'string') { 
 const errorKeywords = ['error', 'no collection', 'not found', 'invalid', 'failed']; 
 return errorKeywords.some(keyword => data.message.toLowerCase().includes(keyword)); 
 } 
  
 // Check for error property 
 if (data.error || data.errorMessage || data.status === 'error') { 
 return true; 
 } 
 } 
 return false; 
 } 
  
 // Show results in raw JSON tab 
 function showResults(data) { 
 apiState.currentData = data; 
  
 // Format and display in raw JSON tab 
 if (rawJsonEl) { 
 try { 
 const formattedJson = JSON.stringify(data, null, 2); 
 rawJsonEl.textContent = formattedJson; 
 } catch (error) { 
 rawJsonEl.textContent = 'Error formatting JSON data'; 
 } 
 } 
 } 
  
 // Switch to specific tab 
 function switchToTab(tabId) { 
 // Find the tab button 
 const tabButton = document.querySelector(`.aog-js-tab-button[data-tab="${tabId}"]`); 
 if (tabButton) { 
 // Create a mock event object 
 const event = { target: tabButton }; 
 switchTab(event); 
 } 
 } 
  
 // Copy JSON to clipboard 
 function copyJsonToClipboard() { 
 try { 
 const text = rawJsonEl.textContent; 
  
 navigator.clipboard.writeText(text).then(function() { 
 showCopiedNotification(); 
 }).catch(function(err) { 
 debug('Clipboard API error:', err); 
 // Fallback method for older browsers 
 copyToClipboardFallback(text); 
 }); 
 } catch (err) { 
 debug('Failed to copy:', err); 
 } 
 } 
  
 // Format JSON 
 function formatJson() { 
 try { 
 if (!apiState.currentData) { 
 return; 
 } 
  
 const formatted = JSON.stringify(apiState.currentData, null, 2); 
 rawJsonEl.textContent = formatted; 
 } catch (error) { 
 debug('Error formatting JSON:', error); 
 } 
 } 
  
 // Fallback clipboard method for browsers without clipboard API 
 function copyToClipboardFallback(text) { 
 const textArea = document.createElement('textarea'); 
 textArea.value = text; 
 textArea.style.position = 'fixed'; 
 textArea.style.left = '-999999px'; 
 textArea.style.top = '-999999px'; 
 document.body.appendChild(textArea); 
 textArea.focus(); 
 textArea.select(); 
  
 try { 
 const successful = document.execCommand('copy'); 
 if (successful) { 
 showCopiedNotification(); 
 } else { 
 debug('Failed to copy text with execCommand'); 
 } 
 } catch (err) { 
 debug('Error during execCommand copy:', err); 
 } 
  
 document.body.removeChild(textArea); 
 } 
  
 // Show copied notification 
 function showCopiedNotification() { 
 // Create notification if it doesn't exist 
 let notification = document.querySelector('.aog-js-copied-notification'); 
 if (!notification) { 
 notification = document.createElement('div'); 
 notification.className = 'aog-js-copied-notification'; 
 notification.textContent = 'JSON copied to clipboard'; 
 document.body.appendChild(notification); 
 } 
  
 // Show notification 
 notification.classList.add('show'); 
  
 // Hide notification after delay 
 setTimeout(() => { 
 notification.classList.remove('show'); 
 }, 2000); 
 } 
  
 // Toggle debug mode 
 function toggleDebugMode() { 
 DEBUG = debugToggle.checked; 
 debug('Debug mode toggled:', DEBUG); 
 } 
  
 // Discover Members API 
 async function discoverMembersAPI() { 
 updateApiSectionStatus('members', 'Checking...'); 
  
 try { 
 // Check if getLoggedInMember method exists 
 if (typeof window.dmAPI.getLoggedInMember === 'function') { 
 try { 
 // Try to call the method 
 await window.dmAPI.getLoggedInMember(); 
 updateApiSectionStatus('members', 'Available', 'Members API active'); 
 } catch (error) { 
 // If we get a specific error about not being logged in, API is still available 
 if (error && error.message && error.message.includes('not logged in')) { 
 updateApiSectionStatus('members', 'Available', 'No member logged in'); 
 } else { 
 updateApiSectionStatus('members', 'Not Available', error.message); 
 } 
 } 
 } else { 
 updateApiSectionStatus('members', 'Not Available', 'Members API not found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('members', 'Error', error.message); 
 } 
 } 
  
 // Check for logged-in member 
 async function checkLoggedInMember() { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot check member: dmAPI not detected', 'error', 'members-tab'); 
 return; 
 } 
  
 const memberStatusEl = document.getElementById('aog-js-member-status'); 
 const isLoggedInEl = document.getElementById('aog-js-is-logged-in'); 
 const memberInfoEl = document.getElementById('aog-js-member-info'); 
  
 try { 
 showStatus('Checking for logged-in member...', 'info', 'members-tab'); 
  
 if (typeof window.dmAPI.getLoggedInMember !== 'function') { 
 showStatus('❌ Members API not available on this site', 'error', 'members-tab'); 
 isLoggedInEl.textContent = 'API Not Available'; 
 isLoggedInEl.style.color = '#e53e3e'; 
 return; 
 } 
  
 try { 
 const memberData = await window.dmAPI.getLoggedInMember(); 
  
 // Check if this is a placeholder/default user or a real logged-in user 
 const isPlaceholder = !memberData || 
 (memberData.firstName === 'John' && memberData.lastName === 'Doe') || 
 !memberData.uuid || 
 Object.keys(memberData).length < 3; 
  
 if (isPlaceholder) { 
 isLoggedInEl.textContent = 'Not Logged In (Default Data)'; 
 isLoggedInEl.style.color = '#dd6b20'; 
 showStatus('ℹ️ No real member is logged in (placeholder data detected)', 'info', 'members-tab'); 
 } else { 
 // Real user is logged in 
 isLoggedInEl.textContent = 'Logged In ✓'; 
 isLoggedInEl.style.color = '#38a169'; 
 showStatus('✅ Member is logged in, retrieved member data', 'success', 'members-tab'); 
 } 
  
 showResults(memberData); 
  
 // Display member info 
 // Clear existing items except the first one 
 const items = memberInfoEl.querySelectorAll('.aog-js-info-item'); 
 for (let i = 1; i < items.length; i++) { 
 items[i].remove(); 
 } 
  
 // Add new info items 
 if (memberData) { 
 // Add a note if we think it's placeholder data 
 if (isPlaceholder) { 
 const placeholderNote = document.createElement('div'); 
 placeholderNote.className = 'aog-js-placeholder-note'; 
 placeholderNote.textContent = 'Note: This appears to be placeholder data, not a real logged-in user.'; 
 placeholderNote.style.color = '#dd6b20'; 
 placeholderNote.style.fontStyle = 'italic'; 
 placeholderNote.style.marginBottom = '15px'; 
 placeholderNote.style.padding = '8px'; 
 placeholderNote.style.backgroundColor = '#fff5f5'; 
 placeholderNote.style.borderRadius = '4px'; 
 memberInfoEl.appendChild(placeholderNote); 
 } 
  
 for (const key in memberData) { 
 const item = document.createElement('div'); 
 item.className = 'aog-js-info-item'; 
  
 const label = document.createElement('div'); 
 label.className = 'aog-js-info-label'; 
 label.textContent = formatLabel(key) + ':'; 
  
 const value = document.createElement('div'); 
 value.className = 'aog-js-info-value'; 
 value.textContent = typeof memberData[key] === 'object' 
 ? JSON.stringify(memberData[key]).substring(0, 50) + '...' 
 : memberData[key]; 
  
 item.appendChild(label); 
 item.appendChild(value); 
 memberInfoEl.appendChild(item); 
 } 
 } 
 } catch (error) { 
 if (error && error.message && error.message.includes('not logged in')) { 
 isLoggedInEl.textContent = 'Not Logged In'; 
 isLoggedInEl.style.color = '#dd6b20'; 
 showStatus('ℹ️ No member is currently logged in', 'info', 'members-tab'); 
 } else { 
 isLoggedInEl.textContent = 'Error'; 
 isLoggedInEl.style.color = '#e53e3e'; 
 showStatus(`❌ Error checking member: ${error.message}`, 'error', 'members-tab'); 
 } 
 } 
 } catch (error) { 
 showStatus(`❌ Error: ${error.message}`, 'error', 'members-tab'); 
 } 
 } 
  
 // Discover Sitemap 
 async function discoverSitemap() { 
 updateApiSectionStatus('sitemap', 'Checking...'); 
  
 try { 
 // Try to fetch the sitemap.xml file 
 const domain = window.location.hostname; 
 const sitemapUrl = `https://${domain}/sitemap.xml`; 
  
 try { 
 const response = await fetch(sitemapUrl, { method: 'HEAD' }); 
  
 if (response.ok) { 
 updateApiSectionStatus('sitemap', 'Available', 'Sitemap.xml found'); 
 } else { 
 updateApiSectionStatus('sitemap', 'Not Available', 'Sitemap.xml not found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('sitemap', 'Not Available', 'Cannot access sitemap.xml'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('sitemap', 'Error', error.message); 
 } 
 } 
  
 // Fetch and parse sitemap 
 async function fetchSitemap() { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot fetch sitemap: Site not detected', 'error', 'sitemap-tab'); 
 return; 
 } 
  
 const sitemapStatusEl = document.getElementById('aog-js-sitemap-status'); 
 const sitemapStatsEl = document.getElementById('aog-js-sitemap-stats'); 
 const sitemapCountEl = document.getElementById('aog-js-sitemap-count'); 
 const sitemapUpdatedEl = document.getElementById('aog-js-sitemap-updated'); 
 const sitemapContainerEl = document.getElementById('aog-js-sitemap-container'); 
 const sitemapUrlsEl = document.getElementById('aog-js-sitemap-urls'); 
  
 try { 
 showStatus('Fetching sitemap.xml...', 'info', 'sitemap-tab'); 
  
 const domain = window.location.hostname; 
 const sitemapUrl = `https://${domain}/sitemap.xml`; 
  
 try { 
 // Try to fetch the sitemap directly 
 const response = await fetch(sitemapUrl); 
  
 if (response.ok) { 
 const text = await response.text(); 
  
 // Parse the XML 
 const parser = new DOMParser(); 
 const xmlDoc = parser.parseFromString(text, 'text/xml'); 
 const urls = xmlDoc.getElementsByTagName('url'); 
  
 if (urls.length > 0) { 
 // Build site URL list 
 sitemapUrlsEl.innerHTML = ''; 
 const urlList = document.createElement('ul'); 
 urlList.className = 'aog-js-sitemap-url-list'; 
  
 // Extract URLs 
 const siteUrls = []; 
 for (let i = 0; i < urls.length; i++) { 
 const loc = urls[i].getElementsByTagName('loc')[0]; 
 if (loc) { 
 siteUrls.push({ 
 url: loc.textContent, 
 lastmod: urls[i].getElementsByTagName('lastmod')[0]?.textContent 
 }); 
 } 
 } 
  
 // Sort by URL 
 siteUrls.sort((a, b) => a.url.localeCompare(b.url)); 
  
 // Add to list 
 siteUrls.forEach(item => { 
 const li = document.createElement('li'); 
 li.className = 'aog-js-sitemap-url-item'; 
  
 const urlEl = document.createElement('a'); 
 urlEl.href = item.url; 
 urlEl.target = '_blank'; 
 urlEl.textContent = item.url.replace(`https://${domain}`, ''); 
  
 li.appendChild(urlEl); 
  
 if (item.lastmod) { 
 const lastmodEl = document.createElement('span'); 
 lastmodEl.className = 'aog-js-sitemap-lastmod'; 
 lastmodEl.textContent = ` (${new Date(item.lastmod).toLocaleDateString()})`; 
 li.appendChild(lastmodEl); 
 } 
  
 urlList.appendChild(li); 
 }); 
  
 sitemapUrlsEl.appendChild(urlList); 
  
 // Update stats 
 sitemapCountEl.textContent = urls.length; 
 sitemapUpdatedEl.textContent = new Date().toLocaleDateString(); 
  
 // Show the sections 
 sitemapStatsEl.style.display = 'block'; 
 sitemapContainerEl.style.display = 'block'; 
  
 showStatus(`✅ Successfully retrieved sitemap with ${urls.length} URLs`, 'success', 'sitemap-tab'); 
 showResults({ 
 sitemapUrl: sitemapUrl, 
 urlCount: urls.length, 
 urls: siteUrls 
 }); 
 } else { 
 showStatus('⚠️ Sitemap found but contains no URLs', 'info', 'sitemap-tab'); 
 } 
 } else { 
 showStatus(`❌ Could not access sitemap.xml: ${response.status} ${response.statusText}`, 'error', 'sitemap-tab'); 
 } 
 } catch (error) { 
 // If direct fetch fails, try a proxy approach or CORS workaround 
 showStatus(`❌ Error fetching sitemap: ${error.message}`, 'error', 'sitemap-tab'); 
 showStatus('Note: Direct access to sitemap.xml may be restricted by CORS. Try viewing it directly in your browser.', 'info', 'sitemap-tab'); 
 } 
 } catch (error) { 
 showStatus(`❌ Error: ${error.message}`, 'error', 'sitemap-tab'); 
 } 
 } 
  
 // Update API section status in discovery tab 
 function updateApiSectionStatus(section, status, details = '') { 
 const sectionEl = document.querySelector(`.aog-js-api-section[data-section="${section}"]`); 
 if (!sectionEl) return; 
  
 const statusEl = sectionEl.querySelector('.aog-js-api-section-status'); 
 if (!statusEl) return; 
  
 // Set status text 
 statusEl.textContent = status + (details ? ': ' + details : ''); 
  
 // Set status color 
 if (status === 'Available' || status === 'Active') { 
 statusEl.style.color = '#38a169'; 
 } else if (status === 'Not Available') { 
 statusEl.style.color = '#dd6b20'; 
 } else if (status === 'Error') { 
 statusEl.style.color = '#e53e3e'; 
 } else { 
 statusEl.style.color = '#666'; 
 } 
 } 
  
 // Discover core API methods 
 function discoverCoreAPI() { 
 updateApiSectionStatus('core', 'Checking...'); 
  
 try { 
 const coreMethodsAvailable = []; 
  
 // List of core methods to check 
 const coreMethods = [ 
 'getSiteName', 
 'getSiteExternalId', 
 'getSitePlanID', 
 'getCurrentDeviceType', 
 'getCurrentEnvironment', 
 'getNavItemsAsync' 
 ]; 
  
 // Check which methods are available 
 coreMethods.forEach(method => { 
 if (typeof window.dmAPI[method] === 'function') { 
 coreMethodsAvailable.push(method); 
 } 
 }); 
  
 if (coreMethodsAvailable.length > 0) { 
 updateApiSectionStatus('core', 'Available', `${coreMethodsAvailable.length} methods found`); 
  
 // Display available methods 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="core"] .aog-js-api-section-results'); 
 resultsEl.innerHTML = ''; 
  
 coreMethodsAvailable.forEach(method => { 
 const methodEl = document.createElement('div'); 
 methodEl.className = 'aog-js-discovered-method'; 
 methodEl.textContent = method; 
 resultsEl.appendChild(methodEl); 
 }); 
 } else { 
 updateApiSectionStatus('core', 'Not Available', 'No core methods found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('core', 'Error', error.message); 
 } 
 } 
  
 // Discover content library 
 async function discoverContentLibrary() { 
 updateApiSectionStatus('contentLibrary', 'Checking...'); 
  
 try { 
 if (!apiState.contentLibraryAPI) { 
 try { 
 apiState.contentLibraryAPI = await window.dmAPI.loadContentLibrary(); 
 } catch (error) { 
 updateApiSectionStatus('contentLibrary', 'Not Available', error.message); 
 return; 
 } 
 } 
  
 if (apiState.contentLibraryAPI) { 
 const sections = []; 
  
 // Check which content library sections have data 
 if (apiState.contentLibraryAPI.business_data) sections.push('business_data'); 
 if (apiState.contentLibraryAPI.location_data) sections.push('location_data'); 
 if (apiState.contentLibraryAPI.additional_locations) sections.push('additional_locations'); 
 if (apiState.contentLibraryAPI.site_texts) sections.push('site_texts'); 
 if (apiState.contentLibraryAPI.site_images) sections.push('site_images'); 
  
 updateApiSectionStatus('contentLibrary', 'Available', `${sections.length} sections with data`); 
  
 // Display available sections 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="contentLibrary"] .aog-js-api-section-results'); 
 resultsEl.innerHTML = ''; 
  
 sections.forEach(section => { 
 const sectionEl = document.createElement('div'); 
 sectionEl.className = 'aog-js-discovered-item'; 
 sectionEl.textContent = formatLabel(section); 
 resultsEl.appendChild(sectionEl); 
 }); 
 } else { 
 updateApiSectionStatus('contentLibrary', 'Not Available', 'No content library data found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('contentLibrary', 'Error', error.message); 
 } 
 } 
  
 // Discover store API 
 async function discoverStoreAPI() { 
 updateApiSectionStatus('store', 'Checking...'); 
  
 try { 
 if (!apiState.collectionsAPI) { 
 try { 
 apiState.collectionsAPI = await window.dmAPI.loadCollectionsAPI(); 
 } catch (error) { 
 updateApiSectionStatus('store', 'Not Available', error.message); 
 return; 
 } 
 } 
  
 // Check if storeData method exists 
 if (typeof apiState.collectionsAPI.storeData === 'function') { 
 try { 
 // Try to get a product from the catalog 
 const product = await apiState.collectionsAPI.storeData('catalog_product').pageSize(1).get(); 
 const hasProducts = Array.isArray(product) && product.length > 0; 
  
 // Try to get a category 
 const category = await apiState.collectionsAPI.storeData('catalog_category').pageSize(1).get(); 
 const hasCategories = Array.isArray(category) && category.length > 0; 
  
 if (hasProducts || hasCategories) { 
 updateApiSectionStatus('store', 'Available', 'Store API active'); 
  
 // Display store data info 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="store"] .aog-js-api-section-results'); 
 resultsEl.innerHTML = ''; 
  
 if (hasProducts) { 
 const productEl = document.createElement('div'); 
 productEl.className = 'aog-js-discovered-item'; 
 productEl.textContent = 'Product Catalog Available'; 
 resultsEl.appendChild(productEl); 
 } 
  
 if (hasCategories) { 
 const categoryEl = document.createElement('div'); 
 categoryEl.className = 'aog-js-discovered-item'; 
 categoryEl.textContent = 'Product Categories Available'; 
 resultsEl.appendChild(categoryEl); 
 } 
 } else { 
 updateApiSectionStatus('store', 'Available', 'No products or categories found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('store', 'Not Available', 'Store API error: ' + error.message); 
 } 
 } else { 
 updateApiSectionStatus('store', 'Not Available', 'Store API method not found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('store', 'Error', error.message); 
 } 
 } 
  
 // Discover dynamic pages 
 async function discoverDynamicPages() { 
 updateApiSectionStatus('dynamicPages', 'Checking...'); 
  
 try { 
 if (!apiState.dynamicPagesAPI) { 
 try { 
 apiState.dynamicPagesAPI = window.dmAPI.dynamicPageApi(); 
 } catch (error) { 
 updateApiSectionStatus('dynamicPages', 'Not Available', error.message); 
 return; 
 } 
 } 
  
 const isDynamic = apiState.dynamicPagesAPI.isDynamicPage(); 
  
 if (isDynamic) { 
 const pageData = await apiState.dynamicPagesAPI.pageData(); 
 updateApiSectionStatus('dynamicPages', 'Active', 'Current page is a dynamic page'); 
  
 // Display dynamic page info 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="dynamicPages"] .aog-js-api-section-results'); 
 resultsEl.innerHTML = ''; 
  
 if (pageData) { 
 const keysEl = document.createElement('div'); 
 keysEl.className = 'aog-js-discovered-item'; 
 keysEl.textContent = `Available fields: ${Object.keys(pageData).join(', ')}`; 
 resultsEl.appendChild(keysEl); 
 } 
 } else { 
 updateApiSectionStatus('dynamicPages', 'Available', 'Current page is not a dynamic page'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('dynamicPages', 'Error', error.message); 
 } 
 } 
  
 // Setup event listeners 
 debug('Setting up event listeners'); 
  
 // Main button toggle 
 if (explorerButton) { 
 explorerButton.addEventListener('click', togglePanel); 
 } 
  
 // Close button 
 if (closeButton) { 
 closeButton.addEventListener('click', closePanel); 
 } 
  
 // Initialize All APIs button 
 if (initAllBtn) { 
 initAllBtn.addEventListener('click', initAllAPIs); 
 } 
  
 // Content section toggles 
 contentSectionElements.forEach(section => { 
 const headerEl = section.querySelector('.aog-js-content-section-header'); 
 if (headerEl) { 
 headerEl.addEventListener('click', toggleContentSection); 
 } 
 }); 
  
 // Find collection button 
 if (findBtn) { 
 findBtn.addEventListener('click', () => findCollection()); 
 } 
  
 // Collection input enter key 
 if (collectionInput) { 
 collectionInput.addEventListener('keypress', (e) => { 
 if (e.key === 'Enter') { 
 findCollection(); 
 } 
 }); 
 } 
  
 // Store buttons 
 if (loadCatalogBtn) { 
 loadCatalogBtn.addEventListener('click', () => findStoreData('catalog')); 
 } 
  
 if (loadCategoriesBtn) { 
 loadCategoriesBtn.addEventListener('click', () => findStoreData('categories')); 
 } 
  
 // Content Library button 
 if (loadContentLibraryBtn) { 
 loadContentLibraryBtn.addEventListener('click', loadContentLibrary); 
 } 
  
 // Dynamic Pages button 
 if (checkDynamicPageBtn) { 
 checkDynamicPageBtn.addEventListener('click', checkDynamicPage); 
 } 
  
 // Members API button 
 const checkMemberBtn = document.getElementById('aog-js-check-member'); 
 if (checkMemberBtn) { 
 checkMemberBtn.addEventListener('click', checkLoggedInMember); 
 } 
  
 // Sitemap button 
 const fetchSitemapBtn = document.getElementById('aog-js-fetch-sitemap'); 
 if (fetchSitemapBtn) { 
 fetchSitemapBtn.addEventListener('click', fetchSitemap); 
 } 
  
 // Core method buttons 
 methodButtons.forEach(button => { 
 button.addEventListener('click', () => { 
 const method = button.getAttribute('data-method'); 
 if (method) { 
 callCoreMethod(method); 
 } 
 }); 
 }); 
  
 // API Discovery button 
 if (discoverAllBtn) { 
 discoverAllBtn.addEventListener('click', discoverAPIs); 
 } 
  
 // Debug toggle 
 if (debugToggle) { 
 debugToggle.addEventListener('change', toggleDebugMode); 
 } 
  
 // Copy JSON button 
 if (copyJsonBtn) { 
 copyJsonBtn.addEventListener('click', copyJsonToClipboard); 
 } 
  
 // Format JSON button 
 if (formatJsonBtn) { 
 formatJsonBtn.addEventListener('click', formatJson); 
 } 
  
 // Tab switching 
 tabButtons.forEach(button => { 
 button.addEventListener('click', switchTab); 
 }); 
  
 // Show data section by default 
 dataEl.style.display = 'block'; 
  
 // Check if we're on a Duda site 
 checkDudaEnvironment(); 
  
 // Apply style updates 
 applyStyleUpdates(); 
 } 
  
 // Initialize on load 
 if (document.readyState === 'complete' || document.readyState === 'interactive') { 
 // Document already loaded, initialize immediately 
 initEnhancedJSAPIExplorer(); 
 } else { 
 // Wait for document to load 
 document.addEventListener('DOMContentLoaded', initEnhancedJSAPIExplorer); 
 } 
 })(); 
 <div id="snippet-2od8g29h"> 
 <!-- HTML SECTION START --> 
 <!-- 
 Enhanced Duda JS API Explorer Widget 
 This is a self-contained HTML widget that provides a comprehensive interface 
 for exploring the full Duda JS API including Collections, Store API, Dynamic 
 Pages, Content Library and core API methods. 
 Created: May 2025 
 --> 
 <div id="aog-enhanced-js-explorer-widget"> 
 <!-- Widget Button --> 
 <button id="aog-js-explorer-button" class="aog-js-explorer-button" type="button"> 
 <span class="aog-js-explorer-icon">🔍</span> 
 <span class="aog-js-explorer-text">JS API Explorer</span> 
 </button> 
  
 <!-- Widget Panel --> 
 <div id="aog-js-explorer-panel" class="aog-js-explorer-panel"> 
 <div class="aog-js-explorer-header"> 
 <div class="aog-js-logo-container"> 
 <img src="https://irp.cdn-website.com/a778beb9/dms3rep/multi/Group+206.svg" alt="Agents of Genius" class="aog-js-logo"> 
 </div> 
 <h5 class="aog-js-title">JS API Explorer</h5> 
 <div class="aog-js-explorer-controls"> 
 <button id="aog-js-explorer-close" class="aog-js-explorer-close" type="button">×</button> 
 </div> 
 </div> 
  
 <div class="aog-js-explorer-content"> 
 <div id="aog-js-explorer-loading" class="aog-js-explorer-loading"> 
 <div class="aog-js-spinner"></div> 
 <div>Initializing API...</div> 
 </div> 
  
 <div id="aog-js-explorer-error" class="aog-js-explorer-error"> 
 <div class="aog-js-error-icon">⚠️</div> 
 <div> 
 <strong>Error retrieving data</strong> 
 <p id="aog-js-error-message">Could not load API data. Please try again.</p> 
 </div> 
 </div> 
  
 <div id="aog-js-explorer-data"> 
 <!-- Tabs Navigation --> 
 <div class="aog-js-explorer-tabs"> 
 <button class="aog-js-tab-button active" data-tab="api-discovery" type="button">API Discovery</button> 
 <button class="aog-js-tab-button" data-tab="collections" type="button">Collections</button> 
 <button class="aog-js-tab-button" data-tab="content-library" type="button">Content Library</button> 
 <button class="aog-js-tab-button" data-tab="store" type="button">Store</button> 
 <button class="aog-js-tab-button" data-tab="dynamic-pages" type="button">Dynamic Pages</button> 
 <button class="aog-js-tab-button" data-tab="members" type="button">Members</button> 
 <button class="aog-js-tab-button" data-tab="sitemap" type="button">Sitemap</button> 
 <button class="aog-js-tab-button" data-tab="core-methods" type="button">Core Methods</button> 
 <button class="aog-js-tab-button" data-tab="raw-json" type="button">Raw JSON</button> 
 <button class="aog-js-tab-button" data-tab="api-settings" type="button">Settings</button> 
 </div> 
  
 <!-- Tab Content --> 
 <div class="aog-js-explorer-tab-content"> 
 <!-- API Discovery Tab --> 
 <div id="api-discovery-tab" class="aog-js-tab-pane active"> 
 <h5 class="aog-js-section-title">API Discovery</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Scan this Duda site to discover available API features and data sources.</p> 
 <p>This will check for Collections, Content Library data, Store information, Dynamic Pages, and Members API.</p> 
 </div> 
 <button id="aog-js-discover-all" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">🔍</span> 
 Discover Available APIs 
 </button> 
 <div id="aog-js-discovery-results" class="aog-js-discovery-results"> 
 <div class="aog-js-api-section" data-section="core"> 
 <h5 class="aog-js-api-section-title">Core API</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="collections"> 
 <h5 class="aog-js-api-section-title">Collections</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="contentLibrary"> 
 <h5 class="aog-js-api-section-title">Content Library</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="store"> 
 <h5 class="aog-js-api-section-title">Store API</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="dynamicPages"> 
 <h5 class="aog-js-api-section-title">Dynamic Pages</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="members"> 
 <h5 class="aog-js-api-section-title">Members API</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 <div class="aog-js-api-section" data-section="sitemap"> 
 <h5 class="aog-js-api-section-title">Sitemap</h5> 
 <div class="aog-js-api-section-status">Not checked</div> 
 <div class="aog-js-api-section-results"></div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Collections Tab --> 
 <div id="collections-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Collection Explorer</h5> 
 <div class="aog-js-input-container"> 
 <div class="aog-js-collection-actions"> 
 <button id="aog-js-find-all-btn" class="aog-js-primary-button aog-js-secondary-button"> 
 <span class="aog-js-button-icon">🔍</span> 
 Find All Collections 
 </button> 
 <div class="aog-js-specific-collection"> 
 <label for="aog-js-collection-input" class="aog-js-label">Specific Collection Name/ID:</label> 
 <div class="aog-js-input-group"> 
 <input id="aog-js-collection-input" type="text" placeholder="Enter collection name or ID" class="aog-js-input"> 
 <button id="aog-js-find-btn" class="aog-js-action-button">Find</button> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <div id="aog-js-collections-status" class="aog-js-status"></div> 
  
 <div id="aog-js-discovered-collections" class="aog-js-discovered-collections"> 
 <div class="aog-js-collections-header"> 
 <div class="aog-js-section-subtitle">Discovered Collections</div> 
 <div class="aog-js-discovery-count">0 found</div> 
 </div> 
 <div id="aog-js-collections-list" class="aog-js-collections-list"> 
 <!-- Collections will be populated here --> 
 <div class="aog-js-empty-state">No collections discovered yet. Use "API Discovery" to scan the page.</div> 
 </div> 
 </div> 
  
 <div class="aog-js-filter-section"> 
 <div class="aog-js-section-subtitle">Filtering &amp; Sorting (Optional)</div> 
 <div class="aog-js-filter-inputs"> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-filter-field" class="aog-js-label">Field:</label> 
 <input id="aog-js-filter-field" type="text" placeholder="Field name" class="aog-js-input"> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-filter-operator" class="aog-js-label">Operator:</label> 
 <select id="aog-js-filter-operator" class="aog-js-input"> 
 <option value="EQ">Equal to (EQ)</option> 
 <option value="NE">Not equal to (NE)</option> 
 <option value="GT">Greater than (GT)</option> 
 <option value="GTE">Greater than or equal (GTE)</option> 
 <option value="LT">Less than (LT)</option> 
 <option value="LTE">Less than or equal (LTE)</option> 
 <option value="IN">In array (IN)</option> 
 <option value="NIN">Not in array (NIN)</option> 
 <option value="BTWN">Between (BTWN)</option> 
 </select> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-filter-value" class="aog-js-label">Value:</label> 
 <input id="aog-js-filter-value" type="text" placeholder="Value or comma-separated values for IN/BTWN" class="aog-js-input"> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-sort-field" class="aog-js-label">Sort by:</label> 
 <input id="aog-js-sort-field" type="text" placeholder="Field name (optional)" class="aog-js-input"> 
 <select id="aog-js-sort-direction" class="aog-js-input aog-js-small-input"> 
 <option value="asc">Ascending</option> 
 <option value="desc">Descending</option> 
 </select> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-page-size" class="aog-js-label">Page size:</label> 
 <input id="aog-js-page-size" type="number" value="50" min="1" max="100" class="aog-js-input aog-js-small-input"> 
 <label for="aog-js-page-number" class="aog-js-label aog-js-inline-label">Page:</label> 
 <input id="aog-js-page-number" type="number" value="0" min="0" class="aog-js-input aog-js-small-input"> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Content Library Tab --> 
 <div id="content-library-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Content Library Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Explore site's business info, text and images from the Content Library API.</p> 
 </div> 
 <button id="aog-js-load-content-library" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">📚</span> 
 Load Content Library 
 </button> 
 <div id="aog-js-content-lib-status" class="aog-js-status"></div> 
 <div id="aog-js-content-sections" class="aog-js-content-sections"> 
 <div class="aog-js-content-section-list"> 
 <div class="aog-js-content-section" data-section="business_data"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Business Data</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 <div class="aog-js-content-section" data-section="location_data"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Location Data</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 <div class="aog-js-content-section" data-section="additional_locations"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Additional Locations</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 <div class="aog-js-content-section" data-section="site_texts"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Site Texts</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 <div class="aog-js-content-section" data-section="site_images"> 
 <div class="aog-js-content-section-header"> 
 <span class="aog-js-content-section-title">Site Images</span> 
 <span class="aog-js-content-section-toggle">▶</span> 
 </div> 
 <div class="aog-js-content-section-body"></div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Store Tab --> 
 <div id="store-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Store API Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Explore the Store API to access product catalog and categories.</p> 
 </div> 
 <div class="aog-js-store-actions"> 
 <button id="aog-js-load-catalog" class="aog-js-action-button aog-js-wide-button"> 
 <span class="aog-js-button-icon">🛒</span> 
 Load Product Catalog 
 </button> 
 <button id="aog-js-load-categories" class="aog-js-action-button aog-js-wide-button"> 
 <span class="aog-js-button-icon">📁</span> 
 Load Product Categories 
 </button> 
 </div> 
 <div id="aog-js-store-status" class="aog-js-status"></div> 
 <div class="aog-js-filter-section"> 
 <div class="aog-js-section-subtitle">Filtering &amp; Sorting (Optional)</div> 
 <div class="aog-js-filter-inputs"> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-store-filter-field" class="aog-js-label">Field:</label> 
 <input id="aog-js-store-filter-field" type="text" placeholder="Field name" class="aog-js-input"> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-store-filter-operator" class="aog-js-label">Operator:</label> 
 <select id="aog-js-store-filter-operator" class="aog-js-input"> 
 <option value="EQ">Equal to (EQ)</option> 
 <option value="NE">Not equal to (NE)</option> 
 <option value="GT">Greater than (GT)</option> 
 <option value="GTE">Greater than or equal (GTE)</option> 
 <option value="LT">Less than (LT)</option> 
 <option value="LTE">Less than or equal (LTE)</option> 
 <option value="IN">In array (IN)</option> 
 <option value="NIN">Not in array (NIN)</option> 
 <option value="BTWN">Between (BTWN)</option> 
 </select> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-store-filter-value" class="aog-js-label">Value:</label> 
 <input id="aog-js-store-filter-value" type="text" placeholder="Value or comma-separated values for IN/BTWN" class="aog-js-input"> 
 </div> 
 <div class="aog-js-input-row"> 
 <label for="aog-js-store-sort-field" class="aog-js-label">Sort by:</label> 
 <input id="aog-js-store-sort-field" type="text" placeholder="Field name (optional)" class="aog-js-input"> 
 <select id="aog-js-store-sort-direction" class="aog-js-input aog-js-small-input"> 
 <option value="asc">Ascending</option> 
 <option value="desc">Descending</option> 
 </select> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Dynamic Pages Tab --> 
 <div id="dynamic-pages-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Dynamic Pages Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Check if the current page is a dynamic page and explore its data.</p> 
 </div> 
 <button id="aog-js-check-dynamic-page" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">📄</span> 
 Check Current Page 
 </button> 
 <div id="aog-js-dynamic-page-status" class="aog-js-status"></div> 
 <div id="aog-js-dynamic-page-info" class="aog-js-dynamic-page-info"> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Is Dynamic Page:</div> 
 <div id="aog-js-is-dynamic" class="aog-js-info-value">Unknown</div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Core Methods Tab --> 
 <div id="core-methods-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Core API Methods</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Access core API methods to get site information, navigation items, and more.</p> 
 </div> 
 <div class="aog-js-method-group"> 
 <h3 class="aog-js-method-group-title">Site Information</h3> 
 <div class="aog-js-method-buttons"> 
 <button class="aog-js-method-button" data-method="getSiteName">getSiteName</button> 
 <button class="aog-js-method-button" data-method="getSiteExternalId">getSiteExternalId</button> 
 <button class="aog-js-method-button" data-method="getSitePlanID">getSitePlanID</button> 
 <button class="aog-js-method-button" data-method="getCurrentDeviceType">getCurrentDeviceType</button> 
 <button class="aog-js-method-button" data-method="getCurrentEnvironment">getCurrentEnvironment</button> 
 </div> 
 </div> 
 <div class="aog-js-method-group"> 
 <h3 class="aog-js-method-group-title">Navigation</h3> 
 <div class="aog-js-method-buttons"> 
 <button class="aog-js-method-button" data-method="getNavItemsAsync">getNavItemsAsync</button> 
 </div> 
 </div> 
 <div id="aog-js-method-result-container" class="aog-js-method-result-container"> 
 <div class="aog-js-section-subtitle">Method Result</div> 
 <pre id="aog-js-method-result" class="aog-js-method-result">Click a method button to see its result</pre> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Raw JSON Tab --> 
 <div id="raw-json-tab" class="aog-js-tab-pane"> 
 <div class="aog-js-code-controls"> 
 <button id="aog-js-copy-json" class="aog-js-control-button" type="button">Copy JSON</button> 
 <button id="aog-js-format-json" class="aog-js-control-button" type="button">Format JSON</button> 
 </div> 
 <pre id="aog-js-raw-json" class="aog-js-json-display">No data available. Use the other tabs to fetch data first.</pre> 
 </div> 
  
 <!-- Members API Tab --> 
 <div id="members-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Members API Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Check for logged-in members and access member data.</p> 
 </div> 
 <button id="aog-js-check-member" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">👤</span> 
 Check Logged-in Member 
 </button> 
 <div id="aog-js-member-status" class="aog-js-status"></div> 
 <div id="aog-js-member-info" class="aog-js-member-info"> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Login Status:</div> 
 <div id="aog-js-is-logged-in" class="aog-js-info-value">Unknown</div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- Sitemap Tab --> 
 <div id="sitemap-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">Sitemap Explorer</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Fetch and explore the site's sitemap.xml file.</p> 
 </div> 
 <button id="aog-js-fetch-sitemap" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">🗺️</span> 
 Fetch Sitemap 
 </button> 
 <div id="aog-js-sitemap-status" class="aog-js-status"></div> 
 <div id="aog-js-sitemap-stats" class="aog-js-sitemap-stats" style="display: none;"> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Total URLs:</div> 
 <div id="aog-js-sitemap-count" class="aog-js-info-value">0</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Last Updated:</div> 
 <div id="aog-js-sitemap-updated" class="aog-js-info-value">Unknown</div> 
 </div> 
 </div> 
 <div id="aog-js-sitemap-container" class="aog-js-sitemap-container" style="display: none;"> 
 <h5 class="aog-js-section-subtitle">Sitemap URLs</h5> 
 <div id="aog-js-sitemap-urls" class="aog-js-sitemap-urls"></div> 
 </div> 
 </div> 
 </div> 
 </div> 
  
 <!-- API Settings Tab --> 
 <div id="api-settings-tab" class="aog-js-tab-pane"> 
 <h5 class="aog-js-section-title">API Configuration</h5> 
 <div class="aog-js-card"> 
 <div class="aog-js-card-body"> 
 <div class="aog-js-notice"> 
 <p>Initialize the APIs to explore available data on this page.</p> 
 </div> 
 <button id="aog-js-init-all-btn" class="aog-js-primary-button"> 
 <span class="aog-js-button-icon">⚡</span> 
 Initialize All APIs 
 </button> 
 <div class="aog-js-api-info"> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Collections API:</div> 
 <div id="aog-js-collections-api-status" class="aog-js-info-value">Not initialized</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Content Library:</div> 
 <div id="aog-js-content-api-status" class="aog-js-info-value">Not initialized</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Dynamic Pages API:</div> 
 <div id="aog-js-dynamic-api-status" class="aog-js-info-value">Not initialized</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Members API:</div> 
 <div id="aog-js-members-api-status" class="aog-js-info-value">Not initialized</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Core dmAPI:</div> 
 <div id="aog-js-core-api-status" class="aog-js-info-value"> 
 <span id="aog-js-core-api-available">Checking...</span> 
 </div> 
 </div> 
 </div> 
 <div class="aog-js-debug-section"> 
 <div class="aog-js-section-subtitle">Debug Settings</div> 
 <div class="aog-js-debug-toggle"> 
 <label class="aog-js-switch"> 
 <input type="checkbox" id="aog-js-debug-toggle"> 
 <span class="aog-js-slider"></span> 
 </label> 
 <span class="aog-js-debug-label">Enable debug mode</span> 
 </div> 
 <p class="aog-js-debug-description"> 
 When debug mode is enabled, detailed logs will be output to the browser console. 
 This helps troubleshoot issues with API connections and data retrieval. 
 </p> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 </div> 
 <!-- HTML SECTION END --> 
  
 <!-- CSS SECTION START --> 
 <style> 
 /* 
 * Enhanced Duda JS API Explorer Widget - Styles 
 * Uses Inter font family and adaptive colors 
 */ 
  
 /* Import Inter font */ 
 @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); 
  
 /* Define nav display styles */ 
 .aog-js-nav-display { 
 background-color: #f8f9fa; 
 border-radius: 6px; 
 padding: 12px; 
 margin-bottom: 15px; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-nav-heading { 
 font-weight: bold; 
 margin-bottom: 10px; 
 font-size: 15px; 
 color: #1A1B4B; 
 } 
  
 .aog-js-nav-item { 
 padding: 6px 0; 
 border-bottom: 1px solid #eee; 
 } 
  
 .aog-js-nav-title { 
 font-weight: 500; 
 color: #1A1B4B; 
 } 
  
 .aog-js-nav-path { 
 color: #666; 
 font-size: 13px; 
 } 
  
 .aog-js-raw-link-container { 
 text-align: right; 
 padding-top: 10px; 
 } 
  
 .aog-js-show-raw { 
 font-size: 13px; 
 color: #6B46C1; 
 text-decoration: none; 
 } 
  
 .aog-js-show-raw:hover { 
 text-decoration: underline; 
 } 
  
 /* Widget Container */ 
 #aog-enhanced-js-explorer-widget { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 14px; 
 line-height: 1.5; 
 color: #333; 
 position: relative; 
 z-index: 999999; 
 } 
  
 /* Button Styles */ 
 .aog-js-explorer-button { 
 position: fixed; 
 bottom: 20px; 
 left: 20px; 
 background-color: #ad24a6; /* Agents of Genius CTA color */ 
 color: white; 
 border: none; 
 border-radius: 50px; 
 padding: 12px 20px; 
 font-size: 14px; 
 font-weight: 500; 
 cursor: pointer; 
 display: flex; 
 align-items: center; 
 box-shadow: 0 2px 10px rgba(0,0,0,0.2); 
 transition: all 0.3s ease; 
 z-index: 999999; 
 } 
  
 .aog-js-explorer-button:hover { 
 background-color: #851c83; /* Agents of Genius CTA hover color */ 
 box-shadow: 0 4px 12px rgba(0,0,0,0.3); 
 } 
  
 .aog-js-explorer-icon { 
 margin-right: 8px; 
 font-weight: bold; 
 font-size: 16px; 
 } 
  
 /* Panel Styles */ 
 .aog-js-explorer-panel { 
 position: fixed; 
 bottom: 90px; 
 left: 20px; 
 width: 800px; 
 height: 80vh; 
 max-height: 800px; 
 background-color: white; 
 border-radius: 10px; /* Changed to 10px as requested */ 
 box-shadow: 0 5px 25px rgba(0,0,0,0.3); 
 display: none; 
 flex-direction: column; 
 z-index: 999998; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-explorer-header { 
 background-color: #ad24a6; /* Agents of Genius CTA color */ 
 padding: 15px 20px; 
 border-bottom: 1px solid rgba(255,255,255,0.2); 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 border-top-left-radius: 10px; 
 border-top-right-radius: 10px; 
 } 
  
 .aog-js-logo-container { 
 display: flex; 
 align-items: center; 
 height: 32px; 
 } 
  
 .aog-js-logo { 
 height: 100%; 
 max-width: 150px; 
 } 
  
 .aog-js-title { 
 margin: 0; 
 font-size: 16px; 
 font-weight: 600; 
 color: white !important; /* White text for better contrast */ 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-explorer-controls { 
 display: flex; 
 align-items: center; 
 } 
  
 .aog-js-explorer-close { 
 background: none; 
 border: none; 
 font-size: 24px; 
 color: white; 
 cursor: pointer; 
 padding: 0 5px; 
 line-height: 1; 
 } 
  
 .aog-js-explorer-content { 
 padding: 0; 
 overflow-y: auto; 
 flex-grow: 1; 
 position: relative; 
 } 
  
 /* Loading state */ 
 .aog-js-explorer-loading { 
 display: none; 
 flex-direction: column; 
 justify-content: center; 
 align-items: center; 
 height: 100%; 
 padding: 30px; 
 text-align: center; 
 color: #666; 
 } 
  
 .aog-js-spinner { 
 width: 40px; 
 height: 40px; 
 border: 3px solid #f3f3f3; 
 border-top: 3px solid #ad24a6; /* Agents of Genius CTA color */ 
 border-radius: 50%; 
 animation: spin 1s linear infinite; 
 margin-bottom: 15px; 
 } 
  
 @keyframes spin { 
 0% { transform: rotate(0deg); } 
 100% { transform: rotate(360deg); } 
 } 
  
 /* Error state */ 
 .aog-js-explorer-error { 
 display: none; 
 padding: 30px; 
 text-align: center; 
 color: #e74c3c; 
 flex-direction: column; 
 align-items: center; 
 justify-content: center; 
 height: 100%; 
 } 
  
 .aog-js-error-icon { 
 font-size: 40px; 
 margin-bottom: 15px; 
 } 
  
 /* Tab navigation */ 
 .aog-js-explorer-tabs { 
 display: flex; 
 border-bottom: 1px solid #E5E9F2; 
 background-color: #F5F7FB; 
 overflow-x: auto; 
 white-space: nowrap; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-tab-button { 
 padding: 12px 15px; 
 background: none; 
 border: none; 
 border-bottom: 2px solid transparent; 
 cursor: pointer; 
 font-size: 14px; 
 font-weight: 500; 
 color: #666; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-tab-button:hover { 
 color: #ad24a6; /* Agents of Genius CTA color */ 
 } 
  
 .aog-js-tab-button.active { 
 color: #ad24a6; /* Agents of Genius CTA color */ 
 border-bottom-color: #ad24a6; /* Agents of Genius CTA color */ 
 } 
  
 /* Tab content */ 
 .aog-js-explorer-tab-content { 
 padding: 20px; 
 } 
  
 .aog-js-tab-pane { 
 display: none; 
 } 
  
 .aog-js-tab-pane.active { 
 display: block; 
 } 
  
 /* General data styles */ 
 .aog-js-section-title { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 22px; 
 font-weight: 600; 
 margin-bottom: 20px; 
 color: #1A1B4B; 
 } 
  
 .aog-js-section-subtitle { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 18px; 
 font-weight: 600; 
 color: #1A1B4B; 
 margin-bottom: 12px; 
 margin-top: 20px; 
 } 
  
 .aog-js-notice { 
 padding: 10px; 
 background-color: #f8f9fa; 
 border-left: 4px solid #ad24a6; /* Agents of Genius CTA color */ 
 margin-bottom: 15px; 
 font-size: 13px; 
 color: #666; 
 } 
  
 .aog-js-notice p { 
 margin: 5px 0; 
 } 
  
 /* Input styles */ 
 .aog-js-input-container { 
 margin-bottom: 20px; 
 } 
  
 .aog-js-label { 
 display: block; 
 margin-bottom: 8px; 
 font-weight: 500; 
 color: #444; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-inline-label { 
 display: inline-block; 
 margin: 0 10px 0 15px; 
 } 
  
 .aog-js-input-group { 
 display: flex; 
 gap: 8px; 
 } 
  
 .aog-js-input { 
 flex-grow: 1; 
 padding: 10px 12px; 
 border: 1px solid #ddd; 
 border-radius: 6px; 
 font-size: 14px; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-small-input { 
 flex-grow: 0; 
 width: 100px; 
 } 
  
 .aog-js-input:focus { 
 outline: none; 
 border-color: #ad24a6; 
 } 
  
 .aog-js-input-row { 
 margin-bottom: 12px; 
 display: flex; 
 align-items: center; 
 } 
  
 .aog-js-filter-section { 
 margin-top: 20px; 
 border-top: 1px solid #eee; 
 padding-top: 20px; 
 } 
  
 .aog-js-filter-inputs { 
 background-color: #f8f9fa; 
 padding: 15px; 
 border-radius: 6px; 
 } 
  
 .aog-js-action-button { 
 background-color: #333; 
 color: white; 
 border: none; 
 border-radius: 6px; 
 padding: 0 15px; 
 font-weight: 500; 
 cursor: pointer; 
 transition: all 0.2s; 
 height: 38px; 
 display: flex; 
 align-items: center; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-action-button:hover { 
 background-color: #222; 
 } 
  
 .aog-js-wide-button { 
 padding: 10px 20px; 
 margin-right: 10px; 
 margin-bottom: 10px; 
 } 
  
 .aog-js-store-actions { 
 display: flex; 
 flex-wrap: wrap; 
 } 
  
 /* Status indicator */ 
 .aog-js-status { 
 margin-bottom: 20px; 
 padding: 12px 15px; 
 border-radius: 6px; 
 font-size: 14px; 
 line-height: 1.4; 
 display: none; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-status.success { 
 background-color: #f0fff4; 
 border-left: 3px solid #38a169; 
 color: #2f855a; 
 } 
  
 .aog-js-status.error { 
 background-color: #fff5f5; 
 border-left: 3px solid #e53e3e; 
 color: #c53030; 
 } 
  
 .aog-js-status.info { 
 background-color: #f8f9fa; 
 border-left: 3px solid #4299e1; 
 color: #2b6cb0; 
 } 
  
 /* Discovered collections */ 
 .aog-js-discovered-collections { 
 margin-bottom: 20px; 
 } 
  
 .aog-js-collections-header { 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 margin-bottom: 10px; 
 } 
  
 .aog-js-discovery-count { 
 font-size: 13px; 
 color: #666; 
 background-color: #f0f0f0; 
 padding: 4px 8px; 
 border-radius: 12px; 
 } 
  
 .aog-js-collections-list { 
 background-color: #f8f9fa; 
 border-radius: 6px; 
 padding: 15px; 
 max-height: 200px; 
 overflow-y: auto; 
 } 
  
 .aog-js-collection-item { 
 padding: 10px; 
 background-color: white; 
 border-radius: 4px; 
 margin-bottom: 8px; 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 cursor: pointer; 
 transition: all 0.2s; 
 } 
  
 .aog-js-collection-item:hover { 
 box-shadow: 0 2px 8px rgba(0,0,0,0.1); 
 } 
  
 .aog-js-collection-id { 
 font-weight: 500; 
 color: #333; 
 } 
  
 .aog-js-collection-load { 
 color: #ad24a6; 
 font-size: 13px; 
 font-weight: 500; 
 } 
  
 .aog-js-empty-state { 
 padding: 20px; 
 text-align: center; 
 color: #888; 
 font-style: italic; 
 } 
  
 /* Card styles */ 
 .aog-js-card { 
 background-color: #ffffff; 
 border-radius: 8px; 
 margin-bottom: 20px; 
 overflow: hidden; 
 box-shadow: 0 2px 10px rgba(0,0,0,0.05); 
 border: 1px solid #E5E9F2; 
 } 
  
 .aog-js-card-body { 
 padding: 20px; 
 } 
  
 /* Button styles */ 
 .aog-js-primary-button { 
 background-color: #ad24a6; 
 color: white; 
 border: none; 
 border-radius: 6px; 
 padding: 12px 20px; 
 font-weight: 500; 
 cursor: pointer; 
 display: flex; 
 align-items: center; 
 justify-content: center; 
 width: 100%; 
 margin-bottom: 15px; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-primary-button:hover { 
 background-color: #851c83; 
 } 
  
 .aog-js-button-icon { 
 margin-right: 8px; 
 } 
  
 /* API Info */ 
 .aog-js-api-info { 
 margin-top: 20px; 
 border-top: 1px solid #eee; 
 padding-top: 15px; 
 } 
  
 .aog-js-info-item { 
 display: flex; 
 margin-bottom: 10px; 
 border-bottom: 1px solid #eee; 
 padding-bottom: 10px; 
 } 
  
 .aog-js-info-label { 
 width: 120px; 
 font-weight: 500; 
 color: #444; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-info-value { 
 flex-grow: 1; 
 color: #666; 
 } 
  
 /* JSON display */ 
 .aog-js-json-display { 
 background-color: #f8f9fa; 
 padding: 15px; 
 border-radius: 6px; 
 overflow: auto; 
 font-family: Monaco, Menlo, Consolas, "Courier New", monospace; 
 font-size: 13px; 
 line-height: 1.5; 
 color: #333; 
 white-space: pre-wrap; 
 max-height: 600px; 
 } 
  
 .aog-js-code-controls { 
 margin-bottom: 10px; 
 display: flex; 
 gap: 8px; 
 } 
  
 .aog-js-control-button { 
 background-color: #f1f3f5; 
 border: 1px solid #dee2e6; 
 border-radius: 4px; 
 padding: 6px 12px; 
 font-size: 13px; 
 cursor: pointer; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-control-button:hover { 
 background-color: #e9ecef; 
 } 
  
 /* Copied notification */ 
 .aog-js-copied-notification { 
 position: fixed; 
 top: 20px; 
 right: 20px; 
 background-color: #ad24a6; 
 color: white; 
 padding: 12px 20px; 
 border-radius: 4px; 
 box-shadow: 0 2px 10px rgba(0,0,0,0.2); 
 opacity: 0; 
 transform: translateY(-10px); 
 transition: all 0.3s ease; 
 pointer-events: none; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-copied-notification.show { 
 opacity: 1; 
 transform: translateY(0); 
 } 
  
 /* Core Methods */ 
 .aog-js-method-group { 
 margin-bottom: 20px; 
 } 
  
 .aog-js-method-group-title { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 18px; 
 margin-bottom: 10px; 
 color: #1A1B4B; 
 } 
  
 .aog-js-method-buttons { 
 display: flex; 
 flex-wrap: wrap; 
 gap: 8px; 
 } 
  
 .aog-js-method-button { 
 background-color: #f1f3f5; 
 border: 1px solid #dee2e6; 
 border-radius: 4px; 
 padding: 8px 12px; 
 font-size: 13px; 
 cursor: pointer; 
 transition: all 0.2s; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-method-button:hover { 
 background-color: #e9ecef; 
 } 
  
 .aog-js-method-result-container { 
 margin-top: 20px; 
 border-top: 1px solid #eee; 
 padding-top: 15px; 
 } 
  
 .aog-js-method-result { 
 background-color: #f8f9fa; 
 padding: 15px; 
 border-radius: 6px; 
 overflow: auto; 
 font-family: Monaco, Menlo, Consolas, "Courier New", monospace; 
 font-size: 13px; 
 line-height: 1.5; 
 color: #666; 
 white-space: pre-wrap; 
 max-height: 200px; 
 } 
  
 /* API Discovery Results */ 
 .aog-js-discovery-results { 
 margin-top: 20px; 
 } 
  
 .aog-js-api-section { 
 border: 1px solid #e5e9f2; 
 border-radius: 6px; 
 margin-bottom: 15px; 
 overflow: hidden; 
 } 
  
 .aog-js-api-section-title { 
 margin: 0; 
 font-size: 15px; 
 font-weight: 500; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-api-section h5 { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 18px; 
 background-color: #f5f7fb; 
 padding: 10px 15px; 
 border-bottom: 1px solid #e5e9f2; 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 margin: 0; 
 color: #1A1B4B; 
 } 
  
 .aog-js-api-section-status { 
 font-size: 13px; 
 color: #666; 
 font-weight: normal; 
 } 
  
 .aog-js-api-section-results { 
 padding: 15px; 
 max-height: 200px; 
 overflow-y: auto; 
 } 
  
 /* Content Library */ 
 .aog-js-content-sections { 
 margin-top: 20px; 
 } 
  
 .aog-js-content-section { 
 border: 1px solid #e5e9f2; 
 border-radius: 6px; 
 margin-bottom: 10px; 
 overflow: hidden; 
 } 
  
 /* Collection actions */ 
 .aog-js-collection-actions { 
 display: flex; 
 flex-direction: column; 
 gap: 15px; 
 width: 100%; 
 } 
  
 .aog-js-secondary-button { 
 background-color: #6B46C1; 
 margin-bottom: 5px; 
 } 
  
 .aog-js-secondary-button:hover { 
 background-color: #553C9A; 
 } 
  
 .aog-js-specific-collection { 
 width: 100%; 
 } 
  
 .aog-js-content-section-header { 
 background-color: #f5f7fb; 
 padding: 10px 15px; 
 cursor: pointer; 
 display: flex; 
 justify-content: space-between; 
 align-items: center; 
 } 
  
 .aog-js-content-section-title { 
 font-weight: 500; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-content-section-body { 
 padding: 0; 
 max-height: 0; 
 overflow: hidden; 
 transition: all 0.3s ease; 
 } 
  
 .aog-js-content-section.expanded .aog-js-content-section-body { 
 padding: 15px; 
 max-height: 500px; 
 overflow-y: auto; 
 } 
  
 .aog-js-content-section.expanded .aog-js-content-section-toggle { 
 transform: rotate(90deg); 
 } 
  
 .aog-js-content-section-toggle { 
 transition: transform 0.3s ease; 
 } 
  
 /* Debug Toggle */ 
 .aog-js-debug-section { 
 margin-top: 20px; 
 border-top: 1px solid #eee; 
 padding-top: 15px; 
 } 
  
 .aog-js-debug-toggle { 
 display: flex; 
 align-items: center; 
 } 
  
 .aog-js-switch { 
 position: relative; 
 display: inline-block; 
 width: 50px; 
 height: 24px; 
 margin-right: 10px; 
 } 
  
 .aog-js-switch input { 
 opacity: 0; 
 width: 0; 
 height: 0; 
 } 
  
 .aog-js-slider { 
 position: absolute; 
 cursor: pointer; 
 top: 0; 
 left: 0; 
 right: 0; 
 bottom: 0; 
 background-color: #ccc; 
 transition: .4s; 
 border-radius: 34px; 
 } 
  
 .aog-js-slider:before { 
 position: absolute; 
 content: ""; 
 height: 16px; 
 width: 16px; 
 left: 4px; 
 bottom: 4px; 
 background-color: white; 
 transition: .4s; 
 border-radius: 50%; 
 } 
  
 input:checked + .aog-js-slider { 
 background-color: #ad24a6; 
 } 
  
 input:checked + .aog-js-slider:before { 
 transform: translateX(26px); 
 } 
  
 .aog-js-debug-label { 
 font-size: 14px; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-debug-description { 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 font-size: 13px; 
 color: #666; 
 line-height: 1.5; 
 } 
  
 /* Mobile responsiveness */ 
 @media (max-width: 992px) { 
 .aog-js-explorer-panel { 
 width: calc(100% - 40px); 
 height: 80vh; 
 bottom: 80px; 
 } 
  
 .aog-js-explorer-tabs { 
 overflow-x: auto; 
 white-space: nowrap; 
 } 
  
 .aog-js-input-row { 
 flex-direction: column; 
 align-items: flex-start; 
 } 
  
 .aog-js-inline-label { 
 margin: 8px 0; 
 } 
  
 .aog-js-store-actions { 
 flex-direction: column; 
 } 
  
 .aog-js-wide-button { 
 width: 100%; 
 margin-right: 0; 
 } 
 } 
  
 @media (max-width: 480px) { 
 .aog-js-method-buttons { 
 flex-direction: column; 
 } 
  
 .aog-js-method-button { 
 width: 100%; 
 } 
 } 
  
 /* Sitemap Styles */ 
 .aog-js-sitemap-url-list { 
 list-style: none; 
 padding: 0; 
 margin: 0; 
 } 
  
 .aog-js-sitemap-url-item { 
 padding: 8px 0; 
 border-bottom: 1px solid #eee; 
 font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 
 } 
  
 .aog-js-sitemap-url-item a { 
 color: #4a5568; 
 text-decoration: none; 
 } 
  
 .aog-js-sitemap-url-item a:hover { 
 color: #ad24a6; 
 text-decoration: underline; 
 } 
  
 .aog-js-sitemap-lastmod { 
 font-size: 12px; 
 color: #718096; 
 margin-left: 8px; 
 } 
 </style> 
 <!-- CSS SECTION END --> 
  
 <!-- JAVASCRIPT SECTION START --> 
 <script> 
 // Enhanced JS API Explorer Widget - Agents of Genius Branded JavaScript 
 // IIFE to avoid polluting global scope 
 (function() { 
 // Debug flag - can be toggled via UI 
 let DEBUG = false; 
  
 // Debug logging function 
 function debug(message, data) { 
 if (DEBUG) { 
 console.log(`[AOGJS Debug] ${message}`, data || ''); 
 } 
 } 
  
 // Initialize immediately 
 debug('Script loaded, initializing...'); 
 document.addEventListener('DOMContentLoaded', initEnhancedJSAPIExplorer); 
  
 // Main initialization function 
 function initEnhancedJSAPIExplorer() { 
 // API State 
 let apiState = { 
 collectionsAPI: null, 
 contentLibraryAPI: null, 
 dynamicPagesAPI: null, 
 currentData: null, 
 discoveredCollections: [], 
 isDudaSite: false 
 }; 
  
 // DOM Elements 
 const explorerButton = document.getElementById('aog-js-explorer-button'); 
 const explorerPanel = document.getElementById('aog-js-explorer-panel'); 
 const closeButton = document.getElementById('aog-js-explorer-close'); 
 const loadingEl = document.getElementById('aog-js-explorer-loading'); 
 const errorEl = document.getElementById('aog-js-explorer-error'); 
 const errorMessage = document.getElementById('aog-js-error-message'); 
 const dataEl = document.getElementById('aog-js-explorer-data'); 
  
 // Settings Elements 
 const initAllBtn = document.getElementById('aog-js-init-all-btn'); 
 const collectionsApiStatusEl = document.getElementById('aog-js-collections-api-status'); 
 const contentApiStatusEl = document.getElementById('aog-js-content-api-status'); 
 const dynamicApiStatusEl = document.getElementById('aog-js-dynamic-api-status'); 
 const coreApiAvailableEl = document.getElementById('aog-js-core-api-available'); 
 const debugToggle = document.getElementById('aog-js-debug-toggle'); 
  
 // Collections Tab Elements 
 const findBtn = document.getElementById('aog-js-find-btn'); 
 // Removed findAllBtn reference since we're removing that button 
 const collectionInput = document.getElementById('aog-js-collection-input'); 
 const collectionsStatusEl = document.getElementById('aog-js-collections-status'); 
 const collectionsListEl = document.getElementById('aog-js-collections-list'); 
 const discoveryCountEl = document.querySelector('.aog-js-discovery-count'); 
  
 // Filter Elements 
 const filterFieldEl = document.getElementById('aog-js-filter-field'); 
 const filterOperatorEl = document.getElementById('aog-js-filter-operator'); 
 const filterValueEl = document.getElementById('aog-js-filter-value'); 
 const sortFieldEl = document.getElementById('aog-js-sort-field'); 
 const sortDirectionEl = document.getElementById('aog-js-sort-direction'); 
 const pageSizeEl = document.getElementById('aog-js-page-size'); 
 const pageNumberEl = document.getElementById('aog-js-page-number'); 
  
 // Store Tab Elements 
 const loadCatalogBtn = document.getElementById('aog-js-load-catalog'); 
 const loadCategoriesBtn = document.getElementById('aog-js-load-categories'); 
 const storeStatusEl = document.getElementById('aog-js-store-status'); 
 const storeFilterFieldEl = document.getElementById('aog-js-store-filter-field'); 
 const storeFilterOperatorEl = document.getElementById('aog-js-store-filter-operator'); 
 const storeFilterValueEl = document.getElementById('aog-js-store-filter-value'); 
 const storeSortFieldEl = document.getElementById('aog-js-store-sort-field'); 
 const storeSortDirectionEl = document.getElementById('aog-js-store-sort-direction'); 
  
 // Content Library Tab Elements 
 const loadContentLibraryBtn = document.getElementById('aog-js-load-content-library'); 
 const contentLibStatusEl = document.getElementById('aog-js-content-lib-status'); 
 const contentSectionElements = document.querySelectorAll('.aog-js-content-section'); 
  
 // Dynamic Pages Tab Elements 
 const checkDynamicPageBtn = document.getElementById('aog-js-check-dynamic-page'); 
 const dynamicPageStatusEl = document.getElementById('aog-js-dynamic-page-status'); 
 const isDynamicEl = document.getElementById('aog-js-is-dynamic'); 
  
 // Core Methods Tab Elements 
 const methodButtons = document.querySelectorAll('.aog-js-method-button'); 
 const methodResultEl = document.getElementById('aog-js-method-result'); 
  
 // API Discovery Tab Elements 
 const discoverAllBtn = document.getElementById('aog-js-discover-all'); 
 const apiSections = document.querySelectorAll('.aog-js-api-section'); 
  
 // Raw JSON Tab Elements 
 const rawJsonEl = document.getElementById('aog-js-raw-json'); 
 const copyJsonBtn = document.getElementById('aog-js-copy-json'); 
 const formatJsonBtn = document.getElementById('aog-js-format-json'); 
  
 // Tab Elements 
 const tabButtons = document.querySelectorAll('.aog-js-tab-button'); 
 const tabPanes = document.querySelectorAll('.aog-js-tab-pane'); 
  
 // UI State 
 let isOpen = false; 
  
 // Apply style updates 
 function applyStyleUpdates() { 
 // 1. Reduce size of section titles in API discovery and other tabs 
 const sectionTitles = document.querySelectorAll('.aog-js-section-title'); 
 sectionTitles.forEach(title => { 
 title.style.fontSize = '16px'; 
 title.style.fontWeight = '600'; 
 }); 
  
 // 2. Reduce size of section subtitles 
 const sectionSubtitles = document.querySelectorAll('.aog-js-section-subtitle'); 
 sectionSubtitles.forEach(subtitle => { 
 subtitle.style.fontSize = '14px'; 
 subtitle.style.fontWeight = '600'; 
 }); 
  
 // 3. Make all CTA buttons the same color (#ad24a6 - purple) 
 const ctaButtons = document.querySelectorAll('.aog-js-primary-button'); 
 ctaButtons.forEach(button => { 
 button.style.backgroundColor = '#ad24a6'; 
 button.style.color = 'white'; 
 }); 
  
 // 4. Remove the main JS API Explorer title from header 
 const headerTitle = document.querySelector('.aog-js-explorer-header h2'); 
 if (headerTitle) { 
 headerTitle.style.display = 'none'; 
 } 
  
 // 5. Remove "Find All Collections" button if it exists 
 const findAllBtn = document.getElementById('aog-js-find-all-btn'); 
 if (findAllBtn) { 
 findAllBtn.style.display = 'none'; 
 } 
  
 // 6. Update the collections tab description 
 const collectionsDesc = document.querySelector('.aog-js-collections-description'); 
 if (collectionsDesc) { 
 collectionsDesc.textContent = 'Enter a collection name or ID to retrieve data. Use filters and sorting options below for more specific queries.'; 
 } 
  
 // 7. Update the API discovery tab description 
 const apiDiscoveryDesc = document.querySelector('.aog-js-api-discovery-description'); 
 if (apiDiscoveryDesc) { 
 apiDiscoveryDesc.textContent = 'Discover available APIs on this site. To search for collections, go to the Collections tab and enter a collection name.'; 
 } 
 } 
  
 // Check if running on a Duda site 
 function checkDudaEnvironment() { 
 const isDudaSite = typeof window.dmAPI !== 'undefined'; 
 debug('Checking Duda environment', { isDudaSite }); 
 apiState.isDudaSite = isDudaSite; 
  
 if (isDudaSite) { 
 coreApiAvailableEl.textContent = 'Available ✓'; 
 coreApiAvailableEl.style.color = '#38a169'; 
 } else { 
 coreApiAvailableEl.textContent = 'Not detected'; 
 coreApiAvailableEl.style.color = '#e53e3e'; 
 // Show warning in API discovery tab 
 showStatus('Warning: dmAPI not detected. Are you on a Duda site?', 'error', 'api-discovery-tab'); 
 } 
  
 return isDudaSite; 
 } 
  
 // Tab switching 
 function switchTab(event) { 
 const tabId = event.target.getAttribute('data-tab'); 
 debug('Tab switch to:', tabId); 
  
 // Update active tab button 
 tabButtons.forEach(button => { 
 button.classList.remove('active'); 
 }); 
 event.target.classList.add('active'); 
  
 // Update active tab pane 
 tabPanes.forEach(pane => { 
 pane.classList.remove('active'); 
 }); 
 document.getElementById(`${tabId}-tab`).classList.add('active'); 
 } 
  
 // Toggle panel 
 function togglePanel() { 
 debug('Toggle panel called, current state:', isOpen); 
 if (isOpen) { 
 explorerPanel.style.display = 'none'; 
 } else { 
 explorerPanel.style.display = 'flex'; 
 // Check if running on a Duda site 
 checkDudaEnvironment(); 
 // Apply style updates 
 applyStyleUpdates(); 
 } 
 isOpen = !isOpen; 
 } 
  
 // Close panel 
 function closePanel() { 
 debug('Close panel called'); 
 explorerPanel.style.display = 'none'; 
 isOpen = false; 
 } 
  
 // Show status message in a specific tab 
 function showStatus(message, type = 'info', tabId = null) { 
 debug(`Status: ${message} (${type}) in tab: ${tabId || 'current'}`); 
 let statusEl; 
  
 // Determine which status element to use 
 if (tabId === 'collections-tab') { 
 statusEl = collectionsStatusEl; 
 } else if (tabId === 'store-tab') { 
 statusEl = storeStatusEl; 
 } else if (tabId === 'content-library-tab') { 
 statusEl = contentLibStatusEl; 
 } else if (tabId === 'dynamic-pages-tab') { 
 statusEl = dynamicPageStatusEl; 
 } else if (tabId === 'api-discovery-tab') { 
 // For discovery tab, show in all status elements 
 const discoveryStatusEl = document.querySelector('#aog-js-discovery-results .aog-js-status'); 
 if (discoveryStatusEl) { 
 discoveryStatusEl.textContent = message; 
 discoveryStatusEl.className = 'aog-js-status'; 
 discoveryStatusEl.classList.add(type); 
 discoveryStatusEl.style.display = 'block'; 
 } 
 return; 
 } else { 
 // Default to collections status 
 statusEl = collectionsStatusEl; 
 } 
  
 statusEl.textContent = message; 
 statusEl.className = 'aog-js-status'; // Reset classes 
 statusEl.classList.add(type); 
 statusEl.style.display = 'block'; 
  
 // Auto-hide success messages after 5 seconds 
 if (type === 'success') { 
 setTimeout(() => { 
 statusEl.style.display = 'none'; 
 }, 5000); 
 } 
 } 
  
 // Create collection item (for when collection is added to discovered collections) 
 function createCollectionItem(id) { 
 const item = document.createElement('div'); 
 item.className = 'aog-js-collection-item'; 
  
 const idEl = document.createElement('div'); 
 idEl.className = 'aog-js-collection-id'; 
 idEl.textContent = id; 
  
 const loadEl = document.createElement('div'); 
 loadEl.className = 'aog-js-collection-load'; 
 loadEl.textContent = 'Load →'; 
  
 item.appendChild(idEl); 
 item.appendChild(loadEl); 
  
 // Add click event to load this collection 
 item.addEventListener('click', () => { 
 collectionInput.value = id; 
 findCollection(id); 
 }); 
  
 return item; 
 } 
  
 // Initialize all APIs 
 async function initAllAPIs() { 
 debug('Initializing all APIs...'); 
  
 if (!apiState.isDudaSite) { 
 showAllErrors('dmAPI not detected. Cannot initialize APIs.'); 
 return; 
 } 
  
 // Show loading state 
 dataEl.style.display = 'none'; 
 loadingEl.style.display = 'flex'; 
  
 try { 
 // Initialize Collections API 
 try { 
 apiState.collectionsAPI = await window.dmAPI.loadCollectionsAPI(); 
 collectionsApiStatusEl.textContent = 'Initialized ✓'; 
 collectionsApiStatusEl.style.color = '#38a169'; 
 } catch (error) { 
 debug('Error initializing Collections API:', error); 
 collectionsApiStatusEl.textContent = 'Failed: ' + error.message; 
 collectionsApiStatusEl.style.color = '#e53e3e'; 
 } 
  
 // Initialize Content Library API 
 try { 
 apiState.contentLibraryAPI = await window.dmAPI.loadContentLibrary(); 
 contentApiStatusEl.textContent = 'Initialized ✓'; 
 contentApiStatusEl.style.color = '#38a169'; 
 } catch (error) { 
 debug('Error initializing Content Library API:', error); 
 contentApiStatusEl.textContent = 'Failed: ' + error.message; 
 contentApiStatusEl.style.color = '#e53e3e'; 
 } 
  
 // Initialize Dynamic Pages API 
 try { 
 apiState.dynamicPagesAPI = window.dmAPI.dynamicPageApi(); 
 dynamicApiStatusEl.textContent = 'Initialized ✓'; 
 dynamicApiStatusEl.style.color = '#38a169'; 
 } catch (error) { 
 debug('Error initializing Dynamic Pages API:', error); 
 dynamicApiStatusEl.textContent = 'Failed: ' + error.message; 
 dynamicApiStatusEl.style.color = '#e53e3e'; 
 } 
  
 // Check Members API 
 const membersApiStatusEl = document.getElementById('aog-js-members-api-status'); 
 try { 
 if (typeof window.dmAPI.getLoggedInMember === 'function') { 
 membersApiStatusEl.textContent = 'Available ✓'; 
 membersApiStatusEl.style.color = '#38a169'; 
 } else { 
 membersApiStatusEl.textContent = 'Not Available'; 
 membersApiStatusEl.style.color = '#dd6b20'; 
 } 
 } catch (error) { 
 debug('Error checking Members API:', error); 
 membersApiStatusEl.textContent = 'Failed: ' + error.message; 
 membersApiStatusEl.style.color = '#e53e3e'; 
 } 
  
 // Show data section 
 loadingEl.style.display = 'none'; 
 dataEl.style.display = 'block'; 
  
 showStatus('✅ APIs initialized successfully!', 'success', 'api-settings-tab'); 
 } catch (error) { 
 loadingEl.style.display = 'none'; 
 dataEl.style.display = 'block'; 
 showStatus(`❌ Error initializing APIs: ${error.message}`, 'error', 'api-settings-tab'); 
 debug('Full initialization error:', error); 
 } 
 } 
  
 // Show error in all status elements 
 function showAllErrors(errorMsg) { 
 showStatus(errorMsg, 'error', 'collections-tab'); 
 showStatus(errorMsg, 'error', 'content-library-tab'); 
 showStatus(errorMsg, 'error', 'store-tab'); 
 showStatus(errorMsg, 'error', 'dynamic-pages-tab'); 
 showStatus(errorMsg, 'error', 'api-discovery-tab'); 
 showStatus(errorMsg, 'error', 'api-settings-tab'); 
 } 
  
 // Find collection with filters and also display in collections tab 
 async function findCollection(collectionId) { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot find collection: dmAPI not detected', 'error', 'collections-tab'); 
 return; 
 } 
  
 if (!apiState.collectionsAPI) { 
 showStatus('Collections API not initialized. Click "Initialize All APIs" in Settings tab first.', 'error', 'collections-tab'); 
 return; 
 } 
  
 if (!collectionId) { 
 collectionId = collectionInput.value.trim(); 
 } 
  
 if (!collectionId) { 
 showStatus('Please enter a collection name or ID', 'error', 'collections-tab'); 
 return; 
 } 
  
 debug(`Finding collection: ${collectionId}`); 
 showStatus(`Searching for collection: ${collectionId}...`, 'info', 'collections-tab'); 
  
 try { 
 // Build query with filters if provided 
 let query = apiState.collectionsAPI.data(collectionId); 
  
 // Add where clause if field is provided 
 const filterField = filterFieldEl.value.trim(); 
 const filterOperator = filterOperatorEl.value; 
 const filterValue = filterValueEl.value.trim(); 
  
 if (filterField && filterValue) { 
 // Handle array operators (IN, NIN, BTWN) 
 if (['IN', 'NIN', 'BTWN'].includes(filterOperator)) { 
 const valueArray = filterValue.split(',').map(v => v.trim()); 
 query = query.where(filterField, filterOperator, valueArray); 
 } else { 
 // Convert to number if it looks like one 
 const value = !isNaN(filterValue) ? parseFloat(filterValue) : filterValue; 
 query = query.where(filterField, filterOperator, value); 
 } 
 } 
  
 // Add sort if field is provided 
 const sortField = sortFieldEl.value.trim(); 
 const sortDirection = sortDirectionEl.value; 
  
 if (sortField) { 
 query = query.orderBy(sortField, sortDirection); 
 } 
  
 // Add pagination 
 const pageSize = parseInt(pageSizeEl.value) || 50; 
 const pageNumber = parseInt(pageNumberEl.value) || 0; 
  
 query = query.pageSize(pageSize).pageNumber(pageNumber); 
  
 // Execute query 
 const data = await query.get(); 
  
 // Check if the response is actually an error 
 if (isErrorResponse(data)) { 
 showStatus(`❌ Error: ${data.message || 'Collection not found'}`, 'error', 'collections-tab'); 
 showResults(data); 
 return; 
 } 
  
 // Check if the response is valid and contains data 
 if (data) { 
 let itemCount = 0; 
 let dataType = 'unknown'; 
  
 // For array responses 
 if (Array.isArray(data)) { 
 itemCount = data.length; 
 dataType = 'array'; 
  
 if (data.length > 0) { 
 showStatus(`✅ Successfully retrieved collection: ${collectionId} (${data.length} items)`, 'success', 'collections-tab'); 
 } else { 
 showStatus('⚠️ Collection found but contains no items.', 'info', 'collections-tab'); 
 } 
 } 
 // For object responses like the one with values property 
 else if (data.values && Array.isArray(data.values)) { 
 itemCount = data.values.length; 
 dataType = 'object with values array'; 
  
 if (data.values.length > 0) { 
 showStatus(`✅ Successfully retrieved collection: ${collectionId} (${data.values.length} items)`, 'success', 'collections-tab'); 
 } else { 
 showStatus('⚠️ Collection found but contains no items.', 'info', 'collections-tab'); 
 } 
 } 
 // For other types of responses 
 else if (typeof data === 'object' && Object.keys(data).length > 0) { 
 itemCount = Object.keys(data).length; 
 dataType = 'object'; 
 showStatus(`✅ Successfully retrieved data for: ${collectionId}`, 'success', 'collections-tab'); 
 } else { 
 showStatus('⚠️ Response received but with unexpected format.', 'info', 'collections-tab'); 
 } 
  
 // Add the collection to discovered collections if not already there 
 if (!apiState.discoveredCollections.includes(collectionId)) { 
 apiState.discoveredCollections.push(collectionId); 
 updateDiscoveredCollections(); 
 } 
  
 // Display in Raw JSON tab 
 showResults(data); 
  
 // Also display in collections tab 
 displayCollectionData(collectionId, data, itemCount, dataType); 
 } else { 
 showStatus('⚠️ Received empty response.', 'error', 'collections-tab'); 
 showResults({}); 
 } 
 } catch (error) { 
 showStatus(`❌ Error finding collection: ${error.message}`, 'error', 'collections-tab'); 
 showResults({ error: error.message }); 
  
 // Try alternative methods if API call fails 
 tryAlternativeMethods(collectionId); 
 } 
 } 
  
 // Display collection data in the collections tab 
 function displayCollectionData(collectionId, data, itemCount, dataType) { 
 // Check if collection details section exists, create if not 
 let collectionDetailsEl = document.getElementById('aog-js-collection-details'); 
 if (!collectionDetailsEl) { 
 collectionDetailsEl = document.createElement('div'); 
 collectionDetailsEl.id = 'aog-js-collection-details'; 
 collectionDetailsEl.className = 'aog-js-collection-details'; 
  
 // Find where to insert it (after the discovered collections) 
 const insertAfter = document.getElementById('aog-js-discovered-collections'); 
 if (insertAfter && insertAfter.parentNode) { 
 insertAfter.parentNode.insertBefore(collectionDetailsEl, insertAfter.nextSibling); 
 } else { 
 // Fallback - try to insert before the filter section 
 const filterSection = document.querySelector('.aog-js-filter-section'); 
 if (filterSection && filterSection.parentNode) { 
 filterSection.parentNode.insertBefore(collectionDetailsEl, filterSection); 
 } 
 } 
 } 
  
 // Create the preview content 
 collectionDetailsEl.innerHTML = ''; 
  
 // Create the header 
 const headerEl = document.createElement('div'); 
 headerEl.className = 'aog-js-section-subtitle'; 
 headerEl.textContent = 'Collection Preview'; 
 collectionDetailsEl.appendChild(headerEl); 
  
 // Create the details container 
 const detailsContainer = document.createElement('div'); 
 detailsContainer.className = 'aog-js-card'; 
  
 const detailsBody = document.createElement('div'); 
 detailsBody.className = 'aog-js-card-body'; 
  
 // Create collection info 
 const infoEl = document.createElement('div'); 
 infoEl.className = 'aog-js-collection-info'; 
 infoEl.innerHTML = ` 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Collection Name:</div> 
 <div class="aog-js-info-value">${collectionId}</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Items Count:</div> 
 <div class="aog-js-info-value">${itemCount}</div> 
 </div> 
 <div class="aog-js-info-item"> 
 <div class="aog-js-info-label">Data Type:</div> 
 <div class="aog-js-info-value">${dataType}</div> 
 </div> 
 `; 
  
 detailsBody.appendChild(infoEl); 
  
 // Create data preview 
 const previewTitle = document.createElement('div'); 
 previewTitle.className = 'aog-js-section-subtitle'; 
 previewTitle.textContent = 'Data Preview'; 
 previewTitle.style.marginTop = '20px'; 
 detailsBody.appendChild(previewTitle); 
  
 // Format the data for display 
 let previewContent = ''; 
  
 try { 
 // Show a truncated version (first item if array, or first few properties if object) 
 if (Array.isArray(data) && data.length > 0) { 
 previewContent = JSON.stringify(data[0], null, 2); 
 if (data.length > 1) { 
 previewContent += `\n\n// ... and ${data.length - 1} more items`; 
 } 
 } else if (data.values && Array.isArray(data.values) && data.values.length > 0) { 
 previewContent = JSON.stringify(data.values[0], null, 2); 
 if (data.values.length > 1) { 
 previewContent += `\n\n// ... and ${data.values.length - 1} more items`; 
 } 
 } else { 
 // For objects, limit the preview 
 const fullJson = JSON.stringify(data, null, 2); 
 previewContent = fullJson.length > 1000 ? fullJson.substring(0, 1000) + '...' : fullJson; 
 } 
 } catch (error) { 
 previewContent = 'Error formatting data preview: ' + error.message; 
 } 
  
 const previewEl = document.createElement('pre'); 
 previewEl.className = 'aog-js-collection-preview'; 
 previewEl.textContent = previewContent; 
 detailsBody.appendChild(previewEl); 
  
 // Add view in raw JSON link 
 const viewRawLink = document.createElement('button'); 
 viewRawLink.className = 'aog-js-primary-button'; 
 viewRawLink.style.marginTop = '15px'; 
 viewRawLink.style.backgroundColor = '#ad24a6'; // Consistent purple color 
 viewRawLink.textContent = 'View Full Data in Raw JSON Tab'; 
 viewRawLink.addEventListener('click', () => { 
 // Switch to raw JSON tab 
 switchToTab('raw-json'); 
 }); 
  
 detailsBody.appendChild(viewRawLink); 
 detailsContainer.appendChild(detailsBody); 
 collectionDetailsEl.appendChild(detailsContainer); 
  
 // Make sure the details are visible 
 collectionDetailsEl.style.display = 'block'; 
 } 
  
 // Update discovered collections UI 
 function updateDiscoveredCollections() { 
 if (!collectionsListEl) return; 
  
 collectionsListEl.innerHTML = ''; 
  
 if (apiState.discoveredCollections.length === 0) { 
 const emptyState = document.createElement('div'); 
 emptyState.className = 'aog-js-empty-state'; 
 emptyState.textContent = 'No discovered collections yet. Search for a collection by name in the field above.'; 
 collectionsListEl.appendChild(emptyState); 
 return; 
 } 
  
 // Update count if element exists 
 if (discoveryCountEl) { 
 discoveryCountEl.textContent = `${apiState.discoveredCollections.length} found`; 
 } 
  
 // Add each collection to the list 
 apiState.discoveredCollections.forEach(id => { 
 collectionsListEl.appendChild(createCollectionItem(id)); 
 }); 
 } 
  
 // Try alternative methods to find collection 
 async function tryAlternativeMethods(identifier) { 
 debug('Trying alternative methods for: ' + identifier); 
 showStatus('Trying alternative lookup methods...', 'info', 'collections-tab'); 
  
 let found = false; 
  
 // Method 1: Try to access using external data source if available 
 if (typeof window.dm !== 'undefined' && typeof window.dm.getExternalDataSource === 'function') { 
 try { 
 const externalDataId = isNaN(identifier) ? identifier : parseInt(identifier); 
 const externalData = await window.dm.getExternalDataSource(externalDataId); 
  
 if (externalData && externalData.items) { 
 showStatus(`✅ Found collection using dm.getExternalDataSource`, 'success', 'collections-tab'); 
 showResults(externalData.items); 
 // Also display in collections tab 
 displayCollectionData(identifier, externalData.items, externalData.items.length, 'external data array'); 
 found = true; 
  
 // Add to discovered collections if not already there 
 if (!apiState.discoveredCollections.includes(identifier)) { 
 apiState.discoveredCollections.push(identifier); 
 updateDiscoveredCollections(); 
 } 
 } 
 } catch (error) { 
 debug('Error using getExternalDataSource:', error.message); 
 } 
 } 
  
 // Method 2: Try to look for global collections variable 
 if (!found && (window.collectionsData || window.collections)) { 
 const collections = window.collectionsData || window.collections; 
 if (collections && collections[identifier]) { 
 showStatus(`✅ Found collection in global variables`, 'success', 'collections-tab'); 
 showResults(collections[identifier]); 
 // Also display in collections tab 
 displayCollectionData(identifier, collections[identifier], 
 Array.isArray(collections[identifier]) ? collections[identifier].length : 1, 
 'global collection'); 
 found = true; 
  
 // Add to discovered collections if not already there 
 if (!apiState.discoveredCollections.includes(identifier)) { 
 apiState.discoveredCollections.push(identifier); 
 updateDiscoveredCollections(); 
 } 
 } 
 } 
  
 if (!found) { 
 showStatus(`Could not find collection "${identifier}" using any method.`, 'error', 'collections-tab'); 
 } 
 } 
  
 // Discover APIs - Modified to not search for collections 
 async function discoverAPIs() { 
 if (!apiState.isDudaSite) { 
 updateApiSectionStatus('core', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('collections', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('contentLibrary', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('store', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('dynamicPages', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('members', 'Error', 'dmAPI not detected'); 
 updateApiSectionStatus('sitemap', 'Error', 'dmAPI not detected'); 
 return; 
 } 
  
 debug('Discovering APIs...'); 
 showStatus('Scanning site for available APIs...', 'info', 'api-discovery-tab'); 
  
 // Initialize APIs if needed 
 if (!apiState.collectionsAPI || !apiState.contentLibraryAPI || !apiState.dynamicPagesAPI) { 
 await initAllAPIs(); 
 } 
  
 // Check core API methods 
 discoverCoreAPI(); 
  
 // Check if collections API is available (but don't search for collections) 
 checkCollectionsAPIAvailability(); 
  
 // Check content library 
 discoverContentLibrary(); 
  
 // Check store API 
 discoverStoreAPI(); 
  
 // Check dynamic pages 
 discoverDynamicPages(); 
  
 // Check members API 
 discoverMembersAPI(); 
  
 // Check sitemap 
 discoverSitemap(); 
 } 
  
 // Check if Collections API is available without searching for collections 
 async function checkCollectionsAPIAvailability() { 
 updateApiSectionStatus('collections', 'Checking...'); 
  
 try { 
 if (!apiState.collectionsAPI) { 
 try { 
 apiState.collectionsAPI = await window.dmAPI.loadCollectionsAPI(); 
 } catch (error) { 
 updateApiSectionStatus('collections', 'Not Available', error.message); 
 return; 
 } 
 } 
  
 // If we get here, the API is available 
 updateApiSectionStatus('collections', 'Available', 'Use Collections tab to search for collections'); 
  
 // Display guidance in the results section 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="collections"] .aog-js-api-section-results'); 
 if (resultsEl) { 
 resultsEl.innerHTML = '<div class="aog-js-guidance">Collections API is available. Go to the Collections tab to search for specific collections by name.</div>'; 
 } 
  
 } catch (error) { 
 updateApiSectionStatus('collections', 'Error', error.message); 
 } 
 } 
  
 // Find store catalog or categories 
 async function findStoreData(type) { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot access store data: dmAPI not detected', 'error', 'store-tab'); 
 return; 
 } 
  
 if (!apiState.collectionsAPI) { 
 showStatus('Collections API not initialized. Click "Initialize All APIs" in Settings tab first.', 'error', 'store-tab'); 
 return; 
 } 
  
 const storeType = type === 'catalog' ? 'catalog_product' : 'catalog_category'; 
 debug(`Finding store ${type}`); 
 showStatus(`Searching for store ${type}...`, 'info', 'store-tab'); 
  
 try { 
 // Build query with filters if provided 
 let query = apiState.collectionsAPI.storeData(storeType); 
  
 // Add where clause if field is provided 
 const filterField = storeFilterFieldEl.value.trim(); 
 const filterOperator = storeFilterOperatorEl.value; 
 const filterValue = storeFilterValueEl.value.trim(); 
  
 if (filterField && filterValue) { 
 // Handle array operators (IN, NIN, BTWN) 
 if (['IN', 'NIN', 'BTWN'].includes(filterOperator)) { 
 const valueArray = filterValue.split(',').map(v => v.trim()); 
 query = query.where(filterField, filterOperator, valueArray); 
 } else { 
 // Convert to number if it looks like one 
 const value = !isNaN(filterValue) ? parseFloat(filterValue) : filterValue; 
 query = query.where(filterField, filterOperator, value); 
 } 
 } 
  
 // Add sort if field is provided 
 const sortField = storeSortFieldEl.value.trim(); 
 const sortDirection = storeSortDirectionEl.value; 
  
 if (sortField) { 
 query = query.orderBy(sortField, sortDirection); 
 } 
  
 // Execute query 
 const data = await query.get(); 
  
 // Check response 
 if (isErrorResponse(data)) { 
 showStatus(`❌ Error: ${data.message || 'Store data not found'}`, 'error', 'store-tab'); 
 showResults(data); 
 return; 
 } 
  
 if (data) { 
 if (Array.isArray(data)) { 
 if (data.length > 0) { 
 showStatus(`✅ Successfully retrieved store ${type}: (${data.length} items)`, 'success', 'store-tab'); 
 } else { 
 showStatus(`⚠️ Store ${type} found but contains no items.`, 'info', 'store-tab'); 
 } 
 } else if (typeof data === 'object' && Object.keys(data).length > 0) { 
 showStatus(`✅ Successfully retrieved store ${type} data`, 'success', 'store-tab'); 
 } else { 
 showStatus('⚠️ Response received but with unexpected format.', 'info', 'store-tab'); 
 } 
  
 showResults(data); 
 } else { 
 showStatus('⚠️ Received empty response.', 'error', 'store-tab'); 
 showResults({}); 
 } 
 } catch (error) { 
 showStatus(`❌ Error finding store ${type}: ${error.message}`, 'error', 'store-tab'); 
 showResults({ error: error.message }); 
 } 
 } 
  
 // Load content library 
 async function loadContentLibrary() { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot access content library: dmAPI not detected', 'error', 'content-library-tab'); 
 return; 
 } 
  
 if (!apiState.contentLibraryAPI) { 
 try { 
 showStatus('Initializing Content Library API...', 'info', 'content-library-tab'); 
 apiState.contentLibraryAPI = await window.dmAPI.loadContentLibrary(); 
 } catch (error) { 
 showStatus(`❌ Error initializing Content Library API: ${error.message}`, 'error', 'content-library-tab'); 
 return; 
 } 
 } 
  
 debug('Loading content library'); 
  
 try { 
 const data = apiState.contentLibraryAPI; 
  
 if (!data) { 
 showStatus('❌ Content Library returned no data', 'error', 'content-library-tab'); 
 return; 
 } 
  
 // Display the data in each section 
 displayContentLibraryData(data); 
  
 showStatus('✅ Successfully loaded Content Library data', 'success', 'content-library-tab'); 
 showResults(data); 
 } catch (error) { 
 showStatus(`❌ Error loading Content Library: ${error.message}`, 'error', 'content-library-tab'); 
 showResults({ error: error.message }); 
 } 
 } 
  
 // Display content library data in sections 
 function displayContentLibraryData(data) { 
 // Helper to create a simple key-value display 
 function createDataDisplay(obj, depth = 0) { 
 if (!obj || typeof obj !== 'object') { 
 return document.createTextNode(obj === null ? 'null' : obj === undefined ? 'undefined' : String(obj)); 
 } 
  
 const container = document.createElement('div'); 
 container.style.paddingLeft = depth > 0 ? '15px' : '0'; 
  
 // Handle arrays 
 if (Array.isArray(obj)) { 
 if (obj.length === 0) { 
 const emptyMsg = document.createElement('div'); 
 emptyMsg.textContent = '(empty array)'; 
 emptyMsg.style.fontStyle = 'italic'; 
 emptyMsg.style.color = '#888'; 
 container.appendChild(emptyMsg); 
 } else { 
 obj.forEach((item, index) => { 
 const itemContainer = document.createElement('div'); 
 itemContainer.style.marginBottom = '8px'; 
  
 const indexEl = document.createElement('div'); 
 indexEl.textContent = `[${index}]:`; 
 indexEl.style.fontWeight = 'bold'; 
  
 itemContainer.appendChild(indexEl); 
 itemContainer.appendChild(createDataDisplay(item, depth + 1)); 
 container.appendChild(itemContainer); 
 }); 
 } 
  
 return container; 
 } 
  
 // Handle objects 
 const keys = Object.keys(obj); 
  
 if (keys.length === 0) { 
 const emptyMsg = document.createElement('div'); 
 emptyMsg.textContent = '(empty object)'; 
 emptyMsg.style.fontStyle = 'italic'; 
 emptyMsg.style.color = '#888'; 
 container.appendChild(emptyMsg); 
 } else { 
 keys.forEach(key => { 
 const row = document.createElement('div'); 
 row.style.marginBottom = '8px'; 
  
 const keyEl = document.createElement('div'); 
 keyEl.textContent = `${key}:`; 
 keyEl.style.fontWeight = 'bold'; 
  
 row.appendChild(keyEl); 
  
 const valueContainer = document.createElement('div'); 
 valueContainer.style.marginLeft = '15px'; 
 valueContainer.appendChild(createDataDisplay(obj[key], depth + 1)); 
  
 row.appendChild(valueContainer); 
 container.appendChild(row); 
 }); 
 } 
  
 return container; 
 } 
  
 // Update each section 
 document.querySelectorAll('.aog-js-content-section').forEach(section => { 
 const sectionName = section.getAttribute('data-section'); 
 const bodyEl = section.querySelector('.aog-js-content-section-body'); 
  
 // Clear previous content 
 bodyEl.innerHTML = ''; 
  
 // Add new content 
 if (data && data[sectionName]) { 
 bodyEl.appendChild(createDataDisplay(data[sectionName])); 
 } else { 
 const notFoundEl = document.createElement('div'); 
 notFoundEl.textContent = 'No data found for this section'; 
 notFoundEl.style.fontStyle = 'italic'; 
 notFoundEl.style.color = '#888'; 
 notFoundEl.style.padding = '10px'; 
 bodyEl.appendChild(notFoundEl); 
 } 
 }); 
 } 
  
 // Toggle content section 
 function toggleContentSection(event) { 
 const section = event.currentTarget.closest('.aog-js-content-section'); 
 section.classList.toggle('expanded'); 
 } 
  
 // Check if current page is a dynamic page 
 async function checkDynamicPage() { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot check dynamic page: dmAPI not detected', 'error', 'dynamic-pages-tab'); 
 return; 
 } 
  
 try { 
 if (!apiState.dynamicPagesAPI) { 
 apiState.dynamicPagesAPI = window.dmAPI.dynamicPageApi(); 
 } 
  
 const isDynamic = apiState.dynamicPagesAPI.isDynamicPage(); 
 isDynamicEl.textContent = isDynamic ? 'Yes ✓' : 'No'; 
 isDynamicEl.style.color = isDynamic ? '#38a169' : '#666'; 
  
 if (isDynamic) { 
 showStatus('✅ This is a dynamic page. Loading page data...', 'success', 'dynamic-pages-tab'); 
  
 try { 
 const pageData = await apiState.dynamicPagesAPI.pageData(); 
  
 showStatus('✅ Successfully loaded dynamic page data', 'success', 'dynamic-pages-tab'); 
 showResults(pageData); 
  
 // Display dynamic page info 
 const infoEl = document.getElementById('aog-js-dynamic-page-info'); 
  
 // Clear existing items except the first one 
 const items = infoEl.querySelectorAll('.aog-js-info-item'); 
 for (let i = 1; i < items.length; i++) { 
 items[i].remove(); 
 } 
  
 // Add new info items 
 if (pageData) { 
 for (const key in pageData) { 
 if (key !== 'data') { // Skip the data property, show it in raw JSON instead 
 const item = document.createElement('div'); 
 item.className = 'aog-js-info-item'; 
  
 const label = document.createElement('div'); 
 label.className = 'aog-js-info-label'; 
 label.textContent = formatLabel(key) + ':'; 
  
 const value = document.createElement('div'); 
 value.className = 'aog-js-info-value'; 
 value.textContent = typeof pageData[key] === 'object' 
 ? JSON.stringify(pageData[key]).substring(0, 50) + '...' 
 : pageData[key]; 
  
 item.appendChild(label); 
 item.appendChild(value); 
 infoEl.appendChild(item); 
 } 
 } 
 } 
 } catch (error) { 
 showStatus(`❌ Error loading dynamic page data: ${error.message}`, 'error', 'dynamic-pages-tab'); 
 showResults({ error: error.message }); 
 } 
 } else { 
 showStatus('❌ This is not a dynamic page', 'error', 'dynamic-pages-tab'); 
 } 
 } catch (error) { 
 showStatus(`❌ Error checking dynamic page: ${error.message}`, 'error', 'dynamic-pages-tab'); 
 isDynamicEl.textContent = 'Error'; 
 isDynamicEl.style.color = '#e53e3e'; 
 } 
 } 
  
 // Format label for display 
 function formatLabel(str) { 
 return str 
 .replace(/_/g, ' ') 
 .replace(/\w\S*/g, txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()); 
 } 
  
 // Call core API method 
 async function callCoreMethod(methodName) { 
 if (!apiState.isDudaSite) { 
 methodResultEl.textContent = 'Error: dmAPI not detected'; 
 return; 
 } 
  
 debug(`Calling core method: ${methodName}`); 
  
 try { 
 let result; 
  
 // Handle async methods differently 
 if (methodName === 'getNavItemsAsync') { 
 result = await window.dmAPI[methodName](); 
  
 // Special handling for navigation data to make it more readable 
 if (result) { 
 methodResultEl.innerHTML = ''; 
  
 // Create a formatted navigation display 
 const navContainer = document.createElement('div'); 
 navContainer.className = 'aog-js-nav-display'; 
  
 function addNavItem(item, level = 0) { 
 const itemEl = document.createElement('div'); 
 itemEl.className = 'aog-js-nav-item'; 
 itemEl.style.paddingLeft = `${level * 20}px`; 
  
 const titleEl = document.createElement('span'); 
 titleEl.className = 'aog-js-nav-title'; 
 titleEl.textContent = item.title; 
  
 const pathEl = document.createElement('span'); 
 pathEl.className = 'aog-js-nav-path'; 
 pathEl.textContent = ` (${item.path})`; 
  
 const visibleEl = document.createElement('span'); 
 visibleEl.className = 'aog-js-nav-visible'; 
 visibleEl.textContent = item.visible ? ' - Visible' : ' - Hidden'; 
 visibleEl.style.color = item.visible ? '#38a169' : '#e53e3e'; 
  
 itemEl.appendChild(titleEl); 
 itemEl.appendChild(pathEl); 
 itemEl.appendChild(visibleEl); 
  
 navContainer.appendChild(itemEl); 
  
 // Add subnav items if any 
 if (item.subNav && item.subNav.length > 0) { 
 item.subNav.forEach(subItem => { 
 addNavItem(subItem, level + 1); 
 }); 
 } 
 } 
  
 // Add heading 
 const headingEl = document.createElement('div'); 
 headingEl.className = 'aog-js-nav-heading'; 
 headingEl.textContent = 'Navigation Structure:'; 
 navContainer.appendChild(headingEl); 
  
 // Process all nav items 
 result.forEach(item => { 
 addNavItem(item); 
 }); 
  
 methodResultEl.appendChild(navContainer); 
  
 // Add link to raw JSON 
 const rawLink = document.createElement('a'); 
 rawLink.href = '#'; 
 rawLink.textContent = 'Show raw JSON'; 
 rawLink.className = 'aog-js-show-raw'; 
 rawLink.addEventListener('click', (e) => { 
 e.preventDefault(); 
 methodResultEl.textContent = JSON.stringify(result, null, 2); 
 }); 
  
 const rawLinkContainer = document.createElement('div'); 
 rawLinkContainer.className = 'aog-js-raw-link-container'; 
 rawLinkContainer.appendChild(rawLink); 
  
 methodResultEl.appendChild(rawLinkContainer); 
 } else { 
 methodResultEl.textContent = 'No navigation data returned'; 
 } 
 } else { 
 // Call the method directly for non-async methods 
 result = window.dmAPI[methodName](); 
  
 // Format and display the result 
 methodResultEl.textContent = typeof result === 'object' 
 ? JSON.stringify(result, null, 2) 
 : result; 
 } 
  
 // Also show in Raw JSON tab 
 showResults(result); 
 } catch (error) { 
 methodResultEl.textContent = `Error: ${error.message}`; 
 } 
 } 
  
 // Check if response contains an error message 
 function isErrorResponse(data) { 
 // Check for common error patterns in responses 
 if (data && typeof data === 'object') { 
 // Check for error message property 
 if (data.message && typeof data.message === 'string') { 
 const errorKeywords = ['error', 'no collection', 'not found', 'invalid', 'failed']; 
 return errorKeywords.some(keyword => data.message.toLowerCase().includes(keyword)); 
 } 
  
 // Check for error property 
 if (data.error || data.errorMessage || data.status === 'error') { 
 return true; 
 } 
 } 
 return false; 
 } 
  
 // Show results in raw JSON tab 
 function showResults(data) { 
 apiState.currentData = data; 
  
 // Format and display in raw JSON tab 
 if (rawJsonEl) { 
 try { 
 const formattedJson = JSON.stringify(data, null, 2); 
 rawJsonEl.textContent = formattedJson; 
 } catch (error) { 
 rawJsonEl.textContent = 'Error formatting JSON data'; 
 } 
 } 
 } 
  
 // Switch to specific tab 
 function switchToTab(tabId) { 
 // Find the tab button 
 const tabButton = document.querySelector(`.aog-js-tab-button[data-tab="${tabId}"]`); 
 if (tabButton) { 
 // Create a mock event object 
 const event = { target: tabButton }; 
 switchTab(event); 
 } 
 } 
  
 // Copy JSON to clipboard 
 function copyJsonToClipboard() { 
 try { 
 const text = rawJsonEl.textContent; 
  
 navigator.clipboard.writeText(text).then(function() { 
 showCopiedNotification(); 
 }).catch(function(err) { 
 debug('Clipboard API error:', err); 
 // Fallback method for older browsers 
 copyToClipboardFallback(text); 
 }); 
 } catch (err) { 
 debug('Failed to copy:', err); 
 } 
 } 
  
 // Format JSON 
 function formatJson() { 
 try { 
 if (!apiState.currentData) { 
 return; 
 } 
  
 const formatted = JSON.stringify(apiState.currentData, null, 2); 
 rawJsonEl.textContent = formatted; 
 } catch (error) { 
 debug('Error formatting JSON:', error); 
 } 
 } 
  
 // Fallback clipboard method for browsers without clipboard API 
 function copyToClipboardFallback(text) { 
 const textArea = document.createElement('textarea'); 
 textArea.value = text; 
 textArea.style.position = 'fixed'; 
 textArea.style.left = '-999999px'; 
 textArea.style.top = '-999999px'; 
 document.body.appendChild(textArea); 
 textArea.focus(); 
 textArea.select(); 
  
 try { 
 const successful = document.execCommand('copy'); 
 if (successful) { 
 showCopiedNotification(); 
 } else { 
 debug('Failed to copy text with execCommand'); 
 } 
 } catch (err) { 
 debug('Error during execCommand copy:', err); 
 } 
  
 document.body.removeChild(textArea); 
 } 
  
 // Show copied notification 
 function showCopiedNotification() { 
 // Create notification if it doesn't exist 
 let notification = document.querySelector('.aog-js-copied-notification'); 
 if (!notification) { 
 notification = document.createElement('div'); 
 notification.className = 'aog-js-copied-notification'; 
 notification.textContent = 'JSON copied to clipboard'; 
 document.body.appendChild(notification); 
 } 
  
 // Show notification 
 notification.classList.add('show'); 
  
 // Hide notification after delay 
 setTimeout(() => { 
 notification.classList.remove('show'); 
 }, 2000); 
 } 
  
 // Toggle debug mode 
 function toggleDebugMode() { 
 DEBUG = debugToggle.checked; 
 debug('Debug mode toggled:', DEBUG); 
 } 
  
 // Discover Members API 
 async function discoverMembersAPI() { 
 updateApiSectionStatus('members', 'Checking...'); 
  
 try { 
 // Check if getLoggedInMember method exists 
 if (typeof window.dmAPI.getLoggedInMember === 'function') { 
 try { 
 // Try to call the method 
 await window.dmAPI.getLoggedInMember(); 
 updateApiSectionStatus('members', 'Available', 'Members API active'); 
 } catch (error) { 
 // If we get a specific error about not being logged in, API is still available 
 if (error && error.message && error.message.includes('not logged in')) { 
 updateApiSectionStatus('members', 'Available', 'No member logged in'); 
 } else { 
 updateApiSectionStatus('members', 'Not Available', error.message); 
 } 
 } 
 } else { 
 updateApiSectionStatus('members', 'Not Available', 'Members API not found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('members', 'Error', error.message); 
 } 
 } 
  
 // Check for logged-in member 
 async function checkLoggedInMember() { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot check member: dmAPI not detected', 'error', 'members-tab'); 
 return; 
 } 
  
 const memberStatusEl = document.getElementById('aog-js-member-status'); 
 const isLoggedInEl = document.getElementById('aog-js-is-logged-in'); 
 const memberInfoEl = document.getElementById('aog-js-member-info'); 
  
 try { 
 showStatus('Checking for logged-in member...', 'info', 'members-tab'); 
  
 if (typeof window.dmAPI.getLoggedInMember !== 'function') { 
 showStatus('❌ Members API not available on this site', 'error', 'members-tab'); 
 isLoggedInEl.textContent = 'API Not Available'; 
 isLoggedInEl.style.color = '#e53e3e'; 
 return; 
 } 
  
 try { 
 const memberData = await window.dmAPI.getLoggedInMember(); 
  
 // Check if this is a placeholder/default user or a real logged-in user 
 const isPlaceholder = !memberData || 
 (memberData.firstName === 'John' && memberData.lastName === 'Doe') || 
 !memberData.uuid || 
 Object.keys(memberData).length < 3; 
  
 if (isPlaceholder) { 
 isLoggedInEl.textContent = 'Not Logged In (Default Data)'; 
 isLoggedInEl.style.color = '#dd6b20'; 
 showStatus('ℹ️ No real member is logged in (placeholder data detected)', 'info', 'members-tab'); 
 } else { 
 // Real user is logged in 
 isLoggedInEl.textContent = 'Logged In ✓'; 
 isLoggedInEl.style.color = '#38a169'; 
 showStatus('✅ Member is logged in, retrieved member data', 'success', 'members-tab'); 
 } 
  
 showResults(memberData); 
  
 // Display member info 
 // Clear existing items except the first one 
 const items = memberInfoEl.querySelectorAll('.aog-js-info-item'); 
 for (let i = 1; i < items.length; i++) { 
 items[i].remove(); 
 } 
  
 // Add new info items 
 if (memberData) { 
 // Add a note if we think it's placeholder data 
 if (isPlaceholder) { 
 const placeholderNote = document.createElement('div'); 
 placeholderNote.className = 'aog-js-placeholder-note'; 
 placeholderNote.textContent = 'Note: This appears to be placeholder data, not a real logged-in user.'; 
 placeholderNote.style.color = '#dd6b20'; 
 placeholderNote.style.fontStyle = 'italic'; 
 placeholderNote.style.marginBottom = '15px'; 
 placeholderNote.style.padding = '8px'; 
 placeholderNote.style.backgroundColor = '#fff5f5'; 
 placeholderNote.style.borderRadius = '4px'; 
 memberInfoEl.appendChild(placeholderNote); 
 } 
  
 for (const key in memberData) { 
 const item = document.createElement('div'); 
 item.className = 'aog-js-info-item'; 
  
 const label = document.createElement('div'); 
 label.className = 'aog-js-info-label'; 
 label.textContent = formatLabel(key) + ':'; 
  
 const value = document.createElement('div'); 
 value.className = 'aog-js-info-value'; 
 value.textContent = typeof memberData[key] === 'object' 
 ? JSON.stringify(memberData[key]).substring(0, 50) + '...' 
 : memberData[key]; 
  
 item.appendChild(label); 
 item.appendChild(value); 
 memberInfoEl.appendChild(item); 
 } 
 } 
 } catch (error) { 
 if (error && error.message && error.message.includes('not logged in')) { 
 isLoggedInEl.textContent = 'Not Logged In'; 
 isLoggedInEl.style.color = '#dd6b20'; 
 showStatus('ℹ️ No member is currently logged in', 'info', 'members-tab'); 
 } else { 
 isLoggedInEl.textContent = 'Error'; 
 isLoggedInEl.style.color = '#e53e3e'; 
 showStatus(`❌ Error checking member: ${error.message}`, 'error', 'members-tab'); 
 } 
 } 
 } catch (error) { 
 showStatus(`❌ Error: ${error.message}`, 'error', 'members-tab'); 
 } 
 } 
  
 // Discover Sitemap 
 async function discoverSitemap() { 
 updateApiSectionStatus('sitemap', 'Checking...'); 
  
 try { 
 // Try to fetch the sitemap.xml file 
 const domain = window.location.hostname; 
 const sitemapUrl = `https://${domain}/sitemap.xml`; 
  
 try { 
 const response = await fetch(sitemapUrl, { method: 'HEAD' }); 
  
 if (response.ok) { 
 updateApiSectionStatus('sitemap', 'Available', 'Sitemap.xml found'); 
 } else { 
 updateApiSectionStatus('sitemap', 'Not Available', 'Sitemap.xml not found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('sitemap', 'Not Available', 'Cannot access sitemap.xml'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('sitemap', 'Error', error.message); 
 } 
 } 
  
 // Fetch and parse sitemap 
 async function fetchSitemap() { 
 if (!apiState.isDudaSite) { 
 showStatus('Cannot fetch sitemap: Site not detected', 'error', 'sitemap-tab'); 
 return; 
 } 
  
 const sitemapStatusEl = document.getElementById('aog-js-sitemap-status'); 
 const sitemapStatsEl = document.getElementById('aog-js-sitemap-stats'); 
 const sitemapCountEl = document.getElementById('aog-js-sitemap-count'); 
 const sitemapUpdatedEl = document.getElementById('aog-js-sitemap-updated'); 
 const sitemapContainerEl = document.getElementById('aog-js-sitemap-container'); 
 const sitemapUrlsEl = document.getElementById('aog-js-sitemap-urls'); 
  
 try { 
 showStatus('Fetching sitemap.xml...', 'info', 'sitemap-tab'); 
  
 const domain = window.location.hostname; 
 const sitemapUrl = `https://${domain}/sitemap.xml`; 
  
 try { 
 // Try to fetch the sitemap directly 
 const response = await fetch(sitemapUrl); 
  
 if (response.ok) { 
 const text = await response.text(); 
  
 // Parse the XML 
 const parser = new DOMParser(); 
 const xmlDoc = parser.parseFromString(text, 'text/xml'); 
 const urls = xmlDoc.getElementsByTagName('url'); 
  
 if (urls.length > 0) { 
 // Build site URL list 
 sitemapUrlsEl.innerHTML = ''; 
 const urlList = document.createElement('ul'); 
 urlList.className = 'aog-js-sitemap-url-list'; 
  
 // Extract URLs 
 const siteUrls = []; 
 for (let i = 0; i < urls.length; i++) { 
 const loc = urls[i].getElementsByTagName('loc')[0]; 
 if (loc) { 
 siteUrls.push({ 
 url: loc.textContent, 
 lastmod: urls[i].getElementsByTagName('lastmod')[0]?.textContent 
 }); 
 } 
 } 
  
 // Sort by URL 
 siteUrls.sort((a, b) => a.url.localeCompare(b.url)); 
  
 // Add to list 
 siteUrls.forEach(item => { 
 const li = document.createElement('li'); 
 li.className = 'aog-js-sitemap-url-item'; 
  
 const urlEl = document.createElement('a'); 
 urlEl.href = item.url; 
 urlEl.target = '_blank'; 
 urlEl.textContent = item.url.replace(`https://${domain}`, ''); 
  
 li.appendChild(urlEl); 
  
 if (item.lastmod) { 
 const lastmodEl = document.createElement('span'); 
 lastmodEl.className = 'aog-js-sitemap-lastmod'; 
 lastmodEl.textContent = ` (${new Date(item.lastmod).toLocaleDateString()})`; 
 li.appendChild(lastmodEl); 
 } 
  
 urlList.appendChild(li); 
 }); 
  
 sitemapUrlsEl.appendChild(urlList); 
  
 // Update stats 
 sitemapCountEl.textContent = urls.length; 
 sitemapUpdatedEl.textContent = new Date().toLocaleDateString(); 
  
 // Show the sections 
 sitemapStatsEl.style.display = 'block'; 
 sitemapContainerEl.style.display = 'block'; 
  
 showStatus(`✅ Successfully retrieved sitemap with ${urls.length} URLs`, 'success', 'sitemap-tab'); 
 showResults({ 
 sitemapUrl: sitemapUrl, 
 urlCount: urls.length, 
 urls: siteUrls 
 }); 
 } else { 
 showStatus('⚠️ Sitemap found but contains no URLs', 'info', 'sitemap-tab'); 
 } 
 } else { 
 showStatus(`❌ Could not access sitemap.xml: ${response.status} ${response.statusText}`, 'error', 'sitemap-tab'); 
 } 
 } catch (error) { 
 // If direct fetch fails, try a proxy approach or CORS workaround 
 showStatus(`❌ Error fetching sitemap: ${error.message}`, 'error', 'sitemap-tab'); 
 showStatus('Note: Direct access to sitemap.xml may be restricted by CORS. Try viewing it directly in your browser.', 'info', 'sitemap-tab'); 
 } 
 } catch (error) { 
 showStatus(`❌ Error: ${error.message}`, 'error', 'sitemap-tab'); 
 } 
 } 
  
 // Update API section status in discovery tab 
 function updateApiSectionStatus(section, status, details = '') { 
 const sectionEl = document.querySelector(`.aog-js-api-section[data-section="${section}"]`); 
 if (!sectionEl) return; 
  
 const statusEl = sectionEl.querySelector('.aog-js-api-section-status'); 
 if (!statusEl) return; 
  
 // Set status text 
 statusEl.textContent = status + (details ? ': ' + details : ''); 
  
 // Set status color 
 if (status === 'Available' || status === 'Active') { 
 statusEl.style.color = '#38a169'; 
 } else if (status === 'Not Available') { 
 statusEl.style.color = '#dd6b20'; 
 } else if (status === 'Error') { 
 statusEl.style.color = '#e53e3e'; 
 } else { 
 statusEl.style.color = '#666'; 
 } 
 } 
  
 // Discover core API methods 
 function discoverCoreAPI() { 
 updateApiSectionStatus('core', 'Checking...'); 
  
 try { 
 const coreMethodsAvailable = []; 
  
 // List of core methods to check 
 const coreMethods = [ 
 'getSiteName', 
 'getSiteExternalId', 
 'getSitePlanID', 
 'getCurrentDeviceType', 
 'getCurrentEnvironment', 
 'getNavItemsAsync' 
 ]; 
  
 // Check which methods are available 
 coreMethods.forEach(method => { 
 if (typeof window.dmAPI[method] === 'function') { 
 coreMethodsAvailable.push(method); 
 } 
 }); 
  
 if (coreMethodsAvailable.length > 0) { 
 updateApiSectionStatus('core', 'Available', `${coreMethodsAvailable.length} methods found`); 
  
 // Display available methods 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="core"] .aog-js-api-section-results'); 
 resultsEl.innerHTML = ''; 
  
 coreMethodsAvailable.forEach(method => { 
 const methodEl = document.createElement('div'); 
 methodEl.className = 'aog-js-discovered-method'; 
 methodEl.textContent = method; 
 resultsEl.appendChild(methodEl); 
 }); 
 } else { 
 updateApiSectionStatus('core', 'Not Available', 'No core methods found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('core', 'Error', error.message); 
 } 
 } 
  
 // Discover content library 
 async function discoverContentLibrary() { 
 updateApiSectionStatus('contentLibrary', 'Checking...'); 
  
 try { 
 if (!apiState.contentLibraryAPI) { 
 try { 
 apiState.contentLibraryAPI = await window.dmAPI.loadContentLibrary(); 
 } catch (error) { 
 updateApiSectionStatus('contentLibrary', 'Not Available', error.message); 
 return; 
 } 
 } 
  
 if (apiState.contentLibraryAPI) { 
 const sections = []; 
  
 // Check which content library sections have data 
 if (apiState.contentLibraryAPI.business_data) sections.push('business_data'); 
 if (apiState.contentLibraryAPI.location_data) sections.push('location_data'); 
 if (apiState.contentLibraryAPI.additional_locations) sections.push('additional_locations'); 
 if (apiState.contentLibraryAPI.site_texts) sections.push('site_texts'); 
 if (apiState.contentLibraryAPI.site_images) sections.push('site_images'); 
  
 updateApiSectionStatus('contentLibrary', 'Available', `${sections.length} sections with data`); 
  
 // Display available sections 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="contentLibrary"] .aog-js-api-section-results'); 
 resultsEl.innerHTML = ''; 
  
 sections.forEach(section => { 
 const sectionEl = document.createElement('div'); 
 sectionEl.className = 'aog-js-discovered-item'; 
 sectionEl.textContent = formatLabel(section); 
 resultsEl.appendChild(sectionEl); 
 }); 
 } else { 
 updateApiSectionStatus('contentLibrary', 'Not Available', 'No content library data found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('contentLibrary', 'Error', error.message); 
 } 
 } 
  
 // Discover store API 
 async function discoverStoreAPI() { 
 updateApiSectionStatus('store', 'Checking...'); 
  
 try { 
 if (!apiState.collectionsAPI) { 
 try { 
 apiState.collectionsAPI = await window.dmAPI.loadCollectionsAPI(); 
 } catch (error) { 
 updateApiSectionStatus('store', 'Not Available', error.message); 
 return; 
 } 
 } 
  
 // Check if storeData method exists 
 if (typeof apiState.collectionsAPI.storeData === 'function') { 
 try { 
 // Try to get a product from the catalog 
 const product = await apiState.collectionsAPI.storeData('catalog_product').pageSize(1).get(); 
 const hasProducts = Array.isArray(product) && product.length > 0; 
  
 // Try to get a category 
 const category = await apiState.collectionsAPI.storeData('catalog_category').pageSize(1).get(); 
 const hasCategories = Array.isArray(category) && category.length > 0; 
  
 if (hasProducts || hasCategories) { 
 updateApiSectionStatus('store', 'Available', 'Store API active'); 
  
 // Display store data info 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="store"] .aog-js-api-section-results'); 
 resultsEl.innerHTML = ''; 
  
 if (hasProducts) { 
 const productEl = document.createElement('div'); 
 productEl.className = 'aog-js-discovered-item'; 
 productEl.textContent = 'Product Catalog Available'; 
 resultsEl.appendChild(productEl); 
 } 
  
 if (hasCategories) { 
 const categoryEl = document.createElement('div'); 
 categoryEl.className = 'aog-js-discovered-item'; 
 categoryEl.textContent = 'Product Categories Available'; 
 resultsEl.appendChild(categoryEl); 
 } 
 } else { 
 updateApiSectionStatus('store', 'Available', 'No products or categories found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('store', 'Not Available', 'Store API error: ' + error.message); 
 } 
 } else { 
 updateApiSectionStatus('store', 'Not Available', 'Store API method not found'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('store', 'Error', error.message); 
 } 
 } 
  
 // Discover dynamic pages 
 async function discoverDynamicPages() { 
 updateApiSectionStatus('dynamicPages', 'Checking...'); 
  
 try { 
 if (!apiState.dynamicPagesAPI) { 
 try { 
 apiState.dynamicPagesAPI = window.dmAPI.dynamicPageApi(); 
 } catch (error) { 
 updateApiSectionStatus('dynamicPages', 'Not Available', error.message); 
 return; 
 } 
 } 
  
 const isDynamic = apiState.dynamicPagesAPI.isDynamicPage(); 
  
 if (isDynamic) { 
 const pageData = await apiState.dynamicPagesAPI.pageData(); 
 updateApiSectionStatus('dynamicPages', 'Active', 'Current page is a dynamic page'); 
  
 // Display dynamic page info 
 const resultsEl = document.querySelector('.aog-js-api-section[data-section="dynamicPages"] .aog-js-api-section-results'); 
 resultsEl.innerHTML = ''; 
  
 if (pageData) { 
 const keysEl = document.createElement('div'); 
 keysEl.className = 'aog-js-discovered-item'; 
 keysEl.textContent = `Available fields: ${Object.keys(pageData).join(', ')}`; 
 resultsEl.appendChild(keysEl); 
 } 
 } else { 
 updateApiSectionStatus('dynamicPages', 'Available', 'Current page is not a dynamic page'); 
 } 
 } catch (error) { 
 updateApiSectionStatus('dynamicPages', 'Error', error.message); 
 } 
 } 
  
 // Setup event listeners 
 debug('Setting up event listeners'); 
  
 // Main button toggle 
 if (explorerButton) { 
 explorerButton.addEventListener('click', togglePanel); 
 } 
  
 // Close button 
 if (closeButton) { 
 closeButton.addEventListener('click', closePanel); 
 } 
  
 // Initialize All APIs button 
 if (initAllBtn) { 
 initAllBtn.addEventListener('click', initAllAPIs); 
 } 
  
 // Content section toggles 
 contentSectionElements.forEach(section => { 
 const headerEl = section.querySelector('.aog-js-content-section-header'); 
 if (headerEl) { 
 headerEl.addEventListener('click', toggleContentSection); 
 } 
 }); 
  
 // Find collection button 
 if (findBtn) { 
 findBtn.addEventListener('click', () => findCollection()); 
 } 
  
 // Collection input enter key 
 if (collectionInput) { 
 collectionInput.addEventListener('keypress', (e) => { 
 if (e.key === 'Enter') { 
 findCollection(); 
 } 
 }); 
 } 
  
 // Store buttons 
 if (loadCatalogBtn) { 
 loadCatalogBtn.addEventListener('click', () => findStoreData('catalog')); 
 } 
  
 if (loadCategoriesBtn) { 
 loadCategoriesBtn.addEventListener('click', () => findStoreData('categories')); 
 } 
  
 // Content Library button 
 if (loadContentLibraryBtn) { 
 loadContentLibraryBtn.addEventListener('click', loadContentLibrary); 
 } 
  
 // Dynamic Pages button 
 if (checkDynamicPageBtn) { 
 checkDynamicPageBtn.addEventListener('click', checkDynamicPage); 
 } 
  
 // Members API button 
 const checkMemberBtn = document.getElementById('aog-js-check-member'); 
 if (checkMemberBtn) { 
 checkMemberBtn.addEventListener('click', checkLoggedInMember); 
 } 
  
 // Sitemap button 
 const fetchSitemapBtn = document.getElementById('aog-js-fetch-sitemap'); 
 if (fetchSitemapBtn) { 
 fetchSitemapBtn.addEventListener('click', fetchSitemap); 
 } 
  
 // Core method buttons 
 methodButtons.forEach(button => { 
 button.addEventListener('click', () => { 
 const method = button.getAttribute('data-method'); 
 if (method) { 
 callCoreMethod(method); 
 } 
 }); 
 }); 
  
 // API Discovery button 
 if (discoverAllBtn) { 
 discoverAllBtn.addEventListener('click', discoverAPIs); 
 } 
  
 // Debug toggle 
 if (debugToggle) { 
 debugToggle.addEventListener('change', toggleDebugMode); 
 } 
  
 // Copy JSON button 
 if (copyJsonBtn) { 
 copyJsonBtn.addEventListener('click', copyJsonToClipboard); 
 } 
  
 // Format JSON button 
 if (formatJsonBtn) { 
 formatJsonBtn.addEventListener('click', formatJson); 
 } 
  
 // Tab switching 
 tabButtons.forEach(button => { 
 button.addEventListener('click', switchTab); 
 }); 
  
 // Show data section by default 
 dataEl.style.display = 'block'; 
  
 // Check if we're on a Duda site 
 checkDudaEnvironment(); 
  
 // Apply style updates 
 applyStyleUpdates(); 
 } 
  
 // Initialize on load 
 if (document.readyState === 'complete' || document.readyState === 'interactive') { 
 // Document already loaded, initialize immediately 
 initEnhancedJSAPIExplorer(); 
 } else { 
 // Wait for document to load 
 document.addEventListener('DOMContentLoaded', initEnhancedJSAPIExplorer); 
 } 
 })(); 
 </script> 
 <!-- JAVASCRIPT SECTION END --> 
 </div> 

Once published, you'll see a little widget appear in the bottom left corner of your page.

Step 4: Extract Your Collection Data

This is the clever bit:

  • Click on the JS API Explorer widget
  • Hit "Discover Available APIs" – this initializes everything
  • Go to the "Collections" tab
  • Type in your collection name ("Team Members")
  • Click "Find"

If you've published your collection properly, you'll see your data appear. Want the full JSON? Click "View Full Data" in the Raw JSON tab and copy the whole thing.

Step 5: The Claude Prompt That Makes Magic

Head over to Claude (if you're an Agency Genius member with our custom instructions installed, this will work even better).

Start your prompt with something like:

Team Member Grid Design Prompt
I want to create a modern, visually stunning team member grid component for my website. The site uses a purple and white color scheme (#ad24a6 as the primary color). I want it to have:
- Smooth hover animations
- Maybe some filtering alphabetically by first name
- A layout that actually looks good on mobile
- Something that feels fresh and modern

Then add this crucial bit:

Collection Integration Prompt Template
I want this component to be powered by a Duda collection called [COLLECTION_NAME]. The widget must work in both the Duda editor and on published live sites.
For the collection integration:
- In the editor, use dmAPI.loadCollectionsAPI() 
- On live sites, check these locations in order:
  1. window.$COLLECTION_DATA[' [COLLECTION_NAME] 
']
  2. window.site_data.collections (find by name)
  3. window.runtime.collections[' [COLLECTION_NAME] 
']
  4. Script tags with data-collection-name=" [COLLECTION_NAME] 
"
- Handle both array format and object with values array
- Show "Loading..." while fetching, and meaningful error messages if collection not found
- Wait for DOM ready and retry once if dmAPI isn't immediately available
Here is the raw JSON for what the collection's output data will typically look like: [PASTE YOUR JSON FROM THE JS API EXPLORER HERE] 

Hit enter and watch Claude create something beautiful.

Step 6: The "Wow" Moment

Copy the code Claude gives you, paste it into an HTML widget on your Duda site, publish, and see your collection data transformed into something special.

But Wait, There's More (The Creative Bit)

Here's where I love to push things further. AI has seen thousands of design patterns and can combine them in ways we might not think of.

So here's your challenge: Once Claude gives you that first design, follow up with:

Alternative Designs Follow-up Prompt
That's really good, thank you! But I'd like you to give me 3-4 different alternative designs using the same color scheme. I want each design to have something unique – maybe something I haven't thought about. Surprise me.

I guarantee you'll get at least one design that makes you think "Oh, I like that approach!"

The Bottom Line

Duda collections are powerful, and now they can be beautiful too. The combination of the JS API Explorer and Claude means you can create collection-powered components that look like they were custom-coded by a developer.

We've all built functional things that we wished looked better. Now we don't have to compromise. We can have both the power of dynamic data and designs that make us proud.

So let's raise the bar together. Let's make collections that make other Duda users ask "How did you do that?"

Now go create something amazing. And when someone asks how you did it, send them this blog.


Want to level up your Duda game even more? Join Agency Genius and get access to our custom Claude instructions, exclusive widgets, and a community of people who love pushing the boundaries of what's possible with Duda.

Join For Free

Become a member today on our free tier and get instant access to 5 custom components.

Recent Posts

A drawing of a person 's head with a bunch of lines coming out of it.
by Callum Wells 9 July 2025
Confused by Duda’s new MCP? Learn what it is, how it works with AI tools like Claude, and why it’s a game-changer for website automation.