PageSourceSearch

https://academiesciencesmoralesetpolitiques.fr/_static/??-eJyFj0kO…/mk4rveH1Wa9a7bNCy6OY+g=

js academiesciencesmoralesetpolitiques.fr collected 2026-10-01 12:19:40 UTC 37,053 bytes, 683 lines download raw bytes

1    // Function to scroll to the div element with the query ID
2    function scrollToQueryId( queryId ) {
3        const targetElement = document.getElementById( `uagb-block-queryid-${queryId}` );
4        
5        if ( targetElement ) {
6            const rect = targetElement.getBoundingClientRect();
7            const adminBar = document.querySelector( '#wpadminbar' );
8            const adminBarOffSetHeight = adminBar?.offsetHeight || 0;
9            const scrollTop = window?.pageYOffset || document?.documentElement?.scrollTop;
10            const targetOffset = ( rect?.top + scrollTop ) - adminBarOffSetHeight;
11
12            window.scrollTo( {
13                top: targetOffset,
14                behavior: 'smooth'
15            } );
16        }
17    }
18
19    /**
20     * Function to find the ancestor with the given class name.
21     *
22     * @param {Element} element   The element.
23     * @param {string}  className The class name.
24     * @return {Element} The element.
25     * @since 1.2.0
26     */
27    function findAncestorWithClass( element, className ) {
28        while ( element && ! element.classList.contains( className ) ) {
29            element = element.parentNode;
30        }
31        return element;
32    }
33
34    document.addEventListener( 'DOMContentLoaded', function () {
35        // Debounce function to limit the rate of execution
36        function debounce( func, wait ) {
37            let timeout;
38
39            return function executedFunction( ...args ) {
40                const context = this;
41                const later = () => {
42                    timeout = null;
43                    func.apply( context, args );
44                };
45
46                clearTimeout( timeout );
47                timeout = setTimeout( later, wait );
48            };
49        };
50
51        // Add functions to store and get active filters
52        function storeActiveFilter( loopBuilder, filterData, filterType ) {
53            if ( loopBuilder && filterData ) {
54                loopBuilder.setAttribute( `data-active-filter-${filterType}`, filterData );
55            }
56        }
57
58        function getActiveFilter( loopBuilder, filterType ) {
59            return loopBuilder?.getAttribute( `data-active-filter-${filterType}` ) || null;
60        }
61
62        /**
63         * Function to update the loop wrapper content
64         * as per data in filters.
65         *
66         * @param {Event}  event               The event.
67         * @param {string} paged               The paged parameter for displaying a particular page on click of pagination links.
68         * @param {string} buttonFilter        The array of selected button value.
69         * @param {string} loopParentContainer The loop parent container.
70         * @return {Promise} The Promise.
71         * @throws {Error} The error.
72         * @since 1.2.0
73         */
74        async function updateContent( event, paged = null, buttonFilter = null, loopParentContainer ) {
75            try {
76                const loopBuilder = loopParentContainer;
77                const formData = new FormData();
78
79                // Get all form data
80                const search = loopBuilder?.querySelector( '.uagb-loop-search' )?.value || '';
81                const sorting = loopBuilder?.querySelector( '.uagb-loop-sort' )?.value || '';
82                
83                // Get category select value
84                const categorySelect = loopBuilder?.querySelector( '.uagb-loop-category' );
85                if ( categorySelect?.value ) {
86                    formData.append( 'category', categorySelect.value );
87                    storeActiveFilter( loopBuilder, categorySelect.value, 'select' );
88                } else {
89                    // Try to get stored select filter
90                    const storedSelectFilter = getActiveFilter( loopBuilder, 'select' );
91                    if ( storedSelectFilter ) {
92                        formData.append( 'category', storedSelectFilter );
93                    }
94                }
95
96                // Handle checkboxes
97                const checkBoxValues = loopBuilder?.querySelectorAll( '.uagb-cat-checkbox' );
98                const checkedValues = [];
99                checkBoxValues?.forEach( checkBox => {
100                    if ( checkBox.checked && checkBox.getAttribute( 'data-uagb-block-query-id' ) === event.target.dataset.uagbBlockQueryId ) {
101                        checkedValues.push( checkBox.value );
102                    }
103                } );
104                
105                // Handle button filter
106                let activeButtonData = getActiveFilter( loopBuilder, 'button' );
107                if ( ! activeButtonData && buttonFilter?.type ) {
108                    activeButtonData = buttonFilter.type;
109                    storeActiveFilter( loopBuilder, activeButtonData, 'button' );
110                }
111
112                // Clear all filters first
113                formData.delete( 'buttonFilter' );
114                formData.delete( 'checkbox' );
115                formData.delete( 'category' );
116                loopBuilder.removeAttribute( 'data-active-filter-checkbox' );
117                loopBuilder.removeAttribute( 'data-active-filter-select' );
118                loopBuilder.removeAttribute( 'data-active-filter-button' );
119
120                // Handle filters based on the event target
121                if ( event.target.classList.contains( 'uagb-cat-checkbox' ) ) {
122                    // Checkbox was clicked - clear select and apply checkbox
123                    if ( categorySelect ) categorySelect.value = '';
124                    formData.append( 'checkbox', checkedValues );
125                    storeActiveFilter( loopBuilder, JSON.stringify( checkedValues ), 'checkbox' );
126                } else if ( event.target.classList.contains( 'uagb-loop-category' ) ) {
127                    // Select was changed - clear checkboxes and apply select
128                    checkBoxValues?.forEach( checkBox => {
129                        if ( checkBox.getAttribute( 'data-uagb-block-query-id' ) === event.target.dataset.uagbBlockQueryId ) {
130                            checkBox.checked = false;
131                        }
132                    } );
133                    formData.append( 'category', categorySelect.value );
134                    storeActiveFilter( loopBuilder, categorySelect.value, 'select' );
135                } else if ( buttonFilter?.type ) {
136                    // Button was clicked - clear select and checkboxes
137                    if ( categorySelect ) categorySelect.value = '';
138                    checkBoxValues?.forEach( checkBox => {
139                        if ( checkBox.getAttribute( 'data-uagb-block-query-id' ) === event.target.dataset.uagbBlockQueryId ) {
140                            checkBox.checked = false;
141                        }
142                    } );
143                    formData.append( 'buttonFilter', buttonFilter.type );
144                    storeActiveFilter( loopBuilder, buttonFilter.type, 'button' );
145                }
146
147                // Add other form data
148                if ( search ) {
149                    formData.append( 'search', search );
150                }
151                if ( sorting ) {
152                    formData.append( 'sorting', sorting );
153                }
154                if ( paged ) {
155                    formData.append( 'paged', paged );
156                }
157
158                let queryId = null;
159                if ( buttonFilter?.type === 'all' ) {
160                    const el = document.querySelector( '[data-query-id]' );
161                    if ( el ) {
162                        queryId = el.getAttribute( 'data-query-id' );
163                      } else {
164                        queryId = 0; // fallback to default
165                      }                    
166                    
167                } else {
168                    // Get query ID
169                    queryId = event.target?.dataset?.uagbBlockQueryId || 
170                               event.target?.parentElement?.dataset?.uagbBlockQueryId || 
171                               event?.dataset?.uagbBlockQueryId || 
172                               event.target.closest( 'a' )?.getAttribute( 'data-uagb-block-query-id' ) || 0;
173                }
174
175                // Scroll to the query ID
176                scrollToQueryId( queryId );
177
178                formData.append( 'queryId', queryId );
179                formData.append( 'block_id', loopBuilder?.getAttribute( 'data-block_id' ) );
180                formData.append( 'action', 'uagb_update_loop_builder_content' );
181                formData.append( 'postId', uagb_loop_builder.post_id );
182                formData.append( 'postType', uagb_loop_builder.post_type );
183                formData.append( 'security', uagb_loop_builder.nonce );
184
185                // Log the complete form data
186                const formDataObj = {};
187                formData.forEach( ( value, key ) => {
188                    formDataObj[key] = value;
189                } );
190                
191                const output = await getUpdatedLoopWrapperContent( formData );
192                
193                // Update content
194                if ( output?.content?.wrapper ) {
195                    const loopElement = loopBuilder?.querySelector( '#uagb-block-queryid-' + queryId );
196                    if ( loopElement ) {
197                        loopElement.innerHTML = output.content.wrapper;
198                    }
199                }
200                
201                // Update pagination
202                if ( output?.content?.pagination ) {
203                    const paginationElements = loopBuilder?.querySelectorAll( '#uagb-block-pagination-queryid-' + queryId );
204                    paginationElements?.forEach( element => {
205                        element.innerHTML = output.content.pagination;
206                    } );
207                }
208
209            } catch ( error ) {
210                throw error;
211            }
212        }
213
214        /**
215         * Handles the input event for the search functionality within the UAGB Loop Builder block.
216         * Synchronizes input values across all search inputs within the same loop builder container
217         * and triggers a content update.
218         *
219         * @param {Event} event - The input event triggered by the user.
220         * @since 1.2.0
221         */
222        function handleInput( event ) {
223            const loopParentContainer = this.closest( '.wp-block-uagb-loop-builder' );
224            const searchInputs = loopParentContainer.querySelectorAll( '.uagb-loop-search' );
225            searchInputs.forEach( searchInput => {
226                if( searchInput.getAttribute( 'data-uagb-block-query-id' ) === event.target.dataset.uagbBlockQueryId ){
227                    searchInput.value = event.target.value;
228                }
229            } );
230            updateContent( event, null, null, loopParentContainer );
231        }
232
233        /**
234         * Handles the checkbox selection within the UAGB Loop Builder block.
235         * Collects the values of all checked checkboxes that match the block query ID 
236         * and triggers a content update.
237         *
238         * @param {Event} event - The change event triggered by the user when interacting with a checkbox.
239         * @since 1.2.0
240         */
241        function handleCheckBoxVal( event ) {
242            const loopParentContainer = this.closest( '.wp-block-uagb-loop-builder' );
243            const checkBoxValues = loopParentContainer.querySelectorAll( '.uagb-cat-checkbox' );
244            // Initialize an array to store checked checkbox values.
245            const checkedValues = [];
246            checkBoxValues.forEach( checkBoxVal => {
247                // Check if the checkbox is checked.
248                const isChecked = checkBoxVal.checked;
249                if ( isChecked && checkBoxVal.getAttribute( 'data-uagb-block-query-id' ) === event.target.dataset.uagbBlockQueryId ) {
250                    // Add the value to the array.
251                    checkedValues.push( checkBoxVal.value );
252                }
253            } );
254            
255            // Always update content when checkbox state changes, even if no checkboxes are checked
256            updateContent( event, null, null, loopParentContainer );
257        }
258
259        /**
260         * Handles the selection event on the search filter.
261         * Updates the value of all relevant search filter elements with the same query ID and triggers content update.
262         *
263         * @param {Event} event - The select event triggered by the user interaction.
264         * @since 1.2.0
265         */
266        function handleSelect( event ) {
267            const loopParentContainer = this.closest( '.wp-block-uagb-loop-builder' );
268            const sortSelects = loopParentContainer.querySelectorAll( '.uagb-loop-sort' );
269            sortSelects.forEach( sortSelect => {
270                if( sortSelect.getAttribute( 'data-uagb-block-query-id' ) === event.target.dataset.uagbBlockQueryId ){
271                    sortSelect.value = event.target.value;
272                }
273            } );
274            updateContent( event, null, null, loopParentContainer );
275        }
276
277        /**
278         * Handles the category selection event on a dropdown filter.
279         * Updates the value of all relevant category select elements with the same query ID and triggers content update.
280         *
281         * @param {Event} event - The select event triggered by the user interaction.
282         * @since 1.2.0
283         */
284        function handleCatSelect( event ) {
285            const loopParentContainer = this.closest( '.wp-block-uagb-loop-builder' );
286            const categorySelects = loopParentContainer.querySelectorAll( '.uagb-loop-category' );
287            categorySelects.forEach( categorySelect => {
288                if ( categorySelect.getAttribute( 'data-uagb-block-query-id' ) === event.target.dataset.uagbBlockQueryId ) {
289                    categorySelect.value = event.target.value;
290                }
291            } );
292            
293            // If "all" or empty value is selected, clear the stored filter
294            if ( !event.target.value || event.target.value === '' || event.target.value === 'all' ) {
295                loopParentContainer.removeAttribute( 'data-active-filter-select' );
296            }
297            
298            updateContent( event, null, null, loopParentContainer );
299        }
300
301        /**
302         * Resets the values of elements within a container based on their query ID.
303         *
304         * @param {HTMLElement} container     - The container element to search within.
305         * @param {string}      selector      - The CSS selector for the elements to reset.
306         * @param {string}      queryId       - The query ID to match.
307         * @param {Function}    resetCallback - A callback function to apply the reset logic to each element.
308         * @since 1.2.0
309         */
310        function resetValues( container, selector, queryId, resetCallback ) {
311            const elements = container.querySelectorAll( selector );
312            elements.forEach( element => {
313                const elementQueryId = element.dataset.uagbBlockQueryId;
314                if ( elementQueryId === queryId ) {
315                    resetCallback( element );
316                }
317            } );
318        }
319
320        /**
321         * Handles the reset event for all filters within the loop builder block.
322         * Resets the values of search inputs, sort selects, category selects, and checkboxes to their default state.
323         *
324         * @param {Event} event - The reset event triggered by the user interaction.
325         * @since 1.2.0
326         */
327        function handleReset( event ) {
328            const loopParentContainer = this.closest( '.wp-block-uagb-loop-builder' );
329                // Get the query ID from the event target
330                let queryId = event.target.parentElement.dataset.uagbBlockQueryId;
331                if ( event.target.tagName.toLowerCase() === 'a' ) {
332                    queryId = event.target.dataset.uagbBlockQueryId;
333                } else if ( event.target.tagName.toLowerCase() === 'svg' || event.target.tagName.toLowerCase() === 'path' ) {
334                    queryId = event.target.closest( 'a' )?.getAttribute( 'data-uagb-block-query-id' );
335                }
336
337                // Reset the value of the filter inputs
338                const loopBuilder = findAncestorWithClass( event.target.parentNode, 'wp-block-uagb-loop-builder' );
339
340                resetValues( loopBuilder, '.uagb-loop-search', queryId, element => {
341                    element.value = ''; // Reset search input value
342                } );
343
344                resetValues( loopBuilder, '.uagb-loop-sort', queryId, element => {
345                    element.value = ''; // Reset sort select value
346                } );
347
348                resetValues( loopBuilder, '.uagb-loop-category', queryId, element => {
349                    element.value = ''; // Reset category select value
350                } );
351
352                resetValues( loopBuilder, '.uagb-cat-checkbox', queryId, element => {
353                    element.checked = false; // Uncheck category checkbox
354                } );
355
356                // Clear all stored filter data attributes
357                if ( loopBuilder ) {
358                    loopBuilder.removeAttribute( 'data-active-filter-select' );
359                    loopBuilder.removeAttribute( 'data-active-filter-checkbox' );
360                    loopBuilder.removeAttribute( 'data-active-filter-button' );
361                }
362
363                // Trigger the updateContent function to reflect the changes
364                updateContent( event, null, null, loopParentContainer );
365        }
366
367        const resetButtons = document.querySelectorAll( '.uagb-loop-reset' );
368
369        const searchInputs = document.querySelectorAll( '.uagb-loop-search' );
370
371        searchInputs.forEach( searchInput => {
372            const debouncedHandleInput = debounce( handleInput, 250 );
373            searchInput.addEventListener( 'input', debouncedHandleInput );
374        } );
375
376        const sortSelects = document.querySelectorAll( '.uagb-loop-sort' );
377
378        sortSelects.forEach( sortSelect => {
379            const debouncedHandleInput = debounce( handleSelect, 250 );
380            sortSelect.addEventListener( 'change', debouncedHandleInput );
381        } );
382
383        const categorySelects = document.querySelectorAll( '.uagb-loop-category' );
384
385        categorySelects.forEach( categorySelect => {
386            const debouncedHandleInput = debounce( handleCatSelect, 250 );
387            categorySelect.addEventListener( 'change', debouncedHandleInput );
388        } );
389
390        // Get a reference to the checkbox element.
391        const checkBoxValues = document.querySelectorAll( '.uagb-cat-checkbox' );
392        checkBoxValues.forEach( checkBoxVal => {
393            const debouncedHandleInput = debounce( handleCheckBoxVal, 250 );
394            checkBoxVal.addEventListener( 'click', debouncedHandleInput );
395        } );
396
397        resetButtons.forEach( resetButton => {
398            const debouncedHandleReset = debounce( handleReset, 250 );
399            resetButton.addEventListener( 'click', debouncedHandleReset );
400        } );
401        
402        const oldPaginations = document.querySelectorAll( '.wp-block-uagb-loop-builder >
402 :not(.uagb-loop-pagination).wp-block-uagb-buttons' );
403
404        oldPaginations?.forEach( function( container ) {
405            // Create a new div with class "parent-container"
406            const parentContainer = document.createElement( 'div' );
407            parentContainer.classList.add( 'uagb-loop-pagination' );
408            const queryIdPAginationLink = container.querySelector( 'a' ).getAttribute( 'data-uagb-block-query-id' );
409            parentContainer.id = 'uagb-block-pagination-queryid-'+queryIdPAginationLink;
410
411             // Append the container content to the new div
412             parentContainer.innerHTML = container.outerHTML;
413
414             // Append the new div after the original container
415             container.parentNode.insertBefore( parentContainer, container.nextSibling );
416
417             // Remove the original container
418             container.parentNode.removeChild( container );
419        } );
420
421        const paginationContainer = document.querySelectorAll( '.uagb-loop-pagination' );
422
423        paginationContainer.forEach( pagination => {
424            pagination.addEventListener( 'click', function( event ) {
425                event.preventDefault();
426                const loopParentContainer = this.closest( '.wp-block-uagb-loop-builder' );
427                
428                const paged = event.target.dataset.uagbBlockQueryPaged || 
429                             event.target.parentElement.dataset.uagbBlockQueryPaged ||
430                             event?.target?.closest( 'a' )?.getAttribute( 'data-uagb-block-query-paged' );
431
432                // Get all active filter data
433                const activeButtonData = getActiveFilter( loopParentContainer, 'button' );
434                const activeSelectData = getActiveFilter( loopParentContainer, 'select' );
435                const activeCheckboxData = getActiveFilter( loopParentContainer, 'checkbox' );
436
437                // Create form data based on active filter
438                const formData = new FormData();
439                
440                // Add pagination
441                if ( paged ) {
442                    formData.append( 'paged', paged );
443                }
444
445                // Add active filter based on type
446                if ( activeButtonData ) {
447                    formData.append( 'buttonFilter', activeButtonData );
448                } else if ( activeSelectData ) {
449                    formData.append( 'category', activeSelectData );
450                } else if ( activeCheckboxData ) {
451                    formData.append( 'checkbox', activeCheckboxData );
452                }
453
454                // Add other required data
455                formData.append( 'queryId', event.target.dataset.uagbBlockQueryId || 
456                    event.target.parentElement.dataset.uagbBlockQueryId || 
457                    event?.target?.closest( 'a' )?.getAttribute( 'data-uagb-block-query-id' ) || 0 );
458                formData.append( 'block_id', loopParentContainer?.getAttribute( 'data-block_id' ) );
459                formData.append( 'action', 'uagb_update_loop_builder_content' );
460                formData.append( 'postId', uagb_loop_builder.post_id );
461                formData.append( 'postType', uagb_loop_builder.post_type );
462                formData.append( 'security', uagb_loop_builder.nonce );
463
464                // Get search and sorting values if they exist
465                const search = loopParentContainer?.querySelector( '.uagb-loop-search' )?.value || '';
466                const sorting = loopParentContainer?.querySelector( '.uagb-loop-sort' )?.value || '';
467
468                if ( search ) {
469                    formData.append( 'search', search );
470                }
471                if ( sorting ) {
472                    formData.append( 'sorting', sorting );
473                }
474
475                // Make the AJAX request
476                getUpdatedLoopWrapperContent( formData )
477                    .then( output => {
478                        if ( output?.content?.wrapper ) {
479                            const loopElement = loopParentContainer?.querySelector( '#uagb-block-queryid-' + formData.get( 'queryId' ) );
480                            if ( loopElement ) {
481                                loopElement.innerHTML = output.content.wrapper;
482                            }
483                        }
484                        if ( output?.content?.pagination ) {
485                            const paginationElements = loopParentContainer?.querySelectorAll( '#uagb-block-pagination-queryid-' + formData.get( 'queryId' ) );
486                            paginationElements?.forEach( element => {
487                                element.innerHTML = output.content.pagination;
488                            } );
489                        }
490                    } )
491                    .catch( error => {
492                        throw error; // Propagate the error
493                    } );
494            } );
495        } );
496
497        const categoryButtonFilterContainer = document.querySelectorAll( '.uagb-loop-category-inner a' );
498
499        categoryButtonFilterContainer.forEach( ( buttons ) => {
500            buttons.addEventListener( 'click', function ( event ) {
501                event.preventDefault();
502                const loopParentContainer = this.closest( '.wp-block-uagb-loop-builder' );
503                let buttonData = null;
504                
505                if ( event.target.tagName.toLowerCase() === 'a' ) {
506                    buttonData = event.target.children[0].dataset.type;
507                } else if ( event.target.tagName.toLowerCase() === 'div' && event.target.parentElement.tagName.toLowerCase() === 'a' ) {
508                    buttonData = event.target.dataset.type;
509                }
510                
511                // Uncheck all checkboxes when a button is clicked
512                checkBoxValues?.forEach( checkBox => {
513                    checkBox.checked = false;
514                } );
515                
516                // Check if "all" button was clicked.
517                if ( buttonData === 'all' || buttonData === undefined ) {
518                    // Clear stored button filter.
519                    loopParentContainer.removeAttribute( 'data-active-filter-button' );
520                    // Update content with all type.
521                    updateContent( event, null, { type: 'all' }, loopParentContainer );
522                } else if ( buttonData ) {
523                    storeActiveFilter( loopParentContainer, buttonData, 'button' );
524                    updateContent( event, null, { type: buttonData }, loopParentContainer );
525                }
526            } );
527        } );
528    } );
529
530    /**
531     * Function to get the updated loop wrapper content.
532     * as per data in filters.
533     *
534     * @param {FormData} data The form data.
535     * @since 1.2.0
536     * @return {Promise} The Promise.
537     */
538    function getUpdatedLoopWrapperContent( data ) {
539        // Create a new FormData object
540        data.append( 'action', 'uagb_update_loop_builder_content' );
541        data.append( 'postId', uagb_loop_builder?.post_id );
542        data.append( 'postType', uagb_loop_builder?.what_post_type );
543        data.append( 'security', uagb_loop_builder?.nonce )
544
545        // The function now returns a Promise
546        return fetch( uagb_loop_builder?.ajax_url, {
547            method: 'POST',
548            credentials: 'same-origin',
549            body: data,
550        } )
551        .then( response => {
552            if ( ! response.ok ) {
553                throw new Error( 'Network response was not ok' );
554            }
555            return response.json();
556        } )
557        .then( output => {
558            if ( output.success ) {
559                // Return the actual output.
560                return output.data;
561            }
562                throw new Error( output.data.message );
563
564        } )
565        .catch( error => {
566            throw error; // Propagate the error
567        } );
568    };
569/**
570 * navigation.js
571 *
572 * Handles toggling the navigation menu for small screens.
573 */
574( function() {
575	var container, button, menu;
576
577	container = document.getElementById( 'site-navigation' );
578	if ( ! container )
579		return;
580
581	button = container.getElementsByClassName( 'menu-toggle' )[0];
582	if ( 'undefined' === typeof button )
583		return;
584
585	menu = container.getElementsByTagName( 'ul' )[0];
586
587	// Hide menu toggle button if menu is empty and return early.
588	if ( 'undefined' === typeof menu ) {
589		button.style.display = 'none';
590		return;
591	}
592
593	if ( -1 === menu.className.indexOf( 'nav-menu' ) )
594		menu.className += 'nav-menu';
595
596	button.onclick = function() {
597		if ( -1 !== container.className.indexOf( 'main-small-navigation' ) )
598			container.className = container.className.replace( 'main-small-navigation', 'main-navigation' );
599		else
600			container.className = container.className.replace( 'main-navigation', 'main-small-navigation' );
601	};
602
603   /**
604    * Toggles `focus` class to allow submenu access on tablets.
605    */
606   ( function( container ) {
607      var touchStartFn, i,
608         parentLink = container.querySelectorAll( '.menu-item-has-children > a, .page_item_has_children > a' );
609
610      if ( 'ontouchstart' in window ) {
611         touchStartFn = function( e ) {
612            var menuItem = this.parentNode, i;
613
614            if ( ! menuItem.classList.contains( 'focus' ) ) {
615               e.preventDefault();
616               for ( i = 0; i < menuItem.parentNode.children.length; ++i ) {
617                  if ( menuItem === menuItem.parentNode.children[i] ) {
618                     continue;
619                  }
620                  menuItem.parentNode.children[i].classList.remove( 'focus' );
621               }
622               menuItem.classList.add( 'focus' );
623            } else {
624               menuItem.classList.remove( 'focus' );
625            }
626         };
627
628         for ( i = 0; i < parentLink.length; ++i ) {
629            parentLink[i].addEventListener( 'touchstart', touchStartFn, false );
630         }
631      }
632   }( container ) );
633} )();
634;
635( function() {
636	var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1,
637	    is_opera  = navigator.userAgent.toLowerCase().indexOf( 'opera' )  > -1,
638	    is_ie     = navigator.userAgent.toLowerCase().indexOf( 'msie' )   > -1;
639
640	if ( ( is_webkit || is_opera || is_ie ) && 'undefined' !== typeof( document.getElementById ) ) {
641		var eventMethod = ( window.addEventListener ) ? 'addEventListener' : 'attachEvent';
642		window[ eventMethod ]( 'hashchange', function() {
643			var element = document.getElementById( location.hash.substring( 1 ) );
644
645			if ( element ) {
646				if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) )
647					element.tabIndex = -1;
648
649				element.focus();
650			}
651		}, false );
652	}
653})();
654;
655// For compatibility with optimizers
656if (document.readyState !== 'loading') {
657    //console.log('Newsletter loaded (late)');
658    tnp_ajax_init();
659} else {
660    document.addEventListener("DOMContentLoaded", function () {
661        //console.log('Newsletter loaded');
662        tnp_ajax_init();
663    });
664}
665
666function tnp_ajax_init() {
667    document.querySelectorAll('form.tnp-ajax').forEach(el => {
668        el.addEventListener('submit', async function(ev) {
669            ev.preventDefault();
670            ev.stopPropagation();
671            const response = await fetch(newsletter_data.action_url + '?action=tnp&na=sa', {
672                method: "POST",
673                body: new FormData(this)
674            });
675            this.innerHTML = await response.text();
676        });
677    });
678}
679
680
681
682;
683(()=>{var e=[],t=!1,n=2e3,i=[],o=new Promise(e=>{"loading"!==document.readyState?e():window.addEventListener("DOMContentLoaded",()=>e())});function s(e,t){if("string"==typeof e)try{e=JSON.parse(e)}catch{return}if(t&&"function"==typeof t.postMessage)try{t.postMessage(JSON.stringify({type:"likesMessage",data:e}),"*")}catch{}}function r(){const t=[];document.querySelectorAll("div.jetpack-likes-widget-unloaded").forEach(n=>{if(!(e.indexOf(n.id)>-1)&&d(n)){e.push(n.id);var i,o=/like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/.exec(n.id);o&&5===o.length&&(i={blog_id:o[2],width:n.width},"post"===o[1]?i.post_id=o[3]:"comment"===o[1]&&(i.comment_id=o[3]),i.obj_id=o[4],t.push(i))}}),t.length>0&&s({event:"initialBatch",requests:t},window.frames["likes-master"])}function a(){const e=document.querySelector("#likes-other-gravatars");if(e){e.style.display="none",e.setAttribute("aria-hidden","true");const t=e.__resizeHandler;t&&(window.removeEventListener("resize",t),delete e.__resizeHandler)}}function l(){var e;if(!t)return s({event:"queryMasterReady"},window.frames["likes-master"]),void setTimeout(l,500);!function(){for(let e=i.length-1;e>=0;e--){const t=i[e];if(!d(t)){const n=t&&t.parentElement&&t.parentElement.parentElement;n.classList.remove("jetpack-likes-widget-loaded"),n.classList.remove("jetpack-likes-widget-loading"),n.classList.add("jetpack-likes-widget-unloaded");const o=n.querySelector(".likes-widget-placeholder");o&&(o.style.display=""),i.splice(e,1),t.remove()}}}(),function(){if(!g)return;document.querySelectorAll("div.jetpack-likes-widget-unloaded").forEach(e=>g.observe(e))}();var n=[...document.querySelectorAll("div.jetpack-likes-widget-unloaded")].filter(e=>d(e));n.length>0&&r();for(var o=0,a=n.length;o<=a-1;o++)(e=n[o].id)&&c(e)}function c(e){if(void 0===e)return;const t=document.querySelector("#"+e);t.querySelectorAll("iframe").forEach(e=>e.remove());const n=t.querySelector(".likes-widget-placeholder");if(n&&n.classList.contains("post-likes-widget-placeholder")){const e=document.createElement("iframe");e.classList.add("post-likes-widget","jetpack-likes-widget"),e.name=t.dataset.name,e.src=t.dataset.src,e.height="55px",e.width="100%",e.frameBorder="0",e.scrolling="no",e.title=t.dataset.title,n.after(e)}if(n.classList.contains("comment-likes-widget-placeholder")){const e=document.createElement("iframe");e.class="comment-likes-widget-frame jetpack-likes-widget-frame",e.name=t.dataset.name,e.src=t.dataset.src,e.height="18px",e.width="100%",e.frameBorder="0",e.scrolling="no",t.querySelector(".comment-like-feedback").after(e),i.push(e)}t.classList.remove("jetpack-likes-widget-unloaded"),t.classList.add("jetpack-likes-widget-loading"),t.querySelector("iframe").addEventListener("load",e=>{t.contains(e.target)&&(s({event:"loadLikeWidget",name:e.target.name,width:e.target.width},window.frames["likes-master"]),n&&(n.style.display="none"),t.classList.remove("jetpack-likes-widget-loading"),t.classList.add("jetpack-likes-widget-loaded"))})}function d(e){const t=e.getBoundingClientRect().top,i=e.getBoundingClientRect().bottom;return t+n>=0&&i<=window.innerHeight+n}window.addEventListener("message",function(e){let n=e&&e.data;if("string"==typeof n)try{n=JSON.parse(n)}catch{return}const i=n&&n.type,l=n&&n.data;if("likesMessage"!==i||void 0===l.event)return;if("https://widgets.wp.com"===e.origin)switch(l.event){case"masterReady":o.then(()=>{t=!0;const e={event:"injectStyles"},n=document.querySelector(".sd-text-color"),i=document.querySelector(".sd-link-color"),o=n&&getComputedStyle(n)||{},a=i&&getComputedStyle(i)||{};document.body.classList.contains("single")&&s({event:"reblogsEnabled"},window.frames["likes-master"]),e.textStyles={color:o.color,fontFamily:o["font-family"],fontSize:o["font-size"],direction:o.direction,fontWeight:o["font-weight"],fontStyle:o["font-style"],textDecoration:o["text-decoration"]},e.linkStyles={color:a.color,fontFamily:a["font-family"],fontSize:a["font-size"],textDecoration:a["text-decoration"],fontWeight:a["font-weight"],fontStyle:a["font-style"]},s(e,window.frames["likes-master"]),r()});break;case"showLikeWidget":case"showCommentLikeWidget":break;case"killCommentLikes":document.querySelectorAll(".jetpack-comment-likes-widget-wrapper").forEach(e
683=>e.remove());break;case"clickReblogFlair":wpcom_reblog&&"function"==typeof wpcom_reblog.toggle_reblog_box_flair&&wpcom_reblog.toggle_reblog_box_flair(l.obj_id);break;case"hideOtherGravatars":a();break;case"showOtherGravatars":{const e=document.querySelector("#likes-other-gravatars");if(!e)break;const t=e.querySelector("ul");e.style.display="none",t.innerHTML="",e.querySelectorAll(".likes-text span").forEach(e=>e.textContent=l.totalLikesLabel),(l.likers||[]).forEach(async(e,n)=>{if("http"!==e.profile_URL.substr(0,4))return;const i=document.createElement("li");t.append(i);const o=encodeURI(e.profile_URL),r=encodeURI(e.avatar_URL);i.innerHTML=`<a href="${o}" rel="nofollow" target="_parent" class="wpl-liker">\n\t\t\t\t\t\t<img src="${r}"\n\t\t\t\t\t\t\talt=""\n\t\t\t\t\t\t\tstyle="width: 28px; height: 28px;" />\n\t\t\t\t\t\t<span></span>\n\t\t\t\t\t</a>`,i.classList.add(e.css_class),i.querySelector("img").alt=l.avatarAltTitle.replace("%s",e.name),i.querySelector("span").innerText=e.name,n===l.likers.length-1&&i.addEventListener("keydown",e=>{"Tab"!==e.key||e.shiftKey||(e.preventDefault(),a(),s({event:"focusLikesCount",parent:l.parent},window.frames["likes-master"]))})});const n=function(){const t="rtl"===getComputedStyle(e).direction,n=document.querySelector(`*[name='${l.parent}']`),i=n.getBoundingClientRect(),o=n.ownerDocument.defaultView,s=i.top+o.pageYOffset,r=i.left+o.pageXOffset;let a;if(e.style.top=s+l.position.top-1+"px",t){const t=l&&l.likers?Math.min(l.likers.length,5):0;a=r+l.position.left+24*t+4,e.style.transform="translateX(-100%)"}else a=r+l.position.left;e.style.left=a+"px",e.style.left="-9999px",e.style.display="block";const c=e.offsetWidth;a+c>o.innerWidth&&(a=i.right-c),e.style.left=a+"px",e.setAttribute("aria-hidden","false")};n(),e.focus();const i=function(e,t){var n;return function(){var i=this,o=arguments;clearTimeout(n),n=setTimeout(function(){e.apply(i,o)},t)}},o=i(n,100);e.__resizeHandler=o,window.addEventListener("resize",o),e.focus()}}}),document.addEventListener("click",a);var f,m,u,p=(f=250,m=l,function(){clearTimeout(u),u=setTimeout(m,f)}),g="function"==typeof IntersectionObserver?new IntersectionObserver(p,{rootMargin:"2000px",threshold:[0,1]}):null;l(),window.addEventListener("scroll",p,!0)})();;

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