<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Ján Regeš, https://www.siteone.io/">
<title>SiteOne Crawler Report - {$initialHost} | {$executedAt}</title>
<style>
:root {
--color-white: #fff;
--color-black: #000000;
--color-gray-50: #f9fafb;
--color-gray-100: #eeecec;
--color-gray-200: #E5E7EB;
--color-gray-300: #D1D5DB;
--color-gray-400: #9CA3AF;
--color-gray-500: #6B7280;
--color-gray-600: #4B5563;
--color-gray-700: #374151;
--color-gray-800: #1F2937;
--color-gray-900: #111827;
--color-gray-950: rgb(9, 15, 32);
--color-blue-100: #DBEAFE;
--color-blue-500: #3B82F6;
--color-blue-600: #2563EB;
--color-blue-950: rgb(23, 37, 84);
--text-color-default: var(--color-gray-900);
--text-color-neutral: var(--color-gray-300);
--text-color-blue: var(--color-blue-500);
--text-color-blue-dark: var(--color-blue-600);
--background-color-default: var(--color-white);
--background-color-neutral: var(--color-gray-100);
--border-radius: 1.5rem;
--padding-inline: 2rem;
}
html * {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
width: 100%;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: var(--background-color-neutral);
color: var(--text-color-default);
transition: background-color 0.2s ease-out, color 0.2s ease-out;
}
main {
display: flex;
flex-direction: column;
gap: 2rem;
}
section {
background-color: var(--background-color-default);
padding: 2rem var(--padding-inline);
border-radius: var(--border-radius);
transition: background-color 0.2s ease-out;
}
body h2 {
margin-top: 0;
}
body a {
color: var(--text-color-default);
transition: color 0.2s ease-out;
}
table {
border-collapse: collapse;
min-width: 300px;
}
table.table-compact {
font-size: 0.7em;
}
table,
table th,
table td {
border: 1px solid var(--color-gray-100);
padding: 2px 4px !important;
vertical-align: top;
text-align: left;
transition: border-color 0.2s ease-out, background-color 0.2s ease-out;
}
table td.warning {
text-align: center;
color: var(--text-color-neutral);
}
table td svg {
max-width: 100px;
max-height: 18px;
}
.table-sortable th {
cursor: pointer;
}
html:has(.theme-switch__input:checked) table,
html:has(.theme-switch__input:checked) table td,
html:has(.theme-switch__input:checked) table th {
border-color: var(--background-color-neutral);
}
table th {
background-color: var(--background-color-neutral);
}
html:has(.theme-switch__input:checked) table th {
background-color: var(--background-color-neutral);
}
table th table.table-two-col th {
width: 20%;
}
.container {
display: flex;
flex-direction: column;
gap: 2rem;
max-width: 187.5rem;
margin: 0 auto;
padding: 1.5rem 4rem;
}
header.header {
display: flex;
align-items: center;
justify-content: space-between;
background-color: var(--background-color-default);
padding-inline: var(--padding-inline);
padding-block: 2rem;
border-radius: 1000px;
border: 1px solid var(--color-gray-100);
transition: background-color 0.2s ease-out, border-color 0.2s ease-out;
}
header.header a.logo {
display: flex;
}
header.header h1 {
margin: 0;
}
html:has(.theme-switch__input:checked) .body {
--text-color-default: var(--color-gray-200);
--text-color-neutral: var(--color-gray-600);
--background-color-default: var(--color-gray-900);
--background-color-neutral: var(--color-gray-800);
}
html:has(.theme-switch__input:checked) header.header {
border-color: transparent;
}
.theme-switch__dot--light {
transform: translateX(0rem);
}
html:has(.theme-switch__input:checked) .theme-switch__dot{
transform: translateX(2rem);
background-color: var(--color-gray-300);
}
.theme-switch label {
display: flex;
align-items: center;
gap: .375rem;
cursor: pointer;
}
.theme-switch__wrapper {
display: flex;
align-items: center;
position: relative;
border-radius: var(--border-radius);
background-color: var(--color-gray-300);
width: 4rem;
height: 2rem;
transition: all 0.2s ease-out;
}
html:has(.theme-switch__input:checked) .theme-switch__wrapper {
background-color: var(--color-gray-600);
}
.theme-switch__input {
display: none;
}
.theme-switch__dot {
position: absolute;
height: 1.5rem;
width: 1.5rem;
left: .25rem;
background-color: var(--color-gray-600);
border-radius: 50%;
transition: all .2s ease-out;
}
.theme-switch__dot--light {
transform: translateX(0rem);
}
.theme-switch__dot--dark {
transform: translateX(2rem);
background-color: var(--color-gray-300);
}
.info__wrapper {
overflow-x: auto;
}
.summary ul {
padding-left: 20px;
}
.tabs {
display: grid;
grid-template-columns: minmax(0, 18.225rem) 1fr;
gap: 2rem;
}
.tabs__navigation {
display: flex;
flex-direction: column;
gap: 0.5rem;
border-right: 1px solid var(--color-gray-700);
padding-right: 2rem;
}
.tabs__radio {
display: none;
}
.tabs__tab {
display: none;
}
.tabs__content {
overflow: auto;
font-size: 0.8em;
}
.tabs__content ul {
padding-left: 0px;
}
.tabs__content ul li {
list-style: none;
}
.tabs__title {
margin: 0;
font-size: 1rem;
padding: .5rem .75rem;
background-color: var(--background-color-neutral);
border-radius: var(--border-radius);
transition: background-color .2s ease-out;
cursor: pointer;
}
.tabs__title:hover {
background-color: var(--color-blue-500);
color: var(--color-white);
}
html:has(.theme-switch__input:checked) .tabs__title {
background-color: var(--background-color-neutral);
}
html:has(.theme-switch__input:checked) .tabs__title:hover {
background-color: var(--color-blue-600);
color: var(--color-white);
}
.tabs__table {
border-radius: var(--border-radius);
font-size: 0.875rem;
}
.badge {
display: inline-block;
padding: 2px 4px;
color: var(--color-white);
border-radius: 8px;
font-size: 0.75rem;
line-height: 1;
min-width: 18px;
text-align: center;
}
html:has(.theme-switch__input:checked) .badge {
color: var(--color-white);
}
.badge.red {
background-color: #e3342f;
}
.badge.green {
background-color: #38c172;
}
.badge.blue {
background-color: #3490dc;
}
.badge.orange {
background-color: #ff9234;
}
.badge.yellow {
background-color: #ffed4a;
color: var(--color-gray-800) !important;
}
.badge.neutral {
background-color: #9ba7b4;
}
html:has(.theme-switch__input:checked) .badge.neutral {
background-color: #718096;
}
.badge.in-table {
background-color: var(--background-color-neutral);
}
.fulltext-container {
display: none;
margin-bottom: 8px;
}
.fulltext-container .found-rows {
margin-bottom: 8px;
}
.js-enabled .fulltext-container {
display: block;
}
input.fulltext {
width: 100%;
padding: 0.4rem;
border-radius: 2px;
border: 1px solid var(--background-color-neutral);
background-color: var(--background-color-default);
color: var(--text-color-blue);
transition: border-color 0.2s ease-out;
margin-right: 8px;
}
input.fulltext:focus, input.fulltext:focus-visible {
outline: none;
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1);
border-color: var(--background-color-neutral) !important;
}
table tr.empty-fulltext {
display: none;
}
::placeholder {
color: var(--text-color-neutral);
opacity: 1;
}
::-ms-input-placeholder {
color: var(--text-color-neutral);
}
@media screen and (max-width: 64rem) {
main {
gap: 2.5rem;
}
h1 {
font-size: 1.25rem;
}
.container {
padding: 2.5rem;
}
.tabs {
grid-template-columns: 1fr;
}
.tabs__navigation {
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
padding: 0;
border: none;
text-align: center;
}
.tabs__tab {
justify-content: center;
}
}
@media screen and (max-width: 40rem) {
:root {
--padding-inline: 1rem;
}
main {
gap: 2rem;
}
h1 {
font-size: 1.25rem;
text-align: center;
}
h2 {
font-size: 1.125rem;
}
.container {
padding: 1.25rem;
gap: 2rem;
}
header.header {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto;
gap: 1rem;
padding-block: 1.5rem;
border-radius: var(--border-radius);
}
header.header .theme-switch {
justify-self: end;
}
header.header h1 {
grid-row: 2;
grid-column: 1 / 3;
}
.tabs__title {
font-size: .875rem;
padding: .25rem .5rem;
}
}
table.seo-headings td ul {
margin: 0;
}
table.seo-headings td ul ul {
padding-left: 20px;
}
table.seo-headings td ul li {
list-style: none;
}
table.seo-headings td.headings .badge {
text-align: left;
background-color: transparent;
color: #ff9234 !important;
}
.table-container.show-more {
display: block;
max-height: 658px !important;
overflow: hidden;
transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);
}
.show-more-label {
display: block;
cursor: pointer;
text-align: left;
padding: 10px 50px 10px 0;
color: var(--color-blue-600);
}
.show-more-checkbox {
display: none;
}
.show-more-checkbox:checked ~ .table-container.show-more {
transition: max-height 1s ease;
max-height: none !important;
}
.show-more-checkbox:checked ~ .show-more-label {
display: none;
}
table tr td.urlPathAndQuery, table tr td.url {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
table tr td.urlPathAndQuery {
max-width: 300px;
}
table.large-inline-svgs tr td.detail, table.duplicate-inline-svgs tr td.detail, table.invalid-inline-svgs tr td.detail {
min-width: 150px;
}
table.large-inline-svgs tr td.detail svg, table.duplicate-inline-svgs tr td.detail svg, table.invalid-inline-svgs tr td.detail svg {
float: right;
}
table tr td.header {
min-width: 120px;
white-space: nowrap;
}
td.status, td.type, td.time, td.size {
white-space: nowrap;
}
.text-muted {
color: var(--color-gray-600);
}
.help {
cursor: help;
}
.form-group {
flex-grow: 0;
flex-basis: auto;
}
.btn-group {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
gap: 1px;
border: 0;
}
.btn-group label {
padding: 3px 6px;
cursor: pointer;
background-color: var(--background-color-neutral);
color: var(--text-color-default);
transition: background-color 0.3s, color 0.3s;
white-space: nowrap;
z-index: 1000;
}
.btn-group label:hover,
.btn-group input[type="radio"]:checked + label {
background-color: var(--color-blue-600);
color: var(--color-white);
}
.btn-group input[type="radio"] {
display: none;
}
.btn-group label:first-of-type {
border-radius: 4px 0 0 4px;
}
.btn-group label:last-of-type {
border-radius: 0 4px 4px 0;
}
.btn {
padding: 0.5rem 1rem;
border-radius: 1rem;
border: 0;
background-color: var(--color-blue-600);
color: var(--color-white);
cursor: pointer;
margin-bottom: 1rem;
}
.image-gallery {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.image-gallery img {
object-fit: contain;
transition: transform 0.3s ease;
cursor: help;
}
.small .image-gallery img {
max-width: 140px;
max-height: 140px;
}
.medium .image-gallery img {
max-width: 200px;
max-height: 200px;
}
.large .image-gallery img {
max-width: 360px;
max-height: 360px;
}
.cover .image-gallery img {
object-fit: cover;
}
.contain .image-gallery img {
object-fit: contain;
}
.scaleDown .image-gallery img {
object-fit: scale-down;
}
.image-gallery img:hover {
transform: scale(1.3);
z-index: -1000;
}
.image-gallery .highlighted {
border: 2px solid red;
padding: 4px;
box-sizing: border-box;
}
.video-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.video-card {
display: flex;
flex-direction: column;
border: 1px solid var(--background-color-default);
padding: 10px;
background-color: var(--background-color-neutral);
box-sizing: border-box;
min-width: 400px;
flex: 1 1 400px;
}
.video-card video {
min-width: 100%;
min-height: 300px;
}
.video-caption {
margin-top: 10px;
text-align: center;
font-size: 14px;
color: var(--text-color-default);
flex-grow: 1;
}
.video-container {
align-items: stretch;
}
.iconset-preview {
display: flex;
flex-wrap: wrap;
width: 100%;
justify-content: flex-start;
align-items: center;
gap: 6px;
}
.iconset-icon {
max-width: 20px;
max-height: 20px;
height: auto;
}
{$tabsCss}
</style>
</head>
<body class="body">
<script>
document.getElementsByTagName('body')[0].setAttribute('class', 'body js-enabled');
</script>
<div class="container">
<header class="header">
<a href="https://crawler.siteone.io/?utm_source=siteone_crawler&utm_medium=logo&utm_campaign=crawler_report&utm_content=v{$version}"
target="_blank" class="logo" aria-label="Clickable logo of SiteOne Crawler linking to crawler.siteone.io">
<svg width="70px" height="34px" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 119 59" xml:space="preserve">
<path d="M49.4 29.1L49.4 29.1L49.4 29.1l8.8-8.8l0 0h0V0h-9.9v16.2l-5.9 5.9L29.1 8.9L15.9 22.1l-5.9-5.9V0H0v20.2h0l0 0l8.8 8.8
l0 0l0 0L0 37.9l0 0h0v20.2h9.9V42l5.9-5.9l13.3 13.3l13.3-13.3l5.9 5.9v16.2h9.9V38h0l0 0L49.4 29.1z M29.1 35.4l-6.3-6.3l6.3-6.3
l6.3 6.3L29.1 35.4z" fill="var(--text-color-default)"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M92.3 15v33.2H75.5v10H119v-10h-16.4V0h-9.3L67.1 26.2l7 7C74.1 33.2 92.3 15 92.3 15z"
fill="var(--text-color-neutral)"/>
</svg>
</a>
<h1>Crawler Report for <a href="{$initialUrl}" aria-label="Link to Crawler target website {$initialHost}">{$initialHost}</a></h1>
<div class="theme-switch">
<label>
<input type="checkbox" class="theme-switch__input" arial-label="Theme switch - dark mode is enabled by default" checked>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
<div class="theme-switch__wrapper">
<div class="theme-switch__dot"></div>
</div>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
</svg>
</label>
</div>
</header>
<main>
<section class="tabs">
{$tabsRadios}
<nav class="tabs__navigation" aria-label="Navigation">
{$tabs}
</nav>
<div class="tabs__content">
{$tabsContent}
</div>
</section>
</main>
<footer aria-label="Footer with basic info about report and crawler">
<br/>
<hr/>
The report was generated <strong>{$executedAt}</strong> using the <span style="color: red;">♥</span>
<a href="https://github.com/janreges/siteone-crawler" aria-label="Link to SiteOne Crawler Github repository"><strong>SiteOne Crawler</strong></a>
by Ján Regeš from <a
href="https://www.siteone.io/?utm_source=siteone_crawler&utm_medium=email&utm_campaign=crawler_report&utm_content=v{$version}" aria-label="Link to SiteOne.io - main author of this crawler"><strong>SiteOne</strong></a>
(Czech Republic).<br/>
<br/>
</footer>
<script>
function sortTable(tableId, columnKey) {
const table = document.querySelector('#' + tableId);
const tbody = table.querySelector('tbody');
const rows = Array.from(tbody.querySelectorAll('tr'));
const headerCells = Array.from(table.querySelectorAll('thead th'));
const columnIndex = Array.from(table.querySelectorAll('thead th')).findIndex(th => th.getAttribute('data-key') === columnKey);
const direction = headerCells[columnIndex].getAttribute('data-direction');
const dataType = headerCells[columnIndex].getAttribute('data-type');
rows.sort((a, b) => {
if (a.children.length !== b.children.length) {
return 0;
}
let aValue = a.children[columnIndex].getAttribute('data-value');
let bValue = b.children[columnIndex].getAttribute('data-value');
if (dataType === 'number') {
aValue = parseFloat(aValue);
bValue = parseFloat(bValue);
}
if (direction === 'ASC') {
return aValue > bValue ? 1 : aValue < bValue ? -1 : 0;
} else {
return aValue < bValue ? 1 : aValue > bValue ? -1 : 0;
}
});
rows.forEach(row => tbody.appendChild(row));
headerCells.forEach(th => {
let label = th.getAttribute('data-label');
if (th.getAttribute('data-key') === columnKey) {
th.innerHTML = label + (direction === 'ASC' ? ' 🔼' : ' 🔽');
th.setAttribute('data-direction', direction === 'ASC' ? 'DESC' : 'ASC');
} else {
th.textContent = label;
}
});
}
function debounce(callback, timeout) {
let timerId;
return function (...args) {
clearTimeout(timerId);
timerId = setTimeout(() => {
callback.apply(this, args);
}, timeout);
};
}
function tableFulltext(tableId, searchTerm) {
var table = document.getElementById(tableId);
if (!table) {
console.warn('Table with id "' + tableId + '" was not found.');
return;
}
searchTerm = searchTerm.trim().toLowerCase();
if (table.getAttribute('data-fulltext-ready') !== '1') {
var rows = table.getElementsByTagName('tr');
for (var i = 0; i < rows.length; i++) {
var cells = rows[i].getElementsByTagName('td');
var fulltextValue = '';
for (var j = 0; j < cells.length; j++) {
fulltextValue += cells[j].textContent + ' ';
}
fulltextValue = fulltextValue.trim();
rows[i].setAttribute('data-fulltext', fulltextValue.toLowerCase());
}
table.setAttribute('data-fulltext-ready', '1');
}
var terms = searchTerm.split(' ');
var tbody = table.getElementsByTagName('tbody')[0];
var rows = tbody.getElementsByTagName('tr');
var foundRows = 0;
for (var i = 0; i < rows.length; i++) {
var rowFulltext = rows[i].getAttribute('data-fulltext') || '';
var display = terms.every(function(term) {
return rowFulltext.includes(term);
}) ? '' : 'none';
if (display === '') {
foundRows++;
}
rows[i].style.display = display;
}
var emptyFulltextRow = table.getElementsByClassName('empty-fulltext')[0];
emptyFulltextRow.style.display = foundRows > 0 ? 'none' : 'table-row';
document.getElementById('foundRows_' + tableId).textContent = 'Found ' + foundRows + ' row(s).';
}
function debouncedTableFulltext(tableId, searchTerm) {
debounce(tableFulltext, 250)(tableId, searchTerm);
}
document.addEventListener('DOMContentLoaded', function () {
function onFulltextKeyup(event) {
const dataUqId = event.target.getAttribute('data-uq-id');
const inputValue = event.target.value;
debouncedTableFulltext(dataUqId, inputValue);
}
const inputs = document.querySelectorAll('input.fulltext[data-uq-id]');
inputs.forEach(input => {
input.addEventListener('keyup', onFulltextKeyup);
});
function onTableHeaderClick(event) {
const dataUqId = event.target.getAttribute('data-uq-id');
const dataKey = event.target.getAttribute('data-key');
sortTable(dataUqId, dataKey);
}
const tableHeaders = document.querySelectorAll('th.sortable-th[data-uq-id]');
tableHeaders.forEach(th => {
th.addEventListener('click', onTableHeaderClick);
});
function onImageFilterClick(event) {
const dataKey = event.target.getAttribute('data-key');
updateClassName(dataKey, event.target.value);
}
const imgFilters = document.querySelectorAll('input.idf[data-key]');
imgFilters.forEach(f => {
f.addEventListener('change', onImageFilterClick);
});
});
</script>
</div>
</body>
</html>