Die Inhaltsanalyse zeigt, ob Seitentitel, Beschreibungen, Überschriften, Bilder und Textstruktur Suchmaschinen und Besuchern klare Signale geben.
Seitentitel
Joe Browns Official | Women’s & Men’s Clothing, Homeware & Sale
Länge : 71
Der Seitentitel von indystar.de umfasst aktuell 71 Zeichen und liegt damit außerhalb des empfohlenen Bereichs von 10 bis 70 Zeichen. Eine etwas präzisere Länge kann helfen, das Thema der Seite in Suchergebnissen besser zu vermitteln. Zur Kontrolle können Sie dieses kostenlose Werkzeug verwenden.
Seitenbeschreibung
Discover your unique style with Joe Browns. Browse distinctive women’s, men’s clothing & vibrant homeware collections for every season.
Länge : 139
Für indystar.de ist eine passende Meta-Beschreibung vorhanden: 139 Zeichen bieten genug Raum für den Inhalt der Seite, ohne den empfohlenen Rahmen von 70 bis 160 Zeichen zu sprengen.
Suchbegriffe
indystar.de nutzt keine META-Suchbegriffe. Der wichtigste SEO-Faktor bleibt der sichtbare Inhalt, aber ergänzende Keywords können bei der Pflege und Dokumentation der Seite hilfreich sein. Bei Bedarf können Sie dieses kostenlose Werkzeug verwenden.
Og META Eigenschaften
Die OG-Meta-Daten von indystar.de sind vorhanden. Das verbessert die technische Grundlage für geteilte Links, weil Vorschauen nicht allein automatisch erraten werden müssen.
Eigenschaft
Inhalt
type
website
title
Joe Browns Official | Women’s & Men’s Clothing, Homeware & Sale
[H1] Women's and Men's Clothes, Shoes and Accessories
[H1] Results for\n \n \n \n \n \n instead of \n \n Did you mean:\n \n \n \n \n \n Redirected from \"\".\n \n \n \n \n \n \n \n Results for \n Redirected from \"\" \n \n \n \n \n \n \n items for \"\"\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Filter & Sort\n \n \n \n \n Filters\n \n \n \n \n \n \n \n 0) { %>\n \n Clear all filters\n \n \n \n \u00d7\n \n \n \n \n \n \n \n \n Price\n \n \n \n \n Clear\n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 0) { %>\n \n \n \n \n \n \n \n \n ()\n \n \n \n config.search.initial_number_of_facet_values) { %>\n View More\n \n \n \n \n \n \n \n \n \n \n \n \n \n \nGroup By: \n \n \n \n \n \n \n \n 0) { %>\n \nSize: \n \n\n \n \n \n \n \nSort By: \n \n \n \n \n \n \n \n \n \n \n View Items\n \n \n \n \n \n \n 0) { %>\n \n Clear all filters\n \n \n \n \u00d7\n \n \n \n \n \n \n 0;\n const haveGroupedResults = locals.grouped_products && grouped_products.groups.length > 0;\n %>\n \n \n \n items\n \n \n \n \n \nGroup By: \n \n \n \n \n \n \n \n 0) { %>\n \nSize: \n \n\n \n \n \n \n \nSort By: \n \n \n \n \n \n \n \n \n \n No results found\n \n \n \n \n \n 0)) { %>\n %%-PRODUCT_LIST_TEMPLATE-%%\n \n \n \n 0) { %>\n \n \n { %>\n \n \n \n \n \n \n \n \n \n","product_list_template":"\n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \nWas: \n \n \n \n \n \n \n \n \n 0) { %>\n \n \n \n \n defaultMaxColorSwatches) { %>\n +\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n"},"autosuggest":{"enabled":1,"catalog_views":"joebrowns","endpoint":"https:\/\/suggest.dxpapi.com\/api\/v2\/suggest\/","number_of_terms":"10","number_of_products":"8","number_of_collections":"4","selector":"#search","template":"\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n"},"category":{"enabled":1,"endpoint":"https:\/\/core.dxpapi.com\/api\/v1\/core\/","sorting_options":[{"label":"Relevance","value":""},{"label":"Price (low - high)","value":"sale_price+asc"},{"label":"Name (A - Z)","value":"title+asc"},{"label":"Price (high - low)","value":"sale_price+desc"},{"label":"Name (Z - A)","value":"title+desc"}],"items_per_page":"60","facets_included":1,"initial_number_of_facets":"10","initial_number_of_facet_values":"10000","infinite_scroll":1,"selector":"#maincontent .columns","display_variants":0,"is_category_page":0,"category_id":"","fields":"pid,title,brand,price,sale_price,thumb_image,sku_thumb_images,sku_swatch_images,sku_color_group,url,price_range,sale_price_range,description,swatches,feefo_summary_rating,colours,color,colors,image,simple_item_sku,amasty_labels,entity_id,parent_entity_id,parent_sku,product_category,price_eur,sale_price_eur","template":"\r\n\r\n 0) { %>\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n 0) {\r\n const url = window.location.href;\r\n const active_facet_name = 'sizes';\r\n const active_facet = 'sizes';\r\n\r\n top_picks.sizes= facets.find(facet => facet.original_title === 'sizes' )?.section || [];\r\n\r\n \/*Triggers facet*\/\r\n window.bloomreach_trigger = (e) => {\r\n document.getElementById(e.dataset.id).click();\r\n}\r\n\r\n \/* Remove 'blm-shop-by-size-list' before injecting a new one *\/\r\n const oldBlmShopBySizeList = document.getElementById('blm-shop-by-size-list');\r\n if (oldBlmShopBySizeList) {\r\n oldBlmShopBySizeList.remove();\r\n}\r\n\r\n const shopBySize = document.createElement('div');\r\n shopBySize.id = 'blm-shop-by-size-list';\r\nshopBySize.className = active_facet_name === 'sizes' ? 'blm-shop-by-size w-full' : 'blm-shop-by-category';\r\n \r\n const heading = document.createElement('p');\r\n heading.className = 'blm-shop-by-size__heading text-xl my-4';\r\nheading.innerText = 'Shop by ' + (active_facet_name === 'sizes' ? 'Size' : 'Type');\r\n shopBySize.appendChild(heading);\r\n \r\n const ul = document.createElement('ul');\r\n ul.className = 'blm-shop-by-size__list inline-flex gap-4 font-semibold mb-8 overflow-x-auto w-full';\r\n \r\n top_picks[active_facet].forEach((facet, id) => {\r\n const li = document.createElement('li');\r\n const a = document.createElement('a');\r\n a.href = 'javascript:void(0)';\r\n a.onclick = function () { window.bloomreach_trigger(this); };\r\n a.id = 'blm-cat-link-' + id;\r\na.dataset.id = `${active_facet_name}[${active_facet_name === 'sizes' ? facet.name : facet.cat_name}]`;\r\n a.innerText = facet.name;\r\n li.appendChild(a);\r\n ul.appendChild(li);\r\n});\r\n\r\n\r\n shopBySize.appendChild(ul);\r\n if (cvcid) {\r\n cvcid.appendChild(shopBySize);\r\n}\r\n\r\n} %>\r\n\r\n \r\n \r\n \r\n \r\n \r\n Results for\r\n \r\n \r\n \r\n \r\n \r\n instead of \r\n \r\n Did you mean:\r\n \r\n \r\n \r\n \r\n \r\n Redirected from \"\".\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n Results for \r\n Redirected from \"\" \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n Filter & Sort\r\n \r\n\r\n \r\n\r\n \r\n Filters\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n 0) { %>\r\n \r\n Clear all filters\r\n \r\n \r\n \r\n \u00d7\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n Price\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n Clear\r\n \r\n \r\n \r\n \r\n\r\n \r\n 0) { %>\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n ()\r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n config.search.initial_number_of_facet_values) { %>\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\nGroup By: \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n 0) { %>\r\n \r\nSize: \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\nSort By: \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n View Items\r\n \r\n\r\n \r\n \r\n \r\n \r\n 0) { %>\r\n \r\n Clear all filters\r\n \r\n \r\n \r\n \u00d7\r\n \r\n \r\n \r\n \r\n \r\n \r\n 0;\r\n const haveGroupedResults = locals.grouped_products && grouped_products.groups.length > 0;\r\n %>\r\n \r\n\r\n \r\n \r\n \r\nGroup By: \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n 0) { %>\r\n \r\nSize: \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\nSort By: \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n No results found\r\n \r\n \r\n\r\n \r\n \r\n 0)) { %>\r\n %%-PRODUCT_LIST_TEMPLATE-%%\r\n \r\n \r\n\r\n \r\n \r\n","product_list_template":"\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n selectedColors.includes(variant.sku_color_group ? variant.sku_color_group.toLowerCase() : null))\r\n %>\r\n \r\n 1) { %>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n 0) { %>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n 0) { %>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n -\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\nWas: \r\n \r\n \r\n \r\n -\r\n \r\n \r\n \r\n \r\n \r\n \r\nWas: \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n 0) { %>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n defaultMaxColorSwatches) { %>\r\n \r\n \r\n +\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n { %>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n"},"widget":{"endpoint":"https:\/\/pathways.dxpapi.com\/api\/v2\/widgets\/","fields":"pid,title,brand,price,sale_price,thumb_image,sku_thumb_images,sku_swatch_images,sku_color_group,url,price_range,sale_price_range,description,price_eur,currency_eur,currency_gbp,parent_sku,simple_item_sku,colour,colours,skuid,is_available,swatches,feefo_summary_rating,sku_size","template":"\n config.number_of_items_to_show) { %>\n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n config.number_of_items_to_show) { %>\n \n \n \n \n \n \n \n\n"}}
window.onload = (() => {
window.pixelReady = window.pixelReady || new Promise(r => (window.pixelResolve = r));
// Implement post pixel logic here if needed.
window.pixelReady.then(() => {
if (window.BloomreachModules !== void 0) {
if (window.BloomreachModules.events !== void 0) {
window.BloomreachModules.events.load();
}
}
});
if (window.BloomreachModules !== void 0) {
if (window.BloomreachModules.autosuggest !== void 0) {
window.BloomreachModules.autosuggest.load();
}
}
})
var BASE_URL = 'https://www.joebrowns.co.uk/';
var THEME_PATH = 'https://www.joebrowns.co.uk/static/version1772100942/frontend/JoeBrowns/hyva/en_US';
var COOKIE_CONFIG = {
"expires": null,
"path": "\u002F",
"domain": ".www.joebrowns.co.uk",
"secure": true,
"lifetime": "2592000",
"cookie_restriction_enabled": false };
var CURRENT_STORE_CODE = 'GBP';
var CURRENT_WEBSITE_ID = '1';
window.hyva = window.hyva || {}
window.cookie_consent_groups = window.cookie_consent_groups || {}
window.cookie_consent_groups['necessary'] = true;
window.cookie_consent_config = window.cookie_consent_config || {};
window.cookie_consent_config['necessary'] = [].concat(
window.cookie_consent_config['necessary'] || [],
[
'user_allowed_save_cookie',
'form_key',
'mage-messages',
'private_content_version',
'mage-cache-sessid',
'last_visited_store',
'section_data_ids'
]
);
'use strict';
(function( hyva, undefined ) {
function lifetimeToExpires(options, defaults) {
const lifetime = options.lifetime || defaults.lifetime;
if (lifetime) {
const date = new Date;
date.setTime(date.getTime() + lifetime * 1000);
return date;
}
return null;
}
function generateRandomString() {
const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
length = 16;
let formKey = '',
charactersLength = allowedCharacters.length;
for (let i = 0; i < length; i++) {
formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))]
}
return formKey;
}
const sessionCookieMarker = {noLifetime: true}
const cookieTempStorage = {};
const internalCookie = {
get(name) {
const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return v ? v[2] : null;
},
set(name, value, days, skipSetDomain) {
let expires,
path,
domain,
secure,
samesite;
const defaultCookieConfig = {
expires: null,
path: '/',
domain: null,
secure: false,
lifetime: null,
samesite: 'lax'
};
const cookieConfig = window.COOKIE_CONFIG || {};
expires = days && days !== sessionCookieMarker
? lifetimeToExpires({lifetime: 24 * 60 * 60 * days, expires: null}, defaultCookieConfig)
: lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires;
path = cookieConfig.path || defaultCookieConfig.path;
domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain);
secure = cookieConfig.secure || defaultCookieConfig.secure;
samesite = cookieConfig.samesite || defaultCookieConfig.samesite;
document.cookie = name + "=" + encodeURIComponent(value) +
(expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') +
(path ? '; path=' + path : '') +
(domain ? '; domain=' + domain : '') +
(secure ? '; secure' : '') +
(samesite ? '; samesite=' + samesite : 'lax');
},
isWebsiteAllowedToSaveCookie() {
const allowedCookies = this.get('user_allowed_save_cookie');
if (allowedCookies) {
const allowedWebsites = JSON.parse(unescape(allowedCookies));
return allowedWebsites[CURRENT_WEBSITE_ID] === 1;
}
return false;
},
getGroupByCookieName(name) {
const cookieConsentConfig = window.cookie_consent_config || {};
let group = null;
for (let prop in cookieConsentConfig) {
if (!cookieConsentConfig.hasOwnProperty(prop)) continue;
if (cookieConsentConfig[prop].includes(name)) {
group = prop;
break;
}
}
return group;
},
isCookieAllowed(name) {
const cookieGroup = this.getGroupByCookieName(name);
return cookieGroup
? window.cookie_consent_groups[cookieGroup]
: this.isWebsiteAllowedToSaveCookie();
},
saveTempStorageCookies() {
for (const [name, data] of Object.entries(cookieTempStorage)) {
if (this.isCookieAllowed(name)) {
this.set(name, data['value'], data['days'], data['skipSetDomain']);
delete cookieTempStorage[name];
}
}
}
};
hyva.getCookie = (name) => {
const cookieConfig = window.COOKIE_CONFIG || {};
if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) {
return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null;
}
return internalCookie.get(name);
}
hyva.setCookie = (name, value, days, skipSetDomain) => {
const cookieConfig = window.COOKIE_CONFIG || {};
if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) {
cookieTempStorage[name] = {value, days, skipSetDomain};
return;
}
return internalCookie.set(name, value, days, skipSetDomain);
}
hyva.setSessionCookie = (name, value, skipSetDomain) => {
return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain)
}
hyva.getBrowserStorage = () => {
const browserStorage = window.localStorage || window.sessionStorage;
if (!browserStorage) {
console.warn('Browser Storage is unavailable');
return false;
}
try {
browserStorage.setItem('storage_test', '1');
browserStorage.removeItem('storage_test');
} catch (error) {
console.warn('Browser Storage is not accessible', error);
return false;
}
return browserStorage;
}
hyva.postForm = (postParams) => {
const form = document.createElement("form");
let data = postParams.data;
if (! postParams.skipUenc && ! data.uenc) {
data.uenc = btoa(window.location.href);
}
form.method = "POST";
form.action = postParams.action;
Object.keys(postParams.data).map(key => {
const field = document.createElement("input");
field.type = 'hidden'
field.value = postParams.data[key];
field.name = key;
form.appendChild(field);
});
const form_key = document.createElement("input");
form_key.type = 'hidden';
form_key.value = hyva.getFormKey();
form_key.name="form_key";
form.appendChild(form_key);
document.body.appendChild(form);
form.submit();
}
hyva.getFormKey = function () {
let formKey = hyva.getCookie('form_key');
if (!formKey) {
formKey = generateRandomString();
hyva.setCookie('form_key', formKey);
}
return formKey;
}
hyva.formatPrice = (value, showSign, options = {}) => {
const groupSeparator = options.groupSeparator;
const decimalSeparator = options.decimalSeparator
delete options.groupSeparator;
delete options.decimalSeparator;
const formatter = new Intl.NumberFormat(
'en\u002DUS',
Object.assign({
style: 'currency',
currency: 'GBP',
signDisplay: showSign ? 'always' : 'auto'
}, options)
);
return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ?
formatter.formatToParts(value).map(({type, value}) => {
switch (type) {
case 'currency':
return '\u00A3' || value;
case 'minusSign':
return '- ';
case 'plusSign':
return '+ ';
case 'group':
return groupSeparator !== undefined ? groupSeparator : value;
case 'decimal':
return decimalSeparator !== undefined ? decimalSeparator : value;
default :
return value;
}
}).reduce((string, part) => string + part) :
formatter.format(value);
}
const formatStr = function (str, nStart) {
const args = Array.from(arguments).slice(2);
return str.replace(/(%+)([0-9]+)/g, (m, p, n) => {
const idx = parseInt(n) - nStart;
if (args[idx] === null || args[idx] === void 0) {
return m;
}
return p.length % 2
? p.slice(0, -1).replace('%%', '%') + args[idx]
: p.replace('%%', '%') + n;
})
}
hyva.str = function (string) {
const args = Array.from(arguments);
args.splice(1, 0, 1);
return formatStr.apply(undefined, args);
}
hyva.strf = function () {
const args = Array.from(arguments);
args.splice(1, 0, 0);
return formatStr.apply(undefined, args);
}
/**
* Take a html string as `content` parameter and
* extract an element from the DOM to replace in
* the current page under the same selector,
* defined by `targetSelector`
*/
hyva.replaceDomElement = (targetSelector, content) => {
// Parse the content and extract the DOM node using the `targetSelector`
const parser = new DOMParser();
const doc = parser.parseFromString(content, 'text/html');
const contentNode = doc.querySelector(targetSelector);
// Bail if content or target can't be found
if (!contentNode || !document.querySelector(targetSelector)) {
return;
}
hyva.activateScripts(contentNode);
// Replace the old DOM node with the new content
document.querySelector(targetSelector).replaceWith(contentNode);
// Reload customerSectionData and display cookie-messages if present
window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
hyva.initMessages();
}
hyva.removeScripts = (contentNode) => {
const scripts = contentNode.getElementsByTagName('script');
for (let i = 0; i < scripts.length; i++) {
scripts[i].parentNode.removeChild(scripts[i]);
}
const templates = contentNode.getElementsByTagName('template');
for (let i = 0; i < templates.length; i++) {
const container = document.createElement('div');
container.innerHTML = templates[i].innerHTML;
hyva.removeScripts(container);
templates[i].innerHTML = container.innerHTML;
}
}
hyva.activateScripts = (contentNode) => {
// Create new array from HTMLCollection to avoid mutation of collection while manipulating the DOM.
const scripts = Array.from(contentNode.getElementsByTagName('script'));
// Iterate over all script tags to duplicate+inject each into the head
for (const original of scripts) {
const script = document.createElement('script');
original.type && (script.type = original.type);
script.innerHTML = original.innerHTML;
// Remove the original (non-executing) script from the contentNode
original.parentNode.removeChild(original)
// Add script to head
document.head.appendChild(script);
}
return contentNode;
}
const replace = {['+']: '-', ['/']: '_', ['=']: ','};
hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]);
let currentTrap;
const focusableElements = (rootElement) => {
const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]';
return Array.from(rootElement.querySelectorAll(selector))
.filter(el => {
return el.style.display !== 'none'
&& !el.disabled
&& el.tabIndex !== -1
&& (el.offsetWidth || el.offsetHeight || el.getClientRects().length)
})
}
const focusTrap = (e) => {
const isTabPressed = e.key === 'Tab' || e.keyCode === 9;
if (!isTabPressed) return;
const focusable = focusableElements(currentTrap)
const firstFocusableElement = focusable[0]
const lastFocusableElement = focusable[focusable.length - 1]
e.shiftKey
? document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault())
: document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault())
};
hyva.releaseFocus = (rootElement) => {
if (currentTrap && (!rootElement || rootElement === currentTrap)) {
currentTrap.removeEventListener('keydown', focusTrap)
currentTrap = null
}
}
hyva.trapFocus = (rootElement) => {
if (!rootElement) return;
hyva.releaseFocus()
currentTrap = rootElement
rootElement.addEventListener('keydown', focusTrap)
const firstElement = focusableElements(rootElement)[0]
firstElement && firstElement.focus()
}
hyva.safeParseNumber = (rawValue) => {
const number = rawValue ? parseFloat(rawValue) : null;
return Array.isArray(number) || isNaN(number) ? rawValue : number;
}
const toCamelCase = s => s.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
hyva.createBooleanObject = (name, value = false, additionalMethods = {}) => {
const camelCase = toCamelCase(name);
const key = '__hyva_bool_' + name
return new Proxy(Object.assign(
additionalMethods,
{
[key]: !!value,
[name]() {return !!this[key]},
['!' + name]() {return !this[key]}, // @deprecated This does not work with non-CSP Alpine
['not' + camelCase]() {return !this[key]},
['toggle' + camelCase]() {this[key] = !this[key]},
[`set${camelCase}True`]() {this[key] = true},
[`set${camelCase}False`]() {this[key] = false},
}
), {
set(target, prop, value) {
return prop === name
? (target[key] = !!value)
: Reflect.set(...arguments);
}
})
}
hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {once: true})
window.addEventListener('alpine:init', () => Alpine.data('{}', () => ({})), {once: true});
window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies())
}( window.hyva = window.hyva || {} ));
(function () {
'use strict';
const AUTOSUGGEST_MINIMUM_QUERY_LENGTH = 2;
const AUTOSUGGEST_TYPED_QUERY_TEMPLATE = '';
const COOKIE_NAME_SEGMENTATION_CDP_SEGMENTS = 'cdp_segments';
const COOKIE_NAME_SEGMENTATION_CUSTOMER_PROFILE = 'customer_profile';
const DEFAULT_CURRENCY = '$';
const DEFAULT_PAGE_SIZE = 16;
const DEFAULT_SEARCH_PARAMETER = 'q';
const DEFAULT_SORTING_OPTIONS = [{
label: 'Relevance',
value: ''
}, {
label: 'Price (low - high)',
value: 'price+asc'
}, {
label: 'Price (high - low)',
value: 'price+desc'
}, {
label: 'Name (A - Z)',
value: 'title+asc'
}, {
label: 'Name (Z - A)',
value: 'title+desc'
}];
const DEFAULT_START = 0;
const DEFAULT_WIDGETS_TO_DISPLAY = 4;
const FIELD_NAME_PRICE = 'price';
const MAX_COLOR_SWATCHES = 4;
const MAX_PAGINATION_NUMBER_BEFORE_CURRENT = 2;
const MAX_PAGINATION_NUMBER_AFTER_CURRENT = 2;
const NUMBER_OF_AUTOSUGGEST_COLLECTIONS = 8;
const NUMBER_OF_AUTOSUGGEST_PRODUCTS = 8;
const NUMBER_OF_AUTOSUGGEST_TERMS = 4;
const NUMBER_OF_FACET_GROUPS = 5;
const NUMBER_OF_FACET_VALUES = 6;
const PARAMETER_NAME_FACETS = 'fq';
const PARAMETER_NAME_FILTERS_PANEL = 'filterpanel';
const PARAMETER_NAME_GROUPBY = 'groupby';
const PARAMETER_NAME_PAGE = 'page';
const PARAMETER_NAME_SIZE = 'size';
const PARAMETER_NAME_SORT = 'sort';
const REQUEST_TYPE_SEARCH = 'search';
const REQUEST_TYPE_SUGGEST = 'suggest';
const SEARCH_TYPE_CATEGORY = 'category';
const SEARCH_TYPE_KEYWORD = 'keyword';
const SELECTOR_AUTOSUGGEST_INPUT = '.search__input';
const SELECTOR_SEARCH_RESULTS_CONTAINER = '.main-content';
/**
* This is the attribute name used to flag an element as an add to cart event
* generator, such as a butto or link.
*/
const ADD_TO_CART_ATTRIBUTE_NAME = 'data-blm-add-to-cart';
/**
* Attribute that should be applied to the element that has
* ADD_TO_CART_ATTRIBUTE_NAME added to it to populate the sku value sent in the
* pixel event.
*/
const ADD_TO_CART_ATTRIBUTE_SKU = 'data-blm-add-to-cart-sku';
/**
* Attribute that should be applied to the element that has
* ADD_TO_CART_ATTRIBUTE_NAME added to it to populate the prod_id value sent in
* the pixel event.
*/
const ADD_TO_CART_ATTRIBUTE_PROD_ID = 'data-blm-add-to-cart-prod-id';
/**
* Attribute that should be applied to the element that has
* ADD_TO_CART_ATTRIBUTE_NAME added to it to prevent emitting the pixel event.
*/
const ADD_TO_CART_ATTRIBUTE_DISABLE = 'data-blm-add-to-cart-disable';
const QUICKVIEW_ATTRIBUTE_NAME = 'data-blm-quickview';
const QUICKVIEW_ATTRIBUTE_SKU = 'data-blm-quickview-sku';
const QUICKVIEW_ATTRIBUTE_PROD_ID = 'data-blm-quickview-prod-id';
const QUICKVIEW_ATTRIBUTE_PROD_NAME = 'data-blm-quickview-prod-name';
var constants = /*#__PURE__*/Object.freeze({
__proto__: null,
AUTOSUGGEST_MINIMUM_QUERY_LENGTH: AUTOSUGGEST_MINIMUM_QUERY_LENGTH,
AUTOSUGGEST_TYPED_QUERY_TEMPLATE: AUTOSUGGEST_TYPED_QUERY_TEMPLATE,
COOKIE_NAME_SEGMENTATION_CDP_SEGMENTS: COOKIE_NAME_SEGMENTATION_CDP_SEGMENTS,
COOKIE_NAME_SEGMENTATION_CUSTOMER_PROFILE: COOKIE_NAME_SEGMENTATION_CUSTOMER_PROFILE,
DEFAULT_CURRENCY: DEFAULT_CURRENCY,
DEFAULT_PAGE_SIZE: DEFAULT_PAGE_SIZE,
DEFAULT_SEARCH_PARAMETER: DEFAULT_SEARCH_PARAMETER,
DEFAULT_SORTING_OPTIONS: DEFAULT_SORTING_OPTIONS,
DEFAULT_START: DEFAULT_START,
DEFAULT_WIDGETS_TO_DISPLAY: DEFAULT_WIDGETS_TO_DISPLAY,
FIELD_NAME_PRICE: FIELD_NAME_PRICE,
MAX_COLOR_SWATCHES: MAX_COLOR_SWATCHES,
MAX_PAGINATION_NUMBER_BEFORE_CURRENT: MAX_PAGINATION_NUMBER_BEFORE_CURRENT,
MAX_PAGINATION_NUMBER_AFTER_CURRENT: MAX_PAGINATION_NUMBER_AFTER_CURRENT,
NUMBER_OF_AUTOSUGGEST_COLLECTIONS: NUMBER_OF_AUTOSUGGEST_COLLECTIONS,
NUMBER_OF_AUTOSUGGEST_PRODUCTS: NUMBER_OF_AUTOSUGGEST_PRODUCTS,
NUMBER_OF_AUTOSUGGEST_TERMS: NUMBER_OF_AUTOSUGGEST_TERMS,
NUMBER_OF_FACET_GROUPS: NUMBER_OF_FACET_GROUPS,
NUMBER_OF_FACET_VALUES: NUMBER_OF_FACET_VALUES,
PARAMETER_NAME_FACETS: PARAMETER_NAME_FACETS,
PARAMETER_NAME_FILTERS_PANEL: PARAMETER_NAME_FILTERS_PANEL,
PARAMETER_NAME_GROUPBY: PARAMETER_NAME_GROUPBY,
PARAMETER_NAME_PAGE: PARAMETER_NAME_PAGE,
PARAMETER_NAME_SIZE: PARAMETER_NAME_SIZE,
PARAMETER_NAME_SORT: PARAMETER_NAME_SORT,
REQUEST_TYPE_SEARCH: REQUEST_TYPE_SEARCH,
REQUEST_TYPE_SUGGEST: REQUEST_TYPE_SUGGEST,
SEARCH_TYPE_CATEGORY: SEARCH_TYPE_CATEGORY,
SEARCH_TYPE_KEYWORD: SEARCH_TYPE_KEYWORD,
SELECTOR_AUTOSUGGEST_INPUT: SELECTOR_AUTOSUGGEST_INPUT,
SELECTOR_SEARCH_RESULTS_CONTAINER: SELECTOR_SEARCH_RESULTS_CONTAINER,
ADD_TO_CART_ATTRIBUTE_NAME: ADD_TO_CART_ATTRIBUTE_NAME,
ADD_TO_CART_ATTRIBUTE_SKU: ADD_TO_CART_ATTRIBUTE_SKU,
ADD_TO_CART_ATTRIBUTE_PROD_ID: ADD_TO_CART_ATTRIBUTE_PROD_ID,
ADD_TO_CART_ATTRIBUTE_DISABLE: ADD_TO_CART_ATTRIBUTE_DISABLE,
QUICKVIEW_ATTRIBUTE_NAME: QUICKVIEW_ATTRIBUTE_NAME,
QUICKVIEW_ATTRIBUTE_SKU: QUICKVIEW_ATTRIBUTE_SKU,
QUICKVIEW_ATTRIBUTE_PROD_ID: QUICKVIEW_ATTRIBUTE_PROD_ID,
QUICKVIEW_ATTRIBUTE_PROD_NAME: QUICKVIEW_ATTRIBUTE_PROD_NAME
});
const globalBloomreachModules = Object.assign(Object.assign({}, window.BloomreachModules ? window.BloomreachModules : {}), {
version: '4.0.0',
constants
});
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function getAugmentedNamespace(n) {
var f = n.default;
if (typeof f == "function") {
var a = function () {
return f.apply(this, arguments);
};
a.prototype = f.prototype;
} else a = {};
Object.defineProperty(a, '__esModule', {value: true});
Object.keys(n).forEach(function (k) {
var d = Object.getOwnPropertyDescriptor(n, k);
Object.defineProperty(a, k, d.get ? d : {
enumerable: true,
get: function () {
return n[k];
}
});
});
return a;
}
var ejs = {};
var _polyfillNode_fs = {};
var _polyfillNode_fs$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
'default': _polyfillNode_fs
});
var require$$0 = /*@__PURE__*/getAugmentedNamespace(_polyfillNode_fs$1);
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last === '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var splitPath = function(filename) {
return splitPathRe.exec(filename).slice(1);
};
// path.resolve([from ...], to)
// posix version
function resolve() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : '/';
// Skip empty and invalid entries
if (typeof path !== 'string') {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
}
// path.normalize(path)
// posix version
function normalize(path) {
var isPathAbsolute = isAbsolute(path),
trailingSlash = substr(path, -1) === '/';
// Normalize the path
path = normalizeArray(filter(path.split('/'), function(p) {
return !!p;
}), !isPathAbsolute).join('/');
if (!path && !isPathAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isPathAbsolute ? '/' : '') + path;
}
// posix version
function isAbsolute(path) {
return path.charAt(0) === '/';
}
// posix version
function join() {
var paths = Array.prototype.slice.call(arguments, 0);
return normalize(filter(paths, function(p, index) {
if (typeof p !== 'string') {
throw new TypeError('Arguments to path.join must be strings');
}
return p;
}).join('/'));
}
// path.relative(from, to)
// posix version
function relative(from, to) {
from = resolve(from).substr(1);
to = resolve(to).substr(1);
function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}
var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split('/'));
var toParts = trim(to.split('/'));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('/');
}
var sep = '/';
var delimiter = ':';
function dirname(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
// No dirname whatsoever
return '.';
}
if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substr(0, dir.length - 1);
}
return root + dir;
}
function basename(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
}
function extname(path) {
return splitPath(path)[3];
}
var _polyfillNode_path = {
extname: extname,
basename: basename,
dirname: dirname,
sep: sep,
delimiter: delimiter,
relative: relative,
join: join,
isAbsolute: isAbsolute,
normalize: normalize,
resolve: resolve
};
function filter (xs, f) {
if (xs.filter) return xs.filter(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
if (f(xs[i], i, xs)) res.push(xs[i]);
}
return res;
}
// String.prototype.substr - negative index don't work in IE8
var substr = 'ab'.substr(-1) === 'b' ?
function (str, start, len) { return str.substr(start, len) } :
function (str, start, len) {
if (start < 0) start = str.length + start;
return str.substr(start, len);
}
;
var _polyfillNode_path$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
resolve: resolve,
normalize: normalize,
isAbsolute: isAbsolute,
join: join,
relative: relative,
sep: sep,
delimiter: delimiter,
dirname: dirname,
basename: basename,
extname: extname,
'default': _polyfillNode_path
});
var require$$1 = /*@__PURE__*/getAugmentedNamespace(_polyfillNode_path$1);
var utils = {};
/*
* EJS Embedded JavaScript templates
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
(function (exports) {
var regExpChars = /[|\\{}()[\]^$+*?.]/g;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var hasOwn = function (obj, key) { return hasOwnProperty.apply(obj, [key]); };
/**
* Escape characters reserved in regular expressions.
*
* If `string` is `undefined` or `null`, the empty string is returned.
*
* @param {String} string Input string
* @return {String} Escaped string
* @static
* @private
*/
exports.escapeRegExpChars = function (string) {
// istanbul ignore if
if (!string) {
return '';
}
return String(string).replace(regExpChars, '\\$&');
};
var _ENCODE_HTML_RULES = {
'&': '&',
'': '>',
'"': '"',
"'": '''
};
var _MATCH_HTML = /[&'"]/g;
function encode_char(c) {
return _ENCODE_HTML_RULES[c] || c;
}
/**
* Stringified version of constants used by {@link module:utils.escapeXML}.
*
* It is used in the process of generating {@link ClientFunction}s.
*
* @readonly
* @type {String}
*/
var escapeFuncStr =
'var _ENCODE_HTML_RULES = {\n'
+ ' "&": "&"\n'
+ ' , "": ">"\n'
+ ' , \'"\': """\n'
+ ' , "\'": "'"\n'
+ ' }\n'
+ ' , _MATCH_HTML = /[&\'"]/g;\n'
+ 'function encode_char(c) {\n'
+ ' return _ENCODE_HTML_RULES[c] || c;\n'
+ '};\n';
/**
* Escape characters reserved in XML.
*
* If `markup` is `undefined` or `null`, the empty string is returned.
*
* @implements {EscapeCallback}
* @param {String} markup Input string
* @return {String} Escaped string
* @static
* @private
*/
exports.escapeXML = function (markup) {
return markup == undefined
? ''
: String(markup)
.replace(_MATCH_HTML, encode_char);
};
exports.escapeXML.toString = function () {
return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr;
};
/**
* Naive copy of properties from one object to another.
* Does not recurse into non-scalar properties
* Does not check to see if the property has a value before copying
*
* @param {Object} to Destination object
* @param {Object} from Source object
* @return {Object} Destination object
* @static
* @private
*/
exports.shallowCopy = function (to, from) {
from = from || {};
if ((to !== null) && (to !== undefined)) {
for (var p in from) {
if (!hasOwn(from, p)) {
continue;
}
if (p === '__proto__' || p === 'constructor') {
continue;
}
to[p] = from[p];
}
}
return to;
};
/**
* Naive copy of a list of key names, from one object to another.
* Only copies property if it is actually defined
* Does not recurse into non-scalar properties
*
* @param {Object} to Destination object
* @param {Object} from Source object
* @param {Array} list List of properties to copy
* @return {Object} Destination object
* @static
* @private
*/
exports.shallowCopyFromList = function (to, from, list) {
list = list || [];
from = from || {};
if ((to !== null) && (to !== undefined)) {
for (var i = 0; i < list.length; i++) {
var p = list[i];
if (typeof from[p] != 'undefined') {
if (!hasOwn(from, p)) {
continue;
}
if (p === '__proto__' || p === 'constructor') {
continue;
}
to[p] = from[p];
}
}
}
return to;
};
/**
* Simple in-process cache implementation. Does not implement limits of any
* sort.
*
* @implements {Cache}
* @static
* @private
*/
exports.cache = {
_data: {},
set: function (key, val) {
this._data[key] = val;
},
get: function (key) {
return this._data[key];
},
remove: function (key) {
delete this._data[key];
},
reset: function () {
this._data = {};
}
};
/**
* Transforms hyphen case variable into camel case.
*
* @param {String} string Hyphen case string
* @return {String} Camel case string
* @static
* @private
*/
exports.hyphenToCamel = function (str) {
return str.replace(/-[a-z]/g, function (match) { return match[1].toUpperCase(); });
};
/**
* Returns a null-prototype object in runtimes that support it
*
* @return {Object} Object, prototype will be set to null where possible
* @static
* @private
*/
exports.createNullProtoObjWherePossible = (function () {
if (typeof Object.create == 'function') {
return function () {
return Object.create(null);
};
}
if (!({__proto__: null} instanceof Object)) {
return function () {
return {__proto__: null};
};
}
// Not possible, just pass through
return function () {
return {};
};
})();
} (utils));
var name = "ejs";
var description = "Embedded JavaScript templates";
var keywords = [
"template",
"engine",
"ejs"
];
var version = "3.1.8";
var author = "Matthew Eernisse (http://fleegix.org)";
var license = "Apache-2.0";
var bin = {
ejs: "./bin/cli.js"
};
var main = "./lib/ejs.js";
var jsdelivr = "ejs.min.js";
var unpkg = "ejs.min.js";
var repository = {
type: "git",
url: "git://github.com/mde/ejs.git"
};
var bugs = "https://github.com/mde/ejs/issues";
var homepage = "https://github.com/mde/ejs";
var dependencies = {
jake: "^10.8.5"
};
var devDependencies = {
browserify: "^16.5.1",
eslint: "^6.8.0",
"git-directory-deploy": "^1.5.1",
jsdoc: "^3.6.7",
"lru-cache": "^4.0.1",
mocha: "^7.1.1",
"uglify-js": "^3.3.16"
};
var engines = {
node: ">=0.10.0"
};
var scripts = {
test: "mocha"
};
var require$$3 = {
name: name,
description: description,
keywords: keywords,
version: version,
author: author,
license: license,
bin: bin,
main: main,
jsdelivr: jsdelivr,
unpkg: unpkg,
repository: repository,
bugs: bugs,
homepage: homepage,
dependencies: dependencies,
devDependencies: devDependencies,
engines: engines,
scripts: scripts
};
/*
* EJS Embedded JavaScript templates
* Copyright 2112 Matthew Eernisse (mde@fleegix.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
(function (exports) {
/**
* @file Embedded JavaScript templating engine. {@link http://ejs.co}
* @author Matthew Eernisse
* @author Tiancheng "Timothy" Gu
* @project EJS
* @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0}
*/
/**
* EJS internal functions.
*
* Technically this "module" lies in the same file as {@link module:ejs}, for
* the sake of organization all the private functions re grouped into this
* module.
*
* @module ejs-internal
* @private
*/
/**
* Embedded JavaScript templating engine.
*
* @module ejs
* @public
*/
var fs = require$$0;
var path = require$$1;
var utils$1 = utils;
var scopeOptionWarned = false;
/** @type {string} */
var _VERSION_STRING = require$$3.version;
var _DEFAULT_OPEN_DELIMITER = '';
var _DEFAULT_DELIMITER = '%';
var _DEFAULT_LOCALS_NAME = 'locals';
var _NAME = 'ejs';
var _REGEX_STRING = '(|');
var self = this;
var matches = this.parseTemplateText();
var d = this.opts.delimiter;
var o = this.opts.openDelimiter;
var c = this.opts.closeDelimiter;
if (matches && matches.length) {
matches.forEach(function (line, index) {
var closing;
// If this is an opening tag, check for closing tags
// FIXME: May end up with some false positives here
// Better to store modes as k/v with openDelimiter + delimiter as key
// Then this can simply check against the map
if ( line.indexOf(o + d) === 0 // If it is a tag
&& line.indexOf(o + d + d) !== 0) { // and is not escaped
closing = matches[index + 2];
if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) {
throw new Error('Could not find matching close tag for "' + line + '".');
}
}
self.scanLine(line);
});
}
},
parseTemplateText: function () {
var str = this.templateText;
var pat = this.regex;
var result = pat.exec(str);
var arr = [];
var firstPos;
while (result) {
firstPos = result.index;
if (firstPos !== 0) {
arr.push(str.substring(0, firstPos));
str = str.slice(firstPos);
}
arr.push(result[0]);
str = str.slice(result[0].length);
result = pat.exec(str);
}
if (str) {
arr.push(str);
}
return arr;
},
_addOutput: function (line) {
if (this.truncate) {
// Only replace single leading linebreak in the line after
// -%> tag -- this is the single, trailing linebreak
// after the tag that the truncation mode replaces
// Handle Win / Unix / old Mac linebreaks -- do the \r\n
// combo first in the regex-or
line = line.replace(/^(?:\r\n|\r|\n)/, '');
this.truncate = false;
}
if (!line) {
return line;
}
// Preserve literal slashes
line = line.replace(/\\/g, '\\\\');
// Convert linebreaks
line = line.replace(/\n/g, '\\n');
line = line.replace(/\r/g, '\\r');
// Escape double-quotes
// - this will be the delimiter during execution
line = line.replace(/"/g, '\\"');
this.source += ' ; __append("' + line + '")' + '\n';
},
scanLine: function (line) {
var self = this;
var d = this.opts.delimiter;
var o = this.opts.openDelimiter;
var c = this.opts.closeDelimiter;
var newLineCount = 0;
newLineCount = (line.split('\n').length - 1);
switch (line) {
case o + d:
case o + d + '_':
this.mode = Template.modes.EVAL;
break;
case o + d + '=':
this.mode = Template.modes.ESCAPED;
break;
case o + d + '-':
this.mode = Template.modes.RAW;
break;
case o + d + '#':
this.mode = Template.modes.COMMENT;
break;
case o + d + d:
this.mode = Template.modes.LITERAL;
this.source += ' ; __append("' + line.replace(o + d + d, o + d) + '")' + '\n';
break;
case d + d + c:
this.mode = Template.modes.LITERAL;
this.source += ' ; __append("' + line.replace(d + d + c, d + c) + '")' + '\n';
break;
case d + c:
case '-' + d + c:
case '_' + d + c:
if (this.mode == Template.modes.LITERAL) {
this._addOutput(line);
}
this.mode = null;
this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0;
break;
default:
// In script mode, depends on type of tag
if (this.mode) {
// If '//' is found without a line break, add a line break.
switch (this.mode) {
case Template.modes.EVAL:
case Template.modes.ESCAPED:
case Template.modes.RAW:
if (line.lastIndexOf('//') > line.lastIndexOf('\n')) {
line += '\n';
}
}
switch (this.mode) {
// Just executing code
case Template.modes.EVAL:
this.source += ' ; ' + line + '\n';
break;
// Exec, esc, and output
case Template.modes.ESCAPED:
this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\n';
break;
// Exec and output
case Template.modes.RAW:
this.source += ' ; __append(' + stripSemi(line) + ')' + '\n';
break;
case Template.modes.COMMENT:
// Do nothing
break;
// Literal cookie.startsWith('_br_uid_2='));
return trackingCookie ? trackingCookie.replace('_br_uid_2=', '') : 'uid%3D7797686432023%3Av%3D11.5%3Ats%3D1428617911187%3Ahc%3D55';
}
// utils/formatAsCurrency.ts
/**
* Formats a value returned as a double into currency
* @param {number} cents
* @param {string} currencySign
* @param {boolean} onFront
* @returns {string}
*/
const formatAsCurrency = (cents, currencySign = '$', onFront = true) => `${onFront ? currencySign : ''}${(cents / 100.0).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
})}${!onFront ? ` ${currencySign}` : ''}`;
// utils/generateRequestID.ts
/**
* Generates a randomized request ID that is 13 characters long
* @returns {number}
*/
function generateRequestId() {
// eslint-disable-next-line no-mixed-operators
const requestID = Math.floor(1000000000000 + Math.random() * 9000000000000);
return requestID;
}
// api-client/constants
// todo Refactor vanilla js / react implementation to either use or not use the constants config
const ENDPOINT_AUTOSUGGEST_API = 'https://suggest.dxpapi.com/api/v2/suggest/';
const NO_ENCODE_PARAMETERS = ['_br_uid_2', 'fq', 'sort'];
function buildQueryParameters(apiCallParameters) {
return `?${Object.keys(apiCallParameters).reduce((queryParameters, parameterName) => [...queryParameters, `${parameterName}=${NO_ENCODE_PARAMETERS.includes(parameterName) ? apiCallParameters[parameterName] : encodeURIComponent(apiCallParameters[parameterName])}`], []).join('&')}`;
}
function buildAutosuggestRequestUrl(parameters) {
const apiParameters = Object.assign({}, parameters);
const endpoint = (apiParameters === null || apiParameters === void 0 ? void 0 : apiParameters.endpoint) || ENDPOINT_AUTOSUGGEST_API;
if (apiParameters === null || apiParameters === void 0 ? void 0 : apiParameters.endpoint) apiParameters === null || apiParameters === void 0 ? true : delete apiParameters.endpoint;
return `${endpoint}${buildQueryParameters(apiParameters)}`;
}
/**
* Get suggestions API
* @returns {Promise}
*/
async function getSuggestions(params) {
const url = buildAutosuggestRequestUrl(params);
const options = requestOptions;
return getRequest(url, options);
}
var searchLayoutTemplate = "\n \n \n Results for\n \n \n \n \n \n instead of
[H1] Results for
[H2] Welcome to
[H2] Shop Women's & Men's By Category
[H2] Best Sellers
[H2] Discover More
[H2] Give a Remarkable Gift
[H2] Inspiration & Ideas
[H2] \n Showing - of products\n
[H2] \n No results found\n
[H3] Orders & Returns
[H3] Customer Info
[H3] Company Info
[H3] Request A Free Catalogue
[H3]
[H4] Filters
[H4] Price
[H4]
Bilder
Es konnten 64 Bilder auf dieser Webseite gefunden werden.
Auf indystar.de fehlen bei 21 von 64 Bilddateien ALT-Attribute. Beschreibende Alternativtexte helfen Suchmaschinen und verbessern zugleich die Zugänglichkeit der Seite.
Text/HTML Verhältnis
Anteil : 3%
indystar.de hat mit 3% einen sehr niedrigen Textanteil. Die Seite sollte mehr nutzbaren Inhalt erhalten, damit Suchmaschinen nicht nur Code, Navigation oder Gestaltungselemente sehen.
Flash
indystar.de verzichtet auf Flash-Inhalte. Dadurch bleibt die Seite technisch zeitgemäßer und für Nutzer wie Suchmaschinen leichter zugänglich.
IFrame
indystar.de nutzt IFrames. Prüfen Sie, ob wichtige Inhalte direkt auf der Seite ausgegeben werden können, damit sie besser indexierbar und unabhängiger von externen Quellen sind.
SEO Links
Eine klare Linkstruktur erleichtert Suchmaschinen das Crawlen, verteilt interne Relevanz und hilft Besuchern, wichtige Inhalte schnell zu finden.
URL Rewrite
Bei indystar.de sind nicht alle URLs sauber lesbar. Wenn möglich, sollten technische Parameter durch sprechende Pfade ersetzt werden.
Underscores in the URLs
indystar.de enthält URLs mit Unterstrichen. Eine Umstellung auf Bindestriche kann die Trennung einzelner Begriffe deutlicher machen.
In-page links
We found a total of 216 links including 1 link(s) to files
Die Suchbegriffsauswertung zeigt, welche Themen die Seite tatsächlich vermittelt und ob wichtige Begriffe in Inhalt und Seitenelementen konsistent vorkommen.
Gute Benutzerfreundlichkeit stärkt Vertrauen und erleichtert die Nutzung. Geprüft werden unter anderem URL, Favicon, Sprache und Druckdarstellung.
URL
Domain : indystar.de
Länge : 11
Favoriten Icon
indystar.de stellt ein Favicon bereit. Dieses kleine Symbol verbessert Wiedererkennung in Browser-Tabs, Lesezeichen und Suchergebnisumgebungen.
Druckeigenschaften
Für indystar.de wurden Print-Styles erkannt. Dadurch kann die Seite beim Drucken sauberer und ressourcenschonender dargestellt werden.
Sprache
indystar.de deklariert die Sprache als en. Das hilft Browsern, Suchmaschinen und Hilfstechnologien bei Aussprache, Darstellung und regionaler Einordnung.
Dublin Core
Bei indystar.de wurden keine Dublin-Core-Elemente gefunden. Das ist nicht für jede Website zwingend, kann aber bei dokumentenartigen oder redaktionellen Inhalten nützlich sein.
Dokument
Sauberes HTML, eine korrekte Zeichencodierung und moderne Standards verbessern Kompatibilität, Zugänglichkeit und die zuverlässige Verarbeitung der Seite.
Doctype
HTML 5
Verschlüsselung
Der Zeichensatz von indystar.de ist angegeben: UTF-8. Dadurch sinkt das Risiko fehlerhafter Zeichenanzeige in Browsern und Auswertungssystemen.
W3C Validität
Fehler : 0
Warnungen : 0
E-Mail Datenschutz
Auf indystar.de wurde mindestens eine E-Mail-Adresse im Klartext gefunden. Solche Angaben können von Bots gesammelt werden. Mit diesem kostenlosen Werkzeug lassen sich Adressen besser schützen.
Veraltetes HTML
Veraltete Tags
Vorkommen
<u>
4
<strike>
2
Bei indystar.de wurden veraltete HTML-Tags gefunden. Diese funktionieren zwar oft noch, sollten aber durch aktuelle HTML-Elemente ersetzt werden, damit die Seite langfristig stabil bleibt.
Tipps zur Webseitengeschwindigkeit
Bei indystar.de wurden keine verschachtelten Tabellen erkannt. Das ist positiv für sauberes Markup und responsive Gestaltung.
indystar.de nutzt CSS direkt in HTML-Elementen. Eine Auslagerung in CSS-Dateien kann den Quelltext übersichtlicher und besser wartbar machen.
indystar.de verwendet mit 6 CSS-Dateien eine überschaubare Stylesheet-Struktur. Das kann Ladezeit und Wartung positiv beeinflussen.
indystar.de verwendet 16 JavaScript-Dateien und liegt damit über dem Richtwert von 12. Weniger Skripte oder gebündelte Dateien können die Ladezeit verbessern.
indystar.de nutzt gzip-Komprimierung. Dadurch können HTML, CSS und JavaScript kleiner übertragen werden, was die Ladezeit verbessern kann.
Mobile
Mobile Optimierung ist wichtig, weil viele Besucher Smartphones nutzen. Viewport, Icons und ungeeignete Technologien beeinflussen Darstellung und Bedienbarkeit.
Mobile Optimierung
Apple Icon
META Viewport Tag
Flash Inhalt
Optimierung
Sitemap, robots.txt, Komprimierung und Analysesysteme beeinflussen, wie effizient eine Website gecrawlt, ausgeliefert und gezielt weiterentwickelt werden kann.
XML-Sitemap
Eine XML-Sitemap ist für indystar.de vorhanden. Sie unterstützt Crawler dabei, die Seitenstruktur effizienter zu verstehen.
https://www.joebrowns.co.uk/media/sitemap.xml
Robots.txt
http://indystar.de/robots.txt
Eine robots.txt ist für indystar.de vorhanden. Das ist die richtige Stelle, um Suchmaschinen den Umgang mit bestimmten Bereichen der Website zu erklären.
Analytics
Fehlt
Für indystar.de wurde kein Analyse-Tool erkannt. Ohne Webanalyse bleibt schwer nachvollziehbar, wie Besucher die Seite tatsächlich nutzen.
PageSpeed Insights
PageSpeed Insights bewertet Leistung, Barrierefreiheit, bewährte Verfahren und SEO für Desktop und Mobilgeräte und macht technische Bremsen sichtbar.
Gerät
Kategorien
Website-Überprüfung
Website-Überprüfung ist ein kostenloses SEO Werkzeug zur Analyse Ihrer Webseite