PageSourceSearch

https://o.toplist.cz/js/main.bundle.min.7363f908f16078b55f7176aefc6ad4a24c7df78bde276b77e7afa2010d37cae5.js

js toplist.cz collected 2026-10-01 09:10:40 UTC 286,958 bytes, 411 lines download raw bytes

1/*!
2  * Bootstrap v5.3.2 (https://getbootstrap.com/)
3  * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5  */const alert=document.getElementById("page-alert"),closeBtn=document.getElementById("page-alert-btn-close");if(alert!==null&&closeBtn!==null){const version=alert.getAttribute("data-page-alert-version")||"unknown",hideAlert=sessionStorage.getItem(`page-alert-${version}`)!==null;hideAlert&&alert.classList.add("d-none"),closeBtn.addEventListener("click",()=>{sessionStorage.setItem(`page-alert-${version}`,"seen"),alert.classList.add("d-none")})}function reveal(){const reveals=document.querySelectorAll(".reveal");for(let i=0;i<reveals.length;i++){const windowHeight=window.innerHeight,elementTop=reveals[i].getBoundingClientRect().top,elementVisible=150;elementTop<windowHeight-elementVisible?(reveals[i].classList.add("active"),reveals[i].classList.remove("reveal")):reveals[i].classList.remove("active")}}window.addEventListener("scroll",reveal);const svgCopy='<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="16" height="16" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16"><path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/><path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/></svg>',svgCheck='<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" fill="rgb(63, 185, 80)" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>',addCopyButtons=clipboard=>{document.querySelectorAll("pre > code").forEach(codeBlock=>{const button=document.createElement("button");button.className="clipboard-button",button.setAttribute("data-toast-target","toast-copied-code-message"),button.setAttribute("aria-label","kopírovat do schránky"),button.type="button",button.innerHTML=svgCopy,button.addEventListener("click",()=>{const text=codeBlock.innerText.split(`
6`).filter(Boolean).join(`
7`);clipboard.writeText(text).then(()=>{button.blur(),button.innerHTML=svgCheck,setTimeout(()=>button.innerHTML=svgCopy,2e3)},error=>button.innerHTML="Error")});const pre=codeBlock.parentNode;pre.parentNode.insertBefore(button,pre)})};navigator&&navigator.clipboard&&addCopyButtons(navigator.clipboard),document.querySelectorAll("[data-clipboard]").forEach(trigger=>{const text=trigger.getAttribute("data-clipboard");trigger.addEventListener("click",()=>{navigator.clipboard.writeText(text)})});const url=new URL(window.location.href),menu=url.searchParams.get("menu"),child=url.searchParams.get("child"),menuItems=document.querySelectorAll('[data-nav="main"]');if(menu!==null){menuItems.forEach(element=>{element.classList.remove("active")});const targetMainItems=document.querySelectorAll(`[data-nav-main="${menu}"]:not([data-nav-child])`);targetMainItems.forEach(element=>{element.classList.add("active")});const targetChildItems=document.querySelectorAll(`[data-nav-main="${menu}"][data-nav-child="${child}"]`);targetChildItems.forEach(element=>{element.classList.add("active")})}(function(global,factory){typeof exports=="object"&&typeof module!="undefined"?module.exports=factory():typeof define=="function"&&define.amd?define(factory):(global=typeof globalThis!="undefined"?globalThis:global||self,global.bootstrap=factory())})(this,function(){"use strict";const elementMap=new Map,Data={set(element,key,instance){elementMap.has(element)||elementMap.set(element,new Map);const instanceMap=elementMap.get(element);if(!instanceMap.has(key)&&instanceMap.size!==0){console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);return}instanceMap.set(key,instance)},get(element,key){return elementMap.has(element)?elementMap.get(element).get(key)||null:null},remove(element,key){if(!elementMap.has(element))return;const instanceMap=elementMap.get(element);instanceMap.delete(key),instanceMap.size===0&&elementMap.delete(element)}},MAX_UID=1e6,MILLISECONDS_MULTIPLIER=1e3,TRANSITION_END="transitionend",parseSelector=selector=>(selector&&window.CSS&&window.CSS.escape&&(selector=selector.replace(/#([^\s"#']+)/g,(match,id)=>`#${CSS.escape(id)}`)),selector),toType=object=>object==null?`${object}`:Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase(),getUID=prefix=>
7{do prefix+=Math.floor(Math.random()*MAX_UID);while(document.getElementById(prefix))return prefix},getTransitionDurationFromElement=element=>{if(!element)return 0;let{transitionDuration,transitionDelay}=window.getComputedStyle(element);const floatTransitionDuration=Number.parseFloat(transitionDuration),floatTransitionDelay=Number.parseFloat(transitionDelay);return!floatTransitionDuration&&!floatTransitionDelay?0:(transitionDuration=transitionDuration.split(",")[0],transitionDelay=transitionDelay.split(",")[0],(Number.parseFloat(transitionDuration)+Number.parseFloat(transitionDelay))*MILLISECONDS_MULTIPLIER)},triggerTransitionEnd=element=>{element.dispatchEvent(new Event(TRANSITION_END))},isElement$1=object=>!!object&&typeof object=="object"&&(typeof object.jquery!="undefined"&&(object=object[0]),typeof object.nodeType!="undefined"),getElement=object=>isElement$1(object)?object.jquery?object[0]:object:typeof object=="string"&&object.length>0?document.querySelector(parseSelector(object)):null,isVisible=element=>{if(!isElement$1(element)||element.getClientRects().length===0)return!1;const elementIsVisible=getComputedStyle(element).getPropertyValue("visibility")==="visible",closedDetails=element.closest("details:not([open])");if(!closedDetails)return elementIsVisible;if(closedDetails!==element){const summary=element.closest("summary");if(summary&&summary.parentNode!==closedDetails)return!1;if(summary===null)return!1}return elementIsVisible},isDisabled=element=>!element||element.nodeType!==Node.ELEMENT_NODE||!!element.classList.contains("disabled")||(typeof element.disabled!="undefined"?element.disabled:element.hasAttribute("disabled")&&element.getAttribute("disabled")!=="false"),findShadowRoot=element=>{if(!document.documentElement.attachShadow)return null;if(typeof element.getRootNode=="function"){const root=element.getRootNode();return root instanceof ShadowRoot?root:null}return element instanceof ShadowRoot?element:element.parentNode?findShadowRoot(element.parentNode):null},noop=()=>{},reflow=element=>{element.offsetHeight},getjQuery=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,DOMContentLoadedCallbacks=[],onDOMContentLoaded=callback=>{document.readyState==="loading"?(DOMContentLoadedCallbacks.length||document.addEventListener("DOMContentLoaded",()=>{for(const callback of DOMContentLoadedCallbacks)callback()}),DOMContentLoadedCallbacks.push(callback)):callback()},isRTL=()=>document.documentElement.dir==="rtl",defineJQueryPlugin=plugin=>{onDOMContentLoaded(()=>{const $=getjQuery();if($){const name=plugin.NAME,JQUERY_NO_CONFLICT=$.fn[name];$.fn[name]=plugin.jQueryInterface,$.fn[name].Constructor=plugin,$.fn[name].noConflict=()=>($.fn[name]=JQUERY_NO_CONFLICT,plugin.jQueryInterface)}})},execute=(possibleCallback,args=[],defaultValue=possibleCallback)=>typeof possibleCallback=="function"?possibleCallback(...args):defaultValue,executeAfterTransition=(callback,transitionElement,waitForTransition=!0)=>{if(!waitForTransition){execute(callback);return}const durationPadding=5,emulatedDuration=getTransitionDurationFromElement(transitionElement)+durationPadding;let called=!1;const handler=({target})=>
7{if(target!==transitionElement)return;called=!0,transitionElement.removeEventListener(TRANSITION_END,handler),execute(callback)};transitionElement.addEventListener(TRANSITION_END,handler),setTimeout(()=>{called||triggerTransitionEnd(transitionElement)},emulatedDuration)},getNextActiveElement=(list,activeElement,shouldGetNext,isCycleAllowed)=>{const listLength=list.length;let index=list.indexOf(activeElement);return index===-1?!shouldGetNext&&isCycleAllowed?list[listLength-1]:list[0]:(index+=shouldGetNext?1:-1,isCycleAllowed&&(index=(index+listLength)%listLength),list[Math.max(0,Math.min(index,listLength-1))])},namespaceRegex=/[^.]*(?=\..*)\.|.*/,stripNameRegex=/\..*/,stripUidRegex=/::\d+$/,eventRegistry={};let uidEvent=1;const customEvents={mouseenter:"mouseover",mouseleave:"mouseout"},nativeEvents=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function makeEventUid(element,uid){return uid&&`${uid}::${uidEvent++}`||element.uidEvent||uidEvent++}function getElementEvents(element){const uid=makeEventUid(element);return element.uidEvent=uid,eventRegistry[uid]=eventRegistry[uid]||{},eventRegistry[uid]}function bootstrapHandler(element,fn){return function handler(event){return hydrateObj(event,{delegateTarget:element}),handler.oneOff&&EventHandler.off(element,event.type,fn),fn.apply(element,[event])}}function bootstrapDelegationHandler(element,selector,fn){return function handler(event){const domElements=element.querySelectorAll(selector);for(let{target}=event;target&&target!==this;target=target.parentNode)for(const domElement of domElements){if(domElement!==target)continue;return hydrateObj(event,{delegateTarget:target}),handler.oneOff&&EventHandler.off(element,event.type,selector,fn),fn.apply(target,[event])}}}function findHandler(events,callable,delegationSelector=null){return Object.values(events).find(event=>event.callable===callable&&event.delegationSelector===delegationSelector)}function normalizeParameters(originalTypeEvent,handler,delegationFunction){const isDelegated=typeof handler=="string",callable=isDelegated?delegationFunction:handler||delegationFunction;let typeEvent=getTypeEvent(originalTypeEvent);return nativeEvents.has(typeEvent)||(typeEvent=originalTypeEvent),[isDelegated,callable,typeEvent]}function addHandler(element,originalTypeEvent,handler,delegationFunction,oneOff){if(typeof originalTypeEvent!="string"||!element)return;let[isDelegated,callable,typeEvent]=normalizeParameters(originalTypeEvent,handler,delegationFunction);if(originalTypeEvent in customEvents){const wrapFunction=fn=>function(event){if(!event.relatedTarget||event.relatedTarget!==event.delegateTarget&&!event.delegateTarget.contains(event.relatedTarget))return fn.call(this,event)};callable=wrapFunction(callable)}const events=getElementEvents(element),handlers=events[typeEvent]||(events[typeEvent]={}),previousFunction=findHandler(handlers,callable,isDelegated?handler:null);if(previousFunction){previousFunction.oneOff=previousFunction.oneOff&&oneOff;return}const uid=makeEventUid(callable,originalTypeEvent.replace(namespaceRegex,"")),fn=isDelegated?bootstrapDelegationHandler(element,handler,callable):bootstrapHandler(element,callable);fn.delegationSelector=isDelegated?handler:null,fn.callable=callable,fn.oneOff=oneOff,fn.uidEvent=uid,handlers[uid]=fn,element.addEventListener(typeEvent,fn,isDelegated)}function removeHandler(element,events,typeEvent,handler,delegationSelector){const fn=findHandler(events[typeEvent],handler,delegationSelector);if(!fn)return;element.removeEventListener(typeEvent,fn,Boolean(delegationSelector)),delete events[typeEvent][fn.uidEvent]}function removeNamespacedHandlers(element,events,typeEvent,namespace){const storeElementEvent=events[typeEvent]||{};for(const[handlerKey,event]of Object.entries(storeElementEvent))handlerKey.includes(namespace)&&removeHandler(element,events,typeEvent,event.callable,event.delegationSelector)}function getTypeEvent(event){return event=event.replace(stripNameRegex,""),customEvents[event]||event}const EventHandler={on(element,event,handler,delegationFunction){addHandler(element,event,handler,delegationFunction,!1)},one(element,event,handler,delegationFunction){addHandler(element,event,handler,delegationFunction,!0)},off(element,originalTypeEvent,handler,delegationFunction){if(typeof originalTypeEvent!="string"||!element)return;const[isDelegated,callable,typeEvent]=normalizeParameters(originalTypeEvent,handler,delegationFunction),inNamespace=typeEvent!==originalTypeEvent,events=getElementEvents(element),storeElementEvent=events[typeEvent]||{},isNamespace=originalTypeEvent.startsWith(".");if(typeof callable!="undefined"){if(!Object.keys(storeElementEvent).length)return;removeHandler(element,events,typeEvent,callable,isDelegated?handler:null);return}
7if(isNamespace)for(const elementEvent of Object.keys(events))removeNamespacedHandlers(element,events,elementEvent,originalTypeEvent.slice(1));for(const[keyHandlers,event]of Object.entries(storeElementEvent)){const handlerKey=keyHandlers.replace(stripUidRegex,"");(!inNamespace||originalTypeEvent.includes(handlerKey))&&removeHandler(element,events,typeEvent,event.callable,event.delegationSelector)}},trigger(element,event,args){if(typeof event!="string"||!element)return null;const $=getjQuery(),typeEvent=getTypeEvent(event),inNamespace=event!==typeEvent;let jQueryEvent=null,bubbles=!0,nativeDispatch=!0,defaultPrevented=!1;inNamespace&&$&&(jQueryEvent=$.Event(event,args),$(element).trigger(jQueryEvent),bubbles=!jQueryEvent.isPropagationStopped(),nativeDispatch=!jQueryEvent.isImmediatePropagationStopped(),defaultPrevented=jQueryEvent.isDefaultPrevented());const evt=hydrateObj(new Event(event,{bubbles,cancelable:!0}),args);return defaultPrevented&&evt.preventDefault(),nativeDispatch&&element.dispatchEvent(evt),evt.defaultPrevented&&jQueryEvent&&jQueryEvent.preventDefault(),evt}};function hydrateObj(obj,meta={}){for(const[key,value]of Object.entries(meta))try{obj[key]=value}catch{Object.defineProperty(obj,key,{configurable:!0,get(){return value}})}return obj}function normalizeData(value){if(value==="true")return!0;if(value==="false")return!1;if(value===Number(value).toString())return Number(value);if(value===""||value==="null")return null;if(typeof value!="string")return value;try{return JSON.parse(decodeURIComponent(value))}catch{return value}}function normalizeDataKey(key){return key.replace(/[A-Z]/g,chr=>`-${chr.toLowerCase()}`)}const Manipulator={setDataAttribute(element,key,value){element.setAttribute(`data-bs-${normalizeDataKey(key)}`,value)},removeDataAttribute(element,key){element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)},getDataAttributes(element){if(!element)return{};const attributes={},bsKeys=Object.keys(element.dataset).filter(key=>key.startsWith("bs")&&!key.startsWith("bsConfig"));for(const key of bsKeys){let pureKey=key.replace(/^bs/,"");pureKey=pureKey.charAt(0).toLowerCase()+pureKey.slice(1,pureKey.length),attributes[pureKey]=normalizeData(element.dataset[key])}return attributes},getDataAttribute(element,key){return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))}};class Config{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(config){return config=this._mergeConfigObj(config),config=this._configAfterMerge(config),this._typeCheckConfig(config),config}_configAfterMerge(config){return config}_mergeConfigObj(config,element){const jsonConfig=isElement$1(element)?Manipulator.getDataAttribute(element,"config"):{};return{...this.constructor.Default,...typeof jsonConfig=="object"?jsonConfig:{},...isElement$1(element)?Manipulator.getDataAttributes(element):{},...typeof config=="object"?config:{}}}_typeCheckConfig(config,configTypes=this.constructor.DefaultType){for(const[property,expectedTypes]of Object.entries(configTypes)){const value=config[property],valueType=isElement$1(value)?"element":toType(value);if(!new RegExp(expectedTypes).test(valueType))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`)}}}const VERSION="5.3.2";class BaseComponent extends Config{constructor(element,config){if(super(),element=getElement(element),!element)return;this._element=element,this._config=this._getConfig(config),Data.set(this._element,this.constructor.DATA_KEY,this)}dispose(){Data.remove(this._element,this.constructor.DATA_KEY),EventHandler.off(this._element,this.constructor.EVENT_KEY);for(const propertyName of Object.getOwnPropertyNames(this))this[propertyName]=null}_queueCallback(callback,element,isAnimated=!0){executeAfterTransition(callback,element,isAnimated)}_getConfig(config){return config=this._mergeConfigObj(config,this._element),config=this._configAfterMerge(config),this._typeCheckConfig(config),config}static getInstance(element){return Data.get(getElement(element),this.DATA_KEY)}static getOrCreateInstance(element,config={}){return this.getInstance(element)||new this(element,typeof config=="object"?config:null)}static get VERSION(){return VERSION}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(name){return`${name}${this.EVENT_KEY}`}}const getSelector=element=>{let selector=element.getAttribute("data-bs-target");if(!selector||selector==="#"){let hrefAttribute=element.getAttribute("href");if(!hrefAttribute||!hrefAttribute.includes("#")&&!hrefAttribute.startsWith("."))return null;hrefAttribute.includes("#")&&!hrefAttribute.startsWith("#")&&(hrefAttribute=`#${hrefAttribute.split("#")[1]}`),selector=hrefAttribute&&hrefAttribute!=="#"?parseSelector(hrefAttribute.trim()):null}return selector},SelectorEngine={find(selector,element=document.documentElement){return[].concat(...Element.prototype.querySelectorAll.call(element,selector))},findOne(selector,element=document.documentElement){return Element.prototype.querySelector.call(element,selector)},children(element,selector){return[].concat(...element.children).filter(child=>child.matches(selector))},parents(element,selector){const parents=[];let ancestor=element.parentNode.closest(selector);for(;ancestor;)parents.push(ancestor),ancestor=ancestor.parentNode.closest(selector);return parents},prev(element,selector){let previous=element.previousElementSibling;for(;previous;){if(previous.matches(selector))return[previous];previous=previous.previousElementSibling}return[]},next(element,selector){let next=element.nextElementSibling;for(;next;){if(next.matches(selector))return[next];next=next.nextElementSibling}return[]},focusableChildren(element){const focusables=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map(selector=>`${selector}:not([tabindex^="-"])`).join(",");return this.find(focusables,element).filter(el=>!isDisabled(el)&&isVisible(el))},getSelectorFromElement(element){const selector=getSelector(element);return selector?SelectorEngine.findOne(selector)?selector:null:null},getElementFromSelector(element){const selector=getSelector(element);return selector?SelectorEngine.findOne(selector):null},getMultipleElementsFromSelector(element){const selector=getSelector(element);return selector?SelectorEngine.find(selector):[]}},enableDismissTrigger=(component,method="hide")=>{const clickEvent=`click.dismiss${component.EVENT_KEY}`,name=component.NAME;EventHandler.on(document,clickEvent,`[data-bs-dismiss="${name}"]`,function(event){if(["A","AREA"].includes(this.tagName)&&event.preventDefault(),isDisabled(this))return;const target=SelectorEngine.getElementFromSelector(this)||this.closest(`.${name}`),instance=component.getOrCreateInstance(target);instance[method]()})},NAME$f="alert",DATA_KEY$a="bs.alert",EVENT_KEY$b=`.${DATA_KEY$a}`,EVENT_CLOSE=`close${EVENT_KEY$b}`,EVENT_CLOSED=`closed${EVENT_KEY$b}`,CLASS_NAME_FADE$5="fade",CLASS_NAME_SHOW$8="show";class Alert extends BaseComponent{static get NAME(){return NAME$f}close(){const closeEvent=EventHandler.trigger(this._element,EVENT_CLOSE);if(closeEvent.defaultPrevented)return;this._element.classList.remove(CLASS_NAME_SHOW$8);const isAnimated=this._element.classList.contains(CLASS_NAME_FADE$5);this._queueCallback(()=>this._destroyElement(),this._element,isAnimated)}_destroyElement(){this._element.remove(),EventHandler.trigger(this._element,EVENT_CLOSED),this.dispose()}static jQueryInterface(config){return this.each(function(){const data=Alert.getOrCreateInstance(this);if(typeof config!="string")return;if(data[config]===void 0||config.startsWith("_")||config==="constructor")throw new TypeError(`No method n
7amed "${config}"`);data[config](this)})}}enableDismissTrigger(Alert,"close"),defineJQueryPlugin(Alert);const NAME$e="button",DATA_KEY$9="bs.button",EVENT_KEY$a=`.${DATA_KEY$9}`,DATA_API_KEY$6=".data-api",CLASS_NAME_ACTIVE$3="active",SELECTOR_DATA_TOGGLE$5='[data-bs-toggle="button"]',EVENT_CLICK_DATA_API$6=`click${EVENT_KEY$a}${DATA_API_KEY$6}`;class Button extends BaseComponent{static get NAME(){return NAME$e}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle(CLASS_NAME_ACTIVE$3))}static jQueryInterface(config){return this.each(function(){const data=Button.getOrCreateInstance(this);config==="toggle"&&data[config]()})}}EventHandler.on(document,EVENT_CLICK_DATA_API$6,SELECTOR_DATA_TOGGLE$5,event=>{event.preventDefault();const button=event.target.closest(SELECTOR_DATA_TOGGLE$5),data=Button.getOrCreateInstance(button);data.toggle()}),defineJQueryPlugin(Button);const NAME$d="swipe",EVENT_KEY$9=".bs.swipe",EVENT_TOUCHSTART=`touchstart${EVENT_KEY$9}`,EVENT_TOUCHMOVE=`touchmove${EVENT_KEY$9}`,EVENT_TOUCHEND=`touchend${EVENT_KEY$9}`,EVENT_POINTERDOWN=`pointerdown${EVENT_KEY$9}`,EVENT_POINTERUP=`pointerup${EVENT_KEY$9}`,POINTER_TYPE_TOUCH="touch",POINTER_TYPE_PEN="pen",CLASS_NAME_POINTER_EVENT="pointer-event",SWIPE_THRESHOLD=40,Default$c={endCallback:null,leftCallback:null,rightCallback:null},DefaultType$c={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Swipe extends Config{constructor(element,config){if(super(),this._element=element,!element||!Swipe.isSupported())return;this._config=this._getConfig(config),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents()}static get Default(){return Default$c}static get DefaultType(){return DefaultType$c}static get NAME(){return NAME$d}dispose(){EventHandler.off(this._element,EVENT_KEY$9)}_start(event){if(!this._supportPointerEvents){this._deltaX=event.touches[0].clientX;return}this._eventIsPointerPenTouch(event)&&(this._deltaX=event.clientX)}_end(event){this._eventIsPointerPenTouch(event)&&(this._deltaX=event.clientX-this._deltaX),this._handleSwipe(),execute(this._config.endCallback)}_move(event){this._deltaX=event.touches&&event.touches.length>1?0:event.touches[0].clientX-this._deltaX}_handleSwipe(){const absDeltaX=Math.abs(this._deltaX);if(absDeltaX<=SWIPE_THRESHOLD)return;const direction=absDeltaX/this._deltaX;if(this._deltaX=0,!direction)return;execute(direction>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(EventHandler.on(this._element,EVENT_POINTERDOWN,event=>this._start(event)),EventHandler.on(this._element,EVENT_POINTERUP,event=>this._end(event)),this._element.classList.add(CLASS_NAME_POINTER_EVENT)):(EventHandler.on(this._element,EVENT_TOUCHSTART,event=>this._start(event)),EventHandler.on(this._element,EVENT_TOUCHMOVE,event=>this._move(event)),EventHandler.on(this._element,EVENT_TOUCHEND,event=>this._end(event)))}_eventIsPointerPenTouch(event){return this._supportPointerEvents&&(event.pointerType===POINTER_TYPE_PEN||event.pointerType===POINTER_TYPE_TOUCH)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const NAME$c="carousel",DATA_KEY$8="bs.carousel",EVENT_KEY$8=`.${DATA_KEY$8}`,DATA_API_KEY$5=".data-api",ARROW_LEFT_KEY$1="ArrowLeft",ARROW_RIGHT_KEY$1="ArrowRight",TOUCHEVENT_COMPAT_WAIT=500,ORDER_NEXT="next",ORDER_PREV="prev",DIRECTION_LEFT="left",DIRECTION_RIGHT="right",EVENT_SLIDE=`slide${EVENT_KEY$8}`,EVENT_SLID=`slid${EVENT_KEY$8}`,EVENT_KEYDOWN$1=`keydown${EVENT_KEY$8}`,EVENT_MOUSEENTER$1=`mouseenter${EVENT_KEY$8}`,EVENT_MOUSELEAVE$1=`mouseleave${EVENT_KEY$8}`,EVENT_DRAG_START=`dragstart${EVENT_KEY$8}`,EVENT_LOAD_DATA_API$3=`load${EVENT_KEY$8}${DATA_API_KEY$5}`,EVENT_CLICK_DATA_API$5=`click${EVENT_KEY$8}${DATA_API_KEY$5}`,CLASS_NAME_CAROUSEL="carousel",CLASS_NAME_ACTIVE$2="active",CLASS_NAME_SLIDE="slide",CLASS_NAME_END="carousel-item-end",CLASS_NAME_START="carousel-item-start",CLASS_NAME_NEXT="carousel-item-next",CLASS_NAME_PREV="carousel-item-prev",SELECTOR_ACTIVE=".active",SELECTOR_ITEM=".carousel-item",SELECTOR_ACTIVE_ITEM=SELECTOR_ACTIVE+SELECTOR_ITEM,SELECTOR_ITEM_IMG=".carousel-item img",SELECTOR_INDICATORS=".carousel-indicators",SELECTOR_DATA_SLIDE="[data-bs-slide], [data-bs-slide-to]",SELECTOR_DATA_RIDE='[data-bs-ride="carousel"]',KEY_TO_DIRECTION={[ARROW_LEFT_KEY$1]:DIRECTION_RIGHT,[ARROW_RIGHT_KEY$1]:DIRECTION_LEFT},Default$b={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},DefaultType$b={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class Carousel extends BaseComponent{constructor(element,config){super(element,config),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=SelectorEngine.findOne(SELECTOR_INDICATORS,this._element),this._addEventListeners(),this._config.ride===CLASS_NAME_CAROUSEL&&this.cycle()}static get Default(){return Default$b}static get DefaultType(){return DefaultType$b}static get NAME(){return NAME$c}next(){this._slide(ORDER_NEXT)}nextWhenVisible(){!document.hidden&&isVisible(this._element)&&this.next()}prev(){this._slide(ORDER_PREV)}pause(){this._isSliding&&triggerTransitionEnd(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval(()=>this.nextWhenVisible(),this._config.interval)}_maybeEnableCycle(){if(!this._config.ride)return;if(this._isSliding){EventHandler.one(this._element,EVENT_SLID,()=>this.cycle());return}this.cycle()}to(index){const items=this._getItems();if(index>items.length-1||index<0)return;if(this._isSliding){EventHandler.one(this._element,EVENT_SLID,()=>this.to(index));return}const activeIndex=this._getItemIndex(this._getActive());if(activeIndex===index)return;const order=index>activeIndex?ORDER_NEXT:ORDER_PREV;this._slide(order,items[index])}
vendor: 4,450 bytes, line 7
7dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(config){return config.defaultInterval=config.interval,config}_addEventListeners(){this._config.keyboard&&EventHandler.on(this._element,EVENT_KEYDOWN$1,event=>this._keydown(event)),this._config.pause==="hover"&&(EventHandler.on(this._element,EVENT_MOUSEENTER$1,()=>this.pause()),EventHandler.on(this._element,EVENT_MOUSELEAVE$1,()=>this._maybeEnableCycle())),this._config.touch&&Swipe.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const img of SelectorEngine.find(SELECTOR_ITEM_IMG,this._element))EventHandler.on(img,EVENT_DRAG_START,event=>event.preventDefault());const endCallBack=()=>{if(this._config.pause!=="hover")return;this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(()=>this._maybeEnableCycle(),TOUCHEVENT_COMPAT_WAIT+this._config.interval)},swipeConfig={leftCallback:()=>this._slide(this._directionToOrder(DIRECTION_LEFT)),rightCallback:()=>this._slide(this._directionToOrder(DIRECTION_RIGHT)),endCallback:endCallBack};this._swipeHelper=new Swipe(this._element,swipeConfig)}_keydown(event){if(/input|textarea/i.test(event.target.tagName))return;const direction=KEY_TO_DIRECTION[event.key];direction&&(event.preventDefault(),this._slide(this._directionToOrder(direction)))}_getItemIndex(element){return this._getItems().indexOf(element)}_setActiveIndicatorElement(index){if(!this._indicatorsElement)return;const activeIndicator=SelectorEngine.findOne(SELECTOR_ACTIVE,this._indicatorsElement);activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2),activeIndicator.removeAttribute("aria-current");const newActiveIndicator=SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`,this._indicatorsElement);newActiveIndicator&&(newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2),newActiveIndicator.setAttribute("aria-current","true"))}_updateInterval(){const element=this._activeElement||this._getActive();if(!element)return;const elementInterval=Number.parseInt(element.getAttribute("data-bs-interval"),10);this._config.interval=elementInterval||this._config.defaultInterval}_slide(order,element=null){if(this._isSliding)return;const activeElement=this._getActive(),isNext=order===ORDER_NEXT,nextElement=element||getNextActiveElement(this._getItems(),activeElement,isNext,this._config.wrap);if(nextElement===activeElement)return;const nextElementIndex=this._getItemIndex(nextElement),triggerEvent=eventName=>EventHandler.trigger(this._element,eventName,{relatedTarget:nextElement,direction:this._orderToDirection(order),from:this._getItemIndex(activeElement),to:nextElementIndex}),slideEvent=triggerEvent(EVENT_SLIDE);if(slideEvent.defaultPrevented)return;if(!activeElement||!nextElement)return;const isCycling=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(nextElementIndex),this._activeElement=nextElement;const directionalClassName=isNext?CLASS_NAME_START:CLASS_NAME_END,orderClassName=isNext?CLASS_NAME_NEXT:CLASS_NAME_PREV;nextElement.classList.add(orderClassName),reflow(nextElement),activeElement.classList.add(directionalClassName),nextElement.classList.add(directionalClassName);const completeCallBack=()=>{nextElement.classList.remove(directionalClassName,orderClassName),nextElement.classList.add(CLASS_NAME_ACTIVE$2),activeElement.classList.remove(CLASS_NAME_ACTIVE$2,orderClassName,directionalClassName),this._isSliding=!1,triggerEvent(EVENT_SLID)};this._queueCallback(completeCallBack,activeElement,this._isAnimated()),isCycling&&this.cycle()}_isAnimated(){return this._element.classList.contains(CLASS_NAME_SLIDE)}_getActive(){return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM,this._element)}_getItems(){return SelectorEngine.find(SELECTOR_ITEM,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(direction){return isRTL()?direction===DIRECTION_LEFT?ORDER_PREV:ORDER_NEXT:direction===DIRECTION_LEFT?ORDER_NEXT:ORDER_PREV}_orderToDirection(order){return isRTL()?order===ORDER_PREV?DIRECTION_LEFT:DIRECTION_RIGHT:order===ORDER_PREV?DIRECTION_RIGHT:DIRECTION_LEFT}static jQueryInterface(config){return this.each(function(){const data=Carousel.getOrCreateInstance(this,config);if(typeof config=="number"){data.to(config);return}if(typeof config=="string"){if(data[config]===void 0||config.startsWith("_")||config==="constructor")throw new TypeError(`No method n
7amed "${config}"`);data[config]()}})}}EventHandler.on(document,EVENT_CLICK_DATA_API$5,SELECTOR_DATA_SLIDE,function(event){const target=SelectorEngine.getElementFromSelector(this);if(!target||!target.classList.contains(CLASS_NAME_CAROUSEL))return;event.preventDefault();const carousel=Carousel.getOrCreateInstance(target),slideIndex=this.getAttribute("data-bs-slide-to");if(slideIndex){carousel.to(slideIndex),carousel._maybeEnableCycle();return}if(Manipulator.getDataAttribute(this,"slide")==="next"){carousel.next(),carousel._maybeEnableCycle();return}carousel.prev(),carousel._maybeEnableCycle()}),EventHandler.on(window,EVENT_LOAD_DATA_API$3,()=>{const carousels=SelectorEngine.find(SELECTOR_DATA_RIDE);for(const carousel of carousels)Carousel.getOrCreateInstance(carousel)}),defineJQueryPlugin(Carousel);const NAME$b="collapse",DATA_KEY$7="bs.collapse",EVENT_KEY$7=`.${DATA_KEY$7}`,DATA_API_KEY$4=".data-api",EVENT_SHOW$6=`show${EVENT_KEY$7}`,EVENT_SHOWN$6=`shown${EVENT_KEY$7}`,EVENT_HIDE$6=`hide${EVENT_KEY$7}`,EVENT_HIDDEN$6=`hidden${EVENT_KEY$7}`,EVENT_CLICK_DATA_API$4=`click${EVENT_KEY$7}${DATA_API_KEY$4}`,CLASS_NAME_SHOW$7="show",CLASS_NAME_COLLAPSE="collapse",CLASS_NAME_COLLAPSING="collapsing",CLASS_NAME_COLLAPSED="collapsed",CLASS_NAME_DEEPER_CHILDREN=`:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`,CLASS_NAME_HORIZONTAL="collapse-horizontal",WIDTH="width",HEIGHT="height",SELECTOR_ACTIVES=".collapse.show, .collapse.collapsing",SELECTOR_DATA_TOGGLE$4='[data-bs-toggle="collapse"]',Default$a={parent:null,toggle:!0},DefaultType$a={parent:"(null|element)",toggle:"boolean"};class Collapse extends BaseComponent{constructor(element,config){super(element,config),this._isTransitioning=!1,this._triggerArray=[];const toggleList=SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);for(const elem of toggleList){const selector=SelectorEngine.getSelectorFromElement(elem),filterElement=SelectorEngine.find(selector).filter(foundElement=>foundElement===this._element);selector!==null&&filterElement.length&&this._triggerArray.push(elem)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Default$a}static get DefaultType(){return DefaultType$a}static get NAME(){return NAME$b}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let activeChildren=[];if(this._config.parent&&(activeChildren=this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element=>element!==this._element).map(element=>Collapse.getOrCreateInstance(element,{toggle:!1}))),activeChildren.length&&activeChildren[0]._isTransitioning)return;const startEvent=EventHandler.trigger(this._element,EVENT_SHOW$6);if(startEvent.defaultPrevented)return;for(const activeInstance of activeChildren)activeInstance.hide();const dimension=this._getDimension();this._element.classList.remove(CLASS_NAME_COLLAPSE),this._element.classList.add(CLASS_NAME_COLLAPSING),this._element.style[dimension]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const complete=()=>{this._isTransitioning=!1,this._element.classList.remove(CLASS_NAME_COLLAPSING),this._element.classList.add(CLASS_NAME_COLLAPSE,CLASS_NAME_SHOW$7),this._element.style[dimension]="",EventHandler.trigger(this._element,EVENT_SHOWN$6)},capitalizedDimension=dimension[0].toUpperCase()+dimension.slice(1),scrollSize=`scroll${capitalizedDimension}`;this._queueCallback(complete,this._element,!0),this._element.style[dimension]=`${this._element[scrollSize]}px`}hide(){if(this._isTransitioning||!this._isShown())return;const startEvent=EventHandler.trigger(this._element,EVENT_HIDE$6);if(startEvent.defaultPrevented)return;const dimension=this._getDimension();this._element.style[dimension]=`${this._element.getBoundingClientRect()[dimension]}px`,reflow(this._element),this._element.classList.add(CLASS_NAME_COLLAPSING),this._element.classList.remove(CLASS_NAME_COLLAPSE,CLASS_NAME_SHOW$7);for(const trigger of this._triggerArray){const element=SelectorEngine.getElementFromSelector(trigger);element&&!this._isShown(element)&&this._addAriaAndCollapsedClass([trigger],!1)}this._isTransitioning=!0;const complete=()=>{this._isTransitioning=!1,this._element.classList.remove(CLASS_NAME_COLLAPSING),this._element.classList.add(CLASS_NAME_COLLAPSE),EventHandler.trigger(this._element,EVENT_HIDDEN$6
vendor: 3,842 bytes, line 7
7)};this._element.style[dimension]="",this._queueCallback(complete,this._element,!0)}_isShown(element=this._element){return element.classList.contains(CLASS_NAME_SHOW$7)}_configAfterMerge(config){return config.toggle=Boolean(config.toggle),config.parent=getElement(config.parent),config}_getDimension(){return this._element.classList.contains(CLASS_NAME_HORIZONTAL)?WIDTH:HEIGHT}_initializeChildren(){if(!this._config.parent)return;const children=this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);for(const element of children){const selected=SelectorEngine.getElementFromSelector(element);selected&&this._addAriaAndCollapsedClass([element],this._isShown(selected))}}_getFirstLevelChildren(selector){const children=SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN,this._config.parent);return SelectorEngine.find(selector,this._config.parent).filter(element=>!children.includes(element))}_addAriaAndCollapsedClass(triggerArray,isOpen){if(!triggerArray.length)return;for(const element of triggerArray)element.classList.toggle(CLASS_NAME_COLLAPSED,!isOpen),element.setAttribute("aria-expanded",isOpen)}static jQueryInterface(config){const _config={};return typeof config=="string"&&/show|hide/.test(config)&&(_config.toggle=!1),this.each(function(){const data=Collapse.getOrCreateInstance(this,_config);if(typeof config=="string"){if(typeof data[config]=="undefined")throw new TypeError(`No method named "${config}"`);data[config]()}})}}EventHandler.on(document,EVENT_CLICK_DATA_API$4,SELECTOR_DATA_TOGGLE$4,function(event){(event.target.tagName==="A"||event.delegateTarget&&event.delegateTarget.tagName==="A")&&event.preventDefault();for(const element of SelectorEngine.getMultipleElementsFromSelector(this))Collapse.getOrCreateInstance(element,{toggle:!1}).toggle()}),defineJQueryPlugin(Collapse);var top="top",bottom="bottom",right="right",left="left",auto="auto",basePlacements=[top,bottom,right,left],start="start",end="end",clippingParents="clippingParents",viewport="viewport",popper="popper",reference="reference",variationPlacements=basePlacements.reduce(function(acc,placement){return acc.concat([placement+"-"+start,placement+"-"+end])},[]),placements=[].concat(basePlacements,[auto]).reduce(function(acc,placement){return acc.concat([placement,placement+"-"+start,placement+"-"+end])},[]),beforeRead="beforeRead",read="read",afterRead="afterRead",beforeMain="beforeMain",main="main",afterMain="afterMain",beforeWrite="beforeWrite",write="write",afterWrite="afterWrite",modifierPhases=[beforeRead,read,afterRead,beforeMain,main,afterMain,beforeWrite,write,afterWrite];function getNodeName(element){return element?(element.nodeName||"").toLowerCase():null}function getWindow(node){if(node==null)return window;if(node.toString()!=="[object Window]"){var ownerDocument=node.ownerDocument;return ownerDocument?ownerDocument.defaultView||window:window}return node}function isElement(node){var OwnElement=getWindow(node).Element;return node instanceof OwnElement||node instanceof Element}function isHTMLElement(node){var OwnElement=getWindow(node).HTMLElement;return node instanceof OwnElement||node instanceof HTMLElement}function isShadowRoot(node){if(typeof ShadowRoot=="undefined")return!1;var OwnElement=getWindow(node).ShadowRoot;return node instanceof OwnElement||node instanceof ShadowRoot}function applyStyles(_ref){var state=_ref.state;Object.keys(state.elements).forEach(function(name){var style=state.styles[name]||{},attributes=state.attributes[name]||{},element=state.elements[name];if(!isHTMLElement(element)||!getNodeName(element))return;Object.assign(element.style,style),Object.keys(attributes).forEach(function(name){var value=attributes[name];value===!1?element.removeAttribute(name):element.setAttribute(name,value===!0?"":value)})})}function effect$2(_ref2){var state=_ref2.state,initialStyles={popper:{position:state.o
7ptions.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(state.elements.popper.style,initialStyles.popper),state.styles=initialStyles,state.elements.arrow&&Object.assign(state.elements.arrow.style,initialStyles.arrow),function(){Object.keys(state.elements).forEach(function(name){var element=state.elements[name],attributes=state.attributes[name]||{},styleProperties=Object.keys(state.styles.hasOwnProperty(name)?state.styles[name]:initialStyles[name]),style=styleProperties.reduce(function(style,property){return style[property]="",style},{});if(!isHTMLElement(element)||!getNodeName(element))return;Object.assign(element.style,style),Object.keys(attributes).forEach(function(attribute){element.removeAttribute(attribute)})})}}const applyStyles$1={name:"applyStyles",enabled:!0,phase:"write",fn:applyStyles,effect:effect$2,requires:["computeStyles"]};function getBasePlacement(placement){return placement.split("-")[0]}var max=Math.max,min=Math.min,round=Math.round;function getUAString(){var uaData=navigator.userAgentData;return uaData!=null&&uaData.brands&&Array.isArray(uaData.brands)?uaData.brands.map(function(item){return item.brand+"/"+item.version}).join(" "):navigator.userAgent}function isLayoutViewport(){return!/^((?!chrome|android).)*safari/i.test(getUAString())}function getBoundingClientRect(element,includeScale,isFixedStrategy){includeScale===void 0&&(includeScale=!1),isFixedStrategy===void 0&&(isFixedStrategy=!1);var clientRect=element.getBoundingClientRect(),scaleX=1,scaleY=1;includeScale&&isHTMLElement(element)&&(scaleX=element.offsetWidth>0?round(clientRect.width)/element.offsetWidth||1:1,scaleY=element.offsetHeight>0?round(clientRect.height)/element.offsetHeight||1:1);var _ref=isElement(element)?getWindow(element):window,visualViewport=_ref.visualViewport,addVisualOffsets=!isLayoutViewport()&&isFixedStrategy,x=(clientRect.left+(addVisualOffsets&&visualViewport?visualViewport.offsetLeft:0))/scaleX,y=(clientRect.top+(addVisualOffsets&&visualViewport?visualViewport.offsetTop:0))/scaleY,width=clientRect.width/scaleX,height=clientRect.height/scaleY;return{width,height,top:y,right:x+width,bottom:y+height,left:x,x,y}}function getLayoutRect(element){var clientRect=getBoundingClientRect(element),width=element.offsetWidth,height=element.offsetHeight;return Math.abs(clientRect.width-width)<=1&&(width=clientRect.width),Math.abs(clientRect.height-height)<=1&&(height=clientRect.height),{x:element.offsetLeft,y:element.offsetTop,width,height}}function contains(parent,child){var rootNode=child.getRootNode&&child.getRootNode();if(parent.contains(child))return!0;if(rootNode&&isShadowRoot(rootNode)){var next=child;do{if(next&&parent.isSameNode(next))return!0;next=next.parentNode||next.host}while(next)}return!1}function getComputedStyle$1(element){return getWindow(element).getComputedStyle(element)}function isTableElement(element){return["table","td","th"].indexOf(getNodeName(element))>=0}function getDocumentElement(element){return((isElement(element)?element.ownerDocument:element.document)||window.document).documentElement}function getParentNode(element){return getNodeName(element)==="html"?element:element.assignedSlot||element.parentNode||(isShadowRoot(element)?element.host:null)||getDocumentElement(element)}function getTrueOffsetParent(element){return!isHTMLElement(element)||getComputedStyle$1(element).position==="fixed"?null:element.offsetParent}function getContainingBlock(element){var isFirefox=/firefox/i.test(getUAString()),isIE=/Trident/i.test(getUAString());if(isIE&&isHTMLElement(element)){var elementCss=getComputedStyle$1(element);if(elementCss.position==="fixed")return null}var css,currentNode=getParentNode(element);for(isShadowRoot(currentNode)&&(currentNode=currentNode.host);isHTMLElement(currentNode)&&["html","body"].indexOf(getNodeName(currentNode))<0;){if(css=getComputedStyle$1(currentNode),css.transform!=="none"||css.perspective!=="none"||css.contain==="paint"||["transform","perspective"].indexOf(css.willChange)!==-1||isFirefox&&css.willChange==="filter"||isFirefox&&css.filter&&css.filter!=="none")return currentNode;currentNode=currentNode.parentNode}return null}function getOffsetParent(element){for(var window=getWindow(element),offsetParent=getTrueOffsetParent(element);offsetParent&&isTableElement(offsetParent)&&getComputedStyle$1(offsetParent).position==="static";)offsetParent=getTrueOffsetParent(offsetParent);return offsetParent&&(getNodeName(offsetParent)==="html"||getNodeName(offsetParent)==="body"&&getComputedStyle$1(offsetParent).position==="static")?window:offsetParent||getContainingBlock(element)||window}function getMainAxisFromPlacement(placement){return["top","bottom"].indexOf(placement)>=0?"x":"y"}function within(min$1,value,max$1){return max(min$1,min(value,max$1))}function withinMaxClamp(min,value,max){var v=within(min,value,max);return v>max?max:v}function getFreshSideObject(){return{top:0,right:0,bottom:0,left:0}}
7function mergePaddingObject(paddingObject){return Object.assign({},getFreshSideObject(),paddingObject)}function expandToHashMap(value,keys){return keys.reduce(function(hashMap,key){return hashMap[key]=value,hashMap},{})}var toPaddingObject=function(padding,state){return padding=typeof padding=="function"?padding(Object.assign({},state.rects,{placement:state.placement})):padding,mergePaddingObject(typeof padding!="number"?padding:expandToHashMap(padding,basePlacements))};function arrow(_ref){var _state$modifiersData$,state=_ref.state,name=_ref.name,options=_ref.options,arrowElement=state.elements.arrow,popperOffsets=state.modifiersData.popperOffsets,basePlacement=getBasePlacement(state.placement),axis=getMainAxisFromPlacement(basePlacement),isVertical=[left,right].indexOf(basePlacement)>=0,len=isVertical?"height":"width";if(!arrowElement||!popperOffsets)return;var paddingObject=toPaddingObject(options.padding,state),arrowRect=getLayoutRect(arrowElement),minProp=axis==="y"?top:left,maxProp=axis==="y"?bottom:right,endDiff=state.rects.reference[len]+state.rects.reference[axis]-popperOffsets[axis]-state.rects.popper[len],startDiff=popperOffsets[axis]-state.rects.reference[axis],arrowOffsetParent=getOffsetParent(arrowElement),clientSize=arrowOffsetParent?axis==="y"?arrowOffsetParent.clientHeight||0:arrowOffsetParent.clientWidth||0:0,centerToReference=endDiff/2-startDiff/2,min=paddingObject[minProp],max=clientSize-arrowRect[len]-paddingObject[maxProp],center=clientSize/2-arrowRect[len]/2+centerToReference,offset=within(min,center,max),axisProp=axis;state.modifiersData[name]=(_state$modifiersData$={},_state$modifiersData$[axisProp]=offset,_state$modifiersData$.centerOffset=offset-center,_state$modifiersData$)}function effect$1(_ref2){var state=_ref2.state,options=_ref2.options,_options$element=options.element,arrowElement=_options$element===void 0?"[data-popper-arrow]":_options$element;if(arrowElement==null)return;if(typeof arrowElement=="string"&&(arrowElement=state.elements.popper.querySelector(arrowElement),!arrowElement))return;if(!contains(state.elements.popper,arrowElement))return;state.elements.arrow=arrowElement}const arrow$1={name:"arrow",enabled:!0,phase:"main",fn:arrow,effect:effect$1,requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function getVariation(placement){return placement.split("-")[1]}var unsetSides={top:"auto",right:"auto",bottom:"auto",left:"auto"};function roundOffsetsByDPR(_ref,win){var x=_ref.x,y=_ref.y,dpr=win.devicePixelRatio||1;return{x:round(x*dpr)/dpr||0,y:round(y*dpr)/dpr||0}}function mapToStyles(_ref2){var _Object$assign2,_Object$assign,popper=_ref2.popper,popperRect=_ref2.popperRect,placement=_ref2.placement,variation=_ref2.variation,offsets=_ref2.offsets,position=_ref2.position,gpuAcceleration=_ref2.gpuAcceleration,adaptive=_ref2.adaptive,roundOffsets=_ref2.roundOffsets,isFixed=_ref2.isFixed,_offsets$x=offsets.x,x=_offsets$x===void 0?0:_offsets$x,_offsets$y=offsets.y,y=_offsets$y===void 0?0:_offsets$y,_ref3=typeof roundOffsets=="function"?roundOffsets({x,y}):{x,y},x=_ref3.x,y=_ref3.y,hasX=offsets.hasOwnProperty("x"),hasY=offsets.hasOwnProperty("y"),sideX=left,sideY=top,win=window;if(adaptive){var offsetParent=getOffsetParent(popper),heightProp="clientHeight",widthProp="clientWidth";if(offsetParent===getWindow(popper)&&(offsetParent=getDocumentElement(popper),getComputedStyle$1(offsetParent).position!=="static"&&position==="absolute"&&(heightProp="scrollHeight",widthProp="scrollWidth")),offsetParent=offsetParent,placement===top||(placement===left||placement===right)&&variation===end){sideY=bottom;var offsetY=isFixed&&offsetParent===win&&win.visualViewport?win.visualViewport.height:offsetParent[heightProp];y-=offsetY-popperRect.height,y*=gpuAcceleration?1:-1}if(placement===left||(placement===top||placement===bottom)&&variation===end){sideX=right;var offsetX=isFixed&&offsetParent===win&&win.visualViewport?win.visualViewport.width:offsetParent[widthProp];x-=offsetX-popperRect.width,x*=gpuAcceleration?1:-1}}var commonStyles=Object.assign({position},adaptive&&unsetSides),_ref4=roundOffsets===!0?roundOffsetsByDPR({x,y},getWindow(popper)):{x,y},x=_ref4.x,y=_ref4.y;return gpuAcceleration?Object.assign({},commonStyles,(_Object$assign={},_Object$assign[sideY]=hasY?"0":"",_Object$assign[sideX]=hasX?"0":"",_Object$assign.transform=(win.devicePixelRatio||1)<=1?"translate("+x+"px, "+y+"px)":"translate3d("+x+"px, "+y+"px, 0)",_Object$assign)):Object.assign({},commonStyles,(_Object$assign2={},_Object$assign2[sideY]=hasY?y+"px":"",_Object$assign2[sideX]=hasX?x+"px":"",_Object$assign2.transform="",_Object$assign2))}function computeStyles(_ref5){var state=_ref5.state,options=_ref5.options,_options$gpuAccelerat=options.gpuAcceleration,gpuA
vendor: 4,545 bytes, line 7
7cceleration=_options$gpuAccelerat===void 0||_options$gpuAccelerat,_options$adaptive=options.adaptive,adaptive=_options$adaptive===void 0||_options$adaptive,_options$roundOffsets=options.roundOffsets,roundOffsets=_options$roundOffsets===void 0||_options$roundOffsets,commonStyles={placement:getBasePlacement(state.placement),variation:getVariation(state.placement),popper:state.elements.popper,popperRect:state.rects.popper,gpuAcceleration,isFixed:state.options.strategy==="fixed"};state.modifiersData.popperOffsets!=null&&(state.styles.popper=Object.assign({},state.styles.popper,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.popperOffsets,position:state.options.strategy,adaptive,roundOffsets})))),state.modifiersData.arrow!=null&&(state.styles.arrow=Object.assign({},state.styles.arrow,mapToStyles(Object.assign({},commonStyles,{offsets:state.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets})))),state.attributes.popper=Object.assign({},state.attributes.popper,{"data-popper-placement":state.placement})}const computeStyles$1={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:computeStyles,data:{}};var passive={passive:!0};function effect(_ref){var state=_ref.state,instance=_ref.instance,options=_ref.options,_options$scroll=options.scroll,scroll=_options$scroll===void 0||_options$scroll,_options$resize=options.resize,resize=_options$resize===void 0||_options$resize,window=getWindow(state.elements.popper),scrollParents=[].concat(state.scrollParents.reference,state.scrollParents.popper);return scroll&&scrollParents.forEach(function(scrollParent){scrollParent.addEventListener("scroll",instance.update,passive)}),resize&&window.addEventListener("resize",instance.update,passive),function(){scroll&&scrollParents.forEach(function(scrollParent){scrollParent.removeEventListener("scroll",instance.update,passive)}),resize&&window.removeEventListener("resize",instance.update,passive)}}const eventListeners={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect,data:{}};var hash$1={left:"right",right:"left",bottom:"top",top:"bottom"};function getOppositePlacement(placement){return placement.replace(/left|right|bottom|top/g,function(matched){return hash$1[matched]})}var hash={start:"end",end:"start"};function getOppositeVariationPlacement(placement){return placement.replace(/start|end/g,function(matched){return hash[matched]})}function getWindowScroll(node){var win=getWindow(node),scrollLeft=win.pageXOffset,scrollTop=win.pageYOffset;return{scrollLeft,scrollTop}}function getWindowScrollBarX(element){return getBoundingClientRect(getDocumentElement(element)).left+getWindowScroll(element).scrollLeft}function getViewportRect(element,strategy){var win=getWindow(element),html=getDocumentElement(element),visualViewport=win.visualViewport,width=html.clientWidth,height=html.clientHeight,x=0,y=0;if(visualViewport){width=visualViewport.width,height=visualViewport.height;var layoutViewport=isLayoutViewport();(layoutViewport||!layoutViewport&&strategy==="fixed")&&(x=visualViewport.offsetLeft,y=visualViewport.offsetTop)}return{width,height,x:x+getWindowScrollBarX(element),y}}function getDocumentRect(element){var _element$ownerDocumen,html=getDocumentElement(element),winScroll=getWindowScroll(element),body=(_element$ownerDocumen=element.ownerDocument)==null?void 0:_element$ownerDocumen.body,width=max(html.scrollWidth,html.clientWidth,body?body.scrollWidth:0,body?body.clientWidth:0),height=max(html.scrollHeight,html.clientHeight,body?body.scrollHeight:0,body?body.clientHeight:0),x=-winScroll.scrollLeft+getWindowScrollBarX(element),y=-winScroll.scrollTop;return getComputedStyle$1(body||html).direction==="rtl"&&(x+=max(html.clientWidth,body?body.clientWidth:0)-width),{width,height,x,y}}function isScrollParent(element){var _getComputedStyle=getComputedStyle$1(element),overflow=_getComputedStyle.overflow,overflowX=_getComputedStyle.overflowX,overflowY=_getComputedStyle.overflowY;return/auto|scroll|overlay|hidden/.test(overflow+overflowY+overflowX)}function getScrollParent(node){return["html","body","#document"].indexOf(getNodeName(node))>=0?node.ownerDocument.body:isHTMLElement(node)&&isScrollParent(node)?node:getScrollParent(getParentNode(node))}function listScrollParents(element,list){list===void 0&&(list=[]);var _element$ownerDocumen,scrollParent=getScrollParent(element),isBody=scrollParent===((_element$ownerDocumen=element.ownerDocument)==null?void 0:_element$ownerDocumen.body),win=getWindow(scrollParent),target=isBody?[win].concat(win.visualVie
vendor: 4,203 bytes, line 7
7wport||[],isScrollParent(scrollParent)?scrollParent:[]):scrollParent,updatedList=list.concat(target);return isBody?updatedList:updatedList.concat(listScrollParents(getParentNode(target)))}function rectToClientRect(rect){return Object.assign({},rect,{left:rect.x,top:rect.y,right:rect.x+rect.width,bottom:rect.y+rect.height})}function getInnerBoundingClientRect(element,strategy){var rect=getBoundingClientRect(element,!1,strategy==="fixed");return rect.top=rect.top+element.clientTop,rect.left=rect.left+element.clientLeft,rect.bottom=rect.top+element.clientHeight,rect.right=rect.left+element.clientWidth,rect.width=element.clientWidth,rect.height=element.clientHeight,rect.x=rect.left,rect.y=rect.top,rect}function getClientRectFromMixedType(element,clippingParent,strategy){return clippingParent===viewport?rectToClientRect(getViewportRect(element,strategy)):isElement(clippingParent)?getInnerBoundingClientRect(clippingParent,strategy):rectToClientRect(getDocumentRect(getDocumentElement(element)))}function getClippingParents(element){var clippingParents=listScrollParents(getParentNode(element)),canEscapeClipping=["absolute","fixed"].indexOf(getComputedStyle$1(element).position)>=0,clipperElement=canEscapeClipping&&isHTMLElement(element)?getOffsetParent(element):element;return isElement(clipperElement)?clippingParents.filter(function(clippingParent){return isElement(clippingParent)&&contains(clippingParent,clipperElement)&&getNodeName(clippingParent)!=="body"}):[]}function getClippingRect(element,boundary,rootBoundary,strategy){var mainClippingParents=boundary==="clippingParents"?getClippingParents(element):[].concat(boundary),clippingParents=[].concat(mainClippingParents,[rootBoundary]),firstClippingParent=clippingParents[0],clippingRect=clippingParents.reduce(function(accRect,clippingParent){var rect=getClientRectFromMixedType(element,clippingParent,strategy);return accRect.top=max(rect.top,accRect.top),accRect.right=min(rect.right,accRect.right),accRect.bottom=min(rect.bottom,accRect.bottom),accRect.left=max(rect.left,accRect.left),accRect},getClientRectFromMixedType(element,firstClippingParent,strategy));return clippingRect.width=clippingRect.right-clippingRect.left,clippingRect.height=clippingRect.bottom-clippingRect.top,clippingRect.x=clippingRect.left,clippingRect.y=clippingRect.top,clippingRect}function computeOffsets(_ref){var offsets,len,reference=_ref.reference,element=_ref.element,placement=_ref.placement,basePlacement=placement?getBasePlacement(placement):null,variation=placement?getVariation(placement):null,commonX=reference.x+reference.width/2-element.width/2,commonY=reference.y+reference.height/2-element.height/2;switch(basePlacement){case top:offsets={x:commonX,y:reference.y-element.height};break;case bottom:offsets={x:commonX,y:reference.y+reference.height};break;case right:offsets={x:reference.x+reference.width,y:commonY};break;case left:offsets={x:reference.x-element.width,y:commonY};break;default:offsets={x:reference.x,y:reference.y}}var mainAxis=basePlacement?getMainAxisFromPlacement(basePlacement):null;if(mainAxis!=null)switch(len=mainAxis==="y"?"height":"width",variation){case start:offsets[mainAxis]=offsets[mainAxis]-(reference[len]/2-element[len]/2);break;case end:offsets[mainAxis]=offsets[mainAxis]+(reference[len]/2-element[len]/2);break}return offsets}function detectOverflow(state,options){options===void 0&&(options={});var _options=options,_options$placement=_options.placement,placement=_options$placement===void 0?state.placement:_options$placement,_options$strategy=_options.strategy,strategy=_options$strategy===void 0?state.strategy:_options$strategy,_options$boundary=_options.boundary,boundary=_options$boundary===void 0?clippingParents:_options$boundary,_options$rootBoundary=_options.rootBoundary,rootBoundary=_options$rootBoundary===void 0?viewport:_options$rootBoundary,_options$elementConte=_options.elementContext,elementContext=_options$elementConte===void 0?popper:_options$elementConte,_options$altBoundary=_options.altBoundary,altBoundary=_options$altBoundary!==void 0&&_options$altBoundary,_options$padding=_options.padding,padding=_options$padding===void 0?0:_options$padding,paddingObject=mergePaddingOb
vendor: 9,982 bytes, line 7
7ject(typeof padding!="number"?padding:expandToHashMap(padding,basePlacements)),altContext=elementContext===popper?reference:popper,popperRect=state.rects.popper,element=state.elements[altBoundary?altContext:elementContext],clippingClientRect=getClippingRect(isElement(element)?element:element.contextElement||getDocumentElement(state.elements.popper),boundary,rootBoundary,strategy),referenceClientRect=getBoundingClientRect(state.elements.reference),popperOffsets=computeOffsets({reference:referenceClientRect,element:popperRect,strategy:"absolute",placement}),popperClientRect=rectToClientRect(Object.assign({},popperRect,popperOffsets)),elementClientRect=elementContext===popper?popperClientRect:referenceClientRect,overflowOffsets={top:clippingClientRect.top-elementClientRect.top+paddingObject.top,bottom:elementClientRect.bottom-clippingClientRect.bottom+paddingObject.bottom,left:clippingClientRect.left-elementClientRect.left+paddingObject.left,right:elementClientRect.right-clippingClientRect.right+paddingObject.right},offsetData=state.modifiersData.offset;if(elementContext===popper&&offsetData){var offset=offsetData[placement];Object.keys(overflowOffsets).forEach(function(key){var multiply=[right,bottom].indexOf(key)>=0?1:-1,axis=[top,bottom].indexOf(key)>=0?"y":"x";overflowOffsets[key]+=offset[axis]*multiply})}return overflowOffsets}function computeAutoPlacement(state,options){options===void 0&&(options={});var _options=options,placement=_options.placement,boundary=_options.boundary,rootBoundary=_options.rootBoundary,padding=_options.padding,flipVariations=_options.flipVariations,_options$allowedAutoP=_options.allowedAutoPlacements,allowedAutoPlacements=_options$allowedAutoP===void 0?placements:_options$allowedAutoP,variation=getVariation(placement),placements$1=variation?flipVariations?variationPlacements:variationPlacements.filter(function(placement){return getVariation(placement)===variation}):basePlacements,allowedPlacements=placements$1.filter(function(placement){return allowedAutoPlacements.indexOf(placement)>=0});allowedPlacements.length===0&&(allowedPlacements=placements$1);var overflows=allowedPlacements.reduce(function(acc,placement){return acc[placement]=detectOverflow(state,{placement,boundary,rootBoundary,padding})[getBasePlacement(placement)],acc},{});return Object.keys(overflows).sort(function(a,b){return overflows[a]-overflows[b]})}function getExpandedFallbackPlacements(placement){if(getBasePlacement(placement)===auto)return[];var oppositePlacement=getOppositePlacement(placement);return[getOppositeVariationPlacement(placement),oppositePlacement,getOppositeVariationPlacement(oppositePlacement)]}function flip(_ref){var state=_ref.state,options=_ref.options,name=_ref.name;if(state.modifiersData[name]._skip)return;for(var _options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0||_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis===void 0||_options$altAxis,specifiedFallbackPlacements=options.fallbackPlacements,padding=options.padding,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,_options$flipVariatio=options.flipVariations,flipVariations=_options$flipVariatio===void 0||_options$flipVariatio,allowedAutoPlacements=options.allowedAutoPlacements,preferredPlacement=state.options.placement,basePlacement=getBasePlacement(preferredPlacement),isBasePlacement=basePlacement===preferredPlacement,fallbackPlacements=specifiedFallbackPlacements||(isBasePlacement||!flipVariations?[getOppositePlacement(preferredPlacement)]:getExpandedFallbackPlacements(preferredPlacement)),placements=[preferredPlacement].concat(fallbackPlacements).reduce(function(acc,placement){return acc.concat(getBasePlacement(placement)===auto?computeAutoPlacement(state,{placement,boundary,rootBoundary,padding,flipVariations,allowedAutoPlacements}):placement)},[]),referenceRect=state.rects.reference,popperRect=state.rects.popper,checksMap=new Map,makeFallbackChecks=!0,firstFittingPlacement=placements[0],i=0;i<placements.length;i++){var placement=placements[i],_basePlacement=getBasePlacement(placement),isStartVariation=getVariation(placement)===start,isVertical=[top,bottom].indexOf(_basePlacement)>=0,len=isVertical?"width":"height",overflow=detectOverflow(state,{placement,boundary,rootBoundary,altBoundary,padding}),mainVariationSide=isVertical?isStartVariation?right:left:isStartVariation?bottom:top;referenceRect[len]>popperRect[len]&&(mainVariationSide=getOppositePlacement(mainVariationSide));var altVariationSide=getOppositePlacement(mainVariationSide),checks=[];if(checkMainAxis&&checks.push(overflow[_basePlacement]<=0),checkAltAxis&&checks.push(overflow[mainVariationSide]<=0,overflow[altVariationSide]<=0),checks.every(function(check){return check})){firstFittingPlacement=placement,makeFallbackChecks=!1;break}checksMap.set(placement,checks)}if(makeFallbackChecks)for(var numberOfChecks=flipVariations?3:1,_loop=function(_i){var fittingPlacement=placements.find(function(placement){var checks=checksMap.get(placement);if(checks)return checks.slice(0,_i).every(function(check){return check})});if(fittingPlacement)return firstFittingPlacement=fittingPlacement,"break"},_i=numberOfChecks;_i>0;_i--){var _ret=_loop(_i);if(_ret==="break")break}state.placement!==firstFittingPlacement&&(state.modifiersData[name]._skip=!0,state.placement=firstFittingPlacement,state.reset=!0)}const flip$1={name:"flip",enabled:!0,phase:"main",fn:flip,requiresIfExists:["offset"],data:{_skip:!1}};function getSideOffsets(overflow,rect,preventedOffsets){return preventedOffsets===void 0&&(preventedOffsets={x:0,y:0}),{top:overflow.top-rect.height-preventedOffsets.y,right:overflow.right-rect.width+preventedOffsets.x,bottom:overflow.bottom-rect.height+preventedOffsets.y,left:overflow.left-rect.width-preventedOffsets.x}}function isAnySideFullyClipped(overflow){return[top,right,bottom,left].some(function(side){return overflow[side]>=0})}function hide(_ref){var state=_ref.state,name=_ref.name,referenceRect=state.rects.reference,popperRect=state.rects.popper,preventedOffsets=state.modifiersData.preventOverflow,referenceOverflow=detectOverflow(state,{elementContext:"reference"}),popperAltOverflow=detectOverflow(state,{altBoundary:!0}),referenceClippingOffsets=getSideOffsets(referenceOverflow,referenceRect),popperEscapeOffsets=getSideOffsets(popperAltOverflow,popperRect,preventedOffsets),isReferenceHidden=isAnySideFullyClipped(referenceClippingOffsets),hasPopperEscaped=isAnySideFullyClipped(popperEscapeOffsets);state.modifiersData[name]={referenceClippingOffsets,popperEscapeOffsets,isReferenceHidden,hasPopperEscaped},state.attributes.popper=Object.assign({},state.attributes.popper,{"data-popper-reference-hidden":isReferenceHidden,"data-popper-escaped":hasPopperEscaped})}const hide$1={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:hide};function distanceAndSkiddingToXY(placement,rects,offset){var basePlacement=getBasePlacement(placement),invertDistance=[left,top].indexOf(basePlacement)>=0?-1:1,_ref=typeof offset=="function"?offset(Object.assign({},rects,{placement})):offset,skidding=_ref[0],distance=_ref[1],skidding=skidding||0,distance=(distance||0)*invertDistance;return[left,right].indexOf(basePlacement)>=0?{x:distance,y:skidding}:{x:skidding,y:distance}}function offset(_ref2){var state=_ref2.state,options=_ref2.options,name=_ref2.name,_options$offset=options.offset,offset=_options$offset===void 0?[0,0]:_options$offset,data=placements.reduce(function(acc,placement){return acc[placement]=distanceAndSkiddingToXY(placement,state.rects,offset),acc},{}),_data$state$placement=data[state.placement],x=_data$state$placement.x,y=_data$state$placement.y;state.modifiersData.popperOffsets!=null&&(state.modifiersData.popperOffsets.x+=x,state.modifiersData.popperOffsets.y+=y),state.modifiersData[name]=data}const offset$1={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:offset};function popperOffsets(_ref){var state=_ref.state,name=_ref.name;state.modifiersData[name]=computeOffsets({reference:state.rects.reference,element:state.rects.popper,strategy:"absolute",placement:state.placement})}const popperOffsets$1={name:"popperOffsets",enabled:!0,phase:"read",fn:popperOffsets,data:{}};function getAltAxis(axis){return axis==="x"?"y":"x"}function preventOverflow(_ref){var _offsetModifierState$,_offsetModifierState$2,state=_ref.state,options=_ref.options,name=_ref.name,_options$mainAxis=options.mainAxis,checkMainAxis=_options$mainAxis===void 0||_options$mainAxis,_options$altAxis=options.altAxis,checkAltAxis=_options$altAxis!==void 0&&_options$altAxis,boundary=options.boundary,rootBoundary=options.rootBoundary,altBoundary=options.altBoundary,padding=options.padding,_options$tether=options.tether,tether=_options$tether===void 0||_options$tether,_options$tetherOffset=options.tetherOffset,tetherOffset=_options$tetherOffset===void 0?0:_options$tetherOffset,overflow=detectOverflow(state,{boundary,rootBoundary,padding,altBoundary}),basePlacement=getBasePlacement(state.placement),variation=getVariation(state.placement),isBasePlacement=!variation,mainAxis=getMainAxisFromPlacement(basePlacement),altAxis=getAltAxis(mainAxis),popperOffsets=state.modifiersData.popperOffsets,referenceRect=state.rects.reference,popperRect=state.rects.popper,tetherOffsetValue=typeof tetherOffset=="function"?tetherOffset(Object.assign({},state.rects,{placement:state.placement})):tetherOffset,normalizedTetherOffsetValue=typeof tetherOffsetValue=="number"?{mainAxis:tetherOffsetValue,altAxis:tetherOffsetValue}:Object.assign({mainAxis:0,altAxis:0},tetherOffsetValue),offsetModifierState=state.modifiersData.offset?state.modifiersData.offset[state.placement]:null,data={x:0,y:0};if(!popperOffsets)return;if(checkMainAxis){var mainSide=mainAxis==="y"?top:left,altSide=mainAxis==="y"?bottom:right,len=mainAxis==="y"?"height":"width",offset=popperOffsets[mainAxis],min$1=offset+overflow[mainSide],max$1=offset-
vendor: 4,167 bytes, line 7
7overflow[altSide],additive=tether?-popperRect[len]/2:0,minLen=variation===start?referenceRect[len]:popperRect[len],maxLen=variation===start?-popperRect[len]:-referenceRect[len],arrowElement=state.elements.arrow,arrowRect=tether&&arrowElement?getLayoutRect(arrowElement):{width:0,height:0},arrowPaddingObject=state.modifiersData["arrow#persistent"]?state.modifiersData["arrow#persistent"].padding:getFreshSideObject(),arrowPaddingMin=arrowPaddingObject[mainSide],arrowPaddingMax=arrowPaddingObject[altSide],arrowLen=within(0,referenceRect[len],arrowRect[len]),minOffset=isBasePlacement?referenceRect[len]/2-additive-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis:minLen-arrowLen-arrowPaddingMin-normalizedTetherOffsetValue.mainAxis,maxOffset=isBasePlacement?-referenceRect[len]/2+additive+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis:maxLen+arrowLen+arrowPaddingMax+normalizedTetherOffsetValue.mainAxis,arrowOffsetParent=state.elements.arrow&&getOffsetParent(state.elements.arrow),clientOffset=arrowOffsetParent?mainAxis==="y"?arrowOffsetParent.clientTop||0:arrowOffsetParent.clientLeft||0:0,offsetModifierValue=(_offsetModifierState$=offsetModifierState?.[mainAxis])!=null?_offsetModifierState$:0,tetherMin=offset+minOffset-offsetModifierValue-clientOffset,tetherMax=offset+maxOffset-offsetModifierValue,preventedOffset=within(tether?min(min$1,tetherMin):min$1,offset,tether?max(max$1,tetherMax):max$1);popperOffsets[mainAxis]=preventedOffset,data[mainAxis]=preventedOffset-offset}if(checkAltAxis){var _mainSide=mainAxis==="x"?top:left,_altSide=mainAxis==="x"?bottom:right,_offset=popperOffsets[altAxis],_len=altAxis==="y"?"height":"width",_min=_offset+overflow[_mainSide],_max=_offset-overflow[_altSide],isOriginSide=[top,left].indexOf(basePlacement)!==-1,_offsetModifierValue=(_offsetModifierState$2=offsetModifierState?.[altAxis])!=null?_offsetModifierState$2:0,_tetherMin=isOriginSide?_min:_offset-referenceRect[_len]-popperRect[_len]-_offsetModifierValue+normalizedTetherOffsetValue.altAxis,_tetherMax=isOriginSide?_offset+referenceRect[_len]+popperRect[_len]-_offsetModifierValue-normalizedTetherOffsetValue.altAxis:_max,_preventedOffset=tether&&isOriginSide?withinMaxClamp(_tetherMin,_offset,_tetherMax):within(tether?_tetherMin:_min,_offset,tether?_tetherMax:_max);popperOffsets[altAxis]=_preventedOffset,data[altAxis]=_preventedOffset-_offset}state.modifiersData[name]=data}const preventOverflow$1={name:"preventOverflow",enabled:!0,phase:"main",fn:preventOverflow,requiresIfExists:["offset"]};function getHTMLElementScroll(element){return{scrollLeft:element.scrollLeft,scrollTop:element.scrollTop}}function getNodeScroll(node){return node===getWindow(node)||!isHTMLElement(node)?getWindowScroll(node):getHTMLElementScroll(node)}function isElementScaled(element){var rect=element.getBoundingClientRect(),scaleX=round(rect.width)/element.offsetWidth||1,scaleY=round(rect.height)/element.offsetHeight||1;return scaleX!==1||scaleY!==1}function getCompositeRect(elementOrVirtualElement,offsetParent,isFixed){isFixed===void 0&&(isFixed=!1);var isOffsetParentAnElement=isHTMLElement(offsetParent),offsetParentIsScaled=isHTMLElement(offsetParent)&&isElementScaled(offsetParent),documentElement=getDocumentElement(offsetParent),rect=getBoundingClientRect(elementOrVirtualElement,offsetParentIsScaled,isFixed),scroll={scrollLeft:0,scrollTop:0},offsets={x:0,y:0};return(isOffsetParentAnElement||!isOffsetParentAnElement&&!isFixed)&&((getNodeName(offsetParent)!=="body"||isScrollParent(documentElement))&&(scroll=getNodeScroll(offsetParent)),isHTMLElement(offsetParent)?(offsets=getBoundingClientRect(offsetParent,!0),offsets.x+=offsetParent.clientLeft,offsets.y+=offsetParent.clientTop):documentElement&&(offsets.x=getWindowScrollBarX(documentElement))),{x:rect.left+scroll.scrollLeft-offsets.x,y:rect.top+scroll.scrollTop-offsets.y,width:rect.width,height:rect.height}}function order(modifiers){var map=new Map,visited=new Set,result=[];modifiers.forEach(function(modifier){map.set(modifier.name,modifier)});function sort(modifier){visited.add(modifier.name);var requires=[].concat(modifier.requires||[],modifier.requiresIfExists||[]);
vendor: 4,163 bytes, line 7
7requires.forEach(function(dep){if(!visited.has(dep)){var depModifier=map.get(dep);depModifier&&sort(depModifier)}}),result.push(modifier)}return modifiers.forEach(function(modifier){visited.has(modifier.name)||sort(modifier)}),result}function orderModifiers(modifiers){var orderedModifiers=order(modifiers);return modifierPhases.reduce(function(acc,phase){return acc.concat(orderedModifiers.filter(function(modifier){return modifier.phase===phase}))},[])}function debounce(fn){var pending;return function(){return pending||(pending=new Promise(function(resolve){Promise.resolve().then(function(){pending=void 0,resolve(fn())})})),pending}}function mergeByName(modifiers){var merged=modifiers.reduce(function(merged,current){var existing=merged[current.name];return merged[current.name]=existing?Object.assign({},existing,current,{options:Object.assign({},existing.options,current.options),data:Object.assign({},existing.data,current.data)}):current,merged},{});return Object.keys(merged).map(function(key){return merged[key]})}var DEFAULT_OPTIONS={placement:"bottom",modifiers:[],strategy:"absolute"};function areValidElements(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++)args[_key]=arguments[_key];return!args.some(function(element){return!element||typeof element.getBoundingClientRect!="function"})}function popperGenerator(generatorOptions){generatorOptions===void 0&&(generatorOptions={});var _generatorOptions=generatorOptions,_generatorOptions$def=_generatorOptions.defaultModifiers,defaultModifiers=_generatorOptions$def===void 0?[]:_generatorOptions$def,_generatorOptions$def2=_generatorOptions.defaultOptions,defaultOptions=_generatorOptions$def2===void 0?DEFAULT_OPTIONS:_generatorOptions$def2;return function(reference,popper,options){options===void 0&&(options=defaultOptions);var state={placement:"bottom",orderedModifiers:[],options:Object.assign({},DEFAULT_OPTIONS,defaultOptions),modifiersData:{},elements:{reference,popper},attributes:{},styles:{}},effectCleanupFns=[],isDestroyed=!1,instance={state,setOptions:function(setOptionsAction){var options=typeof setOptionsAction=="function"?setOptionsAction(state.options):setOptionsAction;cleanupModifierEffects(),state.options=Object.assign({},defaultOptions,state.options,options),state.scrollParents={reference:isElement(reference)?listScrollParents(reference):reference.contextElement?listScrollParents(reference.contextElement):[],popper:listScrollParents(popper)};var orderedModifiers=orderModifiers(mergeByName([].concat(defaultModifiers,state.options.modifiers)));return state.orderedModifiers=orderedModifiers.filter(function(m){return m.enabled}),runModifierEffects(),instance.update()},forceUpdate:function(){if(isDestroyed)return;var _state$elements=state.elements,reference=_state$elements.reference,popper=_state$elements.popper;if(!areValidElements(reference,popper))return;state.rects={reference:getCompositeRect(reference,getOffsetParent(popper),state.options.strategy==="fixed"),popper:getLayoutRect(popper)},state.reset=!1,state.placement=state.options.placement,state.orderedModifiers.forEach(function(modifier){return state.modifiersData[modifier.name]=Object.assign({},modifier.data)});for(var index=0;index<state.orderedModifiers.length;index++){if(state.reset===!0){state.reset=!1,index=-1;continue}var _state$orderedModifie=state.orderedModifiers[index],fn=_state$orderedModifie.fn,_state$orderedModifie2=_state$orderedModifie.options,_options=_state$orderedModifie2===void 0?{}:_state$orderedModifie2,name=_state$orderedModifie.name;typeof fn=="function"&&(state=fn({state,options:_options,name,instance})||state)}},update:debounce(function(){return new Promise(function(resolve){instance.forceUpdate(),resolve(state)})}),destroy:function(){cleanupModifierEffects(),isDestroyed=!0}};if(!areValidElements(reference,popper))return instance;instance.setOptions(options).then(function(state){!isDestroyed&&options.onFirstUpdate&&options.onFirstUpdate(state)});function runModifierEffects(){state.orderedModifiers.forEach(function(_ref){var name=_ref.name,_ref$options=_ref.options,options=_ref$options===void 0?{}:_ref$options,effect=_ref.effect;
7if(typeof effect=="function"){var cleanupFn=effect({state,name,instance,options}),noopFn=function(){};effectCleanupFns.push(cleanupFn||noopFn)}})}function cleanupModifierEffects(){effectCleanupFns.forEach(function(fn){return fn()}),effectCleanupFns=[]}return instance}}var createPopper$2=popperGenerator(),defaultModifiers$1=[eventListeners,popperOffsets$1,computeStyles$1,applyStyles$1],createPopper$1=popperGenerator({defaultModifiers:defaultModifiers$1}),defaultModifiers=[eventListeners,popperOffsets$1,computeStyles$1,applyStyles$1,offset$1,flip$1,preventOverflow$1,arrow$1,hide$1],createPopper=popperGenerator({defaultModifiers});const Popper=Object.freeze(Object.defineProperty({__proto__:null,afterMain,afterRead,afterWrite,applyStyles:applyStyles$1,arrow:arrow$1,auto,basePlacements,beforeMain,beforeRead,beforeWrite,bottom,clippingParents,computeStyles:computeStyles$1,createPopper,createPopperBase:createPopper$2,createPopperLite:createPopper$1,detectOverflow,end,eventListeners,flip:flip$1,hide:hide$1,left,main,modifierPhases,offset:offset$1,placements,popper,popperGenerator,popperOffsets:popperOffsets$1,preventOverflow:preventOverflow$1,read,reference,right,start,top,variationPlacements,viewport,write},Symbol.toStringTag,{value:"Module"})),NAME$a="dropdown",DATA_KEY$6="bs.dropdown",EVENT_KEY$6=`.${DATA_KEY$6}`,DATA_API_KEY$3=".data-api",ESCAPE_KEY$2="Escape",TAB_KEY$1="Tab",ARROW_UP_KEY$1="ArrowUp",ARROW_DOWN_KEY$1="ArrowDown",RIGHT_MOUSE_BUTTON=2,EVENT_HIDE$5=`hide${EVENT_KEY$6}`,EVENT_HIDDEN$5=`hidden${EVENT_KEY$6}`,EVENT_SHOW$5=`show${EVENT_KEY$6}`,EVENT_SHOWN$5=`shown${EVENT_KEY$6}`,EVENT_CLICK_DATA_API$3=`click${EVENT_KEY$6}${DATA_API_KEY$3}`,EVENT_KEYDOWN_DATA_API=`keydown${EVENT_KEY$6}${DATA_API_KEY$3}`,EVENT_KEYUP_DATA_API=`keyup${EVENT_KEY$6}${DATA_API_KEY$3}`,CLASS_NAME_SHOW$6="show",CLASS_NAME_DROPUP="dropup",CLASS_NAME_DROPEND="dropend",CLASS_NAME_DROPSTART="dropstart",CLASS_NAME_DROPUP_CENTER="dropup-center",CLASS_NAME_DROPDOWN_CENTER="dropdown-center",SELECTOR_DATA_TOGGLE$3='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',SELECTOR_DATA_TOGGLE_SHOWN=`${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`,SELECTOR_MENU=".dropdown-menu",SELECTOR_NAVBAR=".navbar",SELECTOR_NAVBAR_NAV=".navbar-nav",SELECTOR_VISIBLE_ITEMS=".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",PLACEMENT_TOP=isRTL()?"top-end":"top-start",PLACEMENT_TOPEND=isRTL()?"top-start":"top-end",PLACEMENT_BOTTOM=isRTL()?"bottom-end":"bottom-start",PLACEMENT_BOTTOMEND=isRTL()?"bottom-start":"bottom-end",PLACEMENT_RIGHT=isRTL()?"left-start":"right-start",PLACEMENT_LEFT=isRTL()?"right-start":"left-start",PLACEMENT_TOPCENTER="top",PLACEMENT_BOTTOMCENTER="bottom",Default$9={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},DefaultType$9={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class Dropdown extends BaseComponent{constructor(element,config){super(element,config),this._popper=null,this._parent=this._element.parentNode,this._menu=SelectorEngine.next(this._element,SELECTOR_MENU)[0]||SelectorEngine.prev(this._element,SELECTOR_MENU)[0]||SelectorEngine.findOne(SELECTOR_MENU,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return Default$9}static get DefaultType(){return DefaultType$9}static get NAME(){return NAME$a}toggle(){return this._isShown()?this.hide():this.show()}show(){if(isDisabled(this._element)||this._isShown())return;const relatedTarget={relatedTarget:this._element},showEvent=EventHandler.trigger(this._element,EVENT_SHOW$5,relatedTarget);if(showEvent.defaultPrevented)return;if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(SELECTOR_NAVBAR_NAV))for(const element of[].concat(...document.body.children))EventHandler.on(element,"mouseover",noop);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(CLASS_NAME_SHOW$6),this._element.classList.add(CLASS_NAME_SHOW$6),EventHandler.trigger(this._element,EVENT_SHOWN$5,relatedTarget)}
7hide(){if(isDisabled(this._element)||!this._isShown())return;const relatedTarget={relatedTarget:this._element};this._completeHide(relatedTarget)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(relatedTarget){const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE$5,relatedTarget);if(hideEvent.defaultPrevented)return;if("ontouchstart"in document.documentElement)for(const element of[].concat(...document.body.children))EventHandler.off(element,"mouseover",noop);this._popper&&this._popper.destroy(),this._menu.classList.remove(CLASS_NAME_SHOW$6),this._element.classList.remove(CLASS_NAME_SHOW$6),this._element.setAttribute("aria-expanded","false"),Manipulator.removeDataAttribute(this._menu,"popper"),EventHandler.trigger(this._element,EVENT_HIDDEN$5,relatedTarget)}_getConfig(config){if(config=super._getConfig(config),typeof config.reference=="object"&&!isElement$1(config.reference)&&typeof config.reference.getBoundingClientRect!="function")throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return config}_createPopper(){if(typeof Popper=="undefined")throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let referenceElement=this._element;this._config.reference==="parent"?referenceElement=this._parent:isElement$1(this._config.reference)?referenceElement=getElement(this._config.reference):typeof this._config.reference=="object"&&(referenceElement=this._config.reference);const popperConfig=this._getPopperConfig();this._popper=createPopper(referenceElement,this._menu,popperConfig)}_isShown(){return this._menu.classList.contains(CLASS_NAME_SHOW$6)}_getPlacement(){const parentDropdown=this._parent;if(parentDropdown.classList.contains(CLASS_NAME_DROPEND))return PLACEMENT_RIGHT;if(parentDropdown.classList.contains(CLASS_NAME_DROPSTART))return PLACEMENT_LEFT;if(parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER))return PLACEMENT_TOPCENTER;if(parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER))return PLACEMENT_BOTTOMCENTER;const isEnd=getComputedStyle(this._menu).getPropertyValue("--bs-position").trim()==="end";return parentDropdown.classList.contains(CLASS_NAME_DROPUP)?isEnd?PLACEMENT_TOPEND:PLACEMENT_TOP:isEnd?PLACEMENT_BOTTOMEND:PLACEMENT_BOTTOM}_detectNavbar(){return this._element.closest(SELECTOR_NAVBAR)!==null}_getOffset(){const{offset}=this._config;return typeof offset=="string"?offset.split(",").map(value=>Number.parseInt(value,10)):typeof offset=="function"?popperData=>offset(popperData,this._element):offset}_getPopperConfig(){const defaultBsPopperConfig={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||this._config.display==="static")&&(Manipulator.setDataAttribute(this._menu,"popper","static"),defaultBsPopperConfig.modifiers=[{name:"applyStyles",enabled:!1}]),{...defaultBsPopperConfig,...execute(this._config.popperConfig,[defaultBsPopperConfig])}}_selectMenuItem({key,target}){const items=SelectorEngine.find(SELECTOR_VISIBLE_ITEMS,this._menu).filter(element=>isVisible(element));if(!items.length)return;getNextActiveElement(items,target,key===ARROW_DOWN_KEY$1,!items.includes(target)).focus()}static jQueryInterface(config){return this.each(function(){const data=Dropdown.getOrCreateInstance(this,config);if(typeof config!="string")return;if(typeof data[config]=="undefined")throw new TypeError(`No method named "${config}"`);data[config]()})}static clearMenus(event){if(event.button===RIGHT_MOUSE_BUTTON||event.type==="keyup"&&event.key!==TAB_KEY$1)return;const openToggles=SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);for(const toggle of openToggles){const context=Dropdown.getInstance(toggle);if(!context||context._config.autoClose===!1)continue;const composedPath=event.composedPath(),isMenuTarget=composedPath.includes(context._menu);if(composedPath.includes(context._element)||context._config.autoClose==="inside"&&!isMenuTarget||context._config.autoClose==="outside"&&isMenuTarget)continue;
vendor: 7,129 bytes, line 7
7if(context._menu.contains(event.target)&&(event.type==="keyup"&&event.key===TAB_KEY$1||/input|select|option|textarea|form/i.test(event.target.tagName)))continue;const relatedTarget={relatedTarget:context._element};event.type==="click"&&(relatedTarget.clickEvent=event),context._completeHide(relatedTarget)}}static dataApiKeydownHandler(event){const isInput=/input|textarea/i.test(event.target.tagName),isEscapeEvent=event.key===ESCAPE_KEY$2,isUpOrDownEvent=[ARROW_UP_KEY$1,ARROW_DOWN_KEY$1].includes(event.key);if(!isUpOrDownEvent&&!isEscapeEvent)return;if(isInput&&!isEscapeEvent)return;event.preventDefault();const getToggleButton=this.matches(SELECTOR_DATA_TOGGLE$3)?this:SelectorEngine.prev(this,SELECTOR_DATA_TOGGLE$3)[0]||SelectorEngine.next(this,SELECTOR_DATA_TOGGLE$3)[0]||SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3,event.delegateTarget.parentNode),instance=Dropdown.getOrCreateInstance(getToggleButton);if(isUpOrDownEvent){event.stopPropagation(),instance.show(),instance._selectMenuItem(event);return}instance._isShown()&&(event.stopPropagation(),instance.hide(),getToggleButton.focus())}}EventHandler.on(document,EVENT_KEYDOWN_DATA_API,SELECTOR_DATA_TOGGLE$3,Dropdown.dataApiKeydownHandler),EventHandler.on(document,EVENT_KEYDOWN_DATA_API,SELECTOR_MENU,Dropdown.dataApiKeydownHandler),EventHandler.on(document,EVENT_CLICK_DATA_API$3,Dropdown.clearMenus),EventHandler.on(document,EVENT_KEYUP_DATA_API,Dropdown.clearMenus),EventHandler.on(document,EVENT_CLICK_DATA_API$3,SELECTOR_DATA_TOGGLE$3,function(event){event.preventDefault(),Dropdown.getOrCreateInstance(this).toggle()}),defineJQueryPlugin(Dropdown);const NAME$9="backdrop",CLASS_NAME_FADE$4="fade",CLASS_NAME_SHOW$5="show",EVENT_MOUSEDOWN=`mousedown.bs.${NAME$9}`,Default$8={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},DefaultType$8={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Backdrop extends Config{constructor(config){super(),this._config=this._getConfig(config),this._isAppended=!1,this._element=null}static get Default(){return Default$8}static get DefaultType(){return DefaultType$8}static get NAME(){return NAME$9}show(callback){if(!this._config.isVisible){execute(callback);return}this._append();const element=this._getElement();this._config.isAnimated&&reflow(element),element.classList.add(CLASS_NAME_SHOW$5),this._emulateAnimation(()=>{execute(callback)})}hide(callback){if(!this._config.isVisible){execute(callback);return}this._getElement().classList.remove(CLASS_NAME_SHOW$5),this._emulateAnimation(()=>{this.dispose(),execute(callback)})}dispose(){if(!this._isAppended)return;EventHandler.off(this._element,EVENT_MOUSEDOWN),this._element.remove(),this._isAppended=!1}_getElement(){if(!this._element){const backdrop=document.createElement("div");backdrop.className=this._config.className,this._config.isAnimated&&backdrop.classList.add(CLASS_NAME_FADE$4),this._element=backdrop}return this._element}_configAfterMerge(config){return config.rootElement=getElement(config.rootElement),config}_append(){if(this._isAppended)return;const element=this._getElement();this._config.rootElement.append(element),EventHandler.on(element,EVENT_MOUSEDOWN,()=>{execute(this._config.clickCallback)}),this._isAppended=!0}_emulateAnimation(callback){executeAfterTransition(callback,this._getElement(),this._config.isAnimated)}}const NAME$8="focustrap",DATA_KEY$5="bs.focustrap",EVENT_KEY$5=`.${DATA_KEY$5}`,EVENT_FOCUSIN$2=`focusin${EVENT_KEY$5}`,EVENT_KEYDOWN_TAB=`keydown.tab${EVENT_KEY$5}`,TAB_KEY="Tab",TAB_NAV_FORWARD="forward",TAB_NAV_BACKWARD="backward",Default$7={autofocus:!0,trapElement:null},DefaultType$7={autofocus:"boolean",trapElement:"element"};class FocusTrap extends Config{constructor(config){super(),this._config=this._getConfig(config),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return Default$7}static get DefaultType(){return DefaultType$7}static get NAME(){return NAME$8}activate(){if(this._isActive)return;this._config.autofocus&&this._config.trapElement.focus(),EventHandler.off(document,EVENT_KEY$5),EventHandler.on(document,EVENT_FOCUSIN$2,event=>this._handleFocusin(event)),EventHandler.on(document,EVENT_KEYDOWN_TAB,event=>this._handleKeydown(event)),this._isActive=!0}deactivate(){if(!this._isActive)return;this._isActive=!1,EventHandler.off(document,EVENT_KEY$5)}_handleFocusin(event){const{trapElement}=this._config;if(event.target===document||event.target===trapElement||trapElement.contains(event.target))return;const elements=SelectorEngine.focusableChildren(trapElement);elements.length===0?trapElement.focus():this._lastTabNavDirection===TAB_NAV_BACKWARD?elements[elements.length-1].focus():elements[0].focus()}_handleKeydown(event){if(event.key!==TAB_KEY)return;this._lastTabNavDirection=event.shiftKey?TAB_NAV_BACKWARD:TAB_NAV_FORWARD}}const SELECTOR_FIXED_CONTENT=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",SELECTOR_STICKY_CONTENT=".sticky-top",PROPERTY_PADDING="padding-right",PROPERTY_MARGIN="margin-right";class ScrollBarHelper{constructor(){this._element=document.body}getWidth(){const documentWidth=document.documentElement.clientWidth;return Math.abs(window.innerWidth-documentWidth)}hide(){const width=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,PROPERTY_PADDING,calculatedValue=>calculatedValue+width),this._setElementAttributes(SELECTOR_FIXED_CONTENT,PROPERTY_PADDING,calculatedValue=>calculatedValue+width),this._setElementAttributes(SELECTOR_STICKY_CONTENT,PROPERTY_MARGIN,calculatedValue=>calculatedValue-width)}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,PROPERTY_PADDING),this._resetElementAttributes(SELECTOR_FIXED_CONTENT,PROPERTY_PADDING),this._resetElementAttributes(SELECTOR_STICKY_CONTENT,PROPERTY_MARGIN)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(selector,styleProperty,callback){const scrollbarWidth=this.getWidth(),manipulationCallBack=element=>{if(element!==this._element&&window.innerWidth>element.clientWidth+scrollbarWidth)return;this._saveInitialAttribute(element,styleProperty);const calculatedValue=window.getComputedStyle(element).getPropertyValue(styleProperty);element.style.setProperty(styleProperty,`${callback(Number.parseFloat(calculatedValue))}px`)};this._applyManipulationCallback(selector,manipulationCallBack)}_saveInitialAttribute(element,styleProperty){const actualValue=element.style.getPropertyValue(styleProperty);actualValue&&Manipulator.setDataAttribute(element,styleProperty,actualValue)}_resetElementAttributes(selector,styleProperty){const manipulationCallBack=element=>{const value=Manipulator.getDataAttribute(element,styleProperty);if(value===null){element.style.removeProperty(styleProperty);return}Manipulator.removeDataAttribute(element,styleProperty),element.style.setProperty(styleProperty,value)};this._applyManipulationCallback(selector,manipulationCallBack)}
7_applyManipulationCallback(selector,callBack){if(isElement$1(selector)){callBack(selector);return}for(const sel of SelectorEngine.find(selector,this._element))callBack(sel)}}const NAME$7="modal",DATA_KEY$4="bs.modal",EVENT_KEY$4=`.${DATA_KEY$4}`,DATA_API_KEY$2=".data-api",ESCAPE_KEY$1="Escape",EVENT_HIDE$4=`hide${EVENT_KEY$4}`,EVENT_HIDE_PREVENTED$1=`hidePrevented${EVENT_KEY$4}`,EVENT_HIDDEN$4=`hidden${EVENT_KEY$4}`,EVENT_SHOW$4=`show${EVENT_KEY$4}`,EVENT_SHOWN$4=`shown${EVENT_KEY$4}`,EVENT_RESIZE$1=`resize${EVENT_KEY$4}`,EVENT_CLICK_DISMISS=`click.dismiss${EVENT_KEY$4}`,EVENT_MOUSEDOWN_DISMISS=`mousedown.dismiss${EVENT_KEY$4}`,EVENT_KEYDOWN_DISMISS$1=`keydown.dismiss${EVENT_KEY$4}`,EVENT_CLICK_DATA_API$2=`click${EVENT_KEY$4}${DATA_API_KEY$2}`,CLASS_NAME_OPEN="modal-open",CLASS_NAME_FADE$3="fade",CLASS_NAME_SHOW$4="show",CLASS_NAME_STATIC="modal-static",OPEN_SELECTOR$1=".modal.show",SELECTOR_DIALOG=".modal-dialog",SELECTOR_MODAL_BODY=".modal-body",SELECTOR_DATA_TOGGLE$2='[data-bs-toggle="modal"]',Default$6={backdrop:!0,focus:!0,keyboard:!0},DefaultType$6={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class Modal extends BaseComponent{constructor(element,config){super(element,config),this._dialog=SelectorEngine.findOne(SELECTOR_DIALOG,this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new ScrollBarHelper,this._addEventListeners()}static get Default(){return Default$6}static get DefaultType(){return DefaultType$6}static get NAME(){return NAME$7}toggle(relatedTarget){return this._isShown?this.hide():this.show(relatedTarget)}show(relatedTarget){if(this._isShown||this._isTransitioning)return;const showEvent=EventHandler.trigger(this._element,EVENT_SHOW$4,{relatedTarget});if(showEvent.defaultPrevented)return;this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(CLASS_NAME_OPEN),this._adjustDialog(),this._backdrop.show(()=>this._showElement(relatedTarget))}hide(){if(!this._isShown||this._isTransitioning)return;const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE$4);if(hideEvent.defaultPrevented)return;this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(CLASS_NAME_SHOW$4),this._queueCallback(()=>this._hideModal(),this._element,this._isAnimated())}dispose(){EventHandler.off(window,EVENT_KEY$4),EventHandler.off(this._dialog,EVENT_KEY$4),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Backdrop({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new FocusTrap({trapElement:this._element})}_showElement(relatedTarget){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const modalBody=SelectorEngine.findOne(SELECTOR_MODAL_BODY,this._dialog);modalBody&&(modalBody.scrollTop=0),reflow(this._element),this._element.classList.add(CLASS_NAME_SHOW$4);const transitionComplete=()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,EventHandler.trigger(this._element,EVENT_SHOWN$4,{relatedTarget})};this._queueCallback(transitionComplete,this._dialog,this._isAnimated())}_addEventListeners(){EventHandler.on(this._element,EVENT_KEYDOWN_DISMISS$1,event=>{if(event.key!==ESCAPE_KEY$1)return;if(this._config.keyboard){this.hide();return}this._triggerBackdropTransition()}),EventHandler.on(window,EVENT_RESIZE$1,()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()}),EventHandler.on(this._element,EVENT_MOUSEDOWN_DISMISS,event=>{EventHandler.one(this._element,EVENT_CLICK_DISMISS,event2=>{if(this._element!==event.target||this._element!==event2.target)return;if(this._config.backdrop==="static"){this._triggerBackdropTransition();return}this._config.backdrop&&this.hide()})})}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide(()=>{document.body.classList.remove(CLASS_NAME_OPEN),this._resetAdjustments(),this._scrollBar.reset(),EventHandler.trigger(this._element,EVENT_HIDDEN$4)})}_isAnimated(){return this._element.classList.contains(CLASS_NAME_FADE$3)}_triggerBackdropTransition(){const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE_PREVENTED$1);if(hideEvent.defaultPrevented)return;const isModalOverflowing=this._element.scrollHeight>document.documentElement.clientHeight,initialOverflowY=this._element.style.overflowY;if(initialOverflowY==="hidden"||this._element.classList.contains(CLASS_NAME_STATIC))return;isModalOverflowing||(this._element.style.overflowY="hidden"),this._element.classList.add(CLASS_NAME_STATIC),this._queueCallback(()=>{this._element.classList.remove(CLASS_NAME_STATIC),this._queueCallback(()=>{this._element.style.overflowY=initialOverflowY},this._dialog)},this._dialog),this._element.focus()}_adjustDialog(){const isModalOverflowing=this._element.scrollHeight>document.documentElement.clientHeight,scrollbarWidth=this._scrollBar.getWidth(),isBodyOverflowing=scrollbarWidth>0;if(isBodyOverflowing&&!isModalOverflowing){const property=isRTL()?"paddingLeft":"paddingRight";this._element.style[property]=`${scrollbarWidth}px`}if(!isBodyOverflowing&&isModalOverflowing){const property=isRTL()?"paddingRight":"paddingLeft";this._element.style[property]=`${scrollbarWidth}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(config,relatedTarget){return this.each(function(){const data=Modal.getOrCreateInstance(this,config);if(typeof config!="string")return;if(typeof data[config]=="undefined")throw new TypeError(`No method n
7amed "${config}"`);data[config](relatedTarget)})}}EventHandler.on(document,EVENT_CLICK_DATA_API$2,SELECTOR_DATA_TOGGLE$2,function(event){const target=SelectorEngine.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&event.preventDefault(),EventHandler.one(target,EVENT_SHOW$4,showEvent=>{if(showEvent.defaultPrevented)return;EventHandler.one(target,EVENT_HIDDEN$4,()=>{isVisible(this)&&this.focus()})});const alreadyOpen=SelectorEngine.findOne(OPEN_SELECTOR$1);alreadyOpen&&Modal.getInstance(alreadyOpen).hide();const data=Modal.getOrCreateInstance(target);data.toggle(this)}),enableDismissTrigger(Modal),defineJQueryPlugin(Modal);const NAME$6="offcanvas",DATA_KEY$3="bs.offcanvas",EVENT_KEY$3=`.${DATA_KEY$3}`,DATA_API_KEY$1=".data-api",EVENT_LOAD_DATA_API$2=`load${EVENT_KEY$3}${DATA_API_KEY$1}`,ESCAPE_KEY="Escape",CLASS_NAME_SHOW$3="show",CLASS_NAME_SHOWING$1="showing",CLASS_NAME_HIDING="hiding",CLASS_NAME_BACKDROP="offcanvas-backdrop",OPEN_SELECTOR=".offcanvas.show",EVENT_SHOW$3=`show${EVENT_KEY$3}`,EVENT_SHOWN$3=`shown${EVENT_KEY$3}`,EVENT_HIDE$3=`hide${EVENT_KEY$3}`,EVENT_HIDE_PREVENTED=`hidePrevented${EVENT_KEY$3}`,EVENT_HIDDEN$3=`hidden${EVENT_KEY$3}`,EVENT_RESIZE=`resize${EVENT_KEY$3}`,EVENT_CLICK_DATA_API$1=`click${EVENT_KEY$3}${DATA_API_KEY$1}`,EVENT_KEYDOWN_DISMISS=`keydown.dismiss${EVENT_KEY$3}`,SELECTOR_DATA_TOGGLE$1='[data-bs-toggle="offcanvas"]',Default$5={backdrop:!0,keyboard:!0,scroll:!1},DefaultType$5={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Offcanvas extends BaseComponent{constructor(element,config){super(element,config),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return Default$5}static get DefaultType(){return DefaultType$5}static get NAME(){return NAME$6}toggle(relatedTarget){return this._isShown?this.hide():this.show(relatedTarget)}show(relatedTarget){if(this._isShown)return;const showEvent=EventHandler.trigger(this._element,EVENT_SHOW$3,{relatedTarget});if(showEvent.defaultPrevented)return;this._isShown=!0,this._backdrop.show(),this._config.scroll||(new ScrollBarHelper).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(CLASS_NAME_SHOWING$1);const completeCallBack=()=>{(!this._config.scroll||this._config.backdrop)&&this._focustrap.activate(),this._element.classList.add(CLASS_NAME_SHOW$3),this._element.classList.remove(CLASS_NAME_SHOWING$1),EventHandler.trigger(this._element,EVENT_SHOWN$3,{relatedTarget})};this._queueCallback(completeCallBack,this._element,!0)}hide(){if(!this._isShown)return;const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE$3);if(hideEvent.defaultPrevented)return;this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(CLASS_NAME_HIDING),this._backdrop.hide();const completeCallback=()=>{this._element.classList.remove(CLASS_NAME_SHOW$3,CLASS_NAME_HIDING),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new ScrollBarHelper).reset(),EventHandler.trigger(this._element,EVENT_HIDDEN$3)};this._queueCallback(completeCallback,this._element,!0)}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const clickCallback=()=>{if(this._config.backdrop==="static"){EventHandler.trigger(this._element,EVENT_HIDE_PREVENTED);return}this.hide()},isVisible=Boolean(this._config.backdrop);return new Backdrop({className:CLASS_NAME_BACKDROP,isVisible,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:isVisible?clickCallback:null})}_initializeFocusTrap(){return new FocusTrap({trapElement:this._element})}_addEventListeners(){EventHandler.on(this._element,EVENT_KEYDOWN_DISMISS,event=>{if(event.key!==ESCAPE_KEY)return;if(this._config.keyboard){this.hide();return}EventHandler.trigger(this._element,EVENT_HIDE_PREVENTED)})}static jQueryInterface(config){return this.each(function(){const data=Offcanvas.getOrCreateInstance(this,config);if(typeof config!="string")return;if(data[config]===void 0||config.startsWith("_")||config==="constructor")throw new TypeError(`No method n
7amed "${config}"`);data[config](this)})}}EventHandler.on(document,EVENT_CLICK_DATA_API$1,SELECTOR_DATA_TOGGLE$1,function(event){const target=SelectorEngine.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&event.preventDefault(),isDisabled(this))return;EventHandler.one(target,EVENT_HIDDEN$3,()=>{isVisible(this)&&this.focus()});const alreadyOpen=SelectorEngine.findOne(OPEN_SELECTOR);alreadyOpen&&alreadyOpen!==target&&Offcanvas.getInstance(alreadyOpen).hide();const data=Offcanvas.getOrCreateInstance(target);data.toggle(this)}),EventHandler.on(window,EVENT_LOAD_DATA_API$2,()=>{for(const selector of SelectorEngine.find(OPEN_SELECTOR))Offcanvas.getOrCreateInstance(selector).show()}),EventHandler.on(window,EVENT_RESIZE,()=>{for(const element of SelectorEngine.find("[aria-modal][class*=show][class*=offcanvas-]"))getComputedStyle(element).position!=="fixed"&&Offcanvas.getOrCreateInstance(element).hide()}),enableDismissTrigger(Offcanvas),defineJQueryPlugin(Offcanvas);const ARIA_ATTRIBUTE_PATTERN=/^aria-[\w-]*$/i,DefaultAllowlist={"*":["class","dir","id","lang","role",ARIA_ATTRIBUTE_PATTERN],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},uriAttributes=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),SAFE_URL_PATTERN=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,allowedAttribute=(attribute,allowedAttributeList)=>{const attributeName=attribute.nodeName.toLowerCase();return allowedAttributeList.includes(attributeName)?!uriAttributes.has(attributeName)||Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue)):allowedAttributeList.filter(attributeRegex=>attributeRegex instanceof RegExp).some(regex=>regex.test(attributeName))};function sanitizeHtml(unsafeHtml,allowList,sanitizeFunction){if(!unsafeHtml.length)return unsafeHtml;if(sanitizeFunction&&typeof sanitizeFunction=="function")return sanitizeFunction(unsafeHtml);const domParser=new window.DOMParser,createdDocument=domParser.parseFromString(unsafeHtml,"text/html"),elements=[].concat(...createdDocument.body.querySelectorAll("*"));for(const element of elements){const elementName=element.nodeName.toLowerCase();if(!Object.keys(allowList).includes(elementName)){element.remove();continue}const attributeList=[].concat(...element.attributes),allowedAttributes=[].concat(allowList["*"]||[],allowList[elementName]||[]);for(const attribute of attributeList)allowedAttribute(attribute,allowedAttributes)||element.removeAttribute(attribute.nodeName)}return createdDocument.body.innerHTML}const NAME$5="TemplateFactory",Default$4={allowList:DefaultAllowlist,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"<div></div>"},DefaultType$4={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},DefaultContentType={entry:"(string|element|function|null)",selector:"(string|element)"};class TemplateFactory extends Config{constructor(config){super(),this._config=this._getConfig(config)}static get Default(){return Default$4}static get DefaultType(){return DefaultType$4}static get NAME(){return NAME$5}getContent(){return Object.values(this._config.content).map(config=>this._resolvePossibleFunction(config)).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(content){return this._checkContent(content),this._config.content={...this._config.content,...content},this}toHtml(){const templateWrapper=document.createElement("div");templateWrapper.innerHTML=this._maybeSanitize(this._config.template);for(const[selector,text]of Object.entries(this._config.content))this._setContent(templateWrapper,text,selector);const template=templateWrapper.children[0],extraClass=this._resolvePossibleFunction(this._config.extraClass);return extraClass&&template.classList.add(...extraClass.split(" ")),template}_typeCheckConfig(config){super._typeCheckConfig(config),this._checkContent(config.content)}_checkContent(arg){for(const[selector,content]of Object.entries(arg))super._typeCheckConfig({selector,entry:content},DefaultContentType)}_setContent(template,content,selector){const templateElement=SelectorEngine.findOne(selector,template);
7if(!templateElement)return;if(content=this._resolvePossibleFunction(content),!content){templateElement.remove();return}if(isElement$1(content)){this._putElementInTemplate(getElement(content),templateElement);return}if(this._config.html){templateElement.innerHTML=this._maybeSanitize(content);return}templateElement.textContent=content}_maybeSanitize(arg){return this._config.sanitize?sanitizeHtml(arg,this._config.allowList,this._config.sanitizeFn):arg}_resolvePossibleFunction(arg){return execute(arg,[this])}_putElementInTemplate(element,templateElement){if(this._config.html){templateElement.innerHTML="",templateElement.append(element);return}templateElement.textContent=element.textContent}}const NAME$4="tooltip",DISALLOWED_ATTRIBUTES=new Set(["sanitize","allowList","sanitizeFn"]),CLASS_NAME_FADE$2="fade",CLASS_NAME_MODAL="modal",CLASS_NAME_SHOW$2="show",SELECTOR_TOOLTIP_INNER=".tooltip-inner",SELECTOR_MODAL=`.${CLASS_NAME_MODAL}`,EVENT_MODAL_HIDE="hide.bs.modal",TRIGGER_HOVER="hover",TRIGGER_FOCUS="focus",TRIGGER_CLICK="click",TRIGGER_MANUAL="manual",EVENT_HIDE$2="hide",EVENT_HIDDEN$2="hidden",EVENT_SHOW$2="show",EVENT_SHOWN$2="shown",EVENT_INSERTED="inserted",EVENT_CLICK$1="click",EVENT_FOCUSIN$1="focusin",EVENT_FOCUSOUT$1="focusout",EVENT_MOUSEENTER="mouseenter",EVENT_MOUSELEAVE="mouseleave",AttachmentMap={AUTO:"auto",TOP:"top",RIGHT:isRTL()?"left":"right",BOTTOM:"bottom",LEFT:isRTL()?"right":"left"},Default$3={allowList:DefaultAllowlist,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',title:"",trigger:"hover focus"},DefaultType$3={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class Tooltip extends BaseComponent{constructor(element,config){if(typeof Popper=="undefined")throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(element,config),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return Default$3}static get DefaultType(){return DefaultType$3}static get NAME(){return NAME$4}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){if(!this._isEnabled)return;if(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()){this._leave();return}this._enter()}dispose(){clearTimeout(this._timeout),EventHandler.off(this._element.closest(SELECTOR_MODAL),EVENT_MODAL_HIDE,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if(this._element.style.display==="none")throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const showEvent=EventHandler.trigger(this._element,this.constructor.eventName(EVENT_SHOW$2)),shadowRoot=findShadowRoot(this._element),isInTheDom=(shadowRoot||this._element.ownerDocument.documentElement).contains(this._element);if(showEvent.defaultPrevented||!isInTheDom)return;this._disposePopper();const tip=this._getTipElement();this._element.setAttribute("aria-describedby",tip.getAttribute("id"));const{container}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(container.append(tip),EventHandler.trigger(this._element,this.constructor.eventName(EVENT_INSERTED))),this._popper=this._createPopper(tip),tip.classList.add(CLASS_NAME_SHOW$2),"ontouchstart"in document.documentElement)for(const element of[].concat(...document.body.children))EventHandler.on(element,"mouseover",noop);const complete=()=>{EventHandler.trigger(this._element,this.constructor.eventName(EVENT_SHOWN$2)),this._isHovered===!1&&this._leave(),this._isHovered=!1};this._queueCallback(complete,this.tip,this._isAnimated())}
7hide(){if(!this._isShown())return;const hideEvent=EventHandler.trigger(this._element,this.constructor.eventName(EVENT_HIDE$2));if(hideEvent.defaultPrevented)return;const tip=this._getTipElement();if(tip.classList.remove(CLASS_NAME_SHOW$2),"ontouchstart"in document.documentElement)for(const element of[].concat(...document.body.children))EventHandler.off(element,"mouseover",noop);this._activeTrigger[TRIGGER_CLICK]=!1,this._activeTrigger[TRIGGER_FOCUS]=!1,this._activeTrigger[TRIGGER_HOVER]=!1,this._isHovered=null;const complete=()=>{if(this._isWithActiveTrigger())return;this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),EventHandler.trigger(this._element,this.constructor.eventName(EVENT_HIDDEN$2))};this._queueCallback(complete,this.tip,this._isAnimated())}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(content){const tip=this._getTemplateFactory(content).toHtml();if(!tip)return null;tip.classList.remove(CLASS_NAME_FADE$2,CLASS_NAME_SHOW$2),tip.classList.add(`bs-${this.constructor.NAME}-auto`);const tipId=getUID(this.constructor.NAME).toString();return tip.setAttribute("id",tipId),this._isAnimated()&&tip.classList.add(CLASS_NAME_FADE$2),tip}setContent(content){this._newContent=content,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(content){return this._templateFactory?this._templateFactory.changeContent(content):this._templateFactory=new TemplateFactory({...this._config,content,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{[SELECTOR_TOOLTIP_INNER]:this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(event){return this.constructor.getOrCreateInstance(event.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(CLASS_NAME_FADE$2)}_isShown(){return this.tip&&this.tip.classList.contains(CLASS_NAME_SHOW$2)}_createPopper(tip){const placement=execute(this._config.placement,[this,tip,this._element]),attachment=AttachmentMap[placement.toUpperCase()];return createPopper(this._element,tip,this._getPopperConfig(attachment))}_getOffset(){const{offset}=this._config;return typeof offset=="string"?offset.split(",").map(value=>Number.parseInt(value,10)):typeof offset=="function"?popperData=>offset(popperData,this._element):offset}_resolvePossibleFunction(arg){return execute(arg,[this._element])}_getPopperConfig(attachment){const defaultBsPopperConfig={placement:attachment,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:data=>{this._getTipElement().setAttribute("data-popper-placement",data.state.placement)}}]};return{...defaultBsPopperConfig,...execute(this._config.popperConfig,[defaultBsPopperConfig])}}_setListeners(){const triggers=this._config.trigger.split(" ");for(const trigger of triggers)if(trigger==="click")EventHandler.on(this._element,this.constructor.eventName(EVENT_CLICK$1),this._config.selector,event=>{const context=this._initializeOnDelegatedTarget(event);context.toggle()});else if(trigger!==TRIGGER_MANUAL){const eventIn=trigger===TRIGGER_HOVER?this.constructor.eventName(EVENT_MOUSEENTER):this.constructor.eventName(EVENT_FOCUSIN$1),eventOut=trigger===TRIGGER_HOVER?this.constructor.eventName(EVENT_MOUSELEAVE):this.constructor.eventName(EVENT_FOCUSOUT$1);EventHandler.on(this._element,eventIn,this._config.selector,event=>{const context=this._initializeOnDelegatedTarget(event);context._activeTrigger[event.type==="focusin"?TRIGGER_FOCUS:TRIGGER_HOVER]=!0,context._enter()}),EventHandler.on(this._element,eventOut,this._config.selector,event=>{const context=this._initializeOnDelegatedTarget(event);context._activeTrigger[event.type==="focusout"?TRIGGER_FOCUS:TRIGGER_HOVER]=context._element.contains(event.relatedTarget),context._leave()})}this._hideModalHandler=()=>{this._element&&this.hide()},EventHandler.on(this._element.closest(SELECTOR_MODAL),EVENT_MODAL_HIDE,this._hideModalHandler)}_fixTitle(){const title=this._element.getAttribute("title");if(!title)return;!this._element.getAttribute("aria-label")&&!this._element.textContent.trim()&&this._element.setAttribute("aria-label",title),this._element.setAttribute("data-bs-original-title",title),this._element.removeAttribute("title")}_enter(){if(this._isShown()||this._isHovered){this._isHovered=!0;return}this._isHovered=!0,this._setTimeout(()=>{this._isHovered&&this.show()},this._config.delay.show)}_leave(){if(this._isWithActiveTrigger())return;this._isHovered=!1,this._setTimeout(()=>{this._isHovered||this.hide()},this._config.delay.hide)}_setTimeout(handler,timeout){clearTimeout(this._timeout),this._timeout=setTimeout(handler,timeout)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(config){const dataAttributes=Manipulator.getDataAttributes(this._element);
vendor: 4,185 bytes, line 7
7for(const dataAttribute of Object.keys(dataAttributes))DISALLOWED_ATTRIBUTES.has(dataAttribute)&&delete dataAttributes[dataAttribute];return config={...dataAttributes,...typeof config=="object"&&config?config:{}},config=this._mergeConfigObj(config),config=this._configAfterMerge(config),this._typeCheckConfig(config),config}_configAfterMerge(config){return config.container=config.container===!1?document.body:getElement(config.container),typeof config.delay=="number"&&(config.delay={show:config.delay,hide:config.delay}),typeof config.title=="number"&&(config.title=config.title.toString()),typeof config.content=="number"&&(config.content=config.content.toString()),config}_getDelegateConfig(){const config={};for(const[key,value]of Object.entries(this._config))this.constructor.Default[key]!==value&&(config[key]=value);return config.selector=!1,config.trigger="manual",config}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(config){return this.each(function(){const data=Tooltip.getOrCreateInstance(this,config);if(typeof config!="string")return;if(typeof data[config]=="undefined")throw new TypeError(`No method named "${config}"`);data[config]()})}}defineJQueryPlugin(Tooltip);const NAME$3="popover",SELECTOR_TITLE=".popover-header",SELECTOR_CONTENT=".popover-body",Default$2={...Tooltip.Default,content:"",offset:[0,8],placement:"right",template:'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>',trigger:"click"},DefaultType$2={...Tooltip.DefaultType,content:"(null|string|element|function)"};class Popover extends Tooltip{static get Default(){return Default$2}static get DefaultType(){return DefaultType$2}static get NAME(){return NAME$3}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{[SELECTOR_TITLE]:this._getTitle(),[SELECTOR_CONTENT]:this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(config){return this.each(function(){const data=Popover.getOrCreateInstance(this,config);if(typeof config!="string")return;if(typeof data[config]=="undefined")throw new TypeError(`No method named "${config}"`);data[config]()})}}defineJQueryPlugin(Popover);const NAME$2="scrollspy",DATA_KEY$2="bs.scrollspy",EVENT_KEY$2=`.${DATA_KEY$2}`,DATA_API_KEY=".data-api",EVENT_ACTIVATE=`activate${EVENT_KEY$2}`,EVENT_CLICK=`click${EVENT_KEY$2}`,EVENT_LOAD_DATA_API$1=`load${EVENT_KEY$2}${DATA_API_KEY}`,CLASS_NAME_DROPDOWN_ITEM="dropdown-item",CLASS_NAME_ACTIVE$1="active",SELECTOR_DATA_SPY='[data-bs-spy="scroll"]',SELECTOR_TARGET_LINKS="[href]",SELECTOR_NAV_LIST_GROUP=".nav, .list-group",SELECTOR_NAV_LINKS=".nav-link",SELECTOR_NAV_ITEMS=".nav-item",SELECTOR_LIST_ITEMS=".list-group-item",SELECTOR_LINK_ITEMS=`${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`,SELECTOR_DROPDOWN=".dropdown",SELECTOR_DROPDOWN_TOGGLE$1=".dropdown-toggle",Default$1={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},DefaultType$1={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class ScrollSpy extends BaseComponent{constructor(element,config){super(element,config),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement=getComputedStyle(this._element).overflowY==="visible"?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Default$1}static get DefaultType(){return DefaultType$1}static get NAME(){return NAME$2}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const section of this._observableSections.values())this._observer.observe(section)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(config){return config.target=getElement(config.target)||document.body,config.rootMargin=config.offset?`${c
7onfig.offset}px 0px -30%`:config.rootMargin,typeof config.threshold=="string"&&(config.threshold=config.threshold.split(",").map(value=>Number.parseFloat(value))),config}_maybeEnableSmoothScroll(){if(!this._config.smoothScroll)return;EventHandler.off(this._config.target,EVENT_CLICK),EventHandler.on(this._config.target,EVENT_CLICK,SELECTOR_TARGET_LINKS,event=>{const observableSection=this._observableSections.get(event.target.hash);if(observableSection){event.preventDefault();const root=this._rootElement||window,height=observableSection.offsetTop-this._element.offsetTop;if(root.scrollTo){root.scrollTo({top:height,behavior:"smooth"});return}root.scrollTop=height}})}_getNewObserver(){const options={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver(entries=>this._observerCallback(entries),options)}_observerCallback(entries){const targetElement=entry=>this._targetLinks.get(`#${entry.target.id}`),activate=entry=>{this._previousScrollData.visibleEntryTop=entry.target.offsetTop,this._process(targetElement(entry))},parentScrollTop=(this._rootElement||document.documentElement).scrollTop,userScrollsDown=parentScrollTop>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=parentScrollTop;for(const entry of entries){if(!entry.isIntersecting){this._activeTarget=null,this._clearActiveClass(targetElement(entry));continue}const entryIsLowerThanPrevious=entry.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(userScrollsDown&&entryIsLowerThanPrevious){if(activate(entry),!parentScrollTop)return;continue}!userScrollsDown&&!entryIsLowerThanPrevious&&activate(entry)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const targetLinks=SelectorEngine.find(SELECTOR_TARGET_LINKS,this._config.target);for(const anchor of targetLinks){if(!anchor.hash||isDisabled(anchor))continue;const observableSection=SelectorEngine.findOne(decodeURI(anchor.hash),this._element);isVisible(observableSection)&&(this._targetLinks.set(decodeURI(anchor.hash),anchor),this._observableSections.set(anchor.hash,observableSection))}}_process(target){if(this._activeTarget===target)return;this._clearActiveClass(this._config.target),this._activeTarget=target,target.classList.add(CLASS_NAME_ACTIVE$1),this._activateParents(target),EventHandler.trigger(this._element,EVENT_ACTIVATE,{relatedTarget:target})}_activateParents(target){if(target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)){SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1,target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);return}for(const listGroup of SelectorEngine.parents(target,SELECTOR_NAV_LIST_GROUP))for(const item of SelectorEngine.prev(listGroup,SELECTOR_LINK_ITEMS))item.classList.add(CLASS_NAME_ACTIVE$1)}_clearActiveClass(parent){parent.classList.remove(CLASS_NAME_ACTIVE$1);const activeNodes=SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`,parent);for(const node of activeNodes)node.classList.remove(CLASS_NAME_ACTIVE$1)}static jQueryInterface(config){return this.each(function(){const data=ScrollSpy.getOrCreateInstance(this,config);if(typeof config!="string")return;if(data[config]===void 0||config.startsWith("_")||config==="constructor")throw new TypeError(`No method named "${config}"`);data[config]()})}}EventHandler.on(window,EVENT_LOAD_DATA_API$1,()=>{for(const spy of SelectorEngine.find(SELECTOR_DATA_SPY))ScrollSpy.getOrCreateInstance(spy)}),defineJQueryPlugin(ScrollSpy);const NAME$1="tab",DATA_KEY$1="bs.tab",EVENT_KEY$1=`.${DATA_KEY$1}`,EVENT_HIDE$1=`hide${EVENT_KEY$1}`,EVENT_HIDDEN$1=`hidden${EVENT_KEY$1}`,EVENT_SHOW$1=`show${EVENT_KEY$1}`,EVENT_SHOWN$1=`shown${EVENT_KEY$1}`,EVENT_CLICK_DATA_API=`click${EVENT_KEY$1}`,EVENT_KEYDOWN=`keydown${EVENT_KEY$1}`,EVENT_LOAD_DATA_API=`load${EVENT_KEY$1}`,ARROW_LEFT_KEY="ArrowLeft",ARROW_RIGHT_KEY="ArrowRight",ARROW_UP_KEY="ArrowUp",ARROW_DOWN_KEY="ArrowDown",HOME_KEY="Home",END_KEY="End",CLASS_NAME_ACTIVE="active",CLASS_NAME_FADE$1="fade",CLASS_NAME_SHOW$1="show",CLASS_DROPDOWN="dropdown",SELECTOR_DROPDOWN_TOGGLE=".dropdown-toggle",SELECTOR_DROPDOWN_MENU=".dropdown-menu",NOT_SELECTOR_DROPDOWN_TOGGLE=`
7:not(${SELECTOR_DROPDOWN_TOGGLE})`,SELECTOR_TAB_PANEL='.list-group, .nav, [role="tablist"]',SELECTOR_OUTER=".nav-item, .list-group-item",SELECTOR_INNER=`.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`,SELECTOR_DATA_TOGGLE='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',SELECTOR_INNER_ELEM=`${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`,SELECTOR_DATA_TOGGLE_ACTIVE=`.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`;class Tab extends BaseComponent{constructor(element){if(super(element),this._parent=this._element.closest(SELECTOR_TAB_PANEL),!this._parent)return;this._setInitialAttributes(this._parent,this._getChildren()),EventHandler.on(this._element,EVENT_KEYDOWN,event=>this._keydown(event))}static get NAME(){return NAME$1}show(){const innerElem=this._element;if(this._elemIsActive(innerElem))return;const active=this._getActiveElem(),hideEvent=active?EventHandler.trigger(active,EVENT_HIDE$1,{relatedTarget:innerElem}):null,showEvent=EventHandler.trigger(innerElem,EVENT_SHOW$1,{relatedTarget:active});if(showEvent.defaultPrevented||hideEvent&&hideEvent.defaultPrevented)return;this._deactivate(active,innerElem),this._activate(innerElem,active)}_activate(element,relatedElem){if(!element)return;element.classList.add(CLASS_NAME_ACTIVE),this._activate(SelectorEngine.getElementFromSelector(element));const complete=()=>{if(element.getAttribute("role")!=="tab"){element.classList.add(CLASS_NAME_SHOW$1);return}element.removeAttribute("tabindex"),element.setAttribute("aria-selected",!0),this._toggleDropDown(element,!0),EventHandler.trigger(element,EVENT_SHOWN$1,{relatedTarget:relatedElem})};this._queueCallback(complete,element,element.classList.contains(CLASS_NAME_FADE$1))}_deactivate(element,relatedElem){if(!element)return;element.classList.remove(CLASS_NAME_ACTIVE),element.blur(),this._deactivate(SelectorEngine.getElementFromSelector(element));const complete=()=>{if(element.getAttribute("role")!=="tab"){element.classList.remove(CLASS_NAME_SHOW$1);return}element.setAttribute("aria-selected",!1),element.setAttribute("tabindex","-1"),this._toggleDropDown(element,!1),EventHandler.trigger(element,EVENT_HIDDEN$1,{relatedTarget:relatedElem})};this._queueCallback(complete,element,element.classList.contains(CLASS_NAME_FADE$1))}_keydown(event){if(![ARROW_LEFT_KEY,ARROW_RIGHT_KEY,ARROW_UP_KEY,ARROW_DOWN_KEY,HOME_KEY,END_KEY].includes(event.key))return;event.stopPropagation(),event.preventDefault();const children=this._getChildren().filter(element=>!isDisabled(element));let nextActiveElement;if([HOME_KEY,END_KEY].includes(event.key))nextActiveElement=children[event.key===HOME_KEY?0:children.length-1];else{const isNext=[ARROW_RIGHT_KEY,ARROW_DOWN_KEY].includes(event.key);nextActiveElement=getNextActiveElement(children,event.target,isNext,!0)}nextActiveElement&&(nextActiveElement.focus({preventScroll:!0}),Tab.getOrCreateInstance(nextActiveElement).show())}_getChildren(){return SelectorEngine.find(SELECTOR_INNER_ELEM,this._parent)}_getActiveElem(){return this._getChildren().find(child=>this._elemIsActive(child))||null}_setInitialAttributes(parent,children){this._setAttributeIfNotExists(parent,"role","tablist");for(const child of children)this._setInitialAttributesOnChild(child)}_setInitialAttributesOnChild(child){child=this._getInnerElement(child);const isActive=this._elemIsActive(child),outerElem=this._getOuterElement(child);child.setAttribute("aria-selected",isActive),outerElem!==child&&this._setAttributeIfNotExists(outerElem,"role","presentation"),isActive||child.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(child,"role","tab"),this._setInitialAttributesOnTargetPanel(child)}_setInitialAttributesOnTargetPanel(child){const target=SelectorEngine.getElementFromSelector(child);if(!target)return;this._setAttributeIfNotExists(target,"role","tabpanel"),child.id&&this._setAttributeIfNotExists(target,"aria-labelledby",`${child.id}`)}_toggleDropDown(element,open){const outerElem=this._getOuterElement(element);if(!outerElem.classList.contains(CLASS_DROPDOWN))return;const toggle=(selector,className)=>{const element=SelectorEngine.findOne(selector,outerElem);element&&element.classList.toggle(className,open)};toggle(SELECTOR_DROPDOWN_TOGGLE,CLASS_NAME_ACTIVE),toggle(SELECTOR_DROPDOWN_MENU,CLASS_NAME_SHOW$1),outerElem.setAttribute("aria-expanded",open)}_setAttributeIfNotExists(element,attribute,value){element.hasAttribute(attribute)||element.setAttribute(attribute,value)}_elemIsActive(elem){return elem.classList.contains(CLASS_NAME_ACTIVE)}_getInnerElement(elem){return elem.matches(SELECTOR_INNER_ELEM)?elem:SelectorEngine.findOne(SELECTOR_INNER_ELEM,elem)}_getOuterElement(elem){return elem.closest(SELECTOR_OUTER)||elem}static jQueryInterface(config){return this.each(function(){const data=Tab.getOrCreateInstance(this);if(typeof config!="string")return;if(data[config]===void 0||config.startsWith("_")||config==="constructor")throw new TypeError(`No method n
7amed "${config}"`);data[config]()})}}EventHandler.on(document,EVENT_CLICK_DATA_API,SELECTOR_DATA_TOGGLE,function(event){if(["A","AREA"].includes(this.tagName)&&event.preventDefault(),isDisabled(this))return;Tab.getOrCreateInstance(this).show()}),EventHandler.on(window,EVENT_LOAD_DATA_API,()=>{for(const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE))Tab.getOrCreateInstance(element)}),defineJQueryPlugin(Tab);const NAME="toast",DATA_KEY="bs.toast",EVENT_KEY=`.${DATA_KEY}`,EVENT_MOUSEOVER=`mouseover${EVENT_KEY}`,EVENT_MOUSEOUT=`mouseout${EVENT_KEY}`,EVENT_FOCUSIN=`focusin${EVENT_KEY}`,EVENT_FOCUSOUT=`focusout${EVENT_KEY}`,EVENT_HIDE=`hide${EVENT_KEY}`,EVENT_HIDDEN=`hidden${EVENT_KEY}`,EVENT_SHOW=`show${EVENT_KEY}`,EVENT_SHOWN=`shown${EVENT_KEY}`,CLASS_NAME_FADE="fade",CLASS_NAME_HIDE="hide",CLASS_NAME_SHOW="show",CLASS_NAME_SHOWING="showing",DefaultType={animation:"boolean",autohide:"boolean",delay:"number"},Default={animation:!0,autohide:!0,delay:5e3};class Toast extends BaseComponent{constructor(element,config){super(element,config),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return Default}static get DefaultType(){return DefaultType}static get NAME(){return NAME}show(){const showEvent=EventHandler.trigger(this._element,EVENT_SHOW);if(showEvent.defaultPrevented)return;this._clearTimeout(),this._config.animation&&this._element.classList.add(CLASS_NAME_FADE);const complete=()=>{this._element.classList.remove(CLASS_NAME_SHOWING),EventHandler.trigger(this._element,EVENT_SHOWN),this._maybeScheduleHide()};this._element.classList.remove(CLASS_NAME_HIDE),reflow(this._element),this._element.classList.add(CLASS_NAME_SHOW,CLASS_NAME_SHOWING),this._queueCallback(complete,this._element,this._config.animation)}hide(){if(!this.isShown())return;const hideEvent=EventHandler.trigger(this._element,EVENT_HIDE);if(hideEvent.defaultPrevented)return;const complete=()=>{this._element.classList.add(CLASS_NAME_HIDE),this._element.classList.remove(CLASS_NAME_SHOWING,CLASS_NAME_SHOW),EventHandler.trigger(this._element,EVENT_HIDDEN)};this._element.classList.add(CLASS_NAME_SHOWING),this._queueCallback(complete,this._element,this._config.animation)}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(CLASS_NAME_SHOW),super.dispose()}isShown(){return this._element.classList.contains(CLASS_NAME_SHOW)}_maybeScheduleHide(){if(!this._config.autohide)return;if(this._hasMouseInteraction||this._hasKeyboardInteraction)return;this._timeout=setTimeout(()=>{this.hide()},this._config.delay)}_onInteraction(event,isInteracting){switch(event.type){case"mouseover":case"mouseout":{this._hasMouseInteraction=isInteracting;break}case"focusin":case"focusout":{this._hasKeyboardInteraction=isInteracting;break}}if(isInteracting){this._clearTimeout();return}const nextElement=event.relatedTarget;if(this._element===nextElement||this._element.contains(nextElement))return;this._maybeScheduleHide()}_setListeners(){EventHandler.on(this._element,EVENT_MOUSEOVER,event=>this._onInteraction(event,!0)),EventHandler.on(this._element,EVENT_MOUSEOUT,event=>this._onInteraction(event,!1)),EventHandler.on(this._element,EVENT_FOCUSIN,event=>this._onInteraction(event,!0)),EventHandler.on(this._element,EVENT_FOCUSOUT,event=>this._onInteraction(event,!1))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(config){return this.each(function(){const data=Toast.getOrCreateInstance(this,config);if(typeof config=="string"){if(typeof data[config]=="undefined")throw new TypeError(`No method named "${config}"`);data[config](this)}})}}enableDismissTrigger(Toast),defineJQueryPlugin(Toast);const index_umd={Alert,Button,Carousel,Collapse,Dropdown,Modal,Offcanvas,Popover,ScrollSpy,Tab,Toast,Tooltip};return index_umd}),function _f(self){"use strict";try{module&&(self=module)}catch{}self._factory=_f;function u(a){return"undefined"==typeof a||a}function v(a){const b=Array(a);for(let c=0;c<a;c++)b[c]=x();return b}function x(){return Object.create(null)}function aa(a,b){return b.length-a.length}function C(a){return"string"==typeof a}function D(a){return"object"==typeof a}function E(a){return"function"==typeof a}function ba(a,b){var c=ca;if(a&&(b&&(a=F(a,b)),this.H&&(a=F(a,this.H)),this.J&&1<a.length&&(a=F(a,this.J)),c||""===c)){if(b=a.split(c),this.filter){a=this.filter,c=b.length;const d=[];for(let e=0,f=0;e<c;e++){const h=b[e];h&&!a[h]&&(d[f++]=h)}a=d}else a=b;return a}return a}const ca=/[\p{Z}\p{S}\p{P}\p{C}]+/u,da=/[\u0300-\u036f]/g;function ea(a,b){const c=Object.keys(a),d=c.length,e=[];let f="",h=0;for(let g=0,k,m;g<d;g++)k=c[g],(m=a[k])?(e[h++]=G(b?"(?!\\b)"+k+"(\\b|_)":k),e[h++]=m):f+=(f?"|":"")+k;return f&&(e[h++]=G(b?"(?!\\b)("+f+")(\\b|_)":"("+f+")"),e[h]=""),e}function F(a,b){for(let c=0,d=b.length;
7c<d&&(a=a.replace(b[c],b[c+1]),a);c+=2);return a}function G(a){return new RegExp(a,"g")}function fa(a){let b="",c="";for(let d=0,e=a.length,f;d<e;d++)(f=a[d])!==c&&(b+=c=f);return b}var t,Aa,Da,Ha,Ka,ia={encode:ha,F:!1,G:""};function ha(a){return ba.call(this,(""+a).toLowerCase(),!1)}const ja={},I={};function ka(a){J(a,"add"),J(a,"append"),J(a,"search"),J(a,"update"),J(a,"remove")}function J(a,b){a[b+"Async"]=function(){const c=this,d=arguments;var e=d[d.length-1];let f;return E(e)&&(f=e,delete d[d.length-1]),e=new Promise(function(h){setTimeout(function(){c.async=!0;const g=c[b].apply(c,d);c.async=!1,h(g)})}),f?(e.then(f),this):e}}function la(a,b,c,d){const e=a.length;let f=[],h,g,k=0;d&&(d=[]);for(let m=e-1;0<=m;m--){const n=a[m],w=n.length,q=x();let r=!h;for(let l=0;l<w;l++){const p=n[l],A=p.length;if(A)for(let B=0,z,y;B<A;B++)if(y=p[B],h){{if(h[y]){if(!m)if(c)c--;else if(f[k++]=y,k===b)return f;(m||d)&&(q[y]=1),r=!0}if(d&&(z=(g[y]||0)+1,g[y]=z,z<e)){const H=d[z-2]||(d[z-2]=[]);H[H.length]=y}}}else q[y]=1}if(d)h||(g=q);else if(!r)return[];h=q}if(d)for(let m=d.length-1,n,w;0<=m;m--){n=d[m],w=n.length;for(let q=0,r;q<w;q++)if(r=n[q],!h[r]){if(c)c--;else if(f[k++]=r,k===b)return f;h[r]=1}}return f}function ma(a,b){const c=x(),d=x(),e=[];for(let f=0;f<a.length;f++)c[a[f]]=1;for(let f=0,h;f<b.length;f++){h=b[f];for(let g=0,k;g<h.length;g++)k=h[g],c[k]&&!d[k]&&(d[k]=1,e[e.length]=k)}return e}function K(a){this.l=!0!==a&&a,this.cache=x(),this.h=[]}function na(a,b,c){D(a)&&(a=a.query);let d=this.cache.get(a);return d||(d=this.search(a,b,c),this.cache.set(a,d)),d}K.prototype.set=function(a,b){if(!this.cache[a]){var c=this.h.length;c===this.l?delete this.cache[this.h[c-1]]:c++;for(--c;0<c;c--)this.h[c]=this.h[c-1];this.h[0]=a}this.cache[a]=b},K.prototype.get=function(a){const b=this.cache[a];if(this.l&&b&&(a=this.h.indexOf(a))){const c=this.h[a-1];this.h[a-1]=this.h[a],this.h[a]=c}return b};
vendor: 1,151 bytes, line 7
7const pa={memory:{charset:"latin:extra",D:3,B:4,m:!1},performance:{D:3,B:3,s:!1,context:{depth:2,D:1}},match:{charset:"latin:extra",G:"reverse"},score:{charset:"latin:advanced",D:20,B:3,context:{depth:3,D:9}},default:{}};function qa(a,b,c,d,e,f,h,g){setTimeout(function(){const k=a(c?c+"."+d:d,JSON.stringify(h));k&&k.then?k.then(function(){b.export(a,b,c,e,f+1,g)}):b.export(a,b,c,e,f+1,g)})}function L(a,b){if(!(this instanceof L))return new L(a);if(a){C(a)?a=pa[a]:(c=a.preset)&&(a=Object.assign({},c[c],a)),c=a.charset;var c,d=a.lang;C(c)&&(-1===c.indexOf(":")&&(c+=":default"),c=I[c]),C(d)&&(d=ja[d])}else a={};let e,f,h=a.context||{};if(this.encode=a.encode||c&&c.encode||ha,this.register=b||x(),this.D=e=a.resolution||9,this.G=b=c&&c.G||a.tokenize||"strict",this.depth="strict"===b&&h.depth,this.l=u(h.bidirectional),this.s=f=u(a.optimize),this.m=u(a.fastupdate),this.B=a.minlength||1,this.C=a.boost,this.map=f?v(e):x(),this.A=e=h.resolution||1,this.h=f?v(e):x(),this.F=c&&c.F||a.rtl,this.H=(b=a.matcher||d&&d.H)&&ea(b,!1),this.J=(b=a.stemmer||d&&d.J)&&ea(b,!0),c=b=a.filter||d&&d.filter){c=b,d=x();for(let g=0,k=c.length;g<k;g++)d[c[g]]=1;c=d}
7this.filter=c,this.cache=(b=a.cache)&&new K(b)}t=L.prototype,t.append=function(a,b){return this.add(a,b,!0)},t.add=function(a,b,c,d){if(b&&(a||0===a)){if(!d&&!c&&this.register[a])return this.update(a,b);if(b=this.encode(b),d=b.length){const m=x(),n=x(),w=this.depth,q=this.D;for(let r=0;r<d;r++){let l=b[this.F?d-1-r:r];if(e=l.length,l&&e>=this.B&&(w||!n[l])){var e,g,k,f=M(q,d,r),h="";switch(this.G){case"full":if(2<e){for(f=0;f<e;f++)for(g=e;g>f;g--)g-f>=this.B&&(k=M(q,d,r,e,f),h=l.substring(f,g),N(this,n,h,k,a,c));break}case"reverse":if(1<e){for(g=e-1;0<g;g--)h=l[g]+h,h.length>=this.B&&N(this,n,h,M(q,d,r,e,g),a,c);h=""}case"forward":if(1<e){for(g=0;g<e;g++)h+=l[g],h.length>=this.B&&N(this,n,h,f,a,c);break}default:if(this.C&&(f=Math.min(f/this.C(b,l,r)|0,q-1)),N(this,n,l,f,a,c),w&&1<d&&r<d-1)for(e=x(),h=this.A,f=l,g=Math.min(w+1,d-r),e[f]=1,k=1;k<g;k++)if((l=b[this.F?d-1-r-k:r+k])&&l.length>=this.B&&!e[l]){e[l]=1;const p=this.l&&l>f;N(this,m,p?f:l,M(h+(d/2>h?0:1),d,r,g-1,k-1),a,c,p?l:f)}}}}this.m||(this.register[a]=1)}}return this};function M(a,b,c,d,e){return c&&1<a?b+(d||0)<=a?c+(e||0):(a-1)/(b+(d||0))*(c+(e||0))+1|0:0}function N(a,b,c,d,e,f,h){let g=h?a.h:a.map;(!b[c]||h&&!b[c][h])&&(a.s&&(g=g[d]),h?(b=b[c]||(b[c]=x()),b[h]=1,g=g[h]||(g[h]=x())):b[c]=1,g=g[c]||(g[c]=[]),a.s||(g=g[d]||(g[d]=[])),f&&g.includes(e)||(g[g.length]=e,a.m&&(a=a.register[e]||(a.register[e]=[]),a[a.length]=g)))}t.search=function(a,b,c){c||(!b&&D(a)?(c=a,a=c.query):D(b)&&(c=b));let d=[],e,f,h=0;if(c){a=c.query||a,b=c.limit,h=c.offset||0;var k,g=c.context;f=c.suggest}if(a&&(a=this.encode(""+a),e=a.length,1<e)){c=x(),k=[];for(let n=0,w=0,q;n<e;n++)if((q=a[n])&&q.length>=this.B&&!c[q])if(this.s||f||this.map[q])k[w++]=q,c[q]=1;else return d;a=k,e=a.length}if(!e)return d;b||(b=100),g=this.depth&&1<e&&!1!==g,c=0;let m;g?(m=a[0],c=1):1<e&&a.sort(aa);for(let n,w;c<e;c++){if(w=a[c],g?(n=ra(this,d,f,b,h,2===e,w,m),f&&!1===n&&d.length||(m=w)):n=ra(this,d,f,b,h,1===e,w),n)return n;if(f&&c===e-1){if(k=d.length,!k){if(g){g=0,c=-1;continue}return d}if(1===k)return sa(d[0],b,h)}}return la(d,b,h,f)};function ra(a,b,c,d,e,f,h,g){let k=[],m=g?a.h:a.map;if(a.s||(m=ta(m,h,g,a.l)),m){let n=0;const w=Math.min(m.length,g?a.A:a.D);for(let q=0,r=0,l,p;q<w;q++)if((l=m[q])&&(a.s&&(l=ta(l,h,g,a.l)),e&&l&&f&&(p=l.length,p<=e?(e-=p,l=null):(l=l.slice(e),e=0)),l&&(k[n++]=l,f&&(r+=l.length,r>=d))))break;if(n){if(f)return sa(k,d,0);b[b.length]=k;return}}return!c&&k}function sa(a,b,c){return a=1===a.length?a[0]:[].concat.apply([],a),c||a.length>b?a.slice(c,c+b):a}function ta(a,b,c,d){return c?(d=d&&b>c,a=(a=a[d?b:c])&&a[d?c:b]):a=a[b],a}t.contain=function(a){return!!this.register[a]},t.update=function(a,b){return this.remove(a).add(a,b)},t.remove=function(a,b){const c=this.register[a];if(c){if(this.m)for(let d=0,e;d<c.length;d++)e=c[d],e.splice(e.indexOf(a),1);else O(this.map,a,this.D,this.s),this.depth&&O(this.h,a,this.A,this.s);if(b||delete this.register[a],this.cache){b=this.cache;for(let d=0,e,f;d<b.h.length;d++)f=b.h[d],e=b.cache[f],e.includes(a)&&(b.h.splice(d--,1),delete b.cache[f])}}return this};function O(a,b,c,d,e){let f=0;if(a.constructor===Array)if(e)b=a.indexOf(b),-1!==b?1<a.length&&(a.splice(b,1),f++):f++;else{e=Math.min(a.length,c);for(let h=0,g;h<e;h++)(g=a[h])&&(f=O(g,b,c,d,e),d||f||delete a[h])}else for(let h in a)(f=O(a[h],b,c,d,e))||delete a[h];return f}t.searchCache=na,t.export=function(a,b,c,d,e,f){let h=!0;"undefined"==typeof f&&(h=new Promise(m=>{f=m}));let g,k;switch(e||(e=0)){case 0:if(g="reg",this.m){k=x();for(let m in this.register)k[m]=1}else k=this.register;break;case 1:g="cfg",k={doc:0,opt:this.s?1:0};break;case 2:g="map",k=this.map;break;case 3:g="ctx",k=this.h;break;default:"undefined"==typeof c&&f&&f();return}return qa(a,b||this,c,g,d,e,k,f),h},t.import=function(a,b){if(b)switch(C(b)&&(b=JSON.parse(b)),a){case"cfg":this.s=!!b.opt;break;case"reg":this.m=!1,this.register=b;break;case"map":this.map=b;break;case"ctx":this.h=b}},ka(L.prototype);function ua(a){a=a.data;var d,b=self._index;const c=a.args;switch(d=a.task,d){case"init":d=a.options||{},a=a.factory,b=d.encode,d.cache=!1,b&&0===b.indexOf("function")&&(d.encode=Function("return "+b)()),a?(Function("return "+a)()(self),self._index=new self.FlexSearch.Index(d),delete self.FlexSearch):self._index=new L(d);break;default:a=a.id,b=b[d].apply(b,c),postMessage("search"===d?{id:a,msg:b}:{id:a})}}let va=0;function P(a){if(!(this instanceof P))return new P(a);var b;a?E(b=a.encode)&&(a.encode=b.toString()):a={},(b=(self||window)._factory)&&(b=b.toString());const c="undefined"==typeof window&&self.exports,d=this;this.o=wa(b,c,a.worker),this.h=x(),this.o&&(c?this.o.on("message",function(e){d.h[e.id](e.msg),delete d.h[e.id]}
7):this.o.onmessage=function(e){e=e.data,d.h[e.id](e.msg),delete d.h[e.id]},this.o.postMessage({task:"init",factory:b,options:a}))}Q("add"),Q("append"),Q("search"),Q("update"),Q("remove");function Q(a){P.prototype[a]=P.prototype[a+"Async"]=function(){const b=this,c=[].slice.call(arguments);var d=c[c.length-1];let e;return E(d)&&(e=d,c.splice(c.length-1,1)),d=new Promise(function(f){setTimeout(function(){b.h[++va]=f,b.o.postMessage({task:a,id:va,args:c})})}),e?(d.then(e),this):d}}function wa(a,b,c){let d;try{d=b?new(require("worker_threads").Worker)(__dirname+"/node/node.js"):a?new Worker(URL.createObjectURL(new Blob(["onmessage="+ua.toString()],{type:"text/javascript"}))):new Worker(C(c)?c:"worker/worker.js",{type:"module"})}catch{}return d}function S(a){if(!(this instanceof S))return new S(a);var c,b=a.document||a.doc||a;this.K=[],this.h=[],this.A=[],this.register=x(),this.key=(c=b.key||b.id)&&T(c,this.A)||"id",this.m=u(a.fastupdate),this.C=(c=b.store)&&!0!==c&&[],this.store=c&&x(),this.I=(c=b.tag)&&T(c,this.A),this.l=c&&x(),this.cache=(c=a.cache)&&new 
vendor: 4,711 bytes, line 7
7K(c),a.cache=!1,this.o=a.worker,this.async=!1,c=x();let d=b.index||b.field||b;C(d)&&(d=[d]);for(let e=0,f,h;e<d.length;e++)f=d[e],C(f)||(h=f,f=f.field),h=D(h)?Object.assign({},a,h):a,this.o&&(c[f]=new P(h),c[f].o||(this.o=!1)),this.o||(c[f]=new L(h,this.register)),this.K[e]=T(f,this.A),this.h[e]=f;if(this.C)for(a=b.store,C(a)&&(a=[a]),b=0;b<a.length;b++)this.C[b]=T(a[b],this.A);this.index=c}function T(a,b){const c=a.split(":");let d=0;for(let e=0;e<c.length;e++)a=c[e],0<=a.indexOf("[]")&&(a=a.substring(0,a.length-2))&&(b[d]=!0),a&&(c[d++]=a);return d<c.length&&(c.length=d),1<d?c:c[0]}function U(a,b){if(C(b))a=a[b];else for(let c=0;a&&c<b.length;c++)a=a[b[c]];return a}function V(a,b,c,d,e){if(a=a[e],d===c.length-1)b[e]=a;else if(a)if(a.constructor===Array)for(b=b[e]=Array(a.length),e=0;e<a.length;e++)V(a,b,c,d,e);else b=b[e]||(b[e]=x()),e=c[++d],V(a,b,c,d,e)}function X(a,b,c,d,e,f,h,g){if(a=a[h])if(d===b.length-1){if(a.constructor===Array){if(c[d]){for(b=0;b<a.length;b++)e.add(f,a[b],!0,!0);return}a=a.join(" ")}e.add(f,a,g,!0)}else if(a.constructor===Array)for(h=0;h<a.length;h++)X(a,b,c,d,e,f,h,g);else h=b[++d],X(a,b,c,d,e,f,h,g)}t=S.prototype,t.add=function(a,b,c){if(D(a)&&(b=a,a=U(b,this.key)),b&&(a||0===a)){if(!c&&this.register[a])return this.update(a,b);for(let d=0,e,f;d<this.h.length;d++)f=this.h[d],e=this.K[d],C(e)&&(e=[e]),X(b,e,this.A,0,this.index[f],a,e[0],c);if(this.I){let d=U(b,this.I),e=x();C(d)&&(d=[d]);for(let f=0,h,g;f<d.length;f++)if(h=d[f],!e[h]&&(e[h]=1,g=this.l[h]||(this.l[h]=[]),!c||!g.includes(a))&&(g[g.length]=a,this.m)){const k=this.register[a]||(this.register[a]=[]);k[k.length]=g}}if(this.store&&(!c||!this.store[a])){let d;if(this.C){d=x();for(let e=0,f;e<this.C.length;e++)f=this.C[e],C(f)?d[f]=b[f]:V(b,d,f,0,f[0])}this.store[a]=d||b}}return this},t.append=function(a,b){return this.add(a,b,!0)},t.update=function(a,b){return this.remove(a).add(a,b)},t.remove=function(a){if(D(a)&&(a=U(a,this.key)),this.register[a]){for(var b=0;b<this.h.length&&(this.index[this.h[b]].remove(a,!this.o),!this.m);b++);if(this.I&&!this.m)for(let c in this.l){b=this.l[c];const d=b.indexOf(a);-1!==d&&(1<b.length?b.splice(d,1):delete this.l[c])}this.store&&delete this.store[a],delete this.register[a]}return this},t.search=function(a,b,c,d){c||(!b&&D(a)?(c=a,a=""):D(b)&&(c=b,b=0));let e=[],f=[],h,g,k,m,n,w,q=0;if(c)if(c.constructor===Array)k=c,c=null;else{if(a=c.query||a,k=(h=c.pluck)||c.index||c.field,m=c.tag,g=this.store&&c.enrich,n="and"===c.bool,b=c.limit||b||100,w=c.offset||0,m&&(C(m)&&(m=[m]),!a)){for(let l=0,p;l<m.length;l++)(p=xa.call(this,m[l],b,w,g))&&(e[e.length]=p,q++);return q?e:[]}C(k)&&(k=[k])}k||(k=this.h),n=n&&(1<k.length||m&&1<m.length);const r=!d&&(this.o||this.async)&&[];for(let l=0,p,A,B;l<k.length;l++){let z;if(A=k[l],C(A)||(z=A,A=z.field,a=z.query||a,b=z.limit||b,g=z.enrich||g),r)r[l]=this.index[A].searchAsync(a,b,z||c);else{if(d?p=d[l]:p=this.index[A].search(a,b,z||c),B=p&&p.length,m&&B){const y=[];let H=0;n&&(y[0]=[p]);for(let W=0,oa,R;W<m.length;W++)(oa=m[W],B=(R=this.l[oa])&&R.length)&&(H++,y[y.length]=n?[R]:R);H&&(p=n?la(y,b||100,w||0):ma(p,y),B=p.length)}if(B)f[q]=A,e[q++]=p;else if(n)return[]}}if(r){const l=this;return new Promise(function(p){Promise.all(r).then(function(A){p(l.search(a,b,c,A))})})}if(!q)return[];if(h&&(!g||!this.store))return e[0];for(let l=0,p;l<f.length;l++){if(p=e[l],p.length&&g&&(p=ya.call(this,p)),h)return p;e[l]={field:f[l],result:p}}return e};function xa(a,b,c,d){let e=this.l[a],f=e&&e.length-c;if(f&&0<f)return(f>b||c)&&(e=e.slice(c,c+b)),d&&(e=ya.call(this,e)),{tag:a,result:e}}function ya(a){const b=Array(a.length);for(let c=0,d;c<a.length;c++)d=a[c],b[c]={id:d,doc:this.store[d]};return b}t.contain=function(a){return!!this.register[a]},t.get=function(a){return this.store[a]},t.set=function(a,b){return this.store[a]=b,this},t.searchCache=na,t.export=function(a,b,c,d,e,f){let h;if("undefined"==typeof f&&(h=new Promise(g=>{f=g})),e||(e=0),d||(d=0),d<this.h.length){const g=this.h[d],k=this.index[g];b=this,setTimeout(function(){k.export(a,b,e?g:"",d,e++,f)||(d++,e=1,b.export(a,b,g,d,e,f))})}else{let g,k;switch(e){case 1:g="tag",k=this.l,c=null;break;case 2:g="store",k=this.store,c=null;break;default:f();return}qa(a,this,c,g,d,e,k,f)}return h},t.import=function(a,b){if(b)switch(C(b)&&(b=JSON.parse(b)),a){case"tag":this.l=b;break;case"reg":this.m=!1,this.register=b;for(let d=0,e;d<this.h.length;d++)e=this.index[this.h[d]],e.register=b,e.m=!1;break;case"store":this.store=b;break;default:a=a.split(".");const c=a[0];a=a[1],c&&a&&this.index[c].import(a,b)}},ka(S.prototype),Aa={encode:za,F:!1,G:""};const Ba=[G("[àáâãäå]"),"a",G("[èéêë]"),"e",G("[ìíîï]"),"i",G("[òóôõö
7ő]"),"o",G("[ùúûüű]"),"u",G("[ýŷÿ]"),"y",G("ñ"),"n",G("[çc]"),"k",G("ß"),"s",G(" & ")," and "];function za(a){var b=a=""+a;return b.normalize&&(b=b.normalize("NFD").replace(da,"")),ba.call(this,b.toLowerCase(),!a.normalize&&Ba)}Da={encode:Ca,F:!1,G:"strict"};const Ea=/[^a-z0-9]+/,Fa={b:"p",v:"f",w:"f",z:"s",x:"s","ß":"s",d:"t",n:"m",c:"k",g:"k",j:"k",q:"k",i:"e",y:"e",u:"o"};function Ca(a){a=za.call(this,a).join(" ");const b=[];if(a){const c=a.split(Ea),d=c.length;for(let e=0,f,h=0;e<d;e++)if((a=c[e])&&(!this.filter||!this.filter[a])){f=a[0];let g=Fa[f]||f,k=g;for(let m=1;m<a.length;m++){f=a[m];const n=Fa[f]||f;n&&n!==k&&(g+=n,k=n)}b[h++]=g}}return b}Ha={encode:Ga,F:!1,G:""};const Ia=[G("ae"),"a",G("oe"),"o",G("sh"),"s",G("th"),"t",G("ph"),"f",G("pf"),"f",G("(?![aeo])h(?![aeo])"),"",G("(?!^[aeo])h(?!^[aeo])"),""];function Ga(a,b){return a&&(a=Ca.call(this,a).join(" "),2<a.length&&(a=F(a,Ia)),b||(1<a.length&&(a=fa(a)),a&&(a=a.split(" ")))),a||[]}Ka={encode:Ja,F:!1,G:""};const La=G("(?!\\b)[aeo]");function Ja(a){return a&&(a=Ga.call(this,a,!0),1<a.length&&(a=a.replace(La,"")),1<a.length&&(a=fa(a)),a&&(a=a.split(" "))),a||[]}I["latin:default"]=ia,I["latin:simple"]=Aa,I["latin:balance"]=Da,I["latin:advanced"]=Ha,I["latin:extra"]=Ka;const Y={Index:L,Document:S,Worker:P,registerCharset:function(a,b){I[a]=b},registerLanguage:function(a,b){ja[a]=b}};let Z;(Z=self.define)&&Z.amd?Z([],function(){return Y}):self.exports?self.exports=Y:self.FlexSearch=Y}(this);const search=document.querySelector(".search-input"),suggestions=document.querySelector(".search-suggestions"),background=document.querySelector(".search-background");var index=new FlexSearch.Document({tokenize:"forward",cache:100,document:{id:"id",tag:"tag",store:["href","title","description"],index:["title","description","content"]}});function initIndex(){index.add({id:0,tag:"cs",href:"/blog/100-000-000/",title:"100 000 000",description:"Tak jsem si všiml, že se celková návštěvost TOPlistu minulý týden přehoupla přes metu 100 miliónů. Díky všem.",content:`Tak jsem si všiml, že se celková návštěvost TOPlistu minulý týden přehoupla přes metu 100 miliónů. Díky všem.
8`}).add({id:1,tag:"cs",href:"/blog/bezpecnostni-kod/",title:"Bezpečnostní kód",description:"Pokud se stane, že je kód pro vaši stránku umístěn jinde, je nejsnažší kontaktovat majitele této stránky, aby omyl napravil. Pokud to nevede k cíli, je nyní možné náhradní řešení.",content:`Pokud se stane, že je kód pro vaši stránku umístěn jinde, je nejsnažší kontaktovat majitele této stránky, aby omyl napravil. Pokud to nevede k cíli, je nyní možné náhradní řešení. V editaci je možné nastavit Bezpečnostní kód, což je číslo v rozsahu 1-99. Pokud jej nastavíte (tj. na hodnotu vyšší než 0) a ke kódu na svých stránkách přidáte parametr seed s jeho hodnotou, budou započítávány pouze tyto návštěvy. Hodnotu můžete libovolně měnit. Funkci zrušíte nastavením bezp. kódu na nulu.
9`}).add({id:2,tag:"cs",href:"/blog/button-80x15/",title:"button 80×15",description:"",content:`
10`}).add({id:3,tag:"cs",href:"/blog/denni-statistiky-pres-rss/",title:"Denní statistiky přes RSS",description:"Pro ty, kteří nechtějí čekat celý týden na email se souhrnem návštěvnosti, jsem připravil RSS feed. Link na něj je v podrobných statistikách.",content:`Pro ty, kteří nechtějí čekat celý týden na email se souhrnem návštěvnosti, jsem připravil RSS feed. Link na něj je v podrobných statistikách. Jednak v menu vpravo nebo je uveden i v headru stránky, takže jej nabídne každý inteligentnější prohlížeč. Obecně má adresu http://www.toplist.cz/stat/?id=ID_stránky&amp;a=rss. Obsahuje počet návštěv a zhlédnutí za konkrétní den a pořadí celkové a v kategorii.
11`}).add({id:4,tag:"cs",href:"/napoveda/faq/",title:"FAQ - často kladené otázky",description:"Co je tohle za stránku? &nbsp; Na této stránce se budeme snažit odpovídat na některé časté dotazy, které nám chodí.",content:` Co je tohle za stránku? &nbsp; Na této stránce se budeme snažit odpovídat na některé časté dotazy, které nám chodí. Odpovědi 
11nejsou nijak uspořádány a budou postupně přibývat, jak se budou objevovat nové otázky. Ty můžete posílat na adresu [email protected].
12Je služba placená nebo zdarma? &nbsp; Služba je zdarma. Je možné přikoupit rozšířenou službu TOPlist Profi.
13Co je to TOPlist ID? &nbsp; TOPlist ID je číslo, které rozlišuje jednotlivé registrované webové stránky. Je proto nedílnou součástí měřícího kódu, slouží k přístupu k nastavení informací o stránce a do statistik. Získáte jej okamžitě po registraci. Později je možné jej najít při vyhledání vaší stránky v podrobných informacích o stránce.
14Jaký je rozdíl mezi návštěvou a zhlédnutím? &nbsp; Hodnoty, které jsou měřeny, a způsob, jakým jsou zaznamenávány, je popsané v metodice měření.
15Co je to „reload“? &nbsp; „Reload“ znamená, že bylo přistoupeno podruhé za sebou ze stejného IP a není počítán do celkového počtu přístupů (aby si někdo jednoduše „nenaklikal“ větší návštevnost). Tj. nevadí, že používáte tlačítko „obnovit“, tento pokus by měl být ignorován.
16Dají se zjistit podrobné statistiky i za delší období? &nbsp; Ano. V rámci rozšířené služby TOPlist Profi lze sledovat podrobné statistiky až rok zpět.
17Jak je to s reklamou na TOPlistu? &nbsp; Hlavní reklamní prostory jsou dva. Na hlavní stránce (dvě pozice) a na stránce s výpisem kategorií (také dvě pozice). Na hlavní stránce je umístění exkluzivní (tzn. že je reklama zobrazena každému návÅ¡tevníkovi). Na stránkách kategorií rotuje více reklam, ale zase je zde dosahován delší čas zobrazení (view-time), takže je více času např. pro zobrazení animovaného banneru apod. O další informace a ceny si piÅ¡te na adresu [email protected].
18Jak zjistím své ID? &nbsp; ID získáte až po registraci. Zjistíte ho tak, že nejdříve najdete Vaši stránku (např. pomocí funkce Hledat ) a poté kliknete na podrobné statistiky (ikonka grafu vpravo) a v tabulce v horní části stránky je uvedeno ID. Pokud je Vaše stránka nově zaregistrována (méně než 1 den), je také v sekci Novinky.
19Co se vlastně v žebříčku zobrazuje? &nbsp; Při kliknutí na kategorii se zobrazí seznam, který vypadá přibližně takto:
20Žebříček kategorie Pozice serveru v dané kategorii. Prvních 10 serverů má pořadí označené ikonkou, ostatní písmem. Počítá se podle průměrné návštěvnosti za posledních 7 dní. Šipka znázorňuje tendenci návštěvnosti (zelená – při růstu nad 10%, modrá – stagnace, červená – pokles o víc než 10%) Číselné vyjádření změny návštěvnosti. Vypočítává se jako poměr mezi průměrnou návštěvností a odhadem dnešní návštěvnosti. Název serveru. Pokud na něm necháte myš chvíli stát, může se – pokud je vyplněn – zobrazit podrobnější popis. Průměrná návštěvnost. Počítá se za posledních 7 dní. Počet návštěv od registrace serveru. Návštěvy dnes – hlavní měřený údaj. Návštěva je jeden uživatel za 30 minut. Tj. pokud 
20se na stránku vrátí po této době, je znovu započítán. Jinak se zaznamená jen jako „reload“. Pageview – počet zhlédnutí stránky. Jedná se vlastně o součet „návštěv“ plus „reloadů“ bez rozlišení. Datum registrace serveru. Jak dlouho je server registrován. Předpověď dnešní návštěvnosti. Z důvodu jednoduchosti (tj. rychlosti) výpočtu se jedná o lineární regresi. Odkaz na podrobnější statistiky jednotlivých serverů. Pokud na něm necháte myš chvíli stát, zobrazí se ID stránky. Jak má vypadat odkaz, když chci zjistit odkud přišli návštěvníci a chci zobrazovat počítadlo začínající od 1723? &nbsp; Jedná se vlastně o využití téměř všech parametrů:
21&lt;a href=&#34;https://www.toplist.cz/&#34; target=&#34;_top&#34;&gt; &lt;script language=&#34;JavaScript&#34;&gt; &lt;/script&gt; &lt;noscript&gt; &lt;img SRC=&#34;https://toplist.cz/count.asp?logo=counter&amp;start=1723&amp;ID=vašeID&#34; border=&#34;0&#34; alt=&#34;TOPlist&#34; width=&#34;88&#34; height=&#34;31&#34;&gt; &lt;/noscript&gt; &lt;/a&gt;POZOR: za čárkou po top.document.referrer je apostrof a uvozovka. Ne tři apostrofy !!! Ale lepší bude použít formulář pro měřící kód.
22Zaregistroval jsem stránku a přesto se u ní v žebříčku stále ukazuje 0 přístupů. &nbsp; Samotná registrace nestačí pro měření. Je potřeba nějakým způsobem návštěvu zaznamenat. A k tomu slouží měřící kód, který musí být na stránce umístěn. Nejrychleji jej získáte vygenerováním v tomto formuláři.
23Má se měřící kód umístit na každou stránku nebo stačí jen na úvodní? &nbsp; Kód musí být umístěn na všech stránkách, jejichž návštěvnost má být započítávána. Dá se předpokládat, že se vyskytnou návštěvníci, kteří úvodní stránku „vynechají“ (např. přijdou přímo z vyhledávače na podstránku) a ti by nebyli zaznamenáni.
24Proč není v Infopanelu týdenní návštěvnost počítána od pondělí? &nbsp; To by znamenalo, že by v pondělí byla návštěvnost jen za 1 den (pondělí), v úterý za dva atd. Proto je počítá tzv. plovoucí týden, tj. posledních 7 dní.
25Nechodí mi týdenní mail s návÅ¡těvností &nbsp; Zkontrolujte, zda není Å¡patně nastavený filtr na SPAM a email nekončí v koÅ¡i. Také pozor na to, že se návÅ¡těvnost posílá z jiné emailové adresy [email protected] než ostatní maily (s registraci, editaci, heslu), takže může být zahazovaná pouze ta. Každý týden je rozesláno několik stovek tisíc těchto emailů, některé mailové servery (zejména freemaily) mohou chybně považovat tento provoz za spam, je dobré se proto zeptat i administrátorů těchto serverů (ale větÅ¡ina velkých českých freemailů o tom ví a má filtry patřičně nastavené). Adresu [email protected] používáme jen na posílání reportů a nic jiného. Když ji ve vaÅ¡em emailu nastavíte jako důvěryhodnou nebo bez k
25ontroly na spam, tak budete mít jistotu, že vám report vždy přijde.
26Druhá možnost je, že se z uvedené adresy vrací email (hlášení o plné schránce, automatické odpovědi apod.). Pokud takové emaily dostaneme třikrát, posílání se automaticky ukončí. Po opravení příčiny stačí editovat záznam na TOPlistu a posílání se znovu zahájí.
27V každém případě můžete celou historii návštěvnosti od registrace v TOPlistu nalézt v podrobných statistikách stránky.
28Jak zruším registraci? &nbsp; Nejdřív je potřeba odstranit měřící kód ze stránek. Poté lze stránku odstranit – odkaz Smazat v pravém menu v podrobných statistikách. Pokud byl ještě nalezen měřící kód (tj. v uplynulých dvou dnech došlo k zaznamenání návštěvy) je místo smazaní vypsán seznam těchto stránek pro kontrolu, zda se na nich měřící kód skutečně nenalézá.
29V měřených doménách se ukazuje nějaká cizí, co mám dělat? &nbsp; „Měřené domény“ ukazují adresy, na kterých je umístěn měřící kód a které mají alespoň 10% podíl na celkové návštěvnosti. Data mají historii 2 dny, takže se každá změna projeví až po jejich uplynutí. Pokud se tam objeví cizí doména, bude na ni patrně umístěn kód s vaším ID. Konkrétní stránky lze dohledat ve statistice Vstupní stránky. Pokud nebude možná domluva s provozovatelem těchto stránek, lze využít Bezpečnostní kód k zamezení počítání z cizích stránek.
30Po převodu stránek na SSL(HTTPS) přestalo měření fungovat &nbsp; V měřícím kódu stačí nahradit znaky http:// za https://. Případně znovu vygenerujte měřící kód. Nyní se vytvoří verze, která už obsahuje tuto úpravu.
31Přesunuli jsme stránky na jinou adresu. Co máme dělat? &nbsp; Nemusíte dělat nic 🙂 Pokud se jedná jen o změnu adresy a stránky stále obsahují stejný měřící kód (se stejným ID), bude měření pokračovat i na nové adrese. Můžete upravit adresu v editaci záznamu na TOPlistu, aby odkaz směřoval na správnou adresu, ale na samotné měření to nemá vliv.
32Splňuje TOPlist podmínky GDPR? &nbsp; Ano. Informace o získavaných osobních údajích, důvody a lhůty pro jejich zpracování naleznete na stránce Osobní údaje.
33Proč je ve statistikách místo adresy pomlčka? &nbsp; Pomlčka místo adresy znamená, že prohlížeč návštěvníka nepředal informaci, jakou stránku si prohlíží. To se děje když je stránka zabezpečená pomocí TLS (https), ale je na ní ještě starý měřící kód, který měřil přes http. Jednoduché řešení je prostě v měřícím kódu změnit http:// za https:// (takže tam bude https://toplist.cz atd.). Nebo lze vygenerovat a použít nový měřící kód, který už obsahuje https rovnou. Na adrese https://www.toplist.cz/code/
34`}).add({id:5,tag:"cs",href:"/blog/hledane-fraze/",title:"Hledané fráze ve vyhledávačích",description:"Přidali jsme do statistik novou sekci „vyhledávače - hledaná slova“. Tato tabulka zobrazuje nejčastěji hledané fráze, které vedly k návštěvám vašich stránek z vyhledávačů.",content:`Přidali jsme do statistik novou sekci „vyhledávače - hledaná slova“. Tato tabulka zobrazuje nejčastěji hledané fráze, které vedly k návštěvám vašich stránek z vyhledávačů.
35Aktualizace (26. 5.): Přidali jsme také statistiku cest po serveru „cesty“
36`}).add({id:6,tag:"cs",href:"/blog/internet-explorer-9-0/",title:"Internet Explorer 9.0",description:"Od začátku týdne je ve statistikách prohlížečů rozlišována i nová verze IE – 9.0. Zatím je její podíl v řádu desetin procenta, ale dá se předpokládat růst 🙂",content:`Od začátku týdne je ve statistikách prohlížečů rozlišována i nová verze IE – 9.0. Zatím je její podíl v řádu desetin procenta, ale dá se předpokládat růst 🙂
37`}).add({id:7,tag:"cs",href:"/blog/ios-13-1-je-uz-v-cesku-nejpouzivanejsi/",title:"iOS 13.1 je už v Česku nejpoužívanější",description:"Nové globální statistiky TOPlistu za minulý týden (7. – 13. říjen 2019) ukazují, jak rychle probíhá aktualizace nové verze iOS. Za tři týdny od svého uvedení (24.",content:`Nové globální statistiky TOPlistu za minulý týden (7. – 13. říjen 2019) ukazují, jak rychle probíhá aktualizace nové verze iOS. Za tři týdny od svého uvedení (24. září) se stává nejpoužívanější verzí mobilního operačního systému firmy Apple (42,48%).
38Ve statistikách lze nálezt i další informace. Třeba podíly prohlížečů a to i rozděleně pro mobily a stolní počítače. Nebo verze Windows, kde je stále vidět vysoký podíl verze 7 a dokonce se ukazují i XP.
39Statistiky se počítají z návštěv z Česka (určené pomocí GeoIP), případně ze Slovenska (tam zatím vede iOS 12.4). Zobrazuje se prvních 10 záznamů, pokud je jednotlivý podíl větší než 1%. Jinak 
39se zahrne do skupiny „ostatní“. Jelikož se jedná o počítání návštěvnosti, zahrnují výsledky i aktivitu uživatelů. Můžou se proto lišit od tržního podílu v případě, že třeba uživatelé určitého prohlížeče méně surfují než ostatní apod.
40`}).add({id:8,tag:"cs",href:"/blog/jak-jsme-slavili-silvestr/",title:"Jak jsme slavili Silvestr",description:"Jak je z obrázku provozu na TOPlistu vidět, začali se lidé na oslavu připravovat už od odpoledne. Chybí odpolední špička, která by rostla od druhé hodiny.",content:`Jak je z obrázku provozu na TOPlistu vidět, začali se lidé na oslavu připravovat už od odpoledne. Chybí odpolední špička, která by rostla od druhé hodiny. Samotné slavení začalo od sedmi večer a, pochopitelně, vyvrcholilo o půlnoci. Pokračovalo do jedné hodiny, kdy se provoz vrátil do běžného stavu. A, jak vidíte, 1. leden je už zase den jako každý jiný.
41Za TOPlist vám v přejeme všechno nejlepší do nového roku, hodně zdraví, úspěchů a vysokou návštěvnost 🙂
42`}).add({id:9,tag:"cs",href:"/napoveda/kod-na-stranku/jak-si-nastavit-merici-kod-toplistu-do-google-tag-manageru/",title:"Jak si nastavit měřící kód TOPlistu do Google Tag Manageru",description:"V případě, že využíváte Google Tag Manager, můžete jednoduše vložit měřící kód (javascript) TOPlistu do Google Tag Manageru, aniž byste museli zasahovat přímo do kódu Vaší stránky.",content:`V případě, že využíváte Google Tag Manager, můžete jednoduše vložit měřící kód (javascript) TOPlistu do Google Tag Manageru, aniž byste museli zasahovat přímo do kódu Vaší stránky. #Jak na to
43Po přihlášení do Google Tag Manageru v části „Workspace“ proveďte následující:
44klikněte v levém menu na položku „Tag“ vytvořte nový „Tag“ kliknutím na tlačítko „New“ v pravé horní části vedle ikonky lupy pojmenujte si nový „Tag“ kliknutím do textového pole „Untitled Tag“ a vepsáním názvu klikněte do části „Tag Configuration“ z nabídky v pravé části stránky vyberte „Custom HTML Tag“ do pole pro vložení html vložte javascript kód TOPlistu, který naleznete na https://www.toplist.cz/code/ a získáte ho zatržením varianty „Nic“neviditelný bod“ zaškrtněte „Support document.write“ klikněte do části „Triggering“ v dolní části stránky pod částí „Tag Configuration“ z nabídky v pravé části stránky vyberte „All Pages“ kliknutím na tlačítko „Save“ v pravé horní části stránky, vše uložíte nezapomeňte změny vypublikovat kliknutím na tlačítko „Submit“ v pravé horní části stránky `}).add({id:10,tag:"cs",href:"/napoveda/jak-zacit/",title:"Jak začít?",description:`K měření návštěvnosti stačí 3 jednoduché kroky:
45Pokud chcete měřit návštěvnost vaší stránky, je potřeba se zaregistrovat. Registrace i provoz služby TOPlist je zdarma.`,content:`K měření návštěvnosti stačí 3 jednoduché kroky:
46Pokud chcete měřit návštěvnost vaší stránky, je potřeba se zaregistrovat. Registrace i provoz služby TOPlist je zdarma. Po registraci je emailem zaslán měřící kód. Pokud nevyhovuje nebo chcete použít jiné počítadlo, můžete vytvořit jiný měřící kód ve formuláři. Kód poté umístíte na každou stránku, kterou chcete měřit. Jedná se o tzn. HTML kód, který lze editovat v jednoduchých editorech typu Poznámkový blok. Více o HTML na www.jakpsatweb.cz. V každém případě je nutné, aby na stránkách byl měřící kód, protože bez něj není technicky možné návštěvnost zaznamenávat. Více o měření se dovíte v Metodice měření. Tipy jak umístit měřící kód do různých redakčních systémů najdete na stránce Kód na stránku
47Pokud máte nějaké otázky, zkuste se podívat do častých dotazů nebo nám napiÅ¡te na [email protected].
48`}).add({id:11,tag:"cs",href:"/blog/kod-na-stranku/",title:"Kód na stránku",description:"Začal jsem dávat dohromady tipy, jak dát měřící kód na různé stránky. Pokud máte nějaký další, pošlete mi ho nebo můžete stránku po registraci rovnou upravit.",content:`Začal jsem dávat dohromady tipy, jak dát měřící kód na různé stránky. Pokud máte nějaký další, pošlete mi ho nebo můžete stránku po registraci rovnou upravit. Viz Kód na stránku
49`}).add({id:12,tag:"cs",href:"/kontakt/",title:"Kontakt",description:`TOPlist s.r.o. &nbsp; nám. Dr. Václava Holého 1054/13, 180 00 Praha 8
50IČ: 27204171
51DIČ: CZ27204171
52dat. schránka: df3vma`,content:` TOPlist s.r.o. &nbsp; nám. Dr. Václava Holého 1054/13, 180 00 Praha 8
53IČ: 27204171
54DIČ: CZ27204171
55dat. schránka: df3vma
56tel. +42O 777 2O2 2O3
57Technická podpora &nbsp; email: [email protected]
58Reklama &nbsp; David Süssemilch
59email: [email protected]
60`}).add({id:13,tag:"cs",href:"/blog/kontrola-gdpr-z-uoou/",title:"Kontrola GDPR z ÚOOÚ",description:`Na začátku roku proběhla kontrola dodržování GDPR na TOPlistu. Hlavní výsledek je:
61„Úřad v souvislosti s předmětným zpracováním osobních údajů nezjistil porušení nařízení (EU) 2016/679.`,content:`Na začátku roku proběhla kontrola dodržování GDPR na TOPlistu. Hlavní výsledek je:
62„Úřad v souvislosti s předmětným zpracováním osobních údajů nezjistil porušení nařízení (EU) 2016/679.“
63Nyní je zpráva zveřejněna přímo na webu Úřadu pro ochranu osobních údaju.
64`}).add({id:14,tag:"cs",href:"/blog/krizova-strategie/",title:"Krizová strategie",description:"Situace &nbsp; Celá situace začala jako banální závada. Ve čtvrtek večer odešel v jednom databázovém serveru pevný disk. Není to nic výjimečného a servery jsou na to připraveny a standardně se celá záležitost obejde bez komplikací.",content:` Situace &nbsp; Celá situace začala jako banální závada. Ve čtvrtek večer odešel v jednom databázovém serveru pevný disk. Není to nic výjimečného a servery jsou na to připraveny a standardně se celá záležitost obejde bez komplikací. Práci automaticky převezmou další disky, kterých bývá několik připravených. V tomto případě se ovšem objevily indicie, že se může jednat o něco závažnějšího. Souborový systém hlásil možné poškození. Na víkend byla proto naplánovaná důkladná kontrola. Během ní se ovšem ukázalo, že server vykazuje další podivné chování. Někdy se zdálo, jakoby docházelo k výpa
64dkům operační paměti. Občas byly problémy se síťovým připojením. Paměť byla vyměněna, zrovna tak kabely a switch na vnitřní síti. Ve finále bylo vyměněno celé chasis serveru. A nové už začalo pracovat bez problému. Původní je už nyní na cestě k výrobci pro analýzu.
65Bohužel, při opravách muselo být přesunuto přibližně 600 GB dat (včetně zpětného importu do databáze). Což probíhalo v noci ze soboty na neděli. A navic během této odstávky přibylo dalších 14 milionů nových záznamů (viz. bod 2 krizové strategie)
66Nyní se statistiky dopočítávají. A já doufám, že dnešní noc už bude klidnější a já konečně doženu ty tři hodiny spánku za víkend 🙂
67Tím se omlouvám za případné problémy a děkuji za pochopení.
68Zároveň bych chtěl poděkovat Renatě, která obětavě i o víkendu vyřizovala dotazy zaslané na helpdesk.
69PF
70Krizová strategie &nbsp; 1. Neomezovat měřené stránky &nbsp; V případě problému je naší prioritou, aby se měřené stránky načítaly bez snížení rychlosti. Toho je dosaženo několika způsoby. Jednak se pro měření nepoužívá žadný externí skript, na který by se mohlo čekat. Zároveň mají měřené ikony definován rozměr, takže se stránka vykreslí ještě před jejich načtením.
71Dále jsou před našimi webovými servery tzn. load balancery. A jsou nastaveny tak, že pokud náš server neodpoví během chvíle, je spojení bez milosti ukončeno, aby nedocházelo k čekání. A to, v krajním případě, i za cenu nezapočtení návštěvy. Rychlé zobrazení měřené stránky je zkrátka absolutní priorita.
722. Získávání dat &nbsp; Další prioritou je získávání dat. Pokud dochází k problémům při jejich zpracování, je důležité, aby se naměřená data alespoň ukládala. To umožní, po vyřešení zdržení, jejich zpětné zpracování.
733. Zobrazení statistik &nbsp; Byť je to z hlediska prezentace samotného TOPlistu na škodu (je hned vidět, že “něco nefunguje”), je samotné zobrazení výsledků statistik až na třetím místě. Chápeme, že jsou někdy potřeba data k dispozici co nejdříve. Ale věříme, že uživatele se mohou ke statistikám vrátit později (v základní verzi až 7 dni, v Profi neomezeně) a pochopí, že zabezpečení prvních dvou bodů je i z jejich hlediska důležitější.
74`}).add({id:15,tag:"cs",href:"/blog/mazani-zaznamu/",title:"Mazaní záznamu",description:"Dneska nastala drobná aktualizace. Smazat stránku lze pouze v případě, že k nebyla alespoň dva dny zaznamenána návštěva. Omezí se tím smazání omylem.",content:`Dneska nastala drobná aktualizace. Smazat stránku lze pouze v případě, že k nebyla alespoň dva dny zaznamenána návštěva. Omezí se tím smazání omylem. Seznam takových stránek je buď vypsán při mazání, nebo lze použít statistiku Vstupní stránky. Chyby mi, prosím, hlaste třeba do diskusí.
75`}).add({id:16,tag:"cs",href:"/blog/memcached/",title:"Memcached",description:`distribuovaná memory storage &nbsp; Doteď jsem informace o právě aktivních sessions ukládal klasicky do databáze.
76Jelikož se nyní dosti zvedlo množství sledovaných návštěvníků, obsahovala ve špičce přes 3 milióny záznamů (součet všech online návštěvníků na všech měřených serverech) a počet dotazů do ní byl v řádech stovek za vteřinu.`,content:` distribuovaná memory storage &nbsp; Doteď jsem informace o právě aktivních sessions ukládal klasicky do databáze.
77Jelikož se nyní dosti zvedlo množství sledovaných návštěvníků, obsahovala ve špičce přes 3 milióny záznamů (součet všech online návštěvníků na všech měřených serverech) a počet dotazů do ní byl v řádech stovek za vteřinu. Proto jsem se rozhodl vyzkoušet na jejich uložení paměťový daemon. Nejsem příznivcem akademického „urob-si-sám“ a tak jsem použil memcached, který už na jiných projektech nějakou dobu používáme.
78Jedná se o jednoduchý prográmek, který umožňuje uložení víceméně libovolné struktury (klientské knihovny jsou pro Perl, Python, PHP, C ad. – samotný protokol je také primitivní) pod klíč.
79Během dneška uvidím, jaký vliv to bude mít na samotné statistiky, ale metodika zůstává nezměněná (proč taky měnit to, co 8 let funguje), tj. min. 30 minut interval mezi návštěvami jednoho uživatele.
80`}).add({id:17,tag:"cs",href:"/blog/memcached-1-vysledky/",title:"Memcached – 1. výsledky",description:`Tento příspěvek je víceméně odpověď Jirkovi Pallasovi v komentáři k předchozímu, ale třeba bude zajímat i někoho dalšího 🙂
81Po přibližně 14.`,content:`Tento příspěvek je víceméně odpověď Jirkovi Pallasovi v komentáři k předchozímu, ale třeba bude zajímat i někoho dalšího 🙂
82Po přibližně 14. dnech provozu je situace následující.
83Průměrný provoz je přes 500 čtení a 300 nastavení za vteřinu. Při objemu dat kolem 170 MB je procesor [email protected] zatížený asi na 5%. A to jeÅ¡tě běží na 2.4 jádru, tj. bez podpory epollu [viz libevent]. Na jiném projektu jej už používáme (Debian sarge a 2.6 jádro). Proklamované zrychlení o řády se sice nekonalo, ale „alespoň“ v násobcích to bylo.
84`}).add({id:18,tag:"cs",href:"/blog/merene-domeny/",title:"Měřené domény",description:"Přemýšlím, že bych v podrobných statistikách, ve veřejné části, vypisoval domény, na kterých došlo k měření. Bylo by hned vidět, kdo nasázel měřící kód na x dalších adres.",content:`Přemýšlím, že bych v podrobných statistikách, ve veřejné části, vypisoval domény, na kterých došlo k měření. Bylo by hned vidět, kdo nasázel měřící kód na x dalších adres. Žádná čísla, žádné detaily, jen seznam domén. Těch, kteří nejsou v žebříčku zobrazeni, by se to netýkalo. Nějaké protinávrhy? 🙂
85`}).add({id:19,tag:"cs",href:"/napoveda/toplist-profi/merene-statistiky/",title:"Měřené statistiky",description:`V reportu lze vytvořit statistiky následujících hodnoty:
86Návštěvy &nbsp; Návštěvy &nbsp; počet návštěv, které byly zaznamenány na webu. Návštěva je definována jako sledování aktivit uživatele na webu.`,content:`V reportu lze vytvořit statistiky následujících hodnoty:
87Návštěvy &nbsp; Návštěvy &nbsp; počet návštěv, které byly zaznamenány na webu. Návštěva je definována jako sledování aktivit uživatele na webu. Návštěva končí po 30 minutách nečinnosti uživatele na webu. Pokud se uživatel vrátí na web po více než 30 minutách, bude to považováno za novou návštěvu.
88Unikátní IP &nbsp; počet unikátních anonymizovaných IP adres, které byly zaznamenány na webu.
89Zhlédnutí &nbsp; počet zhlédnutých stránek na webu. Zhlédnutí je definováno jako zobrazení stránky uživatelem. Zobrazení dalších stránek nebo opětovné zobrazení stejné stránky se počítá jako další zhlédnutí.
90Prohlížeče &nbsp; počet návštěv rozdělený podle prohlížečů. Prohlížeče jsou identifikovány podle názvu a verze.
91Operační systémy &nbsp; počet návštěv rozdělený podle operačních systémů.
92Rozlišení monitorů &nbsp; počet návštěv rozdělený podle rozlišení monitorů. Udává se v počtu pixelů šířky a výšky.
93Barevná hloubka &nbsp; počet návštěv rozdělený podle barevné hloubky monitorů. Udává se v bitech.
94Hloubka návštěv &nbsp; počet návštěv rozdělený podle hloubky návštěv. Hloubka návštěv je definována jako počet zhlédnutých stránek během jedné návštěvy.
95Návštěvy - domény &nbsp; počet návštěv rozdělený podle domén návštěvníků (adresou jejich poskytovatele přípojení). Domény jsou identifikovány podle druhé úrovně domény. Tj. např. seznam.cz, toplist.cz, o2.cz, atd.
96Návštěvy - domény(trend) &nbsp; počet návštěv rozdělený podle domén návštěvníků. Výsledky jsou zobrazeny v grafu v časovém sledu.
97Vyhledávače &nbsp; počet návštěv rozdělený podle vyhledávačů. Vyhledávače jsou identifikovány podle refereru(odkazující stránky), ze kterého přišel návštěvník.
98Typ zařízení &nbsp; počet návštěv rozdělený podle typu zařízení. Typy zařízení mohou být mobilní telefony, tablety, počítače, atd.
99Typ aplikace &nbsp; počet návštěv rozdělený podle typu aplikace. Typy aplikací mohou být webové prohlížeče, mobilní aplikace, chytré televize, automobily atd.
100Návštěvnost během dne &nbsp; počet návštěv rozdělený podle denní doby. Udává se v hodinách.
101Návštěvnost podle dne &nbsp; počet návštěv rozdělený podle dne v týdnu.
102Trend návštěvnosti &nbsp; počet návštěv zobrazený v časovém sledu.
103Celková návštěvnost &nbsp; celkový počet návštěv zobrazený ve zvoleném období.
104Verze prohlížeče &nbsp; počet návštěv rozdělený podle verze prohlížeče.
105Verze operačního systému &nbsp; počet návštěv rozdělený podle verze operačního systému.
106Engine prohlížeče &nbsp; počet návštěv rozdělený podle engine prohlížeče. Jedná se o základní zobrazovací jádro prohlížeče. Mohou to být např. Gecko, Trident, WebKit, atd.
107Země &nbsp; počet návštěv rozdělený podle země návštěvníků.
108návštěvy - TLD &nbsp; počet návštěv rozdělený podle TLD návštěvníků. TLD je doména nejvyšší úrovně. Tj. např. .cz, .com, .net, atd.
109Zdroje &nbsp; Všechny &nbsp; přehled všech zdrojů návštěvnosti. Zdroje jsou identifikovány podle refereru(odkazující stránky), ze kterého přišel návštěvník.
110Domény &nbsp; přehled zdrojů návštěvnosti rozdělený podle domén návštěvníků. Domény jsou identifikovány podle druhé úrovně domény. Tj. např. seznam.cz, toplist.cz, o2.cz, atd.
111Vyhledávače &nbsp; přehled zdrojů návštěvnosti rozdělený podle vyhledávačů. Vyhledávače jsou identifikovány podle refereru(odkazující stránky), ze kterého přišel návštěvník.
112Hledané fráze &nbsp; přehled zdrojů návštěvnosti rozdělený podle frází, které byly hledané ve vyhledávačích.
113Obsah &nbsp; Vstupní stríánky &nbsp; počet návštěv rozdělený podle vstupních stránek. Vstupní stránka je definována jako první zhlédnutá stránka návštěvníkem.
114Výstupní stránky &nbsp; počet návštěv rozdělený podle výstupních stránek. Výstupní stránka je definována jako poslední zhlédnutá stránka návštěvníkem během jedné návštěvy.
115Nejnavštěvovanější &nbsp; počet návštěv rozdělený podle nejnavštěvovanějších stránek.
116Cesty &nbsp; počet návštěv rozdělený podle cest návštěvníků. Cesta je definována jako sled zhlédnutých stránek návštěvníkem během jedné návštěvy.
117Lokální hledání - fráze &nbsp; počet návštěv rozdělený podle frází, které byly hledané ve vyhledávání na měřeném webu.
118`}).add({id:20,tag:"cs",href:"/blog/mereni-navstevnosti-bez-cookie
118s/",title:"Měření návštěvnosti bez cookies",description:"Vždy jsme kladli důraz na soukromí návštěvníků Vašich stránek. Nesledujeme je, nevytváříme jejich profily pro cílení reklamy, nezpracováváme jejich osobní data.",content:`Vždy jsme kladli důraz na soukromí návštěvníků Vašich stránek. Nesledujeme je, nevytváříme jejich profily pro cílení reklamy, nezpracováváme jejich osobní data. Vytváříme statistiky, které jsou určeny pouze pro Vás, majitele a administrátory webových stránek. I proto jsme bez problému prošli kontrolou dodržování GDPR Úřadu pro ochranu osobních údajů. Samotné cookies se používají pouze k technickému rozlišení „návštěvy“ a „zhlédnutí“ viz Metodika měření.
119Během letošního roku byl vyvinutý nový způsob rozlišování. Cílem bylo zcela odstranit nutnost použití cookies. Změna byla úspěšná a podle dosavadních testů je rozdíl v naměřených hodnotách pod úrovní statistické chyby. Měřící kód na Vašich stránkách není potřeba měnit a novinka bude automaticky aktivní u všech stránek 1. ledna 2022.
120Zároveň se trochu změní grafika ikon, která (konečně 🙂) bude ladit se změnou grafiky samotného webu. Zde je ukázka upravených ikon. Jedna z verzí, s nápisem „bez cookies“, Vám umožní informovat Vaše návštěvníky, že si vážíte jejich soukromí a používáte měření, které to respektuje.
121Počítadla &nbsp; Loga &nbsp; Aktualizace [30.12.2021 01:07]: nové měření je spuštěné `}).add({id:21,tag:"cs",href:"/blog/mereni-navstevnosti-na-wapu/",title:"Měření návštěvnosti na WAPu",description:"Není to úplná novinka, ale asi jsem o tom ještě nikde nepsal 🙂 Kdysi jsem si hrál s WAPem, takže stačí použít kód:",content:`Není to úplná novinka, ale asi jsem o tom ještě nikde nepsal 🙂 Kdysi jsem si hrál s WAPem, takže stačí použít kód:
122&lt;img src=“http://toplist.cz/wap.asp?ID=xxx“ alt=“.“/&gt;kde xxx je pochopitelně ID stránky. Posílá to WBMP bílý bod. Nejsou tam žadná rozšiření pomocí Javaskriptu atp. Další omezení je, že WAP neposílá referrer, takže stránky jsou označeny ve statistikách jednotně jako „W@P“. Ještě není udělaná nějaká bližší identifikace mobilů, ale pokud bude zájem a hlavně data, tak se to dá dodělat.
123`}).add({id:22,tag:"cs",href:"/blog/metodika-globalni-statistiky-vyhledavacu/",title:"Metodika globální statistiky vyhledávačů",description:"Pomocí Javaskriptu se zaznamenávají referery na měřeném webu. Vynechány jsou kategorie Erotika a Zahraniční, servery TOPlist a Sreality s Sbazarem (kvůli omezení vlivu odkazů mezi službami Seznamu).",content:`Pomocí Javaskriptu se zaznamenávají referery na měřeném webu. Vynechány jsou kategorie Erotika a Zahraniční, servery TOPlist a Sreality s Sbazarem (kvůli omezení vlivu odkazů mezi službami Seznamu). Dále jsou započítány pouze služby, které během dne přinesly víc než 10 návštěv. V grafech jsou denní hodnoty agregovány podle týdne. Graf umožňuje k URL přidat dva parametry: lang (hodnota CZ vyfiltruje pouze uživatele z Čech rozlišených pomocí databáze GeoIP) a year (výpis statistik za určitý kalendářní rok).
124Snad vám to pomohlo trochu se ve výsledcích zorientovat.
125`}).add({id:23,tag:"cs",href:"/napoveda/dokumentace/metodika-mereni/",title:"Metodika měření",description:"Jak se měří? &nbsp; K měření návštěvnosti sledované stránky se používá kód, který je nutné na ni umístit (další informace viz Jak začít?",content:` Jak se měří? &nbsp; K měření návštěvnosti sledované stránky se používá kód, který je nutné na ni umístit (další informace viz Jak začít?). Jedná se vlastně o obrázek (může to být buď standardní ikona o rozměrech 88×31 bodů nebo „neviditelný“ bod o velikosti 1×1 bod). Z toho plyne určitá možná nepřesnost měření, způsobená např. vypnutým zobrazováním grafiky na straně návštěvníka. Na druhou stranu to daleko lépe odráží např. reklamní možnosti plochy (komu se nezobrazí ikona TOPlistu, tomu se nezobrazí ani reklamní banner). Navíc lze toto částečně eliminovat současným použitím i textového počítadla, které systém TOPlist také nabízí.
126Jaké hodnoty se měří? &nbsp; Návštěvy (visits) &nbsp; Jedná se o základní veličinu měřenou TOPlistem. Podle obecných pravidel se jedná o zobrazení stránky v prohlížeči za určitou dobu. Podle pravidel používaných ve světě (viz. Wiki
126pedie http://en.wikipedia.org/wiki/Bounce_Rate) je tato doba 30 minut. To znamená, že pokud se uživatel ze stejného počítače vrátí po více než 30 minutách na stránku zpět, je započítána nová návštěva. Denní hodnoty jsou archivovány za celou dobu od registrace.
127Zhlédnutí (pageviews) &nbsp; Tato hodnota znamená každé zobrazení stránky (nebo stránek, pokud je kód umístěn na více). A to i v případě, kdy uživatel použije třeba tlačítko Obnovit.
128Toto jsou hlavní veličiny, které TOPlist měří o návštěvnosti. Další hodnoty jsou doplňkové a umožňují další upřesnění informací o návštěvnících. Patří k nim informace o používaných prohlížečích, operačních systémech, domény návštěvníků, rozlišení a barevná hloubka monitorů ad.
129Další popis zobrazovaných hodnot naleznete také v Často kladených otázkách.
130Pojmy &nbsp; IP &nbsp; unikátní číselná adresa každého počítače, který je připojen k internetu.
131cookie &nbsp; krátká textová informace, kterou lze uložit v prohlížeči návštěvníka webové stránky a později zpět vyzvednout. Měření TOPlistem cookies nepoužívá.
132`}).add({id:24,tag:"cs",href:"/blog/mnohonasobne-rychlejsi-statistiky/",title:"Mnohonásobně rychlejší statistiky",description:"Právě byla do provozu spuštěná nová verze statistik. Vzhled a funkce zůstaly stejné, ale je úplně přepracované technické řešení, které běží na pozadí.",content:`Právě byla do provozu spuštěná nová verze statistik. Vzhled a funkce zůstaly stejné, ale je úplně přepracované technické řešení, které běží na pozadí. Používá se jiná databáze a její volání přes REST API. Díky tomu je načítání dat mnohonásobně rychlejší. Proto jsou i výsledky pro stránky se stovkami tisíc zhlédnutí denně zobrazeny během zlomku vteřiny.
133`}).add({id:25,tag:"cs",href:"/napoveda/dokumentace/nastaveni/",title:"Nastavení",description:`https://www.toplist.cz/edit/
134V nastavení lze editovat základní údaje o registrované stránce (adresa, název, popisek, kategorie, kontaktní email), další volby (přístup bez hesla, změna hesla, skrytí statistik a další) a přehled přihlášení k účtu.`,content:`https://www.toplist.cz/edit/
135V nastavení lze editovat základní údaje o registrované stránce (adresa, název, popisek, kategorie, kontaktní email), další volby (přístup bez hesla, změna hesla, skrytí statistik a další) a přehled přihlášení k účtu.
136Přihlášení &nbsp; Do editace se přihlásíte pomoci TOPlist ID a hesla, které jste nastavili při registraci. Pokud jej neznáte, lze jej obnovit pomocí odkazu &ldquo;zapomenuté heslo&rdquo;, kdy po vyplnění správného konktatní email je na něj zaslán odkaz na změnu hesla.
137Údaje &nbsp; Stránka nastavení má tři části. Hlavní je formulář pro nastavení údajů. Umožňuje změnit tyto údaje:
138Adresa - Hlavní webová adresa (URL) registrované webové stránky. Název - Název stránky, který bude zobrazen v žebříčku návštěvnosti, výpisu statistik atd. Popis - Krátký (max. 255 znaků) popis stránky, zobrazený jako alternativní text odkazu v žebříčku, ve výpisu statistik atd. Kategorie - Zvolená hlavní kategorie, v které bude stránka zobrazena v žebříčku. Posílat každý týden statistiky mailem - Volba, zda se má každě pondělí posílat krátký email s přehledem návštěvnosti za předchozí týden na kontaktní emaily. Podrobné statistiky jen s heslem - Zda je ke zobrazení statistik vyžadováno heslo. Je to stejné heslo, jako je potřeba k přistupu do nastavení. Neveřejné měření - Vypnutí zobrazení stránky v žebříčku a výsledcích hledání. Nezapočítavaná IP adresa - IP adresa, nebo její čast (nahrazení pomocí *, např. 127.0.1.*), z kterých se nemá návštěvnost zaznamenávat. Bezpečnostní kód - viz víc informací Email - kontaktní email nebo víc emailů oddělených čárkou. Slouží k zasílání týdenních statistik, případně zaslání odkazu na n
138astavení nového hesla. Pokud dojde k jeho ověření, je aktivní přímý link z žebříčku na měřenou stránku. Menu &nbsp; Druhá čast stránky je menu s odkazy na změnu hesla, vynulování statistik a smazání účtu.
139Log přístupů &nbsp; Poslední částí je seznam přihlášení. Obsahuje čas posledního přihlášení z přislušné IP adresy a akci, které toho přihlášení vyžadovala.
140`}).add({id:26,tag:"cs",href:"/napoveda/nastaveni-hesla/",title:"Nastavení hesla",description:"Jeden z nejčastějších dotazů, které řešíme jsou otázky typu: ‘Jsem nový majitel webu a jak získám heslo, když nemám přístup k emailům v registraci’ nebo ‘Nepamatuju si, jaký email je registrovaný’.",content:`Jeden z nejčastějších dotazů, které řešíme jsou otázky typu: ‘Jsem nový majitel webu a jak získám heslo, když nemám přístup k emailům v registraci’ nebo ‘Nepamatuju si, jaký email je registrovaný’. Nyní lze tuto situaci jednoduše řešit.
141Ve formuláři pro obnovu hesla je ještě jeden formulář. V něm se zobrazí adresa z vašeho webu, na které budeme čekat kontrolní klíč. Patrně to bude stránka, která ještě neexistuje. Není tak potřeba zasahovat do současného webu a stačí tuto novou stránku vytvořit. Nemusí to být ani plnohodnotná stránka (např. i bez designu apod.). Může být i jen obyčejný textový soubor.
142Pak stačí nechat zkontrolovat, že obsahuje klíč. A pokud ano, tak umožníme heslo změnit.
143Konkrétní příklad:
144Formulář pro obnovu hesla Pro TOPlist je nastavení hesla na adrese https://www.toplist.cz/password/reset/1. Po zmáčknutí tlačítka to vypíše požadovanu adresu (každý návštěvník uvidí jinou). Pro náš příklad to může být třeba: www.toplist.cz/jvdrv.html. A také klíč WY3NqZRsbZQPfHbGksyOE7b2SMGLWVU7. Takže stačí, abych vytvořil soubor na požadováné adrese. A po zkontrolování bude možné heslo změnit.
145`}).add({id:27,tag:"cs",href:"/blog/nova-verze-blogu/",title:"Nová verze blogu",description:"Tento blog začínal před více než 20 lety jako poznámky na blogu Lidé.cz. Později se přesunul na vlastní doménu a na redakční systém Wordpress.",content:`Tento blog začínal před více než 20 lety jako poznámky na blogu Lidé.cz. Později se přesunul na vlastní doménu a na redakční systém Wordpress. Nyní nastal čas na další větší změnu. Rozhodl jsem se začít používat statický generátor Hugo. Pro informační web je to vhodné řešení. Díky tomu, že se stránky generují předem, je jejich zobrazení rychlejší a bezpečnější. Editace je jednoduchá díky Markdownu a umožňuje verzování.
146Po vyzkoušení několika šablon jsem se rozhodl pro Hinode. Je to relativně nová šablona, postavená na Bootstrap 5. Zároveň umožňuje kombinaci jak stránek s dokumentací, tak i blogu. Je zatím stále ve vývoji a některé části jsem musel upravit. Pokud to bude dávat smysl, budu se snažit úpravy posílat zpět do upstreamu.
147Například jsem přidal podporu pro Isso, které používám pro komentáře. Je to, alespoň zatím, jediná dynamická část na tomto webu. Všechny komentáře jsou uloženy na vlastním serveru a nejsou závislé na žádné třetí straně.
148`}).add({id:28,tag:"cs",href:"/blog/nove-podkategorie-a-prejmenovani-kategorie-casopisy/",title:"Nové podkategorie a přejmenování kategorie Časopisy",description:`V rámci postupné aktualizace stromu kategorií jsme přejmenovali kategorii „Časopisy“ na „Magazíny“ a přidali jsme nové podkategorie:
149„Magazíny pro ženy“ jako podkategorii kategorie „Magazíny“ „Vaření a recepty“ jako podkategorii kategorie „Životní styl“ „Ordinace“ jako podkategorii kategorie „Zdraví“ Pokud Vám budou nové kategorie vyhovovat, využijte váš účet na TOPlist.`,content:`V rámci postupné aktualizace stromu kategorií jsme přejmenovali kategorii „Časopisy“ na „Magazíny“ a přidali jsme nové podkategorie:
150„Magazíny pro ženy“ jako podkategorii kategorie „Magazíny“ „Vaření a recepty“ jako podkategorii kategorie „Životní styl“ „Ordinace“ jako podkategorii kategorie „Zdraví“ Pokud Vám budou nové kategorie vyhovovat, využijte váš účet na TOPlist.cz a zařaďte si vaše stránky do těchto nových podkategorií. I nadále budou vaše stránky zobrazené i v hlavní kategorii.
151`}).add({id:29,tag:"cs",href:"/blog/nove-podkategorie-cestovani/",title:"Nové podkategorie Cestování",description:"Přidal sem do kategorie Cestování tři nové podkategorie: cestovní kanceláře, ubytování a informace. Pokud máte návrhy na nějaké nové kategorie, tak je směle sem s nimi 🙂.",content:`Přidal sem do kategorie Cestování tři nové podkategorie: cestovní kanceláře, ubytování a informace. Pokud máte návrhy na nějaké nové kategorie, tak je směle sem s nimi 🙂. Jedinou podmínkou je, aby bylo už registrováno minimálně 50 webů, které by mohly do této kategorie patřit.
152`}).add({id:30,tag:"cs",href:"/blog/nove-statistiky-prohlizecu/",title:"Nové statistiky prohlížečů",description:"Většina statistik nyní umožňuje zobrazení výsledku jak v tabulce, tak i grafu (pro statistiky za jeden den je použitý koláčový graf).",content:`Většina statistik nyní umožňuje zobrazení výsledku jak v tabulce, tak i grafu (pro statistiky za jeden den je použitý koláčový graf).
153Zároveň je vytvořený nový způsob identifikování prohlížečů, které umožní měřit více parametrů. Jako ukázka jsou přidané dvě statistiky:
154Typ zařízení &nbsp; Rozlišení, zda se jedná o počítač (desktop), chytrý telefon, tablet, phablet (větší chytrý telefon) apod.
155Engine prohlížeče &nbsp; Také nazývané vykreslovací jádro (Wikipedie). Základní část prohlížeče, která se stará o samotné vykreslení stránky. Právě její vlastnosti určují, jak se návštěvníkům stránka zobrazí. Dnes mezi nejpoužívanější patří Blink (Chrome, Opera), Gecko (Firefox) a Webkit (starší Chrome, Safari).
156Do konce prázdnin by mělo dojít k přechodu na novou identifikaci i u ostatních statistik (verze prohlížeče, operačního systému ad.)
157`}).add({id:31,tag:"cs",href:"/blog/novy-hlavni-databazovy-server/",title:"nový hlavní databázový server",description:`V posledních dnech, kdy objem denních statistik přesáhl 170 miliónů zhlédnutí, se ukázala nutnost výměny hlavního databázového serveru.
158Je docela překvapivé, že na svém místě vydrzel víc než tři roky.`,content:`V posledních dnech, kdy objem denních statistik přesáhl 170 miliónů zhlédnutí, se ukázala nutnost výměny hlavního databázového serveru.
159Je docela překvapivé, že na svém místě vydrzel víc než tři roky. Ale je pravda, že z něj byla během té doby podstatná část zátěže přesunuta na další dva pomocné servery. Takže původní dual Xeon na 3GHz a 2GB paměti byl vyměnen za nový 
159s parametry 2x quad-core Xeon E5335 2GHz, 8GB RAM, 4x 76GB 15krpm SAS v RAID 10.
160Bylo nutné systém ještě trochu vyladit (raid je softwarový, ale server obsahuje i HW RAID s 256 MB vyrovnávací paměti a to trochu mate systém při zápisech), ale jinak se zdá, že by měl mít dostatečný výkon. A je jenom otázka, jestli vydrzí tak dlouho jako jeho předchůdce.
161A jedna perlička na závěr. Když to spočítám, tak TOPlist dnes bězí na 15 procesorech, celkem s 32 jádry, 24 GB RAM a 4TB disků. Nebýt toho, že ty požadavky stoupaly postupně během posledních 4 let (tenkrát ještě všechno běželo na jednom stroji), dalo se to všechno nacpat do jednoho blade serveru 🙂.
162`}).add({id:32,tag:"cs",href:"/blog/novy-server/",title:"Nový server",description:"Problémy začaly minulý týden, kdy na hostingu (Casablanca) vypadl proud a prý jim dvacet minut trvalo než na to vůbec přišli.",content:`Problémy začaly minulý týden, kdy na hostingu (Casablanca) vypadl proud a prý jim dvacet minut trvalo než na to vůbec přišli. Všechno vyvrcholilo včera večer, kdy se při instalaci nového serveru zjistilo, že je na jednom stávajícím disk v takovém stavu, že po rebootu už nenaběhl (nechci spekulovat, jak moc se na této situaci výpadek projevil, ale umřelého železa bylo po serverovně vidět docela dost). Jelikož ani rozběhnutí nového serveru nebylo zcela bez problému (např. podpora pro nový RAID řadič je až v jádře 2.6.14) byl dneska, bohužel, TOPlist v degradovaném stavu. Nyní se podařilo situaci stabilizovat. Nový server se na tom podílí nemalou měrou.
163Jedná se o poměrně zajímavý kousek. Jeho výrobce je Supermicro a z oficiálních stránek se o něm nic nedovíte. Na nich se totiž zdá, se Supermicro je čistě Intel-only výrobce. Takže až na adrese http://www.supermicro.com/Aplus/ se dá objevit, že to není úplně pravda. Tento konkrétní kousek má označení AS1020A-T. Jedná se o 1U server osazený 2GB RAM a dvěma Opterony 270 (2.0GHz, dual-core). Zatím na něm běží 32bitová verze Debianu (sarge). O tom, jakou 64bit distribuci tam dát zatím uvažuji (zatím mi běží Ubuntu a CentOS). Vaše případné tipy jsou vítány 🙂.
164Ještě není celý systém úplně doladěný, ale celkový nárůst výpočetní kapacity je téměř 50%, takže skýtá rezervy. A ještě se trochu zvednou, až se zase zapojí ten odešlý server, co tam leží v koutě, to byl Opteron 144 (1,8Ghz, single-core).
165`}).add({id:33,tag:"cs",href:"/obchodni-podminky/",title:"Obchodní podmínky",description:"I. Základní ustanovení &nbsp; Tyto Všeobecné smluvní podmínky (dále jen „VOP“) upravují smluvní vztah mezi Provozovatelem a Zákazníkem. Provozovatelem služby měření návštěvnosti webových stránek TOPlist Profi (dále jen „Služby“) je společnost TOPlist s.",content:" I. Základní ustanovení &nbsp; Tyto Všeobecné smluvní podmínky (dále jen „VOP“) upravují smluvní vztah mezi Provozovatelem a Zákazníkem. Provozovatelem služby měření návštěvnosti webových stránek TOPlist Profi (dále jen „Služby“) je společnost TOPlist s.r.o., IČ: 27204171, se sídlem náměstí Dr. Václava Holého 1054/13, Libeň, 180 00 Praha 8, spisová značka: C 104234 vedená u Městského soudu v Praze. Zákazníkem se stává svéprávná fyzická osoba nebo právnická osoba, která s Provozovatelem uzavře Smlouvu. K uzavření smlouvy dojde vyplněním objednávky na stránkách „profi.toplist.cz“ na některou z nabízených služeb Provozovatele a současně řádným zaplacením částky dle aktuálního ceníku provozovatele, popř. zřízením služby pokud se jedná o službu bezplatnou. Objednáním služby Zákazník projevuje souhlas s těmito Všeobecnými smluvními podmínkami (VOP). Zákazníkem – spotřebitelem se rozumí svéprávná fyzická osoba, která uzavírá smlouvu s Provozovatelem pro své soukromé, nepodnikatelské účely. Autorizací se myslí prokázání totožnosti zákazníka, zejména prokázání se přihlašovacím jménem a heslem k Zákaznickému účtu, a tím také prokázání práva pro nakládání se zákaznickým účtem a službami, které jsou pod ním vedeny. Zákazník bere na vědomí a souhlasí s tím, že není oprávněn uzavírat smlouvu s Provozovatelem a objednávat služby nabízené Provozovatelem jménem třetích stran, jestliže mu k tomu třetí strana nedala předem písemný souhlas. Tento písemný souhlas může být kdykoliv Provozovatelem vyžádán a Zákazník je povinen jej neprodleně předložit, jinak je Provozovatel oprávněn objednanou službu zrušit. Objednáním služby Zákazník vyjadřuje svůj jednoznačný souhlas a porozumění se Smlouvou, těmito VOP a všemi ostatními podmínkami souvisejícími s objednanou službou, stejně jako s obsahem, specifikací a cen
165ou jím objednané služby dle nabídky Provozovatele. Zákazník i Provozovatel jsou povinni v průběhu trvání Smlouvy dodržovat všeobecně platné právní předpisy, ustanovení Smlouvy, tyto VOP a další podmínky v případě, že jsou součástí zákazníkem objednané služby. Zákazník uzavřením Smlouvy rovněž prohlašuje, že se seznámil s funkcemi dané služby a z toho důvodu není v rámci poskytnuté služby oprávněn požadovat vrácení již uhrazené platby za některou z nabízených služeb s odůvodněním, že mu provedení služby nevyhovuje. Zákazník v plné míře odpovídá za veškeré škody, které způsobí svým jednáním v rozporu s těmito VOP a/nebo právním řádem České republiky Provozovateli, jiným uživatelům Služeb nebo jiným třetím osobám. Této odpovědnosti se nelze zprostit. V případě, že Zákazník porušuje tyto VOP, je Provozovatel oprávněn pozastavit jeho Služby. Při zvlášť závažném porušení nebo opakovaném porušování těchto VOP je Provozovatel oprávněn službu zrušit. Zrušením služby se rozumí její pozastavení, ukončení a smazání dat této služby. II. Povinnosti a práva provozovatele &nbsp; Provozovatel zajistí bezproblémový provoz služeb s výjimkou doby nezbytné pro údržbu technických a softwarových prostředků, jejichž prostřednictvím jsou služby provozovány. Provozovatel je oprávněn provádět plánované odstávky systémů za účelem jejich údržby a aktualizací. Provozovatel je oprávněn provádět neplánované odstávky, pokud to situace vyžaduje a je nutné je neodkladně provést za účelem zajištění dalšího chodu služeb a serverů. Poruchou se rozumí chyba v technických nebo softwarových prostředcích Provozovatele, která způsobuje úplnou nefunkčnost či nedostupnost služeb, následkem čehož je Zákazník nemůže v plné míře využívat. Za poruchu se nepovažuje plánovaná odstávka. Provozovatel neručí za nefunkčnost či nedostupnost služby, která je zapříčiněna třetí stranou. Provozovatel nenese žádnou zodpovědnost za nefunkčnost či nedostupnost systému, která byla způsobena technickým či jiným problémem na straně subdodavatele, poruchou či odstávkou v síti Internet mezi uživatelem a servery Provozovatele či vyšší mocí. Provozovatel nenese zodpovědnost za nedostupnost služby v případě nefunkčnosti připojení uživatele k Internetu. Provozovatel neodpovídá za jakoukoli škodu či ztrátu, která byla nebo by mohla být Zákazníkovi způsobena v souvislosti s používáním služeb. Jakékoliv náhrady škod a dalších nákladů, včetně odpovědnosti za ušlý zisk Zákazníka, jsou vždy limitovány (a ohraničeny) maximální výší, která je rovna poplatku za jeden měsíc provozu příslušné služby. Provozovatel může vkládat reklamní sdělení (o maximální délce textu 200 znaků) a to své nebo třetích stran do pravidelných emailů s týdenním reportem návštěvnosti. III. Vyúčtování a platby &nbsp; Aktuální ceník je k dispozici na stránkách Provozovatele „profi.toplist.cz“. Změny v ceníku Provozovatel včas oznamuje na stejných stránkách. Faktury a zálohové faktury jsou Zákazníkovi zasílány prostřednictvím elektronické pošty na e-mailovou adresu, která je uvedena v zákaznickém účtu Zákazníka. Účetní doklady nejsou poskytovány v papírové podobě, s čímž Zákazník výslovně souhlasí. Jestliže Zákazník neuhradí jakoukoliv zálohovou fakturu (výzvu k platbě) do konce předplaceného období dané služby, je Provozovatel oprávněn službu pozastavit. Jestliže Zákazník neuhradí jakoukoliv fakturu do doby její splatnosti, je Provozovatel oprávněn službu pozastavit. Faktury a zálohové faktury se považují za uhrazené při splnění všech následujících podmínek: platba je zaslána na správný účet Provozovatele je poukázána přesná částka dle výzvy k platbě ve správné měně při platbě je uveden správný variabilní symbol platba je připsána na účet Provozovatele platba je zpracována platebním systémem Provozovatele Provozovatel neakceptuje písemná, faxová, e-mailová ani žádná jiná podobná potvrzení o zaplacení, pokud částka na účet Provozovatele ještě nedorazila. Při mezinárodní platbě je Zákazník povinen uhradit veškeré poplatky spojené se zahraničním platebním stykem (nastavení poplatků „OUR“). V opačném případě provozovatel platbu neakceptuje a Zákazník je povinen dorovnat rozdíl tak, aby přišla Provozovateli částka v plné požadované výši. IV. Ochrana informací a ochrana osobních údajů &nbsp; Provozovatel i Zákazník se zavazují k mlčenlivosti o skutečnostech, které se vzájemně dozvěděli v souvislosti se zřízením a provozem služeb. Ochrana informací se nevztahuje na případ, kdy má Poskytovatel informační povinnost stanovenou zákonem resp. kdy si informace vyžádají státní orgány oprávněné k tomu zákonem, nebo jde o informace, které jsou veřejně dostupné. Detaily ohledně osobních údajů, nakládání s osobními údaji a ochrany osobních údajů jsou v samostatném dokumentu Zásady zpracovaní osobních údajů zákazníků. V případě, že Zákazník u Provozovatele uchovává (ukládá) jakékoliv osobní údaje, tak se mezi Provozovatelem a Zákazníkem uzavírá Zpracovatelská smlouva, podle které je Zákazník správcem těchto osobních údajů a Provozovatel zpracovatelem. Obdobně se postupuje i v případě, že Zákazník působí již jako zpracovatel osobních údajů pro jiného správce. V takovém případě je Provozovatel dalším zpracovatelem. Poskytovatel se zavazuje zabezpečit ochranu osobních údajů před neoprávněným nebo nahodilým přístupem, zabránit jejich změně, ztrátě či zničení, neoprávněnému p
165řenosu či jejich jinému neoprávněnému zpracování, jakož i jinému zneužití V. Doba trvání dohody a její zánik &nbsp; Doba platnosti je 6 nebo 12 měsíců dle druhu služby. Po ukončení služby jsou data naměřená a reporty vytvořené během její platnosti dále uchovány. Pro vytvoření nových statistických reportů je nutná aktivní služba. Zákazník – spotřebitel má v souladu s ust. § 1829 z.č. 89/2012 Sb., občanský zákoník právo odstoupit od smlouvy ve lhůtě 14 dnů ode dne jejího uzavření. Vzhledem k tomu, že Zákazník – spotřebitel výslovně požádal Provozovatele o započetí s poskytováním služeb před koncem lhůty pro odstoupení, bere na vědomí, že je povinen uhradit Provozovateli poměrnou část sjednané ceny za plnění poskytnuté do okamžiku odstoupení od smlouvy. Odstoupit může zákazník vyplněním přísluÅ¡ného formuláře v přísluÅ¡né zákaznické sekci na internetových stránkách Provozovatele. VI. Reklamace &nbsp; Zákazník je oprávněn reklamovat chybně provedené vytvoření statistického reportu či mimořádné události, k nimž doÅ¡lo v souvislosti se Službou, a to ve lhůtě do 3 měsíců od události, která je předmětem reklamace. Reklamaci provedete tak, že zaÅ¡lete přísluÅ¡né oznámení na naÅ¡i e-mailovou adresu pro reklamační řízení [email protected]. Po obdržení reklamace provedeme Å¡etření za účelem zjiÅ¡tění její oprávněnosti. Do 15 pracovních dnů po obdržení reklamace jsme povinni Vám sdělit výsledky naÅ¡eho Å¡etření a stanovisko k reklamaci. V případech výskytu překážek nezávislých na naÅ¡i vůli se v souladu s § 258 odst. (2) Zákona o platebním styku se tato lhůta prodlužuje na 35 pracovních dní. V případě oprávněné reklamace jsme povinni přijmout a provést nápravná opatření. Závěrečná ustanovení &nbsp; VeÅ¡kerá ujednání mezi Provozovatelem a Zákazníkem se řídí platným a účinným českým právním řádem. S ohledem na to, že smluvní vztah je zakládán na delší dobu dobu, a po tuto může dojít ke změnám na trhu či legislativě, vyhrazuje si Provozovatel ve smyslu § 1752 z.č. 89/2012 Sb., občanský zákoník, oprávnění tyto VOP v přiměřeném rozsahu měnit. Nové znění VOP zveřejní Provozovatel na svých WWW stránkách a Zákazník bude na takovou případnou změnu upozorněn e-mailem, a to v přiměřené lhůtě předtím, než nové VOP vstoupí v účinnost. Zákazník má právo změny VOP písemně odmítnout, a to nejpozději do dne, kdy nastane jejich účinnost. V případě, že Zákazník změny VOP v této době neodmítne, platí, že se smluvní vztah řídí novým zněním VOP. V případě, že Zákazník změny/nové úplně znění VOP odmítne, jsou Provozovatel i Zákazník oprávněni přísluÅ¡ný smluvní vztah předčasně ukončit, a to vzájemnou dohodou či výpovědí. Výpovědní lhůta v takovém případě činí 2 měsíce od písemného oznámení o změně VOP druhé smluvní straně. V případě, že jsou tyto VOP k dispozici pro Zákazníka ve více jazykových verzích, má přednost česká verze. Provozovatel v takovém případě neodpovídá za správnost takového překladu. Tyto VOP nabývají účinnosti dnem 13. 3. 2020. "}).add({id:34,tag:"cs",href:"/napoveda/dokumentace/osobni-udaje/",title:"Osobní údaje",description:`Provozovatelem služby TOPlist je firma:
166TOPlist s.r.o. &nbsp; nám. Dr. Václava Holého 1054/13, 180 00 Praha 8
167IČ: 27204171
168DIČ: CZ27204171`,content:`Provozovatelem služby TOPlist je firma:
169TOPlist s.r.o. &nbsp; nám. Dr. Václava Holého 1054/13, 180 00 Praha 8
170IČ: 27204171
171DIČ: CZ27204171
172dat. schránka: df3vma
173dále jen „Provozovatel“.
174Osobní údaje dle Nařízení Evropského parlamentu a rady (EU) 2016/679, dále jen „Nařízení“, jsou zpracovávany ve dvou případech. Jednak při měření návštěvnosti a, za druhé, při provozu samotného webu Toplist. Při měření návštěvnosti Provozovatel, v postavení zpracovatele osobních údajů dle čl. 4 bodu 8) Nařízení, přijal dostatečná technická a organizační opatření k zabezpečení zpracovávaných osobních údajů dle čl. 32 tohoto Nařízení, včetně povinnosti mlčenlivosti.
175Měření návštěvnosti &nbsp; Cookies &nbsp; Cookies se pro měření návštěvnosti nepoužívají.
176IP adresa &nbsp; Anonymizované IP adresy se ukládají po dobu 5 dní a přístup k nim (vždy maximálně 100 posledních záznamů) má správce měřené stránky. V případě, že statistiky nejsou chráněny heslem, jsou veřejné.
177IP adresa je použitá pro technické zabezpečení provozu služby, tj. ke statistickému měření návštěvnosti stránky. Provozovatel, dle článku 11, odstavec 1 Nařízení, neuchovává, nezískává ani nezpracovává dodatečné informace za účelem identifikace subjektu údajů.
178Web TOPlist &nbsp; Web TOPlist používá pro přihlášení ID stránky a uživatelem zvolené heslo, které je uloženo v bcrypt hashovaném tvaru. Kontaktní email (případně emaily
178) nemá souvislost s přihlašováním a heslem. Může sloužit k zaslání odkazu pro změnu zapomenutého hesla a, volitelně, pro zasílání pravidelných statistických reportů. Seznam stránek, kde je email použitý jako kontaktní, lze získat zde.
179Funkční cookies jsou použity pro technické zaznamenání nastavení: (přístup bez nutnosti opakovaného zadání hesla, zapamatování zvolených statistik).
180identifikátor doba platnosti popis použití statList 14 dní zapamatování výběru zobrazených statistik a jejich předvolení při dalším výběru session sezení (do ukončení prohlížeče) zapamatování hesla po přihlášení, aby nebylo nutné jej znovu zadávat různý dle ID stránky 14 dní zapamatovat si, že pro přístup do statistik nemá být vyžadováno heslo I pro tyto údaje platí, že Provozovatel neuchovává, nezískává ani nezpracovává dodatečné informace za účelem identifikace subjektu údajů.
181V případě dotazů či požadavků můžete napsat na email [email protected].
182`}).add({id:35,tag:"cs",href:"/blog/par-novinek-na-toplistu/",title:"Pár novinek na TOPlistu",description:"Je to zejména měření návštěvnosti podle země. Dál jsem u výpisu cest po serveru přidal linky na stránky (ahoj Ivo 🙂) a u výpisu hledaných frází přidal možnost vypsání všech.",content:`Je to zejména měření návštěvnosti podle země. Dál jsem u výpisu cest po serveru přidal linky na stránky (ahoj Ivo 🙂) a u výpisu hledaných frází přidal možnost vypsání všech. A ještě drobnost, u mailu s týdenními statistikami je v subjectu uvedeno číslo týdne a rok.
183`}).add({id:36,tag:"cs",href:"/blog/pocasi-vs-navstevnost/",title:"Počasí vs. návštěvnost",description:"Krátká poznámka, jaký vliv má na návštěvnost počasí. Jak se v minulých dvou týdnech udělalo konečně hezky, zaznamenával TOPlist pouze kolem 140 milionů zhlédnutí za den.",content:`Krátká poznámka, jaký vliv má na návštěvnost počasí. Jak se v minulých dvou týdnech udělalo konečně hezky, zaznamenával TOPlist pouze kolem 140 milionů zhlédnutí za den. A během propršené neděle už to bylo zase běžných 170 milionů (tj. rozdíl víc než 15%). Počet návštěv tolik neklesl (v řádu procent), takže se spíš zkrátila doba strávená na serveru. Zaznamenali jste tento pokles i na vašich serverech nebo vaši navštěvníci hezké počasí ignorovali? 🙂
184`}).add({id:37,tag:"cs",href:"/blog/podil-firefoxu/",title:"Podíl Firefoxu",description:"Podíl Firefoxu u českých uživatelů stabilně překonal 40%. Aktuální stav na https://www.toplist.cz/global/history/browser/?lang=CZ",content:`Podíl Firefoxu u českých uživatelů stabilně překonal 40%. Aktuální stav na https://www.toplist.cz/global/history/browser/?lang=CZ
185`}).add({id:38,tag:"cs",href:"/blog/podily-navstevniku-podle-domen-po-20-letech/",title:"Podíl návštěvníků podle domén 2. úrovně, po 20 letech",description:"Přesně před 20 lety proběhla malá blogová diskuze o podílu poskytovatelů připojení na českém internetu. Pojďme se podívat, co se za tu dobu změnilo.",content:`Přesně před 20 lety proběhla malá blogová diskuze o podílu poskytovatelů připojení na českém internetu. Pojďme se podívat, co se za tu dobu změnilo.
186Krátce řečeno - všechno.
187Doména Podíl 1. o2.cz 17.14 % 2. vodafone.cz 13.21 % 3. tmcz.cz 11.92 % 4. starnet.cz 2.51 % 5. poda.cz 1.32 % 6. nej.cz 0.93 % 7. nordic.tel 0.87 % 8. rionet.cz 0.67 % 9. nbox.cz 0.45 % 10. bluetone.cz 0.43 % U včerejších (pátek 9. března 2024) statistik je použitá trochu jiná metodika. Podíl je počítán na základě návštěv, u kterých je geolokací (která nebyla ještě před 20 lety implementovaná) určená země původu Česká republika. Že tím vypadl, v původních statistikách uvedený, AOL, už dnes vadit nebude.
188I tak je na první pohled patrná konsolidace trhu. Je vidět násobný odskok všech tří mobilních operátotorů od ostatní konkurence. Před dvaceti lety byl největší poskytovatel na prvním místě s podílem 4.72 
188%. Respektive, i kdyby se počítaly společně domény jejichž dnešní pokračovatel je O2 (tj. iol.cz a eurotel.cz), tak by jejich podíl byl 6,93 %, což je stále násobně méně než dnešní 17.14 %. Trochu &ldquo;neviditelný&rdquo; je podíl Nej.cz, který je v TOP 10 zastoupen hned třemi doménami (nej.cz, rionet.cz a nbox.cz), ale ani jejich společný podíl neohrožuje dominanci tří mobilních operátorů. Ta vznikla jednak nástupem mobilního internetu, ale i akvizicemi. Například, v původní tabulce se to týkalo třeba Mistralu (UPC -&gt; Vodafone) nebo Contactelu (GTS -&gt; T-Mobile).
189Ostatní poskytovatelé v podstatě zmizeli. Ať už tehdejší velcí hráči Video On Line nebo Tiscali nebo třeba projekt Indoš.
190`}).add({id:39,tag:"cs",href:"/blog/podily-navstevniku-podle-domen-2-urovne/",title:"Podíly návštěvníků podle domén 2. úrovně",description:"To hlavní už zmínil Yuhů. Já k tomu ještě dodám upřesnění. Filtr je podobný jako u refererů, tj. nepočítají se záznamy z kategorií Anglicky a Erotika.",content:`To hlavní už zmínil Yuhů. Já k tomu ještě dodám upřesnění. Filtr je podobný jako u refererů, tj. nepočítají se záznamy z kategorií Anglicky a Erotika. Jinak 
190se skutečně neměří na unikátní uživatele, ale návštěvy. Čímž, jak Dušan zmiňuje, je zohledněn nejen celkový počet, ale též aktivita zákazníků jednotlivých providerů. K jeho tabulce za neděli připojuji pro ukázku TOP10 ze včerejška (pondělí 9.2.2004).
191Doména Podíl 1. vol.cz 4.72 % 2. tiscali.cz 4.29 % 3. iol.cz 4.17 % 4. mistral.cz 3.78 % 5. eurotel.cz 2.76 % 6. aol.com 2.28 % 7. contactel.net 2.11 % 8. indos.cz 2.08 % 9. contactel.cz 1.89 % 10. karneval.cz 1.29 % Rozdíl je vidět hlavně v poklesu podílu velkých providerů ve prospěch připojení ze škol a firem.
192`}).add({id:40,tag:"cs",href:"/blog/podkategorie-na-toplistu/",title:"Podkategorie na TOPlistu",description:"Vím o tom, že probíhá diskuse nad rozdělením kategorie Weblogy na víc podkategorií (přehled je třeba u Každého blogujícího :-))",content:`Vím o tom, že probíhá diskuse nad rozdělením kategorie Weblogy na víc podkategorií (přehled je třeba u Každého blogujícího :-))
193Nad tím jsem v minulosti už i přemýšlel (např. chovatelé by šli rozdělit na pejskaře, kočičkáře ad.). Nerad bych ale opustil výhody „jedné úrovně“ – např. možnost rychlého přechodu z kategorie do kategorie pomocí selectu, odkaz na všechno hned z homepage apod. A zároveň nechci mít z TOPlistu katalog. V první řadě slouží k měření návštěvnosti.
194Pokud vás ale napadne nějaký jednoduchý a účinný způsob jak to vyřešit, není problém jej aplikovat. Vaše náměty a připomínky jen uvítám buď v diskusi nebo na mailu.
195UPDATE – Robert reagoval s námitkou, že by se měl filtrovat erotický obsah. Tohle TOPlist ovšem dělá odjakživa (viz výpis všech kategorii či hledání, kde nejsou erotické stránky). Jen je někdy těžší rozhodnout, jestli je to víc osobní stránka exhibicionisty, blog nebo porno. Podobně dilema jako třeba v případě obchodu s erotickým zbožím. Je to erotika nebo virtuální obchod?
196`}).add({id:41,tag:"cs",href:"/blog/pomlcka-misto-adresy-stranky/",title:"Pomlčka místo adresy stránky",description:"Stručně &nbsp; Pokud se ve statistikách na TOPlistu místo adresy měřené stránky objevuje pomlčka –, stačí v měřícím kódu změnit http:// za https://",content:` Stručně &nbsp; Pokud se ve statistikách na TOPlistu místo adresy měřené stránky objevuje pomlčka –, stačí v měřícím kódu změnit http:// za https://
197Delší povídání &nbsp; Nové prohlížeče nepředávají informaci o navštívené stránce (tzv. referer) v případě, že je stránka na šifrovaném spojení (HTTPS) a měřící prvek takové spojení nemá (má jen HTTP). Ostatní případy (obojí stejné, nebo stránka HTTP a měření HTTPS) stále fungují. Měřící kód TOPlistu je proto od roku 2012 vytvářen s odkazem přes HTTPS.
198V případě, že jste dlouhodobý uživatel TOPlistu, máte na stránce ještě starou verzi, a svou stránku začnete šifrovat, informace o adrese stránky se přestane posílat. Všechny ostatní statistiky (počet návštěv, informace o prohlížeči apod.) se měří dál.
199Řešení je jednoduché. Buď, jak je napsáno v prvním odstavci, jenom upravíte měřící kód na stránce, nebo jej nahradíte nově vytvořeným ze stránky https://www.toplist.cz/code/. Ten už šifrovaný odkaz obsahuje.
200`}).add({id:42,tag:"cs",href:"/blog/potvrzeni-tydennich-reportu/",title:"Potvrzení týdenních reportů",description:`Celý leden byl do týdenních reportů přidaný následující text:
201abych si byl jistý, že neobtěžuji posíláním tohoto týdenního přehledu návštěvnosti, nastavte zasílání na následujícím odkazu, kde také najdete více informací.`,content:`Celý leden byl do týdenních reportů přidaný následující text:
202abych si byl jistý, že neobtěžuji posíláním tohoto týdenního přehledu návštěvnosti, nastavte zasílání na následujícím odkazu, kde také najdete více informací. V opačném případě stačí tento email ignorovat a nejpozději na začátku února zasílání skončí
203Proč jsem to udělal? &nbsp; Hlavní důvody byly tyto:
204Za ty desítky let, co posílání reportů běží, se nashromáždilo množství uživatelů, kteří už o ně nemají zájem, ale nezrušili odběr v nastavení. Zbytečně to zdržuje odesílání 
204(emailů se posílá přes 300 tisíc) Riskujeme, že budou označovány jako spam a to poškodí posílání i těm, kteří je chtějí. Co dál? &nbsp; A jak jsem slíbil, tak se také stalo. Pokud jste v lednu neklikli na odkaz pro potvrzení zasílání týdenních reportů, tak od února už vám reporty chodit nebudou.
205Co když je chci zpět? &nbsp; Pokud byste si to rozmysleli, můžete zasílání reportů opět povolit v nastavení vašeho účtu na TOPlistu.
206Statistiky &nbsp; A, pochopitelně, o naměřené statistiky jste nepřišli. Stále jsou dostupné na webu.
207`}).add({id:43,tag:"cs",href:"/blog/prehled-prihlaseni/",title:"Přehled přihlášení",description:"Na stránku s editací záznamu jsme přidali přehled příhlášení. Jedná se o deset posledních IP adres, z kterých bylo zadáno heslo.",content:`Na stránku s editací záznamu jsme přidali přehled příhlášení. Jedná se o deset posledních IP adres, z kterých bylo zadáno heslo. Například pro přístup do editace nebo do statistik, pokud jsou heslem chráněné. Pro každou adresu je ještě uvedený poslední čas a akce. Viz obrázek:
208`}).add({id:44,tag:"cs",href:"/blog/prehled-registrovanych-stranek-podle-emailu/",title:"Přehled registrovaných stránek podle emailu",description:"Připravili jsme stránku, která umožní zjistit všechny registrace, u kterých je uvedený váš email jako kontaktní. A zároveň umožní rychlé nastavení posílání pravidelného týdenního reportu.",content:`Připravili jsme stránku, která umožní zjistit všechny registrace, u kterých je uvedený váš email jako kontaktní. A zároveň umožní rychlé nastavení posílání pravidelného týdenního reportu.
209Funguje to tak, že na adrese https://www.toplist.cz/edit/email/ zadáte svůj email a na něj přijde odkaz na příslušný seznam. V něm je možné rovnou zvolit posílání a je v něm i odkaz na podrobné statistiky a editaci každé stránky.
210`}).add({id:45,tag:"cs",href:"/blog/presun-proveden/",title:"Přesun proveden",description:"Takže přesun byl v noci proveden podle plánu. Až na ignoraci hodinové expirace DNS záznamu u některých providerů (Contactel, Tiscali aj.",content:`Takže přesun byl v noci proveden podle plánu. Až na ignoraci hodinové expirace DNS záznamu u některých providerů (Contactel, Tiscali aj.) vše proběhlo relativně hladce.
211Co se týče výkonu, má systém nyní dost velkou rezervu a navíc možnost snadného upgradu.
212`}).add({id:46,tag:"cs",href:"/napoveda/toplist-profi/pridani-noveho-webu/",title:"Přidání nového webu",description:"Nový web musí být nejprve registrován do bezplatné verze TOPlist.cz. Pokud je při jeho registraci použit stejný kontaktní email jako pro přihlášení do TOPlist Profi, je při dalším přihlášení automaticky přiřazen k účtu.",content:`Nový web musí být nejprve registrován do bezplatné verze TOPlist.cz. Pokud je při jeho registraci použit stejný kontaktní email jako pro přihlášení do TOPlist Profi, je při dalším přihlášení automaticky přiřazen k účtu.
213Pokud je web registrován do jiného účtu, je možné jej přidat do TOPlist Profi pomocí jeho TOPlist ID. Přihlaste se do TOPlist Profi a klikněte na tlačítko Přidat web v sekce Seznam webů na úvodní stránce služby Profi.
214Pak stačí zadat TOPlist ID webu a stejné heslo jako je použité pro příhlášení do základní verze TOPlistu. Pokud je heslo správné, web je přidán do TOPlist Profi.
215`}).add({id:47,tag:"cs",href:"/blog/prihlaseni-toplist-id-email/",title:"Přihlášení: TOPlist ID nebo email",description:"TOPlist umožňuje přihlásit se k vašemu účtu pomocí vašeho TOPlist ID nebo emailové adresy spojené s účtem. Oba způsoby mají své výhody a použití závisí na vašich preferencích a potřebách.",content:`TOPlist umožňuje přihlásit se k vašemu účtu pomocí vašeho TOPlist ID nebo emailové adresy spojené s účtem. Oba způsoby mají své výhody a použití závisí na vašich preferencích a potřebách.
216Přihlášení pomocí TOPlist ID &nbsp; Vzniklo jako první způsob v dobách, kdy přihlašování pomocí emailu nebylo běžné. Pro ilustraci, Gmail, který přihlašování pomocí emailu zpopularizoval, vznikl až o 7 let později než TOPlist.
217Dodnes přináší některé výhody:
218Ochrana soukromí: K používání TOPlistu nepotřebujete nikde zadávat svůj email. Email se používá pouze jako kontaktní údaj pro obnovení hesla nebo posílání týdenních reportů. Pokud si tedy heslo budete pamatovat a nebudete chtít dostávat reporty, nemusíte ho mít vyplněný. Jednoduchost: TOPlist ID je stejně potřeba použít v měřícím kódu na vašich stránkách, takže jej máte vždy po ruce a nemusíte vzpomínat jakým emailem se vlastně máte přihlásit. Stabilita: Na rozdíl od emailu, který se může měnit (změna správce stránek, pracovní email apod.), TOPlist ID zůstává konstantní po celou dobu existence vašeho účtu. Přihlášení pomocí emailu &nbsp; Přihlášení pomocí emailu je použito hlavně v rámci služby TOPlist Profi, která umožňuje některé funkce využít i v základní bezplatné verzi TOPlistu.
219Hlavní výhodou přihlášení pomocí emailu je možnost sloučení více účtů pod jednu emailovou adresu. Základní sloučení proběhne automaticky, kdy se při přihlášení přiřadí všechny registrace, které mají stejný email jako kontaktní. Další web lze přidávat ručně pomocí funkce &ldquo;Profi: přidání nového webu&rdquo;. V nových statistikách pak můžete mezi weby jednoduše přepínat.
220V rámci služby Profi to dále umožňuje vytváření přístupů s různou úrovní oprávnění pro různé uživatele. Například rozlišovat přístup pro editaci nastavení a přístup pouze ke statistikám.
221`}).add({id:48,tag:"cs",href:"/napoveda/kod-na-stranku/redakcni-systemy/",title:"Redakční systémy",description:`Krátké návody, jak přidat měřící kód na různé stránky. Pokud máte nějaký podobný návod, pošlete mi jej n
221a [email protected].
222RS WordPress &nbsp; https://wordpress.`,content:`Krátké návody, jak přidat měřící kód na různé stránky. Pokud máte nějaký podobný návod, poÅ¡lete mi jej na [email protected].
223RS WordPress &nbsp; https://wordpress.org/plugins/toplist/
224RS Joomla &nbsp; http://www.phoca.cz/phoca-topliststatistics
225RS Drupal &nbsp; Pro verzi 5 existuje modul http://drupal.org/project/czech_audit
226Dokuwiki &nbsp; http://www.dokuwiki.org/plugin:toplist
227Webnode &nbsp; https://www.wpromotions.eu/ako-vlozit-pocitadlo-navstev-na-web-vo-webnode/
228`}).add({id:49,tag:"cs",href:"/napoveda/toplist-profi/registrace/",title:"Registrace",description:"Registrace do služby TOPlist Profi je také zdarma. Umožňuje použití rozšířených funkcí TOPlistu, které vyžadují přihlášení (např. REST API). Zároveň umožňuje přehled o všech Vašich stránkách, které jsou v TOPlistu zaregistrované.",content:`Registrace do služby TOPlist Profi je také zdarma. Umožňuje použití rozšířených funkcí TOPlistu, které vyžadují přihlášení (např. REST API). Zároveň umožňuje přehled o všech Vašich stránkách, které jsou v TOPlistu zaregistrované.
229Registraci začnete na úvodní stránce služby TOPlist Profi, kde kliknete na odkaz Registrace zdarma.
230Poté vyplníte registrační formulář. Povinné pole je pouze email, pomocí kterého se budete přihlašovat. Po vyplnění formuláře klikněte na tlačítko Registrovat.
231Po registraci obdržíte email s odkazem pro aktivaci účtu a nastavení hesla.
232Po přihlášení jsou k účtu automaticky přiřazeny ty stránky, které mají vyplněný stejný kontaktní email.
233`}).add({id:50,tag:"cs",href:"/napoveda/dokumentace/rest-api/",title:"REST API",description:`Pro přístup k datům, statistikám a správě podporuje TOPlist také rozhranní REST API. Jeho úvodní stránka je na adrese
234https://profi.toplist.cz/api/`,content:`Pro přístup k datům, statistikám a správě podporuje TOPlist také rozhranní REST API. Jeho úvodní stránka je na adrese
235https://profi.toplist.cz/api/
236Dostupné metody jsou rozdělené do 4 skupin:
237web &nbsp; základní informace o registrované stránce, generování měřícího kódu, číselníky
238statistika &nbsp; přístup k výsledkům statistik
239profi &nbsp; operace dostupné při aktivní službě TOPlist Profi
240global &nbsp; metoda pro globální statistiky
241Testování &nbsp; Posílání požadavků na server lze testovat hned v dokumentaci. Stačí u metody vyplnit správně hodnoty a odeslat tlačítkem Zkusit. Pak je vypsán příklad volání pomocí příkazu curl, volaná adresa, tělo požadavku a vracený kód a výsledek.
242Autorizace &nbsp; Autorizace v API Některé metody vyžadují autorizaci. Jsou označené ikonou (viz obrázek bod 1.). Po kliknutí na ikonu se objeví dialog na obrázku.
243Ověření probíhá klíčem, který vytvoříte na adrese https://profi.toplist.cz/#server_setting, vložíte do pole „value“ (bod 2) a odešlete tlačítkem Authorize.
244Při odeslání přímo na server je klíč předávaný headerem serverKey. Lze to vidět i při testu ve výpisu příkazu curl.
245Pro autorizaci je nutná registrace ve službě Profi, která je zdarma a není potřeba, aby byla služba aktivní. Registrace je potřeba pro správu klíčů (těch může být víc pro různé účely) a přístupu k datům.
246`}).add({id:51,tag:"cs",href:"/napoveda/dokumentace/api-autentifikace/",title:"REST API - autentifikace",description:"Pro autorizace do API probíhá ve dvou krocích. Nejprve je potřeba, pomocí přístupového klíče, získat přístupový token a poté ho použít pro autorizaci v dalších požadavcích.",content:`Pro autorizace do API probíhá ve dvou krocích. Nejprve je potřeba, pomocí přístupového klíče, získat přístupový token a poté ho použít pro autorizaci v dalších požadavcích.
247Vytvoření přístupového klíče &nbsp; Přístupový klíč je dvojice privátního a veřejného klíče. Vygenerujete je například pomocí nástroje openssll:
248openssl ecparam -name prime256v1 -genkey -noout -out private.pem openssl ec 
248-in private.pem -pubout &gt; public.pemTím vzniknou dva soubory private.pem a public.pem. První obsahuje privátní klíč, který je potřeba uchovávat v bezpečí.
249Druhý obsahuje veřejný klíč, který je potřeba přidat do nastavení uživatele v TOPlist Profi:
250Získání přístupového tokenu &nbsp; K získání přístupového tokenu je potřeba poslat požadavek na adresu https://profi.toplist.cz/api/v1/login Autentifikace probíhá pomocí HTTP hlavičky Authorization. Hlavička musí obsahovat JWT podepsaný privátním klíčem. Příklad volání v Pythonu:
251import jwt import requests import time privateKey = open(&#39;private.pem&#39;).read() jwtPayload = jwt.encode( &#39;sub&#39;: &#39;[email protected]&#39;, &#39;aud&#39;: &#39;batch&#39;, &#39;iss&#39;: &#39;0123456-789a-bcde-f012-3456789abcd&#39;, &#39;nbf&#39;: int(time.time()), &#39;exp&#39;: int(time.time()) + 5*60, &#39;jti&#39;: &#39;1234567890&#39; , privateKey, algorithm=&#39;ES256&#39;) token = requests.post(f&#34;https://media.toplist.cz/api/v1/login&#34;, headers= &#39;Accept&#39;:&#39;application/json&#39;, &#39;Authorization&#39;: jwtPayload  ).json()[&#39;token&#39;]Význam claimů JWT:
252sub - email uživatele, pro kterého je token vytvořen aud - v tomto případě vždy hodnota &lsquo;batch&rsquo; iss - identifikátor Provozovatele, který je uveden v nastavení serveru nbf - čas, kdy token začne platit exp - čas, kdy token přestane platit (maximálně 1 hodina) jti - unikátní identifikátor tokenu Použití tokenu &nbsp; Vygenerovaný token je potřeba přidat do hlavičky Authorization pro každý další požadavek jako Bearer token. Tj.: Authorization: Bearer &lt;token&gt;
253`}).add({id:52,tag:"cs",href:"/blog/restart/",title:"Restart",description:"Rok 2016 je za námi. Započítali jsme během něj 6 723 268 569 návštěv a 34 851 098 705 zhlédnutí (ano, řád desítek miliard je správně).",content:`Rok 2016 je za námi. Započítali jsme během něj 6 723 268 569 návštěv a 34 851 098 705 zhlédnutí (ano, řád desítek miliard je správně).
254Co nás čeká v tomto roce?
255Restart, který je stejný. Že to zní jako paradox? Souhlasíme, ale nejlépe to vystihuje reakce lidí, kterým jsme předvedli, co připravujeme.
256Restart proto, že se změní téměř vše. Přechod na zobrazovaní webu přes https (samotné měření v https je možné od roku 2011) je jenom jednou z 216 změn, které proběhly v uplynulých měsících v rámci příprav. Hlavním cílem je přechod na novější technologie, které zrychlí další vývoj a zjednoduší i dohnání našich, přiznáváme, i letitých restů.
257Stejný proto, že jsme si vědomi, že za 19 let existence TOPlistu jsou uživatelé na zvyklí na to, jak se náš web používá. A mnohdy jej preferují právě pro snadnost a rychlost ovládání. Proto je pro nás prioritou zachovat tyto vlastnosti. A, pochopitelně, i současný měřící kód zůstane stále funkční.
258Jako u každého paradoxu, nebude řešení jednoduché a čeká nás ještě hodně práce. Ale ještě během této zimy začnou být novinky viditelné.
259Hezký nový rok 2017 a držte nám palce 🙂
260`}).add({id:53,tag:"cs",href:"/blog/srovnani-s-prechozim-tydnem-v-reportu/",title:"Srovnání s přechozím týdnem v reportu",description:"Přidali jsme do týdenního reportu srovnání s přechozím týdnem. Vypisuje se relativní rozdíl mezi posledním a předposledním týdnem. Po najetí myší se v bublině objeví i absolutní hodnota celkové návštěvnosti.",content:`Přidali jsme do týdenního reportu srovnání s přechozím týdnem. Vypisuje se relativní rozdíl mezi posledním a předposledním týdnem. Po najetí myší se v bublině objeví i absolutní hodnota celkové návštěvnosti.
261Celkem 64665 +4.5%
262Je to sice drobnost, ale alepoň nemusíte hledat v došlých mailech a hned vidíte, jaký je vývoj návštěvnosti 🙂
263`}).add({id:54,tag:"cs",href:"/blog/ssl/",title:"SSL",description:"I vygenerovaná verze měřícího kódu už počítá se SSL, takže ji nemusíte přepisovat 🙂 Viz http://www.toplist.cz/edit/?a=l",content:`I vygenerovaná verze měřícího kódu už počítá se SSL, takže ji nemusíte přepisovat 🙂 Viz http://www.toplist.cz/edit/?a=l
264`}).add({id:55,tag:"cs",href:"/blog/staticke-linky-na-toplist/",title:"Statické linky na TOPlist",description:`Jelikož:
265se teď webserver celkem fláká jsem si chtěl vyzkoušet mod_rewrite mě štve Google tou svojí ignorací dynamických stránek nastavil jsem Apache tak, aby bral i linky do kategorií jako adresáře.`,content:`Jelikož:
266se teď webserver celkem fláká jsem si chtěl vyzkoušet mod_rewrite mě štve Google tou svojí ignorací dynamických stránek nastavil jsem Apache tak, aby bral i linky do kategorií jako adresáře. Takže žebříček weblogů nyní funguje i na adrese http://www.toplist.cz/weblogy. Odstránkování se děje přes „podadresář“, např. http://www.toplist.cz/weblogy/50.
267Když už jsem byl v tom, tak jsem zprovoznil i jednodušší přístup k podrobným statistikám, které jsou přes adresář stat a ID. Viz. http://toplist.cz/stat/
26750427.
268Původní cesty přes dynamické adresy zůstávají zachovány.
269`}).add({id:56,tag:"cs",href:"/napoveda/dokumentace/statistiky/",title:"Statistiky",description:`https://www.toplist.cz/statistics/
270Přihlášení &nbsp; Statistiky umožňují příhlášení buď pomocí TOPlist ID stránky a hesla (stejného jako do editace záznamu). Druhá možnost je pomocí emailu.`,content:`https://www.toplist.cz/statistics/
271Přihlášení &nbsp; Statistiky umožňují příhlášení buď pomocí TOPlist ID stránky a hesla (stejného jako do editace záznamu). Druhá možnost je pomocí emailu. To předpokládá registraci do služby TOPlist Profi (bezplatně) a přiřazení měřených stránek k účtu.
272Menu &nbsp; V pravé horní části obrazovky je základní menu pro změnu zobrazeného období:
273&lt; - posun do historie &gt; - posun do budoucnosti &gt;| - posun na dnešní datum
274U velkých monitoru je ještě tlačíčko na přepnutí zobrazení ve dvou nebo třech sloupcích 2 [|]
275Při najetí na menu se rozbalí další možnosti.
276V levé části jsou rychlé odkazy na konkrétní statistiky.
277V pravé je možnost zvolit statistiky za delší období (týden, měsíc, rok). Další je výběr zobrazené stránky. V případě přihlášení přes email můžete mít k němu přiřazeno víc stránek a zde mezi nimi rychle přepínat. A poslední volba je odhlášení.
278Podle vybraného období se mění i krok (minimální časový interval) podle následující tabulky:
279celé období krok den hodina týden den měsíc den rok týden Info &nbsp; Celková historie návštěvnosti &nbsp; První statistikou je celkový přehled návštěvnosti (počet návštěv a zhlédnutí) za celou dobu od registrace. Standardně je zobrazený plovoucí týdenní průměr, který není ovlivněn rozdílem návštěvností během pracovních dní a víkendu. V menu &ldquo;krok&rdquo; jde změnit na počet za 1 den, týden a 30 dní.
280Záznam &nbsp; Následuje výpis posledních zaznamenaných návštěv. V pravém horním rohu je aktualizovaný počet dnešních návštěv, zhlédnutí a aktuální počet online návštěvníků.
281Ve verzi Profi je možné aktivovat volbu &ldquo;live&rdquo;, kdy dochází v automatické aktualizaci zobrazení včetně přehledu dalších zhlédnutí v rámci jedné návštěvy.
282Informace, které jsou zobrazeny:
283čas návštěvy, anonymizovaný hostname a IP návštěvy, ikona s vlajkou země (v popisku je dvouznakový kód země) referer návštěvy titulek stránky, její URL a odkaz na stránku ikona typu zařízení (mobil, počítač atd.), ikona prohlížeče, verze prohlížeče a op. systému, rozlišení ve tvaru šířka x výška x barevná hloubka ikony další zhlednutí s odkazem na stránku (v popisku je čas, titulek stránky) Statistiky &nbsp; Statistiky umožňují dva nebo tři typu zobrazení. To je přepíná pomocí ikon v pravém horním rohu bloku: Např. v případě zemí původu lze přepínat mezi zobrazením:
284V případě, kdy graf zobrazuje jeden typ hodnoty, zárověň ve spodní části ukazuje součet, průměr, maximum a minimum za období. Maximum a minimum v závorce ukazuje v kterém čase k nim došlo.
285Návštěvnost &nbsp; Sekce zobrazující základní statistiky související s přístupy uživatelů na vaše stránky.
286návštěvy &nbsp; Graf návštěv v měřeném období.
287zhlédnutí &nbsp; Průběh počtu zobrazení v období.
288země &nbsp; hodinová návštěvnost &nbsp; Průměrná návštevnost podle hodiny za celé měřené období.
289návštěvnost podle dne v týdnu &nbsp; Průměrná návštevnost podle dne v týdnu za celé měřené období.
290návštěvy - domény &nbsp; návštěvy - TLD &nbsp; reporty Profi &nbsp; Poslední reporty vygenerované službou Profi.
291Zařízení &nbsp; Druhá sekce zobrazuje statistiky související s použitými zařízeními.
292prohlížeče &nbsp; Časový vývoj podílu jednotlivých prohlížečů.
293operační systémy &nbsp; verze prohlížeče &nbsp; verze op. systému &nbsp; typ zařízení &nbsp; engine prohlížeče &nbsp; rozlišení monitoru &nbsp; Zdroje &nbsp; Další sekce zobrazuje statistiky související se zdroji odkud přichází návštěvníci vašich stránek.
294všechny &nbsp; Tabulka všech refererů, odkazujících na vaše stránky.
295domény &nbsp; Tabulka refererů, odkazujících na vaše stránky, seskupených podle domény 2.řádu.
296vyhledávače &nbsp; Graf průběhu počtů návštěv z vyhledávačů.
297Obsah &nbsp; Sekce se statistikami souvisejícími s obsahem vašich stránek.
298vstupní stránky &nbsp; Tabulka vstupních stránek, tj. stránky, které byly první navštívené v rámci návštěvy.
299stránky &nbsp; Tabulka všech zhlédnutých stránek.
300výstupní stránky &nbsp; Tabulka výstupních stránek, tj. stránky, které byly poslední navštívené v rámci návštěvy.
301lokální hledání &nbsp; Pokud v nastavení vašeho webu v službě Profi nastavíte klíčové slovo, které znamená parametr pro vyhledávání na vašem webu (např. pokud adresa výsledků hledání na vašem serveru vypadá jako www.server.cz/?search=novinky, bude klíčové slovo &ldquo;search&rdquo;), budou zde zobrazeny statistiky hledání.
302Kampaně &nbsp; zdroje &nbsp; Graf zdrojů podle parametru utm_source
303kampaně &nbsp; Graf kampaní podle parametru utm_campaign
304`}).add({id:57,tag:"cs",href:"/blog/statistiky-5-dni/",title:"Statistiky 5 dní",description:"Podrobné statistiky ve free verzi jsou nyní archivovány 5 dní. Takže když v pondělí přijdete do práce, stále ještě budete mít statistiky za celý pátek.",content:`Podrobné statistiky ve free verzi jsou nyní archivovány 5 dní. Takže když v pondělí přijdete do práce, stále ještě budete mít statistiky za celý pátek.
305`}).add({id:58,tag:"cs",href:"/blog/statistiky-podle-kategorii/",title:"Statistiky podle kategorií",description:"Yuhůů mne přemluvil, abych vytvořil stránku s nějakými celkovými statistikami TOPlistu. První verze je na adrese http://www.toplist.cz/global.html. Stránka je generována jednou denně.",content:`Yuhůů mne přemluvil, abych vytvořil stránku s nějakými celkovými statistikami TOPlistu. První verze je na adrese http://www.toplist.cz/global.html. Stránka je generována jednou denně.
306Zatím jsou na ní podíly prohlížečů a op. systému podle kategorií za předchozí den (tj. ten den, jehož datum tam je napsáno :-)). Zobrazeny jsou pouze ty typy, které mají alespoň v jedné k
306ategorii podíl nad 0,1%.
307Ještě je tam tabulka s průběhem návštěvnosti během posledního týdne.
308Další statistiky budou postupem času přibývat. Když mi dáte vědět, co chcete, pokusím se je vytvořit.
309Ze statistik určitě vyčtete něco zajímavého. Já upozorním alespoň na to, co je přímo do očí bijící. Tím je skutečnost, jak moc se liší weblogová komunita od ostatních (jediná kategorie, kde má Gecko nad 10%, FreeBSD nad 0,1% apod. :-)).
310`}).add({id:59,tag:"cs",href:"/blog/nove-statistiky/",title:"Statistiky zcela v novém",description:`Na adrese:
311https://www.toplist.cz/statistics/
312jsme připravili zcela novou verzi statistik. Hlavní novinky jsou:
313Všechny statistiky na jedné stránce &nbsp; Není potřeba vybírat jednotlivé statistiky.`,content:`Na adrese:
314https://www.toplist.cz/statistics/
315jsme připravili zcela novou verzi statistik. Hlavní novinky jsou:
316Všechny statistiky na jedné stránce &nbsp; Není potřeba vybírat jednotlivé statistiky. Stačí jen posouvat stránku dolů a všechny statistiky se postupně načtou. Zároveň je možné jednoduše přejít na konkrétní statistiku pomocí menu v horní části stránky.
317Rychlá volba zobrazení &nbsp; Statistiky lze nyní jednoduše přepínat mezi různými zobrazeními. Například mezi grafem, souhrnným kolačovým grafem a tabulkou.
318Jednodušší výběr zobrazeného období &nbsp; Rychlý výběr zobrazeného intervalu den, týden, měsíc, rok a jeho posun.
319Přepínání mezi stránkami &nbsp; Stále funguje přihlášení pomocí TOPlist ID a hesla. Navíc je možné přihlášení pomocí emailu a hesla po bezplatné registraci na TOPlist Profi. Pak je možné jednoduše přepínat mezi statistikami více stránek.
320Zobrazení aktuálních statistik &nbsp; Na stránce se pravidelně aktualizuje počet návštěv, zobrazení a počet online návštěv.
321Plně responzivní design &nbsp; Statistiky jsou optimalizovány pro zobrazení na všech zařízeních. Od mobilních zařízení až po velké monitory, kde je možná volba mezi dvou nebo třísloupcovým zobrazením.
322Nápověda &nbsp; Více detailů o nových statistikách najdete v naší nápovědě.
323API &nbsp; Data všech statistik jsou dostupná také přes REST API.
324&hellip; a ještě jedna věc &nbsp; Nezměnilo se, že statistiky stále zůstávají zdarma pro všechny uživatele. Sjednotili jsme zobrazení i pro naše podporovatele v rámci TOPlist Profi. Ale množství statistik a intervalů zobrazení je v obou případech větší než před změnou.
325`}).add({id:60,tag:"cs",href:"/blog/tabulka-navstev-za-rok/",title:"Tabulka návštěv za rok",description:"Byla přidána tabulka ukazující měsíční návštěvy během roku. Zárověň je zobrazena relativní změna proti stejnému měsící předchozího roku a mezi roky lze jednoduše přepínat.",content:`Byla přidána tabulka ukazující měsíční návštěvy během roku. Zárověň je zobrazena relativní změna proti stejnému měsící předchozího roku a mezi roky lze jednoduše přepínat. Je pod volbou „Návštěvy za rok“. Viz. https://www.toplist.cz/stat/result/1/year-visit-table/?date=01.%2001.%202008
326`}).add({id:61,tag:"cs",href:"/blog/tajny-tip-ke-globalnim-statistikam/",title:"Tajný tip ke globálním statistikám :)",description:"Tajný tip ke globálním statistikám 🙂 U grafu lze filtrovat pouze uživatele z Čech (rozpoznávají se přes GeoIP) pomocí parametru lang=CZ.",content:`Tajný tip ke globálním statistikám 🙂 U grafu lze filtrovat pouze uživatele z Čech (rozpoznávají se přes GeoIP) pomocí parametru lang=CZ. A teď lze i definovat rok parametrem year (data jsou od roku 2006 pro celkový počet a od konce roku 2007 pro Čechy). Takže například podíl vyhledávačů mezi českými uživateli v roce 2008 je na adrese https://www.toplist.cz/stat/?a=history&type=4&lang=CZ&year=2008
327`}).add({id:62,tag:"cs",href:"/blog/termin-spusteni-nove-verze/",title:"Termín spuštění nové verze",description:"Protože slovenský web běží víc než měsíc (konkrétně od 5. září) s novou verzí, rozhodli jsme se, že do toho praštíme a pustíme ji i na českém.",content:`Protože slovenský web běží víc než měsíc (konkrétně od 5. září) s novou verzí, rozhodli jsme se, že do toho praštíme a pustíme ji i na českém. Termín spuštění jsme vybrali sobotu 28.října. Na 20. výročí spuštění našeho serveru, které případá na listopad, tak už budeme v novém hávu.
328Na adrese https://novy.toplist.cz (uživatel i heslo je test) můžete novou verzi vidět hned.
329`}).add({id:63,tag:"cs",href:"/blog/testovani-nove-verze/",title:"Testování nové verze",description:"O pár měsíců a dalších 79 změn později od lednového oznámení máme připravenou novou verzi k veřejnému testu. Najdete ji na adrese https://novy.",content:`O pár měsíců a dalších 79 změn později od lednového oznámení máme připravenou novou verzi k veřejnému testu. Najdete ji na adrese https://novy.toplist.cz. Přístup je 
329chráněn heslem, které je „test“ (uživatel i heslo).
330Jak jsme psali, změny jsou hlavně uvnitř. Celý TOPlist je kompletně napsaný znova. Viditelných změn je pár (listování po dnech ve výsledcích, víc možností při obnově hesla, lepší kontroly při registraci ap.). Změnu vzhledu ani nebereme jako novinku, protože ovládání zůstavá stále stejné. Víc viditelných novinek začneme přidávat po ostrém spuštění této nové verze.
331Budeme rádi, když novou verzi vyzkoušíte. Obsahuje už stejná data jako současná. Pokud se setkáte s nějakou chybou nebo vás napadne nějaké vylepÅ¡ení, dějte nám vědět. Buď třeba sem do komentářů nebo na email [email protected]. Děkujeme.
332`}).add({id:64,tag:"cs",href:"/napoveda/tipy-a-triky/",title:"Tipy a triky",description:"SSL &nbsp; Pokud potřebujete měřit i stránky zabezpečené pomocí protokolu SSL, stačí upravit měřící kód tak, aby použival tento protokol (https://).",content:` SSL &nbsp; Pokud potřebujete měřit i stránky zabezpečené pomocí protokolu SSL, stačí upravit měřící kód tak, aby použival tento protokol (https://). Nebo lze vygenerovat a použít nový kód, který už SSL používá.
333XML výstup &nbsp; Data o návštěvnosti je nyní možné získávat i ve formátu XML. Fungují na podobném principu jako Infopanel, tj. nedochází k vlastnímu měření. Pro něj je nutné použít nějaký klasický měřící kód. Dostupná data jsou stejná jako pro větší verzi panelu: návštěvnost celkem, dnes, za týden, pořadí celkové a v kategorii a počet uživatelů online. Adresa pro volání je:
334https://toplist.cz/images/counter.asp?a=xml&amp;id=ID_strankyPoznámka: jen připomínám, že pokud budete tento způsob využívat k zobrazení návštěvnosti přímo ve stránce, nebude v ní započítáno její aktuální zobrazení, které je zaznamenáno až načtením měřícího kódu.
335Bezpečnostní kód - blokování měření na cizích stránkách &nbsp; Může se stát, že zjistíte (např. ve statistikách měřených stránek), že je váš měřící kód umistěn na cizích stránkách. Nejjednodušší je domluvit se s autorem těch stránek, aby svůj omyl opravil. Pokud to ale není možné, lze měření zamezit tak, že v nastavení na TOPlistu definujete Bezpečnostní kód (číslo v rozsahu 1 až 200). A do měřícího kódu přidáte parametr „seed“ s touto hodnotou. Tím se bude měřit pouze kód, který tuto hodnotu obsahuje. Hodnotu lze libovolně měnit, pouze musí být pro měření stejná s nastavení i měřícím kódu. Funkci lze vypnout nastavením Bezpečnostního kódu na nulu.
336`}).add({id:65,tag:"cs",href:"/blog/toplist-tajne-funkce-i/",title:"TOPlist – tajné funkce I.",description:"Když se Bizi rozhodl, že bude odhalovat některé nepublikované funkce Lidé.cz (viz. Bizi the Blogger), rozhodl jsem se zde uvést i nějaké možnosti TOPlistu, které nemusí být obecně známé.",content:`Když se Bizi rozhodl, že bude odhalovat některé nepublikované funkce Lidé.cz (viz. Bizi the Blogger), rozhodl jsem se zde uvést i nějaké možnosti TOPlistu, které nemusí být obecně známé.
337První příklad je hned ten kód, který tu vpravo ukazuje Infopanel. Je to de facto maximální verze, která nejen, že ukazuje nejvíc online statistik (pořadí, počty za týden, den a online, celkové), ale zároveň i nejvíc měří. Pomocí Javascriptu i rozlišení a barvy monitoru návštěvníků, odkud přišli ad.
338Ale není to ta úplně nejzajímavější čast. Tohle by jiště zručný HTML koder dokázal dát dohromady také. Tím, na co bych rád upozornil, je samotný odkaz:
339http://www.toplist.cz/weblogy/ID50427
340Jak je vidět, ukazuje na statistiky kategorie (weblogy). Navíc se ale posílá ještě i ID stránky. To by mělo způsobit, že je výpis posunutý tak, aby se stránka objevila přibližně kolem pátého místa výpisu, i když je její umístění jiné.
341`}).add({id:66,tag:"cs",href:"/blog/toplist-tajne-funkce-ii/",title:"TOPlist – tajné funkce II.",description:"Je tu další díl pondělního miniseriálu o nedokumentovaných funkcích a vlastnostech TOPlistu. Jednu má i textová verze počítadla. Ta je řešena přes kombinaci iframe a ilayer, takže funguje ve všech moderních prohlížečích a její výhodou je, že je návštěva započítaná i když má uživatel třeba vypnuto zobrazování grafiky.",content:`Je tu další díl pondělního miniseriálu o nedokumentovaných funkcích a vlastnostech TOPlistu. Jednu má i textová verze počítadla. Ta je řešena přes kombinaci iframe a ilayer, takže funguje ve všech moderních prohlížečích a její výhodou je, že je návštěva započítaná i když má uživatel třeba vypnuto zobrazování grafiky. Kód vypadá takto:
342&lt;ILAYER LEFT=1 TOP=1 SRC=“http://www.toplist.cz/count.asp?id=50427&amp;logo=text&amp;bc=00FF11″ WIDTH=“88″ HEIGHT=“31″&gt; &lt;iframe src=“http://www.toplist.cz/count.asp?id=50427&amp;logo=text&amp;bc=00FF11″ SCROLLING=no STYLE=“width: 88px;height: 31px“&gt;&lt;/iframe&gt; &lt;/ilayer&gt;Jak vidíte, pomocí parametru bc (backgroung color) je možné změnit standardní bílou tak, aby víc odpovídala vašim představám. Tj. mužete třeba jej sladit s barvou pozadí stránky nebo, jako v tomto případě, použít jinou decentní barvu.
343Pozn.: pokud tuhle stránku prohlížíte v Mozille či Opeře a máte pocit, že to není ono, tak je to způsobené jen tady nějakým proteklým stylem, který teď bohužel nemám čas opravovat. Zkuste si to na čisté stránce a uvidíte, že to funguje.
344`}).add({id:67,tag:"cs",href:"/blog/toplist-tajne-funkce-iii/",title:"TOPlist – tajné funkce III.",description:"Dnes to nebude ani tak funkce, jako spíš pomůcka k lepší funkcionalitě TOPlistu. Množina rozeznávaných prohlížečů a op. systémů má asi 99% podíl na trhu (za to, že jich dohromady je asi 20 druhů můžem třeba Billovi nadávat, ale prostě je to skutečnost.",content:`Dnes to nebude ani tak funkce, jako spíš pomůcka k lepší funkcionalitě TOPlistu. Množina rozeznávaných prohlížečů a op. systémů má asi 99% podíl na trhu (za to, že jich dohromady je asi 20 druhů můžem třeba Billovi nadávat, ale prostě je to skutečnost. Pochopitelně, bylo by hezké počítat všechno, ale musím zase brát ohled na poměr cena/výkon, resp. počet/zatížení procesoru).
345Pokud máte podezření, že váš prohlížeč či operační systém, jehož podíl se neblíží k nule, není detekován správně, můžete si jej ověřit na stránce http://www.toplist.cz/cgi-bin/test.pl, kde bude vypsáno co si myslí TOPlist a co o sobě tvrdí váš prohlížeč. A pokud to nebude souhlasit, tak mi prosím dejte vědět na [email protected].
346`}).add({id:68,tag:"cs",href:"/blog/toplist-tajne-funkce-iv/",title:"TOPlist – tajné funkce IV.",description:`Dneska poodhalím trochu ze zákulisí TOPlistu. Pokud vás zajímá hardware, na kterém běží, tak vězte, že se jedna o:
347MB MSI KT3 Ultra2 CPU Athlon 1800+ RAM 1GB SCSI SEAGATE Model: ST318453LW @ Tekram DC-390U2W`,content:`Dneska poodhalím trochu ze zákulisí TOPlistu. Pokud vás zajímá hardware, na kterém běží, tak vězte, že se jedna o:
348MB MSI KT3 Ultra2 CPU Athlon 1800+ RAM 1GB SCSI SEAGATE Model: ST318453LW @ Tekram DC-390U2W
349A jak na tom běží mySQL můžete vidět třeba na http://www.toplist.cz/images/mysql.png. Jedná se o graf množství dotazů za vteřinu během několika posledních hodin.
350`}).add({id:69,tag:"cs",href:"/blog/toplist-zakulisi/",title:"TOPlist – zákulisí",description:"Jak je asi každému jasné, že srdcem pod
350obného systému bude databáze a proto nejdřív budu psát o ní. &nbsp; Jelikož zastávám přesvědčení, že se nemá ztrácet čas s tím, co udělali jiní a lépe, je použitá klasická relační databáze.",content:` Jak je asi každému jasné, že srdcem podobného systému bude databáze a proto nejdřív budu psát o ní. &nbsp; Jelikož zastávám přesvědčení, že se nemá ztrácet čas s tím, co udělali jiní a lépe, je použitá klasická relační databáze. Nejdřív MS SQL (proto také ty historické koncovky .asp), nyní když je TOPlist LAMP (je hezké, že se dá zkratka použít pro Perl i Python, ještě by to chtělo nějaký jazyk P a P-shell), používám MySQL. Zatím ve verzi 4.0 a přemýšlím, jestli použít 4.1 nebo počkat až na 5.0. Pro zajímavost jsem vytáhl graf zátěže. Zelená čára je aktuální počet dotazů za vteřinu a modrá je průměr od startu.
351Pochopitelně, v případě že se jedná o zatíženější aplikaci (mimochodem, minulé pondělí, ze kdy je ten graf, byla poprvé překonána hranice 60 miliónů měření za den, běžně je nad 55 miliónů) je potřeba pečlivý návrh a trochu se věnovat nastavení. Ovšem, i příslušný hardware.
352Na TOPlistu mi databáze běží na IBM xSeries 345. V konfiguraci 2xXeon 3GHz, 2 GB RAM a 3+1 36GB (proč plus jedna bude dál) disky. Jedná se o rackový server velikosti 2U. Tradičně výborně je řešené uchycení. Lyžiny se nasazují tím, že se natáhnou západky, které se pak „nastřelí“ do lišt ve skříni. A server se pak už jen na ně položí a zajistí. Takže žádné šroubování deseti šroubků a hledání zapadlých mezi kabeláží, ale s trochou cviku je za dvě minuty všechno vyřízeno. Jediný zádrhel může nastat s délkou. Většina hostingů má skříně pouze 80cm hluboké. A vzhledem k délce 70cm a prostoru potřebného k proudění chladícího vzduchu je potřeba použít skříň alespoň s metrovou hloubkou.
353Na serverovně jsem ho zkusil vyfotit na mobilu. Když jsem to viděl, tak jsem si říkal, že tam někdy musím vzít digiták. Ale nakonec jsem se rozhodl pro tuhle, protože je taková autentická („Proč jsou vždycky záběry UFO rozmazaný?“ Hellboy). Dokonce se mi podařila stihnout zachytit i rozsvícená LEDka disku :-). Chtěl jsem původně všechny tři, ale po asi dvaceti pokusech jsem byl rád aspoň za tu jednu. Je tam vidět i jeden z webserverů, ale o těch třeba až jindy.
354Takže k těm diskům. Někdy v půlce července odešel jeden z disků v poli. Díky RAIDu 5 vše běželo. Během dvou dnů IBM poslala nový a vyměnil se. Ale přecejen to bylo trochu nervoznější období, protože jak píše Terry Pratchett, jestli má něco pravděpodobnost jedna ku miliónu, můžete si být jistí, že se to stane (tedy v případě, že je to něco nepřijemného). Rozhodl jsem se proto využít jednu z funkcí, kterými se liší skutečný RAID řadič od toho, který za něj vydávají výrobci motherboardů. Přidal jsem hot-spare disk. Nyní je to ten vlevo dole.
355Pro ty, kteří si nehrají se servery: jak název napovídá, jedná se o disk, který za normálních okolností „leží ladem“. Ovšem ve chvíli, kdy některý z aktivních disků vykáže chybu a je odpojen, monitoring pošle SMSku a řadič sám automatický začne pole vytvářet na tomto záložním. Rozbitý disk se pak vymění a stane se z něj hot-spare. Možná vás napadlo, co se stane ve chvíli, když by odešel během vytváření další disk. Ano, pak by přišly ke slovu zálohy 🙂 Ovšem pravděpodobnost, že během hodiny (co trvá přestavění pole) odejdou dva disky je taková, že už Pratchettovi věřit nebudu. Není to sice součin obou pravděpodobností (takže ne jedna ku miliónu na druhou :-)), ale i tak je taková, že se spíš stane něco úplně jiného.
356Instalace byla také docela jednoduchá. Disk se strčil do zásuvky, přes ipssend SCANDRIVES se řadiči řeklo, že má zjistit změny (tj. přidaný disk) a pak už jen SETSTATE HSP pro nastavení stavu. Disk dvakrát zablikal jako že jo a pak už jen GETCONFIG hlásí: State: Hot spare (HSP).
357`}).add({id:70,tag:"cs",href:"/blog/toplist-can-i-use/",title:"TOPlist ❤️ Can I Use",description:"Asi znáte web caniuse.com — velmi užitečnou službu, která vám řekne, jestli daný prohlížeč danou vlastnost JavaScriptu/CSS podporuje. Jenže odpovídá na ot
357ázku „zvládne to prohlížeč?",content:`Asi znáte web caniuse.com — velmi užitečnou službu, která vám řekne, jestli daný prohlížeč danou vlastnost JavaScriptu/CSS podporuje. Jenže odpovídá na otázku „zvládne to prohlížeč?&quot;, nikoli „zvládají to moji návštěvníci?&quot;. A to jsou dvě odlišné věci.
358Proto jsem si řekl, že je spojím. Vytvořil jsem Can I Use @ TOPlist — jednoduchou aplikaci, která vezme seznam vlastností z Can I Use a doplní k nim reálná data o tom, jestli je mají vaši návštěvníci ve skutečnosti k dispozici. Namísto statické matice prohlížečů dostanete časovou osu: jak se podpora jednotlivých funkcí měnila v čase, na reálném provozu, který TOPlist měří přímo na vašem webu.
359Jak to funguje &nbsp; Vyberete svůj web. Zvolíte časový rozsah (30 dní, rok, 5 let, nebo vlastní interval). Přidáte funkce a vlastnosti, které vás zajímají. A aplikace nakreslí graf — po jednom grafu na funkci — s tím, kolik procent vašich návštěvníků tu funkci mělo k dispozici v daném okamžiku. Tím vidíte, jestli se „bezpečná&quot; funkce, na kterou se chcete spolehnout, ve vašem provozu skutečně ujala, případně její historii (jestli je to funkce jejíž podpora klesá nebo naopak bude časem použitelnější).
360Co potřebujete &nbsp; Jedná se o osobní nástroj, nikoli o veřejnou službu. Stačí si vytvořit serverKey v TOPlist Profi (povolení read_basic_stats a read_profi_stats) a vložit ho do souboru secrets.js. Aplikace je čistě statická — žádné instalace, stačí stránku otevřít a běží. Delší časové rozsahy vyžadují aktivní předplatné.
361Kód aplikace je dostupný na GitHubu, případně Codebergu. Je publikovaný pod licencí MIT, takže jej můžete volně používat, upravovat (budu rád, pokud přispějete zpět) nebo použít jako referenci při integraci do vlastních nástrojů.
362Poznámka: seznam funkcí i jejich označení pochází z projektu Can I Use, jehož podpora tabulek je licencována jako CC BY 4.0. S projektem Can I Use nejsem nijak spjatý — jen od něj čerpám a zde uvádím.
363Takže příště, když se ptáte „můžu to použít?&quot;, máte k dispozici i odpověď na druhou polovinu otázky: „… a může to použít i můj návštěvník?&quot;
364`}).add({id:71,tag:"cs",href:"/blog/toplist-ma-googlerank-810/",title:"TOPlist má GoogleRank 8/10",description:"Jak jsem nedávno psal, Google snížil u některých serverů GR. O to větší bylo mé překvapení, když jsem si dneska všimnul, že je zelený proužek v toolbaru na TOPlistu nějaký delší.",content:`Jak jsem nedávno psal, Google snížil u některých serverů GR. O to větší bylo mé překvapení, když jsem si dneska všimnul, že je zelený proužek v toolbaru na TOPlistu nějaký delší. Prohledal jsem ostatní české servery a zatím jiný s 8/10 nenašel. Pokud o něm víte, dejte mi vědět třeba do komentářů.
365Tímto děkuji všem, kdo na něj linkují.
366`}).add({id:72,tag:"cs",href:"/blog/tyden-zmen/",title:"Týden změn",description:"V uplynulém týdnu (28.6. – 4.7. 2010) bylo zaznamenáno dokonce několik předělů. Asi nejzajímavější je pokles podílu Microsoft Exploreru verze 6 na úroveň 5 procent.",content:`V uplynulém týdnu (28.6. – 4.7. 2010) bylo zaznamenáno dokonce několik předělů. Asi nejzajímavější je pokles podílu Microsoft Exploreru verze 6 na úroveň 5 procent. Což by mohlo znamenat, že zejména u menších a nových projektů by bylo možné konečně přestat tuto verzi brát v potaz.
367Růst MS IE 8 se víceméně zastavil (kolem 26%). Za poklesem verzí 6 a 7 stojí hlavně Webkit (tažený Google Chromem), který se už velmi přiblížil Exploreru 7 (kolem 11%). Firefox i Opera si za poslední rok svůj podíl udržují konstantní na 40, resp. 6 procentech. http://www.toplist.cz/stat/?a=history&type=1&lang=CZ
368Na poli operačních systémů se dotáhly nové Windows 7 na úroveň klesajících Vist (17%). Dominantní stále zůstavají Win XP, ale jejich podíl už poklesl na 61%. http://www.toplist.cz/stat/?a=history&type=2&lang=CZ
369`}).add({id:73,tag:"cs",href:"/blog/vykon-mysql-4-0-vs-4-1/",title:"Výkon MySQL 4.0 vs. 4.1",description:"O tom, že aktuální verze MySQL – 4.1 je trochu náročnější se ví. &nbsp; Já bych rád ukázal jeden konkrétní graf, na kterém je vidět o kolik.",content:` O tom, že aktuální verze MySQL – 4.1 je trochu náročnější se ví. &nbsp; Já bych rád ukázal jeden konkrétní graf, na kterém je vidět o kolik. Jde o provoz v rozsahu 3000 – 3500 dotazů za vteřinu (modří již vědi :-)). Grafy odpovídají stejnému časovému úseku. Jak je z nich vidět, je nárůst relativně vysoký, přibližně 50%.
370Protože se jedná o velké množství jednoduchých dotazů a hlavně dotazů modifikující obsah tabulek(insert, update), nejsou využity rozšířené možnosti jako query cache, subselecty atd. V případě, že by je projekt využíval (publikační systémy, virtuální obchody atp.) může být situace opačna. Ale pokud máte aplikaci, která používá základní sadu dotazů, je asi lepší zůstat u starší verze.
371`}).add({id:74,tag:"cs",href:"/napoveda/toplist-profi/vytvoreni-noveho-reportu/",title:"Vytvoření nového reportu",description:"Po přihlášení do TOPlist Profi klikněte v levém vertikálním menu na zelené tlačítko „&gt;vytvořit“ Vydefinujte si vlastní report a to z možností zobrazených v pravé části webové stránky.",content:` Po přihlášení do TOPlist Profi klikněte v levém vertikálním menu na zelené tlačítko „&gt;vytvořit“ Vydefinujte si vlastní report a to z možností zobrazených v pravé části webové stránky. Výběr parametrů reportu potvrďte kliknutím na tlačítko „Vytvořit“. Vytvořený report naleznete na stránce „Přehled“ V případě, že nemáte zaktivovanou službu TOPlist Profi, tak místo volby možností reportu, se zobrazí informační stránka s odkazem na aktivaci služby Poznámka: pokud chcete mít nastaveny pravidelné reporty, to znamená reporty, 
371které se automaticky generují na konci příslušného období, klikněte na stránku „Plánování“, kde si můžete pravidelný report nastavit (odkaz na „Plánování“ naleznete v levém vertikálním menu).
372`}).add({id:75,tag:"cs",href:"/blog/windows-10-a-ms-edge/",title:"Windows 10 a MS Edge",description:"Byla přidána detekce nových Windows 10 a prohlížeče MS Edge. A když už se to upravovalo, tak se rozdělila i detekce mobilních verzí u Linuxu (nyní Linux nebo Android) a OS X (OSX/iOS).",content:`Byla přidána detekce nových Windows 10 a prohlížeče MS Edge. A když už se to upravovalo, tak se rozdělila i detekce mobilních verzí u Linuxu (nyní Linux nebo Android) a OS X (OSX/iOS).
373`}).add({id:76,tag:"cs",href:"/blog/windows-vista-dosahly-maximalne-20-podil/",title:"Windows Vista dosáhly maximálně 20% podíl",description:"Předposlední verze systému firmy Microsoft, během více než dvou let od svého uvedení na český trh – 1. března 2007, nedosáhla majoritního rozšíření mezi operačními systémy měřenými v rámci TOPlistu.",content:`Předposlední verze systému firmy Microsoft, během více než dvou let od svého uvedení na český trh – 1. března 2007, nedosáhla majoritního rozšíření mezi operačními systémy měřenými v rámci TOPlistu. Maximum jen těsně nad hranicí 20%, konkrétně 20,35%, bylo dosaženo během týdne 26.10. – 1.11.2009. Vzhledem k oficiálnímu uvedení jeho nástupce Windows 7 dne 22.10.2009 se nedá předpokládat, že by podíl ještě výrazněji stoupnul. Zajímavější bude sledovat, jak si povede právě nová verze. I když dominantní roli, přes klesající tendenci, si stále s přehledem udržují 8 let staré Windows XP s podílem přes 70%.
374Zdroj: historie podílu op. systémů mezi českými uživateli http://www.toplist.cz/stat/?a=history&type=2&lang=CZ
375`}).add({id:77,tag:"cs",href:"/blog/wordpress-plugin/",title:"WordPress plugin",description:"Po mnoho let od roku 2009 vytvářel Honza Skýpala plugin, který umožňoval jednoduché vložení počítadla TOPlistu do WordPressu. Několik let jsem o tom ani nevěděl.",content:`Po mnoho let od roku 2009 vytvářel Honza Skýpala plugin, který umožňoval jednoduché vložení počítadla TOPlistu do WordPressu. Několik let jsem o tom ani nevěděl. Překvapilo a potěšilo mě, že někdo věnuje svůj volný čas zjednodušení použití TOPlistu.
376Za ty roky ovšem došlo k některým změnám. Např. statistiky zobrazoval plugin tak, že stahoval přímo HTML stránky z webu TOPlistu a data vytahoval z nich. To přestalo fungovat při změně designu stránek. Další omezení byla práce s heslem, v případě přístupu na neveřejné statistiky, která neodpovídala požadavkům GDPR a také přestala fungovat. O drobnostech typu změna loga apod. ani nemluvě.
377Tyto úpravy by představovaly poměrně velké usilí a, pochopitelně, při pracovním a rodinném vytížení se čas těžko hledá.
378Rozhodl jsem se, že tyto úpravy zkusím udělat sám. Ač nejsem PHPkář (tenhle plugin je asi největší kus PHP kódu, který jsem v životě spravoval 🙂 ), udělal jsem pár nezbytných úprav, které alespoň opraví hlavní věci. Vznikl tak nový plugin na adrese https://wordpress.org/plugins/toplist/
379Instaluje se jednoduše. V administraci přidáte plugin „TOPlist“ (bude mít nové logo TOPlistu) a starý deaktivujete. Nastavení si převezme.
380Budu rád za všechny náměty a připomínky.
381Změny:
382Data pro statistiky se nyní berou z API, takže je neovlivní změna designu webu. Pro přístup do neveřejných statistik se generuje jednoúčelové heslo. Zdrojový kód jsem umístil na Github. Přecejen je to lepší platforma na zpracovávání námětů a připomínek než je SVN WordPressu. A dovolil jsem si změnit licenci na MIT. Fakticky by se nemělo nic změnit (oboje jsou licence „dělejte si co chcete“), ale MIT alespoň nebývá vyhvězdičkovaná 🙂 `}).add({id:78,tag:"cs",href:"/blog/wordpress-plugin-5-1/",title:"WordPress plugin 5.1",description:`Připravil sem novou verzi pluginu pro WordPress. Změny jsou:
383zrušení cachování statistik Protože je nové stahování dat přes API (viz předchozí verze) rychlejší, není potřeba výsledky ukládat do lokální databáze.`,content:`Připravil sem novou verzi pluginu pro WordPress. Změny jsou:
384zrušení cachování statistik Protože je nové stahování dat přes API (viz předchozí verze) rychlejší, není potřeba výsledky ukládat do lokální databáze. možnost nastavení počáteční hodnoty počítadla Parametr start lze nastavit přímo v konfiguraci widgetu. překlad pomocí translate.wordpress.org Příprava na překlady pomocí jednotného prostředí, které vytvořil WordPress.com. Pokud na vás v pluginu někde vyskočí angličtina, tak mi napište a dopřeložím to. Pokud již používáte novou verzi (tj. 5.0), tak by se vám měla nabídnout aktualizace automaticky.
385OPRAVA [28. října]: Takže se mi opravdu v těch překladech podařila chyba, takže se pokaždé zobrazoval jenom anglický text. Proto vyšla verze 5.1.1, která to již opravuje.
386`}).add({id:79,tag:"cs",href:"/blog/xml-vystup/",title:"XML výstup",description:`Data o návštěvnosti je nyní možné získávat i ve formátu XML.
387Fungují na podobném principu jako Infopanel, tj. nedochází k vlastnímu měření.`,content:`Data o návštěvnosti je nyní možné získávat i ve formátu XML.
388Fungují na podobném principu jako Infopanel, tj. nedochází k vlastnímu měření. Pro něj je nutné použít nějaký klasický měřící kód.
389Dostupná data jsou stejná jako pro větší verzi panelu: návštěvnost celkem, dnes, za týden, pořadí celkové a v kategorii a počet uživatelů online.
390Adresa pro volání je http://toplist.cz/images/counter.asp?a=xml&id=ID_stranky
391Poznámka: jen připomínám, že pokud budete tento způsob využívat k zobrazení návštěvnosti přímo ve stránce, nebude v ní započítáno její aktuální zobrazení, které je zaznamenáno až načtením měřícího kódu.
392`}).add({id:80,tag:"cs",href:"/blog/z-api-do-csv/",title:"Z API do CSV",description:"Všechny statistické výstupy TOPlistu jsou dostupné přes API. Nově je hlavní metoda pro jejich získání /stat/process (viz https://profi.toplist.cz/api/#!/stat/post_stat_process), která se používá i v interaktivních statistikách.",content:`Všechny statistické výstupy TOPlistu jsou dostupné přes API. Nově je hlavní metoda pro jejich získání /stat/process (viz https://profi.toplist.cz/api/#!/stat/post_stat_process), která se používá i v interaktivních statistikách.
393Jeden ze zákazníků potřeboval výstup z této metody ve formátu CSV pro další zpracování. Vytvořil jsem jednoduchý skript, který tento výstup převede do CSV. Je dostupný na Codebergu, případně na GitHubu.
394Skript (api2csv.py) je napsaný v čistém Pythonu, bez použití dalších knihoven (např. requests), takže by měl fungovat i na starších verzích Pythonu, případně i ve Windows bez nutnosti instalace dalších balíčků. Lze jej brát i jako příklad, jak pracovat s API TOPlistu.
395Použití je jednoduché:
396Pro zjednodušení jsou parametry nastavitelné přímo v kódu, takže stačí v souboru api2csv.py upravit hodnoty pro API_TOKEN a POST_DATA.
397API_TOKEN je váš API klíč, který získáte v administraci TOPlistu a v POST_DATA nastavíte parametry pro API volání, které odpovídají vašim požadavkům na statistiky. Jejich struktura je následující:
398POST_DATA =  &#34;date&#34;: &#34;2025-05-30&#34;, &#34;interval&#34;: &#34;day&#34;, &#34;step&#34;: &#34;hour&#34;, &#34;stats&#34;: [&#34;visits&#34;, &#34;totalPages&#34;], &#34;rowLimit&#34;: 100 kde date je datum, pro které chcete získat statistiky (ve formátu YYYY-MM-DD), interval je časové rozmezí (např. day, week, month), step je krok statistik (např. hour, day, week), stats jsou požadované statistiky (viz API metoda /sharedData/job), a rowLimit je maximální počet řádků, které chcete získat.
399poté už stačí spustit skript
400python3 api2csv.pyv tomto případě se výsledky posílají na standardní výstup (stdout).
401Pokud přidáte parametr, je použit jako prefix pro názvy souborů s jednotlivými statistikami:
402python3 api2csv.py prefixVýstup bude vypadat takto:
403prefix-visits.csv prefix-totalPages.csv`}).add({id:81,tag:"cs",href:"/blog/zabezpeceni-statistik/",title:"Zabezpečení statistik",description:"Vzhledem ke stále se zvyšujícímu množství automatických scanování veřejných statistik jsme se rozhodli všem nastavit přístup přes heslo. Jednak to sníží zátěž našich serverů, které nic nepřinášela našim uživatelům a navíc znemožníme potencionální sledování a vyhodnocování provozu na měřených stránkách.",content:`Vzhledem ke stále se zvyšujícímu množství automatických scanování veřejných statistik jsme se rozhodli všem nastavit přístup přes heslo. Jednak to sníží zátěž našich serverů, které nic nepřinášela našim uživatelům a navíc znemožníme potencionální sledování a vyhodnocování provozu na měřených stránkách. V případě, že budete chtít výsledky prezentovat, je stále možné vygenerovat reporty.
404Proběhla ještě jedna novinka, týkající se statistik. V nové verzi https://www.toplist.cz/statistics jsou dostupné statistiky reklamních kampaní na základě UTM parametrů.
405`}).add({id:82,tag:"cs",href:"/blog/zalozni-serverovna/",title:"záložní serverovna",description:"Jeden aktuální obrázek ze záložní lokace. Servery jsou standardní (2x CPU, 32GB RAM) od SGI nebo Supermicra. Asi nejzajímavější je použitý interconnect pomocí Infinibandu, tj.",content:`Jeden aktuální obrázek ze záložní lokace. Servery jsou standardní (2x CPU, 32GB RAM) od SGI nebo Supermicra. Asi nejzajímavější je použitý interconnect pomocí Infinibandu, tj. víc než desetkrát rychlejší než běžný gigový ethernet. A za pár let se budeme jenom usmívat nad tím, co nám dneska přišlo jako slušný výkon.
406`}).add({id:83,tag:"cs",href:"/blog/zmena-hesla/",title:"Změna hesla",de
406scription:"Jak jsme slíbili, začínáme s informacemi o nové verzi. Mohli jsme začít třeba s logem. Psát o tom, že je to pro nás symbol toho, že se mění opravdu všechno.",content:`Jak jsme slíbili, začínáme s informacemi o nové verzi. Mohli jsme začít třeba s logem. Psát o tom, že je to pro nás symbol toho, že se mění opravdu všechno. Že je v podstatě známé, protože je to upravená ikona podrobných statistik. A že její hlavní plus je, že na rozdíl od současného loga, jej lze použít ve všech možných velikostech od ikony po billboard 🙂
407Ale my si řekli ne. Logo je fajn a co jsme napsali je pravda, ale co si budem povídat, klidně by jím mohla být třeba hruška. Důležité je, jak věci fungují.
408Jeden z nejčastějších dotazů, které řešíme jsou otázky typu: ‘Jsem nový majitel webu a jak získám heslo, když nemám přístup k emailům v registraci’ nebo ‘Nepamatuju si, jaký email je registrovaný’. Nyní lze tuto situaci jednoduše řešit. Ve formuláři pro obnovu hesla je ještě jeden formulář. V něm se zobrazí adresa z vašeho webu, na které budeme čekat kontrolní kód. Patrně to bude stránka, která ještě neexistuje. Není tak potřeba zasahovat do současného webu a stačí tuto novou stránku vytvořit. Nemusí to být ani plnohodnotná stránka (např. i bez designu apod.). Může být i jen obyčejný textový soubor. Pak stačí nechat zkontrolovat, že obsahuje klíč. A pokud ano, tak umožníme heslo změnit.
409Konkrétní příklad:
410Formulář pro obnovu hesla Pro TOPlist je nastavení hesla na adrese https://www.toplist.cz/password/reset/1. Po zmáčknutí tlačítka to vypíše požadovanu adresu (každý návštěvník uvidí jinou). Pro náš příklad to může být třeba: www.toplist.cz/jvdrv.html. A také klíč WY3NqZRsbZQPfHbGksyOE7b2SMGLWVU7. Takže stačí, abych vytvořil soubor na požadováné adrese. A po zkontrolování bude možné heslo změnit.
411`}),search.addEventListener("input",showResults,!0)}function hideSuggestions(e){var isClickInsideElement=suggestions.contains(e.target);isClickInsideElement||(suggestions.classList.add("d-none"),background!==null&&background.style.setProperty("--image-opacity","0.1"))}function inputFocus(e){e.ctrlKey&&e.key==="/"&&(e.preventDefault(),search.focus()),e.key==="Escape"&&(search.blur(),suggestions.classList.add("d-none"))}function suggestionFocus(e){const suggestionsHidden=suggestions.classList.contains("d-none");if(suggestionsHidden)return;const focusableSuggestions=[...suggestions.querySelectorAll("a")];if(focusableSuggestions.length===0)return;const index=focusableSuggestions.indexOf(document.activeElement);if(e.key==="ArrowUp"){e.preventDefault();const nextIndex=index>0?index-1:0;focusableSuggestions[nextIndex].focus()}else if(e.key==="ArrowDown"){e.preventDefault();const nextIndex=index+1<focusableSuggestions.length?index+1:index;focusableSuggestions[nextIndex].focus()}}function showResults(){const maxResult=5;var searchQuery=this.value;const lang=document.documentElement.lang;var results=null;searchQuery?(results=index.search(searchQuery,{index:["title","description","content"],limit:maxResult,tag:lang,enrich:!0}),background!==null&&background.style.setProperty("--image-opacity","0")):background!==null&&background.style.setProperty("--image-opacity","0.1");const flatResults=new Map;if(results!==null)for(const result of results.flatMap(r=>r.result)){if(flatResults.has(result.doc.href))continue;flatResults.set(result.doc.href,result.doc)}if(suggestions.innerHTML="",suggestions.classList.remove("d-none"),flatResults.size===0&&searchQuery){const msg=suggestions.dataset.noResults,noResultsMessage=document.createElement("div");noResultsMessage.innerHTML=`${msg} "<strong>${searchQuery}</strong>"`,noResultsMessage.classList.add("suggestion__no-results"),suggestions.appendChild(noResultsMessage);return}for(const[href,doc]of flatResults){const entry=document.createElement("div");suggestions.appendChild(entry);const a=document.createElement("a");a.href=href,entry.appendChild(a);const title=document.createElement("span");title.classList.add("text-start"),title.textContent=doc.title,title.classList.add("suggestion__title"),a.appendChild(title);const description=document.createElement("span");if(description.textContent=doc.description,description.classList.add("suggestion__description"),a.appendChild(description),suggestions.appendChild(entry),suggestions.childElementCount==maxResult)break}}search!==null&&suggestions!==null&&(document.addEventListener("keydown",inputFocus),document.addEventListener("keydown",suggestionFocus),document.addEventListener("click",hideSuggestions),initIndex());const searchModal=document.getElementById("search-modal");searchModal!==null&&searchModal.addEventListener("shown.bs.modal",function(){const searchInput=document.getElementById("search-input-modal");searchInput!==null&&searchInput.focus({focusVisible:!0})}),document.querySelectorAll(".dynamic-svg").forEach(placeholder=>{placeholder.onload=function(){const container=placeholder.parentElement,doc=placeholder.contentDocument,attr=placeholder.getAttribute("data-class"),style=placeholder.getAttribute("data-style");if(container!==null&&doc!==null){const svg=doc.querySelector("svg");svg!==null&&(svg.setAttribute("class","svg-inline--fa "+(attr||"")),svg.setAttribute("fill","currentcolor"),svg.setAttribute("aria-hidden","true"),svg.setAttribute("role","img"),style!==null&&style!==""&&svg.setAttribute("style",style),svg.removeAttribute("height"),svg.removeAttribute("width"),container.innerHTML="",container.appendChild(svg))}}});const navbar=document.querySelector(".navbar"),togglers=document.querySelectorAll(".main-nav-toggler"),modeSelectors=document.querySelectorAll(".switch-mode-collapsed");if(navbar!==null&&togglers!==null){window.onscroll=()=>{window.scrollY>75?navbar.classList.add("nav-active"):navbar.classList.remove("nav-active")};for(let i=0;i<togglers.length;++i)togglers[i].onclick=()=>{navbar.classList.toggle("navbar-expanded")};for(let i=0;i<modeSelectors.length;++i)modeSelectors[i].onclick=()=>{for(let j=0;j<togglers.length;++j){const toggler=togglers[j];toggler.getAttribute("aria-expanded")==="true"&&toggler.click()}}}const popoverTriggerList=document.querySelectorAll('[data-bs-toggle="popover"]'),popoverList=[...popoverTriggerList].map(popoverTriggerEl=>new bootstrap.Popover(popoverTriggerEl));function webShareAPI(title,description,link){navigator.share({title,text:description,url:link}).then(()=>console.log("Successful share")).catch(error=>console.log("Error sharing",error))}const shareBtn=document.getElementById("btn-webshare");if(shareBtn!==null)if(navigator.share){const title=shareBtn.getAttribute("data-sharing-title"),description=shareBtn.getAttribute("data-sharing-description"),url=shareBtn.getAttribute("data-sharing-url");shareBtn.style.display="block",shareBtn.addEventListener("click",()=>webShareAPI(title,description,url))}else shareBtn.style.display="none";const container=document.getElementById("toast-container");container!==null&&document.querySelectorAll("[data-toast-target]").forEach(trigger=>{const target=document.getElementById(trigger.getAttribute("data-toast-target"));if(target!==null){container.appendChild(target);const toast=bootstrap.Toast.getOrCreateInstance(target);toast!==null&&trigger.addEventListener("click",()=>{toast.show()})}});const tooltipTriggerList=document.querySelectorAll('[data-bs-toggle="tooltip"]'),tooltipList=[...tooltipTriggerList].map(tooltipTriggerEl=>new bootstrap.Tooltip(tooltipTriggerEl))

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.