initial commit
@@ -0,0 +1,21 @@
|
||||
# build output
|
||||
dist/
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
@@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html><html lang="en" dir="ltr" data-theme="dark" data-has-hero class="astro-bguv2lll"> <head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>404 | vJailbreak</title><link rel="canonical" href="https://platform9.github.io/404/"/><link rel="sitemap" href="/sitemap-index.xml"/><link rel="shortcut icon" href="/favicon.svg" type="image/svg+xml"/><meta name="generator" content="Astro v5.3.0"/><meta name="generator" content="Starlight v0.32.2"/><meta property="og:title" content="404"/><meta property="og:type" content="article"/><meta property="og:url" content="https://platform9.github.io/404/"/><meta property="og:locale" content="en"/><meta property="og:description"/><meta property="og:site_name" content="vJailbreak"/><meta name="twitter:card" content="summary_large_image"/><script>
|
||||
window.StarlightThemeProvider = (() => {
|
||||
const storedTheme =
|
||||
typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
|
||||
const theme =
|
||||
storedTheme ||
|
||||
(window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark');
|
||||
document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark';
|
||||
return {
|
||||
updatePickers(theme = storedTheme || 'auto') {
|
||||
document.querySelectorAll('starlight-theme-select').forEach((picker) => {
|
||||
const select = picker.querySelector('select');
|
||||
if (select) select.value = theme;
|
||||
/** @type {HTMLTemplateElement | null} */
|
||||
const tmpl = document.querySelector(`#theme-icons`);
|
||||
const newIcon = tmpl && tmpl.content.querySelector('.' + theme);
|
||||
if (newIcon) {
|
||||
const oldIcon = picker.querySelector('svg.label-icon');
|
||||
if (oldIcon) {
|
||||
oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
})();
|
||||
</script><template id="theme-icons"><svg aria-hidden="true" class="light astro-c6vsoqas" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M5 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Zm.64 5-.71.71a1 1 0 0 0 0 1.41 1 1 0 0 0 1.41 0l.71-.71A1 1 0 0 0 5.64 17ZM12 5a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1Zm5.66 2.34a1 1 0 0 0 .7-.29l.71-.71a1 1 0 1 0-1.41-1.41l-.66.71a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.29Zm-12-.29a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.71-.71a1.004 1.004 0 1 0-1.43 1.41l.73.71ZM21 11h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2Zm-2.64 6A1 1 0 0 0 17 18.36l.71.71a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.76-.66ZM12 6.5a5.5 5.5 0 1 0 5.5 5.5A5.51 5.51 0 0 0 12 6.5Zm0 9a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7Zm0 3.5a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1a1 1 0 0 0-1-1Z"/></svg> <svg aria-hidden="true" class="dark astro-c6vsoqas" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.64 13a1 1 0 0 0-1.05-.14 8.049 8.049 0 0 1-3.37.73 8.15 8.15 0 0 1-8.14-8.1 8.59 8.59 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 14 11.69 1 1 0 0 0-.36-1.05Zm-9.5 6.69A8.14 8.14 0 0 1 7.08 5.22v.27a10.15 10.15 0 0 0 10.14 10.14 9.784 9.784 0 0 0 2.1-.22 8.11 8.11 0 0 1-7.18 4.32v-.04Z"/></svg> <svg aria-hidden="true" class="auto astro-c6vsoqas" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg> </template><link rel="stylesheet" href="/_astro/print.BJ0teN4y.css" media="print"><link rel="stylesheet" href="/_astro/index.CK0XFbLG.css">
|
||||
<style>:root{--sl-badge-default-border: var(--sl-color-accent);--sl-badge-default-bg: var(--sl-color-accent-low);--sl-badge-default-text: #fff;--sl-badge-note-border: var(--sl-color-blue);--sl-badge-note-bg: var(--sl-color-blue-low);--sl-badge-note-text: #fff;--sl-badge-danger-border: var(--sl-color-red);--sl-badge-danger-bg: var(--sl-color-red-low);--sl-badge-danger-text: #fff;--sl-badge-success-border: var(--sl-color-green);--sl-badge-success-bg: var(--sl-color-green-low);--sl-badge-success-text: #fff;--sl-badge-caution-border: var(--sl-color-orange);--sl-badge-caution-bg: var(--sl-color-orange-low);--sl-badge-caution-text: #fff;--sl-badge-tip-border: var(--sl-color-purple);--sl-badge-tip-bg: var(--sl-color-purple-low);--sl-badge-tip-text: #fff}[data-theme=light]:root{--sl-badge-default-bg: var(--sl-color-accent-high);--sl-badge-note-bg: var(--sl-color-blue-high);--sl-badge-danger-bg: var(--sl-color-red-high);--sl-badge-success-bg: var(--sl-color-green-high);--sl-badge-caution-bg: var(--sl-color-orange-high);--sl-badge-tip-bg: var(--sl-color-purple-high)}.sl-badge:where(.astro-avdet4wd){display:inline-block;border:1px solid var(--sl-color-border-badge);border-radius:.25rem;font-family:var(--sl-font-system-mono);line-height:normal;color:var(--sl-color-text-badge);background-color:var(--sl-color-bg-badge);overflow-wrap:anywhere}.sidebar-content .sl-badge:where(.astro-avdet4wd){line-height:1;font-size:var(--sl-text-xs);padding:.125rem .375rem}.sidebar-content a[aria-current=page]>.sl-badge:where(.astro-avdet4wd){--sl-color-bg-badge: transparent;--sl-color-border-badge: currentColor;color:inherit}.default:where(.astro-avdet4wd){--sl-color-bg-badge: var(--sl-badge-default-bg);--sl-color-border-badge: var(--sl-badge-default-border);--sl-color-text-badge: var(--sl-badge-default-text)}.note:where(.astro-avdet4wd){--sl-color-bg-badge: var(--sl-badge-note-bg);--sl-color-border-badge: var(--sl-badge-note-border);--sl-color-text-badge: var(--sl-badge-note-text)}.danger:where(.astro-avdet4wd){--sl-color-bg-badge: var(--sl-badge-danger-bg);--sl-color-border-badge: var(--sl-badge-danger-border);--sl-color-text-badge: var(--sl-badge-danger-text)}.success:where(.astro-avdet4wd){--sl-color-bg-badge: var(--sl-badge-success-bg);--sl-color-border-badge: var(--sl-badge-success-border);--sl-color-text-badge: var(--sl-badge-success-text)}.tip:where(.astro-avdet4wd){--sl-color-bg-badge: var(--sl-badge-tip-bg);--sl-color-border-badge: var(--sl-badge-tip-border);--sl-color-text-badge: var(--sl-badge-tip-text)}.caution:where(.astro-avdet4wd){--sl-color-bg-badge: var(--sl-badge-caution-bg);--sl-color-border-badge: var(--sl-badge-caution-border);--sl-color-text-badge: var(--sl-badge-caution-text)}.small:where(.astro-avdet4wd){font-size:var(--sl-text-xs);padding:.125rem .25rem}.medium:where(.astro-avdet4wd){font-size:var(--sl-text-sm);padding:.175rem .35rem}.large:where(.astro-avdet4wd){font-size:var(--sl-text-base);padding:.225rem .45rem}.sl-markdown-content :is(h1,h2,h3,h4,h5,h6) .sl-badge:where(.astro-avdet4wd){vertical-align:middle}
|
||||
.card-grid:where(.astro-zntqmydn){display:grid;grid-template-columns:100%;gap:1rem}.card-grid:where(.astro-zntqmydn)>*{margin-top:0!important}@media (min-width: 50rem){.card-grid:where(.astro-zntqmydn){grid-template-columns:1fr 1fr;gap:1.5rem}.stagger:where(.astro-zntqmydn){--stagger-height: 5rem;padding-bottom:var(--stagger-height)}.stagger:where(.astro-zntqmydn)>*:nth-child(2n){transform:translateY(var(--stagger-height))}}
|
||||
.card:where(.astro-v5tidmuc){--sl-card-border: var(--sl-color-purple);--sl-card-bg: var(--sl-color-purple-low);border:1px solid var(--sl-color-gray-5);background-color:var(--sl-color-black);padding:clamp(1rem,calc(.125rem + 3vw),2.5rem);flex-direction:column;gap:clamp(.5rem,calc(.125rem + 1vw),1rem)}.card:where(.astro-v5tidmuc):nth-child(4n+1){--sl-card-border: var(--sl-color-orange);--sl-card-bg: var(--sl-color-orange-low)}.card:where(.astro-v5tidmuc):nth-child(4n+3){--sl-card-border: var(--sl-color-green);--sl-card-bg: var(--sl-color-green-low)}.card:where(.astro-v5tidmuc):nth-child(4n+4){--sl-card-border: var(--sl-color-red);--sl-card-bg: var(--sl-color-red-low)}.card:where(.astro-v5tidmuc):nth-child(4n+5){--sl-card-border: var(--sl-color-blue);--sl-card-bg: var(--sl-color-blue-low)}.title:where(.astro-v5tidmuc){font-weight:600;font-size:var(--sl-text-h4);color:var(--sl-color-white);line-height:var(--sl-line-height-headings);gap:1rem;align-items:center}.card:where(.astro-v5tidmuc) .icon:where(.astro-v5tidmuc){border:1px solid var(--sl-card-border);background-color:var(--sl-card-bg);padding:.2em;border-radius:.25rem}.card:where(.astro-v5tidmuc) .body:where(.astro-v5tidmuc){margin:0;font-size:clamp(var(--sl-text-sm),calc(.5rem + 1vw),var(--sl-text-body))}
|
||||
svg:where(.astro-c6vsoqas){color:var(--sl-icon-color);font-size:var(--sl-icon-size, 1em);width:1em;height:1em}
|
||||
starlight-tabs:where(.astro-esqgolmp){display:block}.tablist-wrapper:where(.astro-esqgolmp){overflow-x:auto}:where(.astro-esqgolmp)[role=tablist]{display:flex;list-style:none;border-bottom:2px solid var(--sl-color-gray-5);padding:0}.tab:where(.astro-esqgolmp){margin-bottom:-2px}.tab:where(.astro-esqgolmp)>:where(.astro-esqgolmp)[role=tab]{display:flex;align-items:center;gap:.5rem;padding:0 1.25rem;text-decoration:none;border-bottom:2px solid var(--sl-color-gray-5);color:var(--sl-color-gray-3);outline-offset:var(--sl-outline-offset-inside);overflow-wrap:initial}.tab:where(.astro-esqgolmp) :where(.astro-esqgolmp)[role=tab][aria-selected=true]{color:var(--sl-color-white);border-color:var(--sl-color-text-accent);font-weight:600}.tablist-wrapper:where(.astro-esqgolmp)~[role=tabpanel]{margin-top:1rem}
|
||||
.sl-steps{--bullet-size: calc(var(--sl-line-height) * 1rem);--bullet-margin: .375rem;list-style:none;counter-reset:steps-counter var(--sl-steps-start, 0);padding-inline-start:0}.sl-steps>li{counter-increment:steps-counter;position:relative;padding-inline-start:calc(var(--bullet-size) + 1rem);padding-bottom:1px;min-height:calc(var(--bullet-size) + var(--bullet-margin))}.sl-steps>li+li{margin-top:0}.sl-steps>li:before{content:counter(steps-counter);position:absolute;top:0;inset-inline-start:0;width:var(--bullet-size);height:var(--bullet-size);line-height:var(--bullet-size);font-size:var(--sl-text-xs);font-weight:600;text-align:center;color:var(--sl-color-white);background-color:var(--sl-color-gray-6);border-radius:99rem;box-shadow:inset 0 0 0 1px var(--sl-color-gray-5)}.sl-steps>li:after{--guide-width: 1px;content:"";position:absolute;top:calc(var(--bullet-size) + var(--bullet-margin));bottom:var(--bullet-margin);inset-inline-start:calc((var(--bullet-size) - var(--guide-width)) / 2);width:var(--guide-width);background-color:var(--sl-color-hairline-light)}.sl-steps>li>:first-child{--lh: calc(1em * var(--sl-line-height));--shift-y: calc(.5 * (var(--bullet-size) - var(--lh)));transform:translateY(var(--shift-y));margin-bottom:var(--shift-y)}.sl-steps>li>:first-child:where(h1,h2,h3,h4,h5,h6){--lh: calc(1em * var(--sl-line-height-headings))}@supports (--prop: 1lh){.sl-steps>li>:first-child{--lh: 1lh}}
|
||||
.sl-link-button:where(.astro-xwgiixxa){align-items:center;border:1px solid transparent;border-radius:999rem;display:inline-flex;font-size:var(--sl-text-sm);gap:.5em;line-height:1.1875;outline-offset:.25rem;padding:.4375rem 1.125rem;text-decoration:none}.sl-link-button:where(.astro-xwgiixxa).primary{background:var(--sl-color-text-accent);border-color:var(--sl-color-text-accent);color:var(--sl-color-black)}.sl-link-button:where(.astro-xwgiixxa).primary:hover{color:var(--sl-color-black)}.sl-link-button:where(.astro-xwgiixxa).secondary{border-color:inherit;color:var(--sl-color-white)}.sl-link-button:where(.astro-xwgiixxa).minimal{color:var(--sl-color-white);padding-inline:0}.sl-link-button:where(.astro-xwgiixxa) svg{flex-shrink:0}@media (min-width: 50rem){.sl-link-button:where(.astro-xwgiixxa){font-size:var(--sl-text-base);padding:.9375rem 1.25rem}}.sl-markdown-content .sl-link-button:where(.astro-xwgiixxa){margin-inline-end:1rem}.sl-markdown-content .sl-link-button:where(.astro-xwgiixxa):not(:where(p *)){margin-block:1rem}
|
||||
</style><script type="module" src="/_astro/page.7qqag-5g.js"></script></head> <body class="astro-bguv2lll"> <a href="#_top" class="astro-7q3lir66">Skip to content</a> <div class="page sl-flex astro-vrdttmbt"> <header class="header astro-vrdttmbt"><div class="header sl-flex astro-3ef6ksr2"> <div class="title-wrapper sl-flex astro-3ef6ksr2"> <a href="/" class="site-title sl-flex astro-m46x6ez3"> <img class="astro-m46x6ez3" alt src="/_astro/platform9-logo.PaszzYBQ.svg" width="120" height="60"> <span class="sr-only astro-m46x6ez3" translate="no"> vJailbreak </span> </a> </div> <div class="sl-flex print:hidden astro-3ef6ksr2"> <site-search class="astro-3ef6ksr2 astro-v37mnknz" data-translations="{"placeholder":"Search"}"> <button data-open-modal disabled aria-label="Search" aria-keyshortcuts="Control+K" class="astro-v37mnknz"> <svg aria-hidden="true" class="astro-v37mnknz astro-c6vsoqas" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.71 20.29 18 16.61A9 9 0 1 0 16.61 18l3.68 3.68a.999.999 0 0 0 1.42 0 1 1 0 0 0 0-1.39ZM11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z"/></svg> <span class="sl-hidden md:sl-block astro-v37mnknz" aria-hidden="true">Search</span> <kbd class="sl-hidden md:sl-flex astro-v37mnknz" style="display: none;"> <kbd class="astro-v37mnknz">Ctrl</kbd><kbd class="astro-v37mnknz">K</kbd> </kbd> </button> <dialog style="padding:0" aria-label="Search" class="astro-v37mnknz"> <div class="dialog-frame sl-flex astro-v37mnknz"> <button data-close-modal class="sl-flex md:sl-hidden astro-v37mnknz"> Cancel </button> <div class="search-container astro-v37mnknz"> <div id="starlight__search" class="astro-v37mnknz"></div> </div> </div> </dialog> </site-search> <script>
|
||||
(() => {
|
||||
const openBtn = document.querySelector('button[data-open-modal]');
|
||||
const shortcut = openBtn?.querySelector('kbd');
|
||||
if (!openBtn || !(shortcut instanceof HTMLElement)) return;
|
||||
const platformKey = shortcut.querySelector('kbd');
|
||||
if (platformKey && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
|
||||
platformKey.textContent = '⌘';
|
||||
openBtn.setAttribute('aria-keyshortcuts', 'Meta+K');
|
||||
}
|
||||
shortcut.style.display = '';
|
||||
})();
|
||||
</script> <script type="module" src="/_astro/Search.astro_astro_type_script_index_0_lang.18-vQxR-.js"></script> </div> <div class="sl-hidden md:sl-flex print:hidden right-group astro-3ef6ksr2"> <div class="sl-flex social-icons astro-3ef6ksr2"> <a href="https://github.com/platform9/vjailbreak" rel="me" class="sl-flex astro-wy4te6ga"><span class="sr-only astro-wy4te6ga">GitHub</span><svg aria-hidden="true" class="astro-wy4te6ga astro-c6vsoqas" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg> </a><a href="https://join.slack.com/t/vjailbreak/shared_invite/zt-314pppw43-F1vzd6ZaPW5PoZqF~aa8lA" rel="me" class="sl-flex astro-wy4te6ga"><span class="sr-only astro-wy4te6ga">Slack</span><svg aria-hidden="true" class="astro-wy4te6ga astro-c6vsoqas" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52Zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313ZM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834Zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312Zm10.122 2.521a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834Zm-1.268 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312Zm-2.523 10.122a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52Zm0-1.268a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313Z"/></svg> </a> </div> <div class="sl-flex release-dropdown astro-3ef6ksr2"> <!-- Dropdown --><div class="select-container"> <label for="release-select" class="select-label">Latest Release:</label> <select id="release-select" class="release-select"> <option>Loading releases...</option> </select> </div> <script>(function(){const astroBaseURL = "https://platform9.github.io/";
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const CACHE_KEY = 'githubReleases';
|
||||
const CACHE_EXPIRY = 60 * 60 * 1000; // 1 hour
|
||||
const select = document.getElementById('release-select');
|
||||
|
||||
// Check cache first
|
||||
if (typeof window !== 'undefined' && window.localStorage) {
|
||||
const cachedReleases = localStorage.getItem(CACHE_KEY);
|
||||
const cacheExpiry = localStorage.getItem(`${CACHE_KEY}_expiry`);
|
||||
|
||||
if (cachedReleases && cacheExpiry && Date.now() < Number(cacheExpiry)) {
|
||||
try {
|
||||
console.debug("Reading releases from cache:", JSON.parse(cachedReleases)); // Debug log
|
||||
populateDropdown(JSON.parse(cachedReleases));
|
||||
return;
|
||||
} catch (e) {
|
||||
console.warn("Cache corrupted clearing", e);
|
||||
localStorage.removeItem(CACHE_KEY)
|
||||
localStorage.removeItem(`${CACHE_KEY}_expiry`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
console.debug("Fetching releases from GitHub"); // Debug log
|
||||
const response = await fetch('https://api.github.com/repos/platform9/vjailbreak/releases');
|
||||
const data = await response.json();
|
||||
const releases = data.slice(0, 5);
|
||||
|
||||
// Store in cache
|
||||
if (typeof window !== 'undefined' && window.localStorage) {
|
||||
localStorage.setItem(CACHE_KEY, JSON.stringify(releases));
|
||||
localStorage.setItem(`${CACHE_KEY}_expiry`, String(Date.now() + CACHE_EXPIRY));
|
||||
}
|
||||
|
||||
populateDropdown(releases);
|
||||
} catch (error) {
|
||||
console.error("Error fetching releases:", error);
|
||||
populateDropdown([{
|
||||
id: 0,
|
||||
name: "v0.1.7",
|
||||
html_url: "https://github.com/platform9/vjailbreak/releases/tag/v0.1.7"
|
||||
}]);
|
||||
}
|
||||
|
||||
function populateDropdown(releases) {
|
||||
const currentURL = astroBaseURL || window.location.origin; // Use Astro.site if available
|
||||
const pathPrefix = astroBaseURL ? '/vjailbreak/release_docs/' : '/release_docs/';
|
||||
select.innerHTML = releases.map(release => {
|
||||
const nameModified = release.name.replace(/\./g, '');
|
||||
const releaseDocsURL = `${currentURL}${pathPrefix}${nameModified}/`;
|
||||
return `<option value="${releaseDocsURL}">${release.name}</option>`;
|
||||
}).join('');
|
||||
select.onchange = (e) => window.open(e.target.value, '_blank');
|
||||
}
|
||||
});
|
||||
})();</script> </div> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-4yphtoen"> <span class="sr-only astro-4yphtoen">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-4yphtoen astro-c6vsoqas" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg> <select value="auto" autocomplete="off" class="astro-4yphtoen"> <option value="dark" class="astro-4yphtoen">Dark</option><option value="light" class="astro-4yphtoen">Light</option><option value="auto" selected class="astro-4yphtoen">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-4yphtoen astro-c6vsoqas" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg> </label> </starlight-theme-select> <script>
|
||||
StarlightThemeProvider.updatePickers();
|
||||
</script> <script type="module">const r="starlight-theme",o=e=>e==="auto"||e==="dark"||e==="light"?e:"auto",c=()=>o(typeof localStorage<"u"&&localStorage.getItem(r));function n(e){typeof localStorage<"u"&&localStorage.setItem(r,e==="light"||e==="dark"?e:"")}const l=()=>matchMedia("(prefers-color-scheme: light)").matches?"light":"dark";function t(e){StarlightThemeProvider.updatePickers(e),document.documentElement.dataset.theme=e==="auto"?l():e,n(e)}matchMedia("(prefers-color-scheme: light)").addEventListener("change",()=>{c()==="auto"&&t("auto")});class s extends HTMLElement{constructor(){super(),t(c()),this.querySelector("select")?.addEventListener("change",a=>{a.currentTarget instanceof HTMLSelectElement&&t(o(a.currentTarget.value))})}}customElements.define("starlight-theme-select",s);</script> <script type="module">class s extends HTMLElement{constructor(){super();const e=this.querySelector("select");e&&(e.addEventListener("change",t=>{t.currentTarget instanceof HTMLSelectElement&&(window.location.pathname=t.currentTarget.value)}),window.addEventListener("pageshow",t=>{if(!t.persisted)return;const n=e.querySelector("option[selected]")?.index;n!==e.selectedIndex&&(e.selectedIndex=n??0)}))}}customElements.define("starlight-lang-select",s);</script> </div> </div> </header> <div class="main-frame astro-vrdttmbt"> <script type="module">const a=document.getElementById("starlight__sidebar"),n=a?.querySelector("sl-sidebar-state-persist"),o="sl-sidebar-state",i=()=>{let t=[];const e=n?.dataset.hash||"";try{const s=sessionStorage.getItem(o),r=JSON.parse(s||"{}");Array.isArray(r.open)&&r.hash===e&&(t=r.open)}catch{}return{hash:e,open:t,scroll:a?.scrollTop||0}},c=t=>{try{sessionStorage.setItem(o,JSON.stringify(t))}catch{}},d=()=>c(i()),l=(t,e)=>{const s=i();s.open[e]=t,c(s)};n?.addEventListener("click",t=>{if(!(t.target instanceof Element))return;const e=t.target.closest("summary")?.closest("details");if(!e)return;const s=e.querySelector("sl-sidebar-restore"),r=parseInt(s?.dataset.index||"");isNaN(r)||l(!e.open,r)});addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&d()});addEventListener("pageHide",d);</script> <div class="lg:sl-flex astro-67yu43on"> <div class="main-pane astro-67yu43on"> <main class="astro-bguv2lll" lang="en" dir="ltr"> <div class="content-panel astro-7nkwcw3z"> <div class="sl-container astro-7nkwcw3z"> <div class="hero astro-jbfsktt5"> <div class="sl-flex stack astro-jbfsktt5"> <div class="sl-flex copy astro-jbfsktt5"> <h1 id="_top" data-page-title class="astro-jbfsktt5">404</h1> <div class="tagline astro-jbfsktt5">Page not found. Check the URL or try using the search bar.</div> </div> </div> </div> <div class="sl-markdown-content"> </div> <footer class="sl-flex astro-3yyafb3n"> <div class="meta sl-flex astro-3yyafb3n"> </div> <div class="pagination-links print:hidden astro-u2l5gyhi" dir="ltr"> </div> </footer> </div> </div> </main> </div> </div> </div> </div> </body></html>
|
||||
@@ -0,0 +1,54 @@
|
||||
# Starlight Starter Kit: Basics
|
||||
|
||||
[](https://starlight.astro.build)
|
||||
|
||||
```
|
||||
npm create astro@latest -- --template starlight
|
||||
```
|
||||
|
||||
[](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
|
||||
[](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)
|
||||
[](https://app.netlify.com/start/deploy?repository=https://github.com/withastro/starlight&create_from_path=examples/basics)
|
||||
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs)
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro + Starlight project, you'll see the following folders and files:
|
||||
|
||||
```
|
||||
.
|
||||
├── public/
|
||||
├── src/
|
||||
│ ├── assets/
|
||||
│ ├── content/
|
||||
│ │ ├── docs/
|
||||
│ └── content.config.ts
|
||||
├── astro.config.mjs
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
|
||||
|
||||
Images can be added to `src/assets/` and embedded in Markdown with a relative link.
|
||||
|
||||
Static assets, like favicons, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
|
||||
@@ -0,0 +1 @@
|
||||
import{S as r}from"./TableOfContents.astro_astro_type_script_index_0_lang.CKWWgpjV.js";class c extends r{set current(e){super.current=e;const t=this.querySelector(".display-current");t&&(t.textContent=e.textContent)}constructor(){super();const e=this.querySelector("details");if(!e)return;const t=()=>{e.open=!1};e.querySelectorAll("a").forEach(s=>{s.addEventListener("click",t)}),window.addEventListener("click",s=>{e.contains(s.target)||t()}),window.addEventListener("keydown",s=>{if(s.key==="Escape"&&e.open){const o=e.contains(document.activeElement);if(t(),o){const n=e.querySelector("summary");n&&n.focus()}}})}}customElements.define("mobile-starlight-toc",c);
|
||||
@@ -0,0 +1 @@
|
||||
const y="modulepreload",w=function(h){return"/"+h},g={},S=function(u,i,c){let m=Promise.resolve();if(i&&i.length>0){document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),t=r?.nonce||r?.getAttribute("nonce");m=Promise.allSettled(i.map(n=>{if(n=w(n),n in g)return;g[n]=!0;const d=n.endsWith(".css"),f=d?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${n}"]${f}`))return;const o=document.createElement("link");if(o.rel=d?"stylesheet":y,d||(o.as="script"),o.crossOrigin="",o.href=n,t&&o.setAttribute("nonce",t),document.head.appendChild(o),d)return new Promise((e,s)=>{o.addEventListener("load",e),o.addEventListener("error",()=>s(new Error(`Unable to preload CSS for ${n}`)))})}))}function l(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return m.then(r=>{for(const t of r||[])t.status==="rejected"&&l(t.reason);return u().catch(l)})},E={ranking:{pageLength:.1,termFrequency:.1,termSaturation:2,termSimilarity:9}};class v extends HTMLElement{constructor(){super();const u=this.querySelector("button[data-open-modal]"),i=this.querySelector("button[data-close-modal]"),c=this.querySelector("dialog"),m=this.querySelector(".dialog-frame"),l=e=>{("href"in(e.target||{})||document.body.contains(e.target)&&!m.contains(e.target))&&t()},r=e=>{c.showModal(),document.body.toggleAttribute("data-search-modal-open",!0),this.querySelector("input")?.focus(),e?.stopPropagation(),window.addEventListener("click",l)},t=()=>c.close();u.addEventListener("click",r),u.disabled=!1,i.addEventListener("click",t),c.addEventListener("close",()=>{document.body.toggleAttribute("data-search-modal-open",!1),window.removeEventListener("click",l)}),window.addEventListener("keydown",e=>{(e.metaKey===!0||e.ctrlKey===!0)&&e.key==="k"&&(c.open?t():r(),e.preventDefault())});let n={};try{n=JSON.parse(this.dataset.translations||"{}")}catch{}const o=this.dataset.stripTrailingSlash!==void 0?e=>e.replace(/(.)\/(#.*)?$/,"$1$2"):e=>e;window.addEventListener("DOMContentLoaded",()=>{(window.requestIdleCallback||(s=>setTimeout(s,1)))(async()=>{const{PagefindUI:s}=await S(async()=>{const{PagefindUI:a}=await import("./ui-core.DklwHuoF.js");return{PagefindUI:a}},[]);new s({...E,element:"#starlight__search",baseUrl:"/",bundlePath:"/".replace(/\/$/,"")+"/pagefind/",showImages:!1,translations:n,showSubResults:!0,processResult:a=>{a.url=o(a.url),a.sub_results=a.sub_results.map(p=>(p.url=o(p.url),p))}})})})}}customElements.define("site-search",v);export{S as _};
|
||||
@@ -0,0 +1 @@
|
||||
const g="_top";class f extends HTMLElement{constructor(){super(),this._current=this.querySelector('a[aria-current="true"]'),this.minH=parseInt(this.dataset.minH||"2",10),this.maxH=parseInt(this.dataset.maxH||"3",10),this.onIdle=e=>(window.requestIdleCallback||(o=>setTimeout(o,1)))(e),this.init=()=>{const e=[...this.querySelectorAll("a")],o=t=>{if(t instanceof HTMLHeadingElement){if(t.id===g)return!0;const s=t.tagName[1];if(s){const n=parseInt(s,10);if(n>=this.minH&&n<=this.maxH)return!0}}return!1},i=t=>{if(!t)return null;const s=t;for(;t;){if(o(t))return t;for(t=t.previousElementSibling;t?.lastElementChild;)t=t.lastElementChild;const n=i(t);if(n)return n}return i(s.parentElement)},c=t=>{for(const{isIntersecting:s,target:n}of t){if(!s)continue;const l=i(n);if(!l)continue;const m=e.find(d=>d.hash==="#"+encodeURIComponent(l.id));if(m){this.current=m;break}}},a=document.querySelectorAll("main [id], main [id] ~ *, main .content > *");let r;const u=()=>{r||(r=new IntersectionObserver(c,{rootMargin:this.getRootMargin()}),a.forEach(t=>r.observe(t)))};u();let h;window.addEventListener("resize",()=>{r&&(r.disconnect(),r=void 0),clearTimeout(h),h=setTimeout(()=>this.onIdle(u),200)})},this.onIdle(()=>this.init())}set current(e){e!==this._current&&(this._current&&this._current.removeAttribute("aria-current"),e.setAttribute("aria-current","true"),this._current=e)}getRootMargin(){const e=document.querySelector("header")?.getBoundingClientRect().height||0,o=this.querySelector("summary")?.getBoundingClientRect().height||0,i=e+o+32,c=i+53,a=document.documentElement.clientHeight;return`-${i}px 0% ${c-a}px`}}customElements.define("starlight-toc",f);export{f as S};
|
||||
@@ -0,0 +1,636 @@
|
||||
{
|
||||
"$ref": "#/definitions/docs",
|
||||
"definitions": {
|
||||
"docs": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"editUrl": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"default": true
|
||||
},
|
||||
"head": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tag": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"title",
|
||||
"base",
|
||||
"link",
|
||||
"style",
|
||||
"meta",
|
||||
"script",
|
||||
"noscript",
|
||||
"template"
|
||||
]
|
||||
},
|
||||
"attrs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"not": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {}
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"tag"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"tableOfContents": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"minHeadingLevel": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 6,
|
||||
"default": 2
|
||||
},
|
||||
"maxHeadingLevel": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 6,
|
||||
"default": 3
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"minHeadingLevel": 2,
|
||||
"maxHeadingLevel": 3
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"doc",
|
||||
"splash"
|
||||
],
|
||||
"default": "doc"
|
||||
},
|
||||
"hero": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"tagline": {
|
||||
"type": "string"
|
||||
},
|
||||
"image": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alt": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"file": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alt": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"dark": {
|
||||
"type": "string"
|
||||
},
|
||||
"light": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"dark",
|
||||
"light"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"html": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"html"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"link": {
|
||||
"type": "string"
|
||||
},
|
||||
"variant": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"primary",
|
||||
"secondary",
|
||||
"minimal"
|
||||
],
|
||||
"default": "primary"
|
||||
},
|
||||
"icon": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"up-caret",
|
||||
"down-caret",
|
||||
"right-caret",
|
||||
"left-caret",
|
||||
"up-arrow",
|
||||
"down-arrow",
|
||||
"right-arrow",
|
||||
"left-arrow",
|
||||
"bars",
|
||||
"translate",
|
||||
"pencil",
|
||||
"pen",
|
||||
"document",
|
||||
"add-document",
|
||||
"setting",
|
||||
"external",
|
||||
"download",
|
||||
"cloud-download",
|
||||
"moon",
|
||||
"sun",
|
||||
"laptop",
|
||||
"open-book",
|
||||
"information",
|
||||
"magnifier",
|
||||
"forward-slash",
|
||||
"close",
|
||||
"error",
|
||||
"warning",
|
||||
"approve-check-circle",
|
||||
"approve-check",
|
||||
"rocket",
|
||||
"star",
|
||||
"puzzle",
|
||||
"list-format",
|
||||
"random",
|
||||
"comment",
|
||||
"comment-alt",
|
||||
"heart",
|
||||
"github",
|
||||
"gitlab",
|
||||
"bitbucket",
|
||||
"codePen",
|
||||
"farcaster",
|
||||
"discord",
|
||||
"gitter",
|
||||
"twitter",
|
||||
"x.com",
|
||||
"mastodon",
|
||||
"codeberg",
|
||||
"youtube",
|
||||
"threads",
|
||||
"linkedin",
|
||||
"twitch",
|
||||
"azureDevOps",
|
||||
"microsoftTeams",
|
||||
"instagram",
|
||||
"stackOverflow",
|
||||
"telegram",
|
||||
"rss",
|
||||
"facebook",
|
||||
"email",
|
||||
"phone",
|
||||
"reddit",
|
||||
"patreon",
|
||||
"signal",
|
||||
"slack",
|
||||
"matrix",
|
||||
"hackerOne",
|
||||
"openCollective",
|
||||
"blueSky",
|
||||
"discourse",
|
||||
"zulip",
|
||||
"pinterest",
|
||||
"tiktok",
|
||||
"astro",
|
||||
"alpine",
|
||||
"pnpm",
|
||||
"biome",
|
||||
"bun",
|
||||
"mdx",
|
||||
"apple",
|
||||
"linux",
|
||||
"homebrew",
|
||||
"nix",
|
||||
"starlight",
|
||||
"pkl",
|
||||
"node",
|
||||
"cloudflare",
|
||||
"vercel",
|
||||
"netlify",
|
||||
"deno",
|
||||
"jsr",
|
||||
"nostr",
|
||||
"backstage",
|
||||
"confluence",
|
||||
"jira",
|
||||
"storybook",
|
||||
"seti:folder",
|
||||
"seti:bsl",
|
||||
"seti:mdo",
|
||||
"seti:salesforce",
|
||||
"seti:asm",
|
||||
"seti:bicep",
|
||||
"seti:bazel",
|
||||
"seti:c",
|
||||
"seti:c-sharp",
|
||||
"seti:html",
|
||||
"seti:cpp",
|
||||
"seti:clojure",
|
||||
"seti:coldfusion",
|
||||
"seti:config",
|
||||
"seti:crystal",
|
||||
"seti:crystal_embedded",
|
||||
"seti:json",
|
||||
"seti:css",
|
||||
"seti:csv",
|
||||
"seti:xls",
|
||||
"seti:cu",
|
||||
"seti:cake",
|
||||
"seti:cake_php",
|
||||
"seti:d",
|
||||
"seti:word",
|
||||
"seti:elixir",
|
||||
"seti:elixir_script",
|
||||
"seti:hex",
|
||||
"seti:elm",
|
||||
"seti:favicon",
|
||||
"seti:f-sharp",
|
||||
"seti:git",
|
||||
"seti:go",
|
||||
"seti:godot",
|
||||
"seti:gradle",
|
||||
"seti:grails",
|
||||
"seti:graphql",
|
||||
"seti:hacklang",
|
||||
"seti:haml",
|
||||
"seti:mustache",
|
||||
"seti:haskell",
|
||||
"seti:haxe",
|
||||
"seti:jade",
|
||||
"seti:java",
|
||||
"seti:javascript",
|
||||
"seti:jinja",
|
||||
"seti:julia",
|
||||
"seti:karma",
|
||||
"seti:kotlin",
|
||||
"seti:dart",
|
||||
"seti:liquid",
|
||||
"seti:livescript",
|
||||
"seti:lua",
|
||||
"seti:markdown",
|
||||
"seti:argdown",
|
||||
"seti:info",
|
||||
"seti:clock",
|
||||
"seti:maven",
|
||||
"seti:nim",
|
||||
"seti:github",
|
||||
"seti:notebook",
|
||||
"seti:nunjucks",
|
||||
"seti:npm",
|
||||
"seti:ocaml",
|
||||
"seti:odata",
|
||||
"seti:perl",
|
||||
"seti:php",
|
||||
"seti:pipeline",
|
||||
"seti:pddl",
|
||||
"seti:plan",
|
||||
"seti:happenings",
|
||||
"seti:powershell",
|
||||
"seti:prisma",
|
||||
"seti:pug",
|
||||
"seti:puppet",
|
||||
"seti:purescript",
|
||||
"seti:python",
|
||||
"seti:react",
|
||||
"seti:rescript",
|
||||
"seti:R",
|
||||
"seti:ruby",
|
||||
"seti:rust",
|
||||
"seti:sass",
|
||||
"seti:spring",
|
||||
"seti:slim",
|
||||
"seti:smarty",
|
||||
"seti:sbt",
|
||||
"seti:scala",
|
||||
"seti:ethereum",
|
||||
"seti:stylus",
|
||||
"seti:svelte",
|
||||
"seti:swift",
|
||||
"seti:db",
|
||||
"seti:terraform",
|
||||
"seti:tex",
|
||||
"seti:default",
|
||||
"seti:twig",
|
||||
"seti:typescript",
|
||||
"seti:tsconfig",
|
||||
"seti:vala",
|
||||
"seti:vite",
|
||||
"seti:vue",
|
||||
"seti:wasm",
|
||||
"seti:wat",
|
||||
"seti:xml",
|
||||
"seti:yml",
|
||||
"seti:prolog",
|
||||
"seti:zig",
|
||||
"seti:zip",
|
||||
"seti:wgt",
|
||||
"seti:illustrator",
|
||||
"seti:photoshop",
|
||||
"seti:pdf",
|
||||
"seti:font",
|
||||
"seti:image",
|
||||
"seti:svg",
|
||||
"seti:sublime",
|
||||
"seti:code-search",
|
||||
"seti:shell",
|
||||
"seti:video",
|
||||
"seti:audio",
|
||||
"seti:windows",
|
||||
"seti:jenkins",
|
||||
"seti:babel",
|
||||
"seti:bower",
|
||||
"seti:docker",
|
||||
"seti:code-climate",
|
||||
"seti:eslint",
|
||||
"seti:firebase",
|
||||
"seti:firefox",
|
||||
"seti:gitlab",
|
||||
"seti:grunt",
|
||||
"seti:gulp",
|
||||
"seti:ionic",
|
||||
"seti:platformio",
|
||||
"seti:rollup",
|
||||
"seti:stylelint",
|
||||
"seti:yarn",
|
||||
"seti:webpack",
|
||||
"seti:lock",
|
||||
"seti:license",
|
||||
"seti:makefile",
|
||||
"seti:heroku",
|
||||
"seti:todo",
|
||||
"seti:ignored"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\<svg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"attrs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"link"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"default": []
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"lastUpdated": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "unix-time"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"prev": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"link": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"next": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"link": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"sidebar": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"order": {
|
||||
"type": "number"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"hidden": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"badge": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"variant": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"note",
|
||||
"danger",
|
||||
"success",
|
||||
"caution",
|
||||
"tip",
|
||||
"default"
|
||||
],
|
||||
"default": "default"
|
||||
},
|
||||
"class": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"attrs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"not": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"default": {}
|
||||
},
|
||||
"banner": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"content"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"pagefind": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"draft": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export default new Map();
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
export default new Map([
|
||||
["src/content/docs/index.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Findex.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/docs/introduction/getting_started.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fintroduction%2Fgetting_started.mdx&astroContentModuleFlag=true")]]);
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
declare module 'astro:content' {
|
||||
interface Render {
|
||||
'.mdx': Promise<{
|
||||
Content: import('astro').MarkdownInstance<{}>['Content'];
|
||||
headings: import('astro').MarkdownHeading[];
|
||||
remarkPluginFrontmatter: Record<string, any>;
|
||||
components: import('astro').MDXInstance<{}>['components'];
|
||||
}>;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'astro:content' {
|
||||
export interface RenderResult {
|
||||
Content: import('astro/runtime/server/index.js').AstroComponentFactory;
|
||||
headings: import('astro').MarkdownHeading[];
|
||||
remarkPluginFrontmatter: Record<string, any>;
|
||||
}
|
||||
interface Render {
|
||||
'.md': Promise<RenderResult>;
|
||||
}
|
||||
|
||||
export interface RenderedContent {
|
||||
html: string;
|
||||
metadata?: {
|
||||
imagePaths: Array<string>;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'astro:content' {
|
||||
type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
|
||||
|
||||
export type CollectionKey = keyof AnyEntryMap;
|
||||
export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>;
|
||||
|
||||
export type ContentCollectionKey = keyof ContentEntryMap;
|
||||
export type DataCollectionKey = keyof DataEntryMap;
|
||||
|
||||
type AllValuesOf<T> = T extends any ? T[keyof T] : never;
|
||||
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
|
||||
ContentEntryMap[C]
|
||||
>['slug'];
|
||||
|
||||
export type ReferenceDataEntry<
|
||||
C extends CollectionKey,
|
||||
E extends keyof DataEntryMap[C] = string,
|
||||
> = {
|
||||
collection: C;
|
||||
id: E;
|
||||
};
|
||||
export type ReferenceContentEntry<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}) = string,
|
||||
> = {
|
||||
collection: C;
|
||||
slug: E;
|
||||
};
|
||||
|
||||
/** @deprecated Use `getEntry` instead. */
|
||||
export function getEntryBySlug<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(
|
||||
collection: C,
|
||||
// Note that this has to accept a regular string too, for SSR
|
||||
entrySlug: E,
|
||||
): E extends ValidContentEntrySlug<C>
|
||||
? Promise<CollectionEntry<C>>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
|
||||
/** @deprecated Use `getEntry` instead. */
|
||||
export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>(
|
||||
collection: C,
|
||||
entryId: E,
|
||||
): Promise<CollectionEntry<C>>;
|
||||
|
||||
export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>(
|
||||
collection: C,
|
||||
filter?: (entry: CollectionEntry<C>) => entry is E,
|
||||
): Promise<E[]>;
|
||||
export function getCollection<C extends keyof AnyEntryMap>(
|
||||
collection: C,
|
||||
filter?: (entry: CollectionEntry<C>) => unknown,
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
|
||||
export function getEntry<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(
|
||||
entry: ReferenceContentEntry<C, E>,
|
||||
): E extends ValidContentEntrySlug<C>
|
||||
? Promise<CollectionEntry<C>>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
export function getEntry<
|
||||
C extends keyof DataEntryMap,
|
||||
E extends keyof DataEntryMap[C] | (string & {}),
|
||||
>(
|
||||
entry: ReferenceDataEntry<C, E>,
|
||||
): E extends keyof DataEntryMap[C]
|
||||
? Promise<DataEntryMap[C][E]>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
export function getEntry<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(
|
||||
collection: C,
|
||||
slug: E,
|
||||
): E extends ValidContentEntrySlug<C>
|
||||
? Promise<CollectionEntry<C>>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
export function getEntry<
|
||||
C extends keyof DataEntryMap,
|
||||
E extends keyof DataEntryMap[C] | (string & {}),
|
||||
>(
|
||||
collection: C,
|
||||
id: E,
|
||||
): E extends keyof DataEntryMap[C]
|
||||
? string extends keyof DataEntryMap[C]
|
||||
? Promise<DataEntryMap[C][E]> | undefined
|
||||
: Promise<DataEntryMap[C][E]>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
|
||||
/** Resolve an array of entry references from the same collection */
|
||||
export function getEntries<C extends keyof ContentEntryMap>(
|
||||
entries: ReferenceContentEntry<C, ValidContentEntrySlug<C>>[],
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
export function getEntries<C extends keyof DataEntryMap>(
|
||||
entries: ReferenceDataEntry<C, keyof DataEntryMap[C]>[],
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
|
||||
export function render<C extends keyof AnyEntryMap>(
|
||||
entry: AnyEntryMap[C][string],
|
||||
): Promise<RenderResult>;
|
||||
|
||||
export function reference<C extends keyof AnyEntryMap>(
|
||||
collection: C,
|
||||
): import('astro/zod').ZodEffects<
|
||||
import('astro/zod').ZodString,
|
||||
C extends keyof ContentEntryMap
|
||||
? ReferenceContentEntry<C, ValidContentEntrySlug<C>>
|
||||
: ReferenceDataEntry<C, keyof DataEntryMap[C]>
|
||||
>;
|
||||
// Allow generic `string` to avoid excessive type errors in the config
|
||||
// if `dev` is not running to update as you edit.
|
||||
// Invalid collection names will be caught at build time.
|
||||
export function reference<C extends string>(
|
||||
collection: C,
|
||||
): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>;
|
||||
|
||||
type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
|
||||
type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer<
|
||||
ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
|
||||
>;
|
||||
|
||||
type ContentEntryMap = {
|
||||
|
||||
};
|
||||
|
||||
type DataEntryMap = {
|
||||
"docs": Record<string, {
|
||||
id: string;
|
||||
body?: string;
|
||||
collection: "docs";
|
||||
data: InferEntrySchema<"docs">;
|
||||
rendered?: RenderedContent;
|
||||
filePath?: string;
|
||||
}>;
|
||||
|
||||
};
|
||||
|
||||
type AnyEntryMap = ContentEntryMap & DataEntryMap;
|
||||
|
||||
export type ContentConfig = typeof import("../src/content.config.js");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
try{(()=>{function a(e){if(!e)return;let t=e.getAttribute("tabindex")!==null,n=e.scrollWidth>e.clientWidth;n&&!t?e.setAttribute("tabindex","0"):!n&&t&&e.removeAttribute("tabindex")}var u=window.requestIdleCallback||(e=>setTimeout(e,1)),i=window.cancelIdleCallback||clearTimeout;function l(e){let t=new Set,n,r;return new ResizeObserver(c=>{c.forEach(o=>t.add(o.target)),n&&clearTimeout(n),r&&i(r),n=setTimeout(()=>{r&&i(r),r=u(()=>{t.forEach(o=>e(o)),t.clear()})},250)})}function d(e,t){e.querySelectorAll?.(".expressive-code pre > code").forEach(n=>{let r=n.parentElement;r&&t.observe(r)})}var s=l(a);d(document,s);var b=new MutationObserver(e=>e.forEach(t=>t.addedNodes.forEach(n=>{d(n,s)})));b.observe(document.body,{childList:!0,subtree:!0});document.addEventListener("astro:page-load",()=>{d(document,s)});})();}catch(e){console.error("[EC] tabindex-js-module failed:",e)}
|
||||
try{(()=>{function i(o){let e=document.createElement("pre");Object.assign(e.style,{opacity:"0",pointerEvents:"none",position:"absolute",overflow:"hidden",left:"0",top:"0",width:"20px",height:"20px",webkitUserSelect:"auto",userSelect:"all"}),e.ariaHidden="true",e.textContent=o,document.body.appendChild(e);let a=document.createRange();a.selectNode(e);let n=getSelection();if(!n)return!1;n.removeAllRanges(),n.addRange(a);let r=!1;try{r=document.execCommand("copy")}finally{n.removeAllRanges(),document.body.removeChild(e)}return r}async function l(o){let e=o.currentTarget,a=e.dataset,n=!1,r=a.code.replace(/\u007f/g,`
|
||||
`);try{await navigator.clipboard.writeText(r),n=!0}catch{n=i(r)}if(!n||e.parentNode?.querySelector(".feedback"))return;let t=document.createElement("div");t.classList.add("feedback"),t.append(a.copied),e.before(t),t.offsetWidth,requestAnimationFrame(()=>t?.classList.add("show"));let c=()=>!t||t.classList.remove("show"),d=()=>{!t||parseFloat(getComputedStyle(t).opacity)>0||(t.remove(),t=void 0)};setTimeout(c,1500),setTimeout(d,2500),e.addEventListener("blur",c),t.addEventListener("transitioncancel",d),t.addEventListener("transitionend",d)}function s(o){o.querySelectorAll?.(".expressive-code .copy button").forEach(e=>e.addEventListener("click",l))}s(document);var u=new MutationObserver(o=>o.forEach(e=>e.addedNodes.forEach(a=>{s(a)})));u.observe(document.body,{childList:!0,subtree:!0});document.addEventListener("astro:page-load",()=>{s(document)});})();}catch(e){console.error("[EC] copy-js-module failed:",e)}
|
||||
@@ -0,0 +1 @@
|
||||
const d=new Set,c=new WeakSet;let f=!0,h,l=!1;function v(e){l||(l=!0,f??=!1,h??="hover",g(),p(),w(),L())}function g(){for(const e of["touchstart","mousedown"])document.body.addEventListener(e,t=>{i(t.target,"tap")&&s(t.target.href,{ignoreSlowConnection:!0})},{passive:!0})}function p(){let e;document.body.addEventListener("focusin",n=>{i(n.target,"hover")&&t(n)},{passive:!0}),document.body.addEventListener("focusout",o,{passive:!0}),u(()=>{for(const n of document.getElementsByTagName("a"))c.has(n)||i(n,"hover")&&(c.add(n),n.addEventListener("mouseenter",t,{passive:!0}),n.addEventListener("mouseleave",o,{passive:!0}))});function t(n){const r=n.target.href;e&&clearTimeout(e),e=setTimeout(()=>{s(r)},80)}function o(){e&&(clearTimeout(e),e=0)}}function w(){let e;u(()=>{for(const t of document.getElementsByTagName("a"))c.has(t)||i(t,"viewport")&&(c.add(t),e??=y(),e.observe(t))})}function y(){const e=new WeakMap;return new IntersectionObserver((t,o)=>{for(const n of t){const r=n.target,a=e.get(r);n.isIntersecting?(a&&clearTimeout(a),e.set(r,setTimeout(()=>{o.unobserve(r),e.delete(r),s(r.href)},300))):a&&(clearTimeout(a),e.delete(r))}})}function L(){u(()=>{for(const e of document.getElementsByTagName("a"))i(e,"load")&&s(e.href)})}function s(e,t){e=e.replace(/#.*/,"");const o=t?.ignoreSlowConnection??!1;if(S(e,o))if(d.add(e),document.createElement("link").relList?.supports?.("prefetch")&&t?.with!=="fetch"){const n=document.createElement("link");n.rel="prefetch",n.setAttribute("href",e),document.head.append(n)}else fetch(e,{priority:"low"})}function S(e,t){if(!navigator.onLine||!t&&m())return!1;try{const o=new URL(e,location.href);return location.origin===o.origin&&(location.pathname!==o.pathname||location.search!==o.search)&&!d.has(e)}catch{}return!1}function i(e,t){if(e?.tagName!=="A")return!1;const o=e.dataset.astroPrefetch;return o==="false"?!1:t==="tap"&&(o!=null||f)&&m()?!0:o==null&&f||o===""?t===h:o===t}function m(){if("connection"in navigator){const e=navigator.connection;return e.saveData||/2g/.test(e.effectiveType)}return!1}function u(e){e();let t=!1;document.addEventListener("astro:page-load",()=>{if(!t){t=!0;return}e()})}v();
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2.72 -1.34 120 60" width="120" height="60"><path d="M102.768 40.478c-1.87 0-3.452 1.5-3.452 3.38 0 1.798 1.5 3.38 3.38 3.38.288 0 .575-.072.647-.072l-1.87 2.59c-.072.072-.072.144-.072.216s.144.144.216.144h.575c.144 0 .36-.144.503-.216l2.66-3.74c.072-.144.216-.36.288-.432 0-.072.575-1.08.575-1.798-.072-1.942-1.5-3.452-3.452-3.452zm2.373 3.38c0 1.295-1.08 2.373-2.373 2.373s-2.373-1.08-2.373-2.373 1.08-2.373 2.373-2.373 2.373 1.08 2.373 2.373z" fill="#00aae7"/><path d="M34.087 40.982c-.072-.144-.144-.216-.216-.216h-.72c-.144 0-.216.144-.288.216l-4.17 8.846c-.072.072-.072.216-.072.288 0 0 .072.072.144.072h.863c.072 0 .216 0 .216-.072.072-.072.072-.144.072-.216l.863-1.87c.072-.072.072-.144.072-.144h5.178c.072 0 .072 0 .072.072l.935 1.942c.072.072.072.216.288.216h.863c.072 0 .144-.072.144-.072s.072-.072 0-.144zm1.582 5.825h-4.315l2.158-4.53zm-9.925 2.23h-4.962V40.9c0-.144-.072-.216-.216-.216h-.72c-.216 0-.216.072-.216.216v9c0 .144.072.216.216.216h5.825c.144 0 .216-.072.216-.216l-.072-.647c0-.072 0-.144-.072-.216zm-12.873-8.27H8.628c-.288 0-.288.144-.288.36v8.846c0 .072.072.144.216.144h.647c.144 0 .216-.072.216-.288v-3.812c0-.072 0-.144.144-.144h3.524c1.654 0 2.805-1.08 2.805-2.59 0-1.223-.935-2.517-3.02-2.517zm1.942 2.59c0 .79-.647 1.582-1.87 1.582H9.635c-.072 0-.144-.072-.144-.144v-2.95c0-.072.072-.072.072-.072h3.38c.647 0 1.15.216 1.438.503s.432.647.432 1.08zm33.37-2.66H38.69c-.144 0-.144.072-.144.216v.575c0 .144 0 .216.216.216h4.1v8.127c0 .144.072.216.216.216h.72c.144 0 .216-.072.216-.216v-8.055h4.1c.216 0 .216-.072.216-.216V40.9c.072-.216-.072-.216-.144-.216zm34.017 2.59c0-1.295-.935-2.59-3.02-2.59h-4.243c-.288 0-.288.216-.288.36V49.9c0 .144.072.216.216.216h.647c.144 0 .216-.072.216-.288v-3.812c0-.072 0-.144.144-.144h1.438c.36.503 2.086 2.517 3.308 4.027a.55.55 0 0 0 .36.144h.863s.36 0 .216-.144l-.144-.144-3.236-3.955h.575c1.798.144 2.95-.935 2.95-2.517zm-1.08.072c0 .79-.647 1.582-1.87 1.582h-3.308c-.072 0-.144-.072-.144-.144v-2.95c0-.072.072-.072.072-.072h3.38c.647 0 1.15.216 1.438.503s.432.647.432 1.08zm-22.222-2.517h-7.264a.31.31 0 0 0-.288.288v8.918c0 .144.072.216.144.216h.79c.072 0 .144-.072.144-.144v-4.027h5.466c.072 0 .144-.072.144-.144v-.72c0-.072-.072-.144-.144-.144h-5.466v-2.95c0-.072 0-.072.072-.072h6.4c.144 0 .216-.072.216-.216v-.647c0-.072 0-.144-.072-.144 0-.216-.072-.216-.144-.216zm35.96-.144h-.575c-.144 0-.216.072-.288.144l-3.524 3.596s-.072 0-.072-.072l-3.452-3.524s-.144-.072-.288-.072h-.575c-.072 0-.216 0-.216.216v9c0 .216.072.216.216.216h.72c.072 0 .216 0 .216-.216V42.78L90.1 45.8a.55.55 0 0 0 .36.144c.216 0 .36-.144.36-.144l3.092-3.092v7.264c0 .144.072.216.216.216h.79c.144 0 .216-.072.216-.216v-9c-.072-.072-.072-.216-.288-.288zm-28.623-.216c-2.877 0-5.178 2.23-5.178 4.962s2.3 4.962 5.178 4.962 5.178-2.23 5.178-4.962-2.3-4.962-5.178-4.962zm4.027 4.9c0 2.086-1.798 3.812-4.027 3.812s-4.027-1.726-4.027-3.812 1.798-3.812 4.027-3.812c2.23.072 4.027 1.726 4.027 3.812z" fill="#00000a"/><path d="M82.068 16.98l-7.633-3.127-9.196-3.678-7.817-3.22c-.184-.092-.276 0-.276 0l-7.725 3.127-1.38.552-6.437 2.667L32.4 16.98s-.092.092 0 .092l8.644 3.494 16.093 6.62h.276l16-6.53 8.644-3.494c.276-.092 0-.184 0-.184zm-10.483-3.127l-6.437 2.575-6.437-2.575 6.437-2.667zm-7.817 3.22L57.33 19.74l-6.437-2.575 6.437-2.667zM57.24 8.06l6.437 2.667-6.437 2.667-6.437-2.667zm-7.817 3.127l6.437 2.667-6.437 2.667-6.53-2.667zM35.17 17.073l6.437-2.575 6.437 2.667-6.437 2.575zm7.91 3.22l6.437-2.667 6.437 2.667-6.437 2.575zm14.162 5.793l-6.437-2.667 6.437-2.667 6.437 2.575zm7.91-3.22l-6.437-2.575 6.437-2.667 6.437 2.575zm7.91-3.22l-6.437-2.575 6.437-2.575 6.437 2.575z" fill="#00aae7"/><path d="M63.768 17.073L57.33 19.74l-6.437-2.667 6.437-2.667zm7.817 3.22l-6.437 2.575-6.437-2.575 6.437-2.667zm-7.91 3.22l-6.437 2.575-6.345-2.575 6.437-2.667z" fill="#008ccc"/><path d="M81.15 23.878l-24 9.84-24.093-9.84 7.91-3.22 16.093 6.62h.276l16-6.53z" fill="#007bb6"/><path d="M48.043 17.073l-6.437 2.667-6.437-2.667 6.345-2.667z" fill="#68cef2"/><path d="M55.86 20.292l-6.437 2.667-6.345-2.667 6.345-2.575z" fill="#008ccc"/><path d="M55.952 13.855l-6.53 2.667-6.437-2.667 6.437-2.667zm7.817-3.22l-6.437 2.667-6.437-2.667L57.24 8.06zm7.817 3.22l-6.437 2.667-6.437-2.667 6.437-2.575zm7.817 3.22l-6.345 2.575-6.437-2.575 6.345-2.667z" fill="#68cef2"/></svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1 @@
|
||||
@media print{:root[data-theme]:is(:root){--sl-color-white: hsl(224, 10%, 10%);--sl-color-gray-1: hsl(224, 14%, 16%);--sl-color-gray-2: hsl(224, 10%, 23%);--sl-color-gray-3: hsl(224, 7%, 36%);--sl-color-gray-4: hsl(224, 6%, 56%);--sl-color-gray-5: hsl(224, 6%, 77%);--sl-color-gray-6: hsl(224, 20%, 94%);--sl-color-gray-7: hsl(224, 19%, 97%);--sl-color-black: hsl(0, 0%, 100%);--sl-color-orange-high: hsl(var(--sl-hue-orange), 80%, 25%);--sl-color-orange: hsl(var(--sl-hue-orange), 90%, 60%);--sl-color-orange-low: hsl(var(--sl-hue-orange), 90%, 88%);--sl-color-green-high: hsl(var(--sl-hue-green), 80%, 22%);--sl-color-green: hsl(var(--sl-hue-green), 90%, 46%);--sl-color-green-low: hsl(var(--sl-hue-green), 85%, 90%);--sl-color-blue-high: hsl(var(--sl-hue-blue), 80%, 30%);--sl-color-blue: hsl(var(--sl-hue-blue), 90%, 60%);--sl-color-blue-low: hsl(var(--sl-hue-blue), 88%, 90%);--sl-color-purple-high: hsl(var(--sl-hue-purple), 90%, 30%);--sl-color-purple: hsl(var(--sl-hue-purple), 90%, 60%);--sl-color-purple-low: hsl(var(--sl-hue-purple), 80%, 90%);--sl-color-red-high: hsl(var(--sl-hue-red), 80%, 30%);--sl-color-red: hsl(var(--sl-hue-red), 90%, 60%);--sl-color-red-low: hsl(var(--sl-hue-red), 80%, 90%);--sl-color-accent-high: hsl(234, 80%, 30%);--sl-color-accent: hsl(234, 90%, 60%);--sl-color-accent-low: hsl(234, 88%, 90%);--sl-color-text-accent: var(--sl-color-accent);--sl-color-text-invert: var(--sl-color-black);--sl-color-bg-nav: var(--sl-color-gray-7);--sl-color-bg-sidebar: var(--sl-color-bg);--sl-color-bg-inline-code: var(--sl-color-gray-6);--sl-color-bg-accent: var(--sl-color-accent);--sl-color-hairline-light: var(--sl-color-gray-6);--sl-color-hairline-shade: var(--sl-color-gray-6);--sl-color-backdrop-overlay: hsla(225, 9%, 36%, .66);--sl-shadow-sm: none;--sl-shadow-md: none;--sl-shadow-lg: none}.print\:hidden{display:none!important}.print\:flex{display:flex!important}.print\:block{display:block!important}main{padding-bottom:0!important}main>.content-panel{padding-block-start:0!important}.content-panel+.content-panel{border:0!important}.page>header{position:relative!important}.page>.main-frame{padding-top:0;padding-inline-start:0}.main-pane{--sl-sidebar-width: 0px !important;--sl-content-width: 100% !important}.sl-banner{--sl-color-banner-text: var(--sl-color-white) !important;background-color:transparent!important}.sl-markdown-content :is(h1,h2,h3,h4,h5,h6){break-after:avoid}.sl-markdown-content :is(p,li){orphans:2;widows:2}.sl-markdown-content pre{overflow-x:hidden!important;white-space:pre-wrap!important}.sl-markdown-content .expressive-code,.sl-markdown-content figure,.sl-markdown-content pre{break-inside:avoid}.expressive-code .frame.is-terminal .header:before{box-shadow:inset 99rem 99rem var(--sl-color-gray-5)}.expressive-code .frame.has-title:not(.is-terminal) .header{background:transparent!important;border-bottom:1px solid var(--sl-color-gray-6)!important}.expressive-code .frame.has-title:not(.is-terminal) .title{background:transparent!important}.expressive-code .frame.has-title:not(.is-terminal) .title:after{border-top:0!important}.expressive-code .copy{display:none!important}.sl-markdown-content code:not(:where(.not-content *)){background-color:transparent!important;padding:0!important;margin-block:unset!important;font-size:.9375em!important}.sl-badge{background:transparent!important;color:var(--sl-color-white)!important}starlight-file-tree{break-inside:avoid}starlight-file-tree .highlight{outline:3px solid var(--sl-color-accent-low);color:var(--sl-color-text)!important;background-color:transparent!important}.starlight-aside{break-inside:avoid}.sl-link-button.primary{background:transparent!important;border-color:var(--sl-color-white)!important;color:var(--sl-color-white)!important}starlight-tabs{break-inside:avoid}.sl-steps>li:after{box-shadow:inset 99rem 99rem var(--sl-color-hairline-light)}}
|
||||
@@ -0,0 +1,2 @@
|
||||
/// <reference types="astro/client" />
|
||||
/// <reference path="content.d.ts" />
|
||||
@@ -0,0 +1,120 @@
|
||||
// @ts-check
|
||||
import starlight from '@astrojs/starlight';
|
||||
import { defineConfig } from "astro/config";
|
||||
import AutoImport from 'astro-auto-import';
|
||||
import mdx from '@astrojs/mdx';
|
||||
import mermaid from "astro-mermaid";
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: process.env.SITE_URL || 'https://platform9.github.io',
|
||||
//base: '/vjailbreak/',
|
||||
base: '/' + (process.env.BASE || ''),
|
||||
trailingSlash: "always",
|
||||
integrations: [
|
||||
mermaid({
|
||||
theme: 'forest',
|
||||
autoTheme: true,
|
||||
iconPacks: [
|
||||
{
|
||||
name: 'logos',
|
||||
loader: () => fetch('https://unpkg.com/@iconify-json/logos@1/icons.json').then(res => res.json())
|
||||
},
|
||||
],
|
||||
}),
|
||||
AutoImport({
|
||||
imports: [
|
||||
'./src/components/ReadMore.astro',
|
||||
],
|
||||
}),
|
||||
starlight({
|
||||
title: 'vJailbreak',
|
||||
editLink: {
|
||||
baseUrl: 'https://platform9.github.io/vjailbreak/',
|
||||
},
|
||||
social: {
|
||||
github: 'https://github.com/platform9/vjailbreak',
|
||||
slack: 'https://join.slack.com/t/vjailbreak/shared_invite/zt-314pppw43-F1vzd6ZaPW5PoZqF~aa8lA',
|
||||
},
|
||||
plugins: [],
|
||||
components: {
|
||||
Header: './src/components/Header.astro',
|
||||
//SocialIcons: './src/components/githubRelease.astro',
|
||||
},
|
||||
logo: {
|
||||
src: './src/assets/platform9-logo.svg',
|
||||
replacesTitle: true,
|
||||
},
|
||||
head: [
|
||||
],
|
||||
sidebar: [
|
||||
{
|
||||
label: 'Introduction',
|
||||
items: [
|
||||
// Each item here is one entry in the navigation menu.
|
||||
// manually done so to we can keep the order
|
||||
{ label: 'What is vJailbreak', slug: 'introduction/what_is_vjailbreak' },
|
||||
{ label: 'Getting Started', slug: 'introduction/getting_started' },
|
||||
{ label: 'Prerequisites', slug: 'introduction/prerequisites' },
|
||||
{ label: 'FAQ', slug: 'introduction/faq' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Concepts',
|
||||
items: [
|
||||
{ label: 'User Credential Management', slug: 'concepts/user-management' },
|
||||
{ label: 'Credential Management', slug: 'concepts/credential-management' },
|
||||
{ label: 'Network Persistence', slug: 'concepts/network-persistence' },
|
||||
{ label: 'Network & Storage Mapping', slug: 'concepts/network-storage-mapping' },
|
||||
{ label: 'Migration Options', slug: 'concepts/migration-options' },
|
||||
{ label: 'Cluster Conversion', slug: 'concepts/cluster-conversion' },
|
||||
{ label: 'Storage Accelerated Copy', slug: 'concepts/storage-accelerated-copy' },
|
||||
{ label: 'vJailbreak Accelerated Copy', slug: 'concepts/vjailbreak-accelerated-copy' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Architecture',
|
||||
items: [
|
||||
{ label: 'Architecture', slug: 'architecture/architecture-overview' },
|
||||
{ label: 'vJailbreak VM', slug: 'architecture/vjailbreak-vm' },
|
||||
{ label: 'Components', slug: 'architecture/components' },
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Guide',
|
||||
autogenerate: { directory: 'guides' },
|
||||
// items: [
|
||||
// { label: 'Scaling', slug: 'guides/How-to/scaling' },
|
||||
// { label: 'Troubleshooting', autogenerate: { directory: 'guides/troubleshooting' } },
|
||||
// { label: 'Building', slug: 'guides/How-to/building' },
|
||||
// { label: 'Using APIs', slug: 'guides/How-to/using_apis' },
|
||||
// { label: 'Injecting Custom Environment Variables', slug: 'guides/How-to/injecting_custom_env' },
|
||||
// { label: 'Debug Log Collection', slug: 'guides/How-to/debuglogs' },
|
||||
// { label: 'Debug vJailbreak Installation', slug: 'guides/How-to/debug_vjailbreak_install' },
|
||||
// { label: 'VirtIO Windows Driver Support', slug: 'guides/How-to/virtio_doc' },
|
||||
// ],
|
||||
},
|
||||
{
|
||||
label: 'Reference',
|
||||
items: [
|
||||
{ label: 'vJailbreak CRDs', slug: 'reference/reference' },
|
||||
{ label: 'Compatibility Matrix', slug: 'reference/compatibility' },
|
||||
{ label: 'Known Limitations', slug: 'reference/known-limitations' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Release Notes',
|
||||
autogenerate: { directory: 'release_docs' },
|
||||
},
|
||||
{
|
||||
label: 'Archives',
|
||||
autogenerate: { directory: 'archives' },
|
||||
},
|
||||
],
|
||||
customCss: [
|
||||
'./src/styles/custom.css'
|
||||
],
|
||||
}),
|
||||
mdx(),
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M81 36 64 0 47 36l-1 2-9-10a6 6 0 0 0-9 9l10 10h-2L0 64l36 17h2L28 91a6 6 0 1 0 9 9l9-10 1 2 17 36 17-36v-2l9 10a6 6 0 1 0 9-9l-9-9 2-1 36-17-36-17-2-1 9-9a6 6 0 1 0-9-9l-9 10v-2Zm-17 2-2 5c-4 8-11 15-19 19l-5 2 5 2c8 4 15 11 19 19l2 5 2-5c4-8 11-15 19-19l5-2-5-2c-8-4-15-11-19-19l-2-5Z" clip-rule="evenodd"/><path d="M118 19a6 6 0 0 0-9-9l-3 3a6 6 0 1 0 9 9l3-3Zm-96 4c-2 2-6 2-9 0l-3-3a6 6 0 1 1 9-9l3 3c3 2 3 6 0 9Zm0 82c-2-2-6-2-9 0l-3 3a6 6 0 1 0 9 9l3-3c3-2 3-6 0-9Zm96 4a6 6 0 0 1-9 9l-3-3a6 6 0 1 1 9-9l3 3Z"/><style>path{fill:#000}@media (prefers-color-scheme:dark){path{fill:#fff}}</style></svg>
|
||||
|
After Width: | Height: | Size: 696 B |
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^4.2.1",
|
||||
"@astrojs/starlight": "^0.32.1",
|
||||
"astro": "^5.1.5",
|
||||
"astro-auto-import": "^0.4.4",
|
||||
"astro-mermaid": "^1.0.4",
|
||||
"mermaid": "^11.9.0",
|
||||
"sharp": "^0.32.5"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-linux-x64-gnu": "4.6.1"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 416 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2.72 -1.34 64 64" width="64" height="64"><path d="M61.122 26.375l-9.805-4.016-11.813-4.725-10.04-4.135c-.236-.118-.354 0-.354 0l-9.923 4.016-1.772.71-8.27 3.426-11.813 4.725s-.118.118 0 .118l11.104 4.49 20.673 8.505h.354L50.018 31.1l11.104-4.49c.354-.118 0-.236 0-.236zm-13.467-4.016l-8.27 3.308-8.27-3.308 8.27-3.426zm-10.04 4.135l-8.27 3.426-8.27-3.308 8.27-3.426zm-8.387-11.577l8.27 3.426-8.27 3.426-8.27-3.426zm-10.04 4.016l8.27 3.426-8.27 3.426-8.387-3.426zm-18.3 7.56l8.27-3.308 8.27 3.426-8.27 3.308zm10.16 4.135l8.27-3.426 8.27 3.426-8.27 3.308zm18.192 7.442l-8.27-3.426 8.27-3.426 8.27 3.308zm10.16-4.135l-8.27-3.308 8.27-3.426 8.27 3.308zm10.16-4.135l-8.27-3.308 8.27-3.308 8.27 3.308z" fill="#00aae7"/><path d="M37.615 26.493l-8.27 3.426-8.27-3.426 8.27-3.426zm10.04 4.135l-8.27 3.308-8.27-3.308 8.27-3.426zm-10.16 4.135l-8.27 3.308-8.15-3.308 8.27-3.426z" fill="#008ccc"/><path d="M59.94 35.234L29.11 47.874-1.84 35.234 8.32 31.1l20.673 8.505h.354L49.9 31.218z" fill="#007bb6"/><path d="M17.415 26.493l-8.27 3.426-8.27-3.426 8.15-3.426z" fill="#68cef2"/><path d="M27.456 30.627l-8.27 3.426-8.15-3.426 8.15-3.308z" fill="#008ccc"/><path d="M27.574 22.358l-8.387 3.426-8.27-3.426 8.27-3.426zm10.04-4.135l-8.27 3.426-8.27-3.426 8.15-3.308zm10.04 4.135l-8.27 3.426-8.27-3.426 8.27-3.308zm10.04 4.135l-8.15 3.308-8.27-3.308 8.15-3.426z" fill="#68cef2"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 283 KiB |
|
After Width: | Height: | Size: 244 KiB |
|
After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 354 KiB |
|
After Width: | Height: | Size: 350 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 313 KiB |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 434 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 332 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 266 KiB |
|
After Width: | Height: | Size: 240 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 280 KiB |
|
After Width: | Height: | Size: 247 KiB |
|
After Width: | Height: | Size: 364 KiB |
|
After Width: | Height: | Size: 364 KiB |
|
After Width: | Height: | Size: 357 KiB |
|
After Width: | Height: | Size: 838 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 216 KiB |
|
After Width: | Height: | Size: 226 KiB |
|
After Width: | Height: | Size: 279 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 164 KiB |
|
After Width: | Height: | Size: 235 KiB |
|
After Width: | Height: | Size: 472 KiB |
|
After Width: | Height: | Size: 303 KiB |
|
After Width: | Height: | Size: 285 KiB |
|
After Width: | Height: | Size: 412 KiB |
@@ -0,0 +1,386 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Determines whether the Windows system disk is an LDM (dynamic) disk.
|
||||
|
||||
.DESCRIPTION
|
||||
Run this on the SOURCE VM in vCenter, before migrating with vJailbreak.
|
||||
|
||||
Windows VMs whose system volume sits on a dynamic disk (Logical Disk Manager)
|
||||
cannot be converted by virt-v2v and follow vJailbreak's dedicated SATA-first
|
||||
migration path, which has extra prerequisites. Dynamic DATA disks are
|
||||
irrelevant - only the disk carrying the system volume changes the outcome.
|
||||
|
||||
The script is strictly READ-ONLY. It issues no diskpart command other than
|
||||
'list disk', 'select volume', 'detail volume' and 'san', none of which modify
|
||||
the disk layout.
|
||||
|
||||
Detection uses four independent signals, so a wrong answer requires several
|
||||
of them to agree incorrectly:
|
||||
|
||||
1. GPT partition type GUID - 5808C8AA-... (LDM metadata)
|
||||
AF9B60A0-... (LDM data)
|
||||
2. MBR partition type byte - 0x42 (LDM)
|
||||
3. WMI Win32_DiskPartition.Type containing "Logical Disk Manager"
|
||||
4. diskpart's Dyn column in 'list disk' / 'detail volume'
|
||||
|
||||
The system volume is mapped to its physical disk(s) by three independent
|
||||
routes (Storage module, WMI associators, diskpart). On a dynamic disk the
|
||||
Storage-module route fails by design - the partition layer does not model LDM
|
||||
volumes - and that failure is itself recorded as corroborating evidence.
|
||||
|
||||
.PARAMETER LogPath
|
||||
Where the transcript is written. Defaults to %TEMP%\vjb-ldm-check.log.
|
||||
|
||||
.PARAMETER Quiet
|
||||
Suppress the per-signal transcript on the console. The verdict banner is
|
||||
always printed.
|
||||
|
||||
.OUTPUTS
|
||||
A verdict banner, plus a single machine-readable line:
|
||||
VJB_LDM_SYSTEM_DISK=YES|NO|UNKNOWN
|
||||
|
||||
Exit codes:
|
||||
0 NO system disk is basic - normal migration path
|
||||
1 YES system disk is LDM - SATA-first migration path
|
||||
2 UNKNOWN inconclusive, inspect the log
|
||||
|
||||
.NOTES
|
||||
Requires an elevated PowerShell session.
|
||||
Tested against Windows Server 2012 and later. Written to PowerShell 2.0
|
||||
syntax so it also runs on Windows Server 2008 R2, where the Storage module
|
||||
is absent and signals 1 and 2 are unavailable.
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string] $LogPath = (Join-Path $env:TEMP 'vjb-ldm-check.log'),
|
||||
[switch] $Quiet
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Continue'
|
||||
|
||||
# GPT partition type GUIDs that identify an LDM disk.
|
||||
$LDM_GPT_TYPES = @(
|
||||
'5808c8aa-7e8f-42e0-85d2-e1e90434cfb3', # LDM metadata partition
|
||||
'af9b60a0-1431-4f62-bc68-3311714a69ad' # LDM data partition
|
||||
)
|
||||
# MBR partition type byte 0x42 = LDM.
|
||||
$LDM_MBR_TYPE = 66
|
||||
|
||||
$script:LogLines = New-Object System.Collections.ArrayList
|
||||
|
||||
# ---------------------------------------------------------------- logging ----
|
||||
|
||||
function Write-Log {
|
||||
param([string] $Level, [string] $Message)
|
||||
|
||||
$line = '{0} [{1,-5}] {2}' -f (Get-Date).ToString('yyyy-MM-dd HH:mm:ss'), $Level, $Message
|
||||
[void] $script:LogLines.Add($line)
|
||||
|
||||
if (-not $Quiet) {
|
||||
$color = 'Gray'
|
||||
if ($Level -eq 'WARN') { $color = 'Yellow' }
|
||||
if ($Level -eq 'ERROR') { $color = 'Red' }
|
||||
if ($Level -eq 'HIT') { $color = 'Magenta' }
|
||||
Write-Host $line -ForegroundColor $color
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------- primitives ----
|
||||
|
||||
function Test-Elevated {
|
||||
try {
|
||||
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$principal = New-Object Security.Principal.WindowsPrincipal($identity)
|
||||
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-DiskPart {
|
||||
param([string[]] $Commands)
|
||||
|
||||
$scriptFile = [System.IO.Path]::GetTempFileName()
|
||||
try {
|
||||
Set-Content -Path $scriptFile -Value $Commands -Encoding ASCII
|
||||
$output = & diskpart.exe /s $scriptFile 2>&1
|
||||
return @($output | ForEach-Object { [string] $_ })
|
||||
} catch {
|
||||
Write-Log 'WARN' ("diskpart invocation failed: " + $_.Exception.Message)
|
||||
return @()
|
||||
} finally {
|
||||
Remove-Item $scriptFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
function Get-Column {
|
||||
# Slice a fixed-width diskpart column, bleeding one character either side
|
||||
# because diskpart does not always pad exactly to its own rule line.
|
||||
param([string] $Line, $Column, [int] $Bleed = 1)
|
||||
|
||||
$start = $Column.Start - $Bleed
|
||||
if ($start -lt 0) { $start = 0 }
|
||||
if ($Line.Length -le $start) { return '' }
|
||||
|
||||
$length = $Column.Length + ($Column.Start - $start) + $Bleed
|
||||
if (($start + $length) -gt $Line.Length) { $length = $Line.Length - $start }
|
||||
return $Line.Substring($start, $length)
|
||||
}
|
||||
|
||||
function Read-DiskPartDiskTable {
|
||||
# Both 'list disk' and 'detail volume' emit the same six-column table:
|
||||
#
|
||||
# Disk ### Status Size Free Dyn Gpt
|
||||
# -------- ------------- ------- ------- --- ---
|
||||
# Disk 0 Online 100 GB 0 B *
|
||||
#
|
||||
# Column offsets are taken from the rule line rather than from the header,
|
||||
# so parsing does not depend on the console language.
|
||||
param([string[]] $Lines)
|
||||
|
||||
$rows = @()
|
||||
$ruleIndex = -1
|
||||
$columns = @()
|
||||
|
||||
for ($i = 0; $i -lt $Lines.Count; $i++) {
|
||||
if ($Lines[$i] -match '^\s*-{3,}(\s+-{2,}){3,}\s*$') {
|
||||
$ruleIndex = $i
|
||||
foreach ($match in ([regex] '-{2,}').Matches($Lines[$i])) {
|
||||
$columns += New-Object PSObject -Property @{
|
||||
Start = $match.Index
|
||||
Length = $match.Length
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if ($ruleIndex -lt 0 -or $columns.Count -lt 5) {
|
||||
Write-Log 'WARN' 'Could not locate the diskpart column rule line; skipping this signal.'
|
||||
return $rows
|
||||
}
|
||||
|
||||
for ($i = $ruleIndex + 1; $i -lt $Lines.Count; $i++) {
|
||||
if ($Lines[$i].Trim().Length -eq 0) { break }
|
||||
|
||||
$number = [regex]::Match((Get-Column $Lines[$i] $columns[0] 0), '\d+')
|
||||
if (-not $number.Success) { continue }
|
||||
|
||||
$gpt = $false
|
||||
if ($columns.Count -ge 6) {
|
||||
$gpt = (Get-Column $Lines[$i] $columns[5]).Contains('*')
|
||||
}
|
||||
|
||||
$rows += New-Object PSObject -Property @{
|
||||
Number = [int] $number.Value
|
||||
Dynamic = (Get-Column $Lines[$i] $columns[4]).Contains('*')
|
||||
Gpt = $gpt
|
||||
}
|
||||
}
|
||||
|
||||
return $rows
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------ inspection -----
|
||||
|
||||
function Get-DynamicDiskEvidence {
|
||||
# Returns the disk numbers that at least one signal reports as LDM.
|
||||
param([bool] $StorageModule)
|
||||
|
||||
$dynamic = @{}
|
||||
|
||||
# Signal 4 - diskpart Dyn column.
|
||||
foreach ($row in (Read-DiskPartDiskTable (Invoke-DiskPart @('list disk')))) {
|
||||
$state = 'basic'
|
||||
if ($row.Dynamic) { $state = 'DYNAMIC'; $dynamic[$row.Number] = $true }
|
||||
Write-Log 'INFO' ('diskpart : disk {0} -> {1}' -f $row.Number, $state)
|
||||
}
|
||||
|
||||
# Signal 3 - WMI partition type string.
|
||||
foreach ($partition in @(Get-WmiObject -Class Win32_DiskPartition -ErrorAction SilentlyContinue)) {
|
||||
if ($partition.Type -match 'Logical Disk Manager|LDM') {
|
||||
$dynamic[[int] $partition.DiskIndex] = $true
|
||||
Write-Log 'HIT' ('Win32_DiskPartition: disk {0} partition type "{1}"' -f $partition.DiskIndex, $partition.Type)
|
||||
} else {
|
||||
Write-Log 'INFO' ('Win32_DiskPartition: disk {0} partition type "{1}"' -f $partition.DiskIndex, $partition.Type)
|
||||
}
|
||||
}
|
||||
|
||||
# Signals 1 and 2 - GPT type GUID and MBR type byte. Storage module only.
|
||||
if ($StorageModule) {
|
||||
foreach ($partition in @(Get-Partition -ErrorAction SilentlyContinue)) {
|
||||
$gptType = ''
|
||||
if ($partition.GptType) { $gptType = ($partition.GptType -replace '[{}]', '').ToLower() }
|
||||
|
||||
if ($LDM_GPT_TYPES -contains $gptType) {
|
||||
$dynamic[[int] $partition.DiskNumber] = $true
|
||||
Write-Log 'HIT' ('GPT type GUID : disk {0} partition {1} -> {2}' -f $partition.DiskNumber, $partition.PartitionNumber, $gptType)
|
||||
} elseif ([int] $partition.MbrType -eq $LDM_MBR_TYPE) {
|
||||
$dynamic[[int] $partition.DiskNumber] = $true
|
||||
Write-Log 'HIT' ('MBR type byte : disk {0} partition {1} -> 0x42 (LDM)' -f $partition.DiskNumber, $partition.PartitionNumber)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Log 'WARN' 'Storage module unavailable; partition-type signals skipped (expected on Server 2008 R2).'
|
||||
}
|
||||
|
||||
return @($dynamic.Keys | ForEach-Object { [int] $_ })
|
||||
}
|
||||
|
||||
function Get-SystemVolumeDiskNumber {
|
||||
# Three independent routes. Returns the union of whatever resolves.
|
||||
param([string] $DriveLetter, [bool] $StorageModule)
|
||||
|
||||
$found = @{}
|
||||
|
||||
# Route 1 - Storage module. Fails by design when the volume is LDM.
|
||||
if ($StorageModule) {
|
||||
$partition = Get-Partition -DriveLetter $DriveLetter -ErrorAction SilentlyContinue
|
||||
if ($partition) {
|
||||
$hit = @()
|
||||
foreach ($p in @($partition)) {
|
||||
$found[[int] $p.DiskNumber] = $true
|
||||
$hit += [string] $p.DiskNumber
|
||||
}
|
||||
Write-Log 'INFO' ('Get-Partition : {0}: resolves to disk {1}' -f $DriveLetter, ($hit -join ', '))
|
||||
} else {
|
||||
Write-Log 'WARN' ('Get-Partition : {0}: has no partition object. The partition layer does not model LDM volumes, so this is expected on a dynamic disk.' -f $DriveLetter)
|
||||
}
|
||||
}
|
||||
|
||||
# Route 2 - WMI associators. Also unavailable for LDM volumes.
|
||||
$query = "ASSOCIATORS OF {{Win32_LogicalDisk.DeviceID='{0}:'}} WHERE AssocClass=Win32_LogicalDiskToPartition" -f $DriveLetter
|
||||
$associated = @(Get-WmiObject -Query $query -ErrorAction SilentlyContinue)
|
||||
if ($associated.Count -gt 0) {
|
||||
$hit = @()
|
||||
foreach ($p in $associated) {
|
||||
$found[[int] $p.DiskIndex] = $true
|
||||
$hit += [string] $p.DiskIndex
|
||||
}
|
||||
Write-Log 'INFO' ('WMI associator: {0}: resolves to disk {1}' -f $DriveLetter, ($hit -join ', '))
|
||||
} else {
|
||||
Write-Log 'WARN' ('WMI associator: {0}: has no Win32_LogicalDiskToPartition association, which is typical for an LDM volume.' -f $DriveLetter)
|
||||
}
|
||||
|
||||
# Route 3 - diskpart. Works for both basic and dynamic volumes.
|
||||
$detail = Invoke-DiskPart @(('select volume ' + $DriveLetter), 'detail volume')
|
||||
foreach ($row in (Read-DiskPartDiskTable $detail)) {
|
||||
$found[$row.Number] = $true
|
||||
$state = 'basic'
|
||||
if ($row.Dynamic) { $state = 'DYNAMIC' }
|
||||
Write-Log 'INFO' ('detail volume : {0}: resides on disk {1} ({2})' -f $DriveLetter, $row.Number, $state)
|
||||
}
|
||||
|
||||
return @($found.Keys | ForEach-Object { [int] $_ })
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ main -----
|
||||
|
||||
Write-Log 'INFO' '=== vJailbreak LDM system-disk probe (read-only) ==='
|
||||
Write-Log 'INFO' ('Host : {0}' -f $env:COMPUTERNAME)
|
||||
Write-Log 'INFO' ('OS : {0}' -f (Get-WmiObject -Class Win32_OperatingSystem -ErrorAction SilentlyContinue).Caption)
|
||||
Write-Log 'INFO' ('PowerShell : {0}' -f $PSVersionTable.PSVersion.ToString())
|
||||
Write-Log 'INFO' ('System drive : {0}' -f $env:SystemDrive)
|
||||
|
||||
if (-not (Test-Elevated)) {
|
||||
Write-Log 'ERROR' 'Not running elevated. diskpart and the Storage module need Administrator rights.'
|
||||
Write-Log 'ERROR' 'Re-run this script from an elevated PowerShell session.'
|
||||
$verdict = 'UNKNOWN'
|
||||
} else {
|
||||
$driveLetter = $env:SystemDrive.Substring(0, 1)
|
||||
$storageModule = $null -ne (Get-Command Get-Disk -ErrorAction SilentlyContinue)
|
||||
Write-Log 'INFO' ('Storage module: {0}' -f $(if ($storageModule) { 'available' } else { 'NOT available' }))
|
||||
Write-Log 'INFO' '--- mapping the system volume to its physical disk(s) ---'
|
||||
|
||||
$systemDisks = Get-SystemVolumeDiskNumber -DriveLetter $driveLetter -StorageModule $storageModule
|
||||
|
||||
Write-Log 'INFO' '--- collecting LDM evidence for every disk ---'
|
||||
$dynamicDisks = Get-DynamicDiskEvidence -StorageModule $storageModule
|
||||
|
||||
Write-Log 'INFO' '--- summary ---'
|
||||
Write-Log 'INFO' ('System volume resides on disk(s) : {0}' -f $(if ($systemDisks.Count) { ($systemDisks | Sort-Object) -join ', ' } else { '<unresolved>' }))
|
||||
Write-Log 'INFO' ('Disks reported as LDM/dynamic : {0}' -f $(if ($dynamicDisks.Count) { ($dynamicDisks | Sort-Object) -join ', ' } else { 'none' }))
|
||||
|
||||
if ($systemDisks.Count -gt 0) {
|
||||
$hit = @($systemDisks | Where-Object { $dynamicDisks -contains $_ })
|
||||
if ($hit.Count -gt 0) {
|
||||
$verdict = 'YES'
|
||||
Write-Log 'HIT' ('System volume resides on dynamic disk(s): {0}' -f (($hit | Sort-Object) -join ', '))
|
||||
} else {
|
||||
$verdict = 'NO'
|
||||
$dataOnly = @($dynamicDisks | Where-Object { $systemDisks -notcontains $_ })
|
||||
if ($dataOnly.Count -gt 0) {
|
||||
Write-Log 'INFO' ('Disk(s) {0} are dynamic but carry no system volume. Data disks do not affect the migration path.' -f (($dataOnly | Sort-Object) -join ', '))
|
||||
}
|
||||
}
|
||||
} elseif ($dynamicDisks.Count -gt 0) {
|
||||
# No route could map the system volume to a disk, and dynamic disks
|
||||
# exist. Both mapping failures are themselves LDM symptoms.
|
||||
$verdict = 'YES'
|
||||
Write-Log 'HIT' 'The system volume could not be mapped to any partition object while dynamic disks are present. Both facts point to an LDM system volume.'
|
||||
} else {
|
||||
$verdict = 'UNKNOWN'
|
||||
Write-Log 'ERROR' 'The system volume could not be mapped to a disk and no LDM evidence was found. Inspect the log and check the disk layout manually.'
|
||||
}
|
||||
|
||||
# Informational only - not part of the verdict. The SAN policy is a
|
||||
# prerequisite for the LDM migration path.
|
||||
$sanOutput = Invoke-DiskPart @('san')
|
||||
foreach ($line in $sanOutput) {
|
||||
if ($line -match ':') {
|
||||
$trimmed = $line.Trim()
|
||||
if ($trimmed -match 'Online|Offline') {
|
||||
Write-Log 'INFO' ('SAN policy : {0}' -f $trimmed)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Persist the transcript before anything else can fail.
|
||||
try {
|
||||
Set-Content -Path $LogPath -Value $script:LogLines -Encoding ASCII
|
||||
Write-Host ''
|
||||
Write-Host ('Full transcript: {0}' -f $LogPath) -ForegroundColor DarkGray
|
||||
} catch {
|
||||
Write-Host ''
|
||||
Write-Host ('Could not write the transcript to {0}: {1}' -f $LogPath, $_.Exception.Message) -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- verdict ----
|
||||
# Printed last, on its own, so it is never buried in the transcript above.
|
||||
|
||||
$banner = 'Gray'
|
||||
if ($verdict -eq 'YES') { $banner = 'Red' }
|
||||
if ($verdict -eq 'NO') { $banner = 'Green' }
|
||||
if ($verdict -eq 'UNKNOWN') { $banner = 'Yellow' }
|
||||
|
||||
# Built by measurement rather than by hand-counted spaces, so the box always
|
||||
# closes regardless of the verdict length.
|
||||
$width = 64
|
||||
$rule = '#' * $width
|
||||
$blank = '#' + (' ' * ($width - 2)) + '#'
|
||||
$label = ' SYSTEM DISK IS LDM (DYNAMIC): ' + $verdict
|
||||
$pad = $width - 2 - $label.Length
|
||||
if ($pad -lt 0) { $pad = 0 }
|
||||
|
||||
Write-Host ''
|
||||
Write-Host $rule
|
||||
Write-Host $blank
|
||||
Write-Host ('#' + $label + (' ' * $pad) + '#') -ForegroundColor $banner
|
||||
Write-Host $blank
|
||||
Write-Host $rule
|
||||
Write-Host ''
|
||||
|
||||
if ($verdict -eq 'YES') {
|
||||
Write-Host 'This VM takes the SATA-first migration path. Install the VirtIO guest' -ForegroundColor Yellow
|
||||
Write-Host 'tools and set "diskpart > san policy=onlineall" on THIS VM before' -ForegroundColor Yellow
|
||||
Write-Host 'migrating, and expect a manual cutover at LDM Boot Verification.' -ForegroundColor Yellow
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
Write-Host ('VJB_LDM_SYSTEM_DISK={0}' -f $verdict)
|
||||
|
||||
if ($verdict -eq 'YES') { exit 1 }
|
||||
if ($verdict -eq 'NO') { exit 0 }
|
||||
exit 2
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://platform9.github.io/</loc></url><url><loc>https://platform9.github.io/guides/building/</loc></url><url><loc>https://platform9.github.io/guides/injecting_custom_env/</loc></url><url><loc>https://platform9.github.io/guides/scaling/</loc></url><url><loc>https://platform9.github.io/guides/troubleshooting/</loc></url><url><loc>https://platform9.github.io/guides/using_apis/</loc></url><url><loc>https://platform9.github.io/introduction/components/</loc></url><url><loc>https://platform9.github.io/introduction/getting_started/</loc></url><url><loc>https://platform9.github.io/introduction/prerequisites/</loc></url><url><loc>https://platform9.github.io/introduction/what_is_vjailbreak/</loc></url><url><loc>https://platform9.github.io/reference/example/</loc></url><url><loc>https://platform9.github.io/reference/reference/</loc></url><url><loc>https://platform9.github.io/release_docs/v012/</loc></url><url><loc>https://platform9.github.io/release_docs/v013/</loc></url><url><loc>https://platform9.github.io/release_docs/v014/</loc></url><url><loc>https://platform9.github.io/release_docs/v015/</loc></url><url><loc>https://platform9.github.io/release_docs/v016/</loc></url><url><loc>https://platform9.github.io/release_docs/v017/</loc></url><url><loc>https://platform9.github.io/release_docs/v018/</loc></url><url><loc>https://platform9.github.io/release_docs/v019/</loc></url></urlset>
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://platform9.github.io/sitemap-0.xml</loc></sitemap></sitemapindex>
|
||||
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 332 KiB |
|
After Width: | Height: | Size: 180 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 330 KiB |
|
After Width: | Height: | Size: 607 KiB |
|
After Width: | Height: | Size: 927 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2.72 -1.34 120 60" width="120" height="60"><path d="M102.768 40.478c-1.87 0-3.452 1.5-3.452 3.38 0 1.798 1.5 3.38 3.38 3.38.288 0 .575-.072.647-.072l-1.87 2.59c-.072.072-.072.144-.072.216s.144.144.216.144h.575c.144 0 .36-.144.503-.216l2.66-3.74c.072-.144.216-.36.288-.432 0-.072.575-1.08.575-1.798-.072-1.942-1.5-3.452-3.452-3.452zm2.373 3.38c0 1.295-1.08 2.373-2.373 2.373s-2.373-1.08-2.373-2.373 1.08-2.373 2.373-2.373 2.373 1.08 2.373 2.373z" fill="#00aae7"/><path d="M34.087 40.982c-.072-.144-.144-.216-.216-.216h-.72c-.144 0-.216.144-.288.216l-4.17 8.846c-.072.072-.072.216-.072.288 0 0 .072.072.144.072h.863c.072 0 .216 0 .216-.072.072-.072.072-.144.072-.216l.863-1.87c.072-.072.072-.144.072-.144h5.178c.072 0 .072 0 .072.072l.935 1.942c.072.072.072.216.288.216h.863c.072 0 .144-.072.144-.072s.072-.072 0-.144zm1.582 5.825h-4.315l2.158-4.53zm-9.925 2.23h-4.962V40.9c0-.144-.072-.216-.216-.216h-.72c-.216 0-.216.072-.216.216v9c0 .144.072.216.216.216h5.825c.144 0 .216-.072.216-.216l-.072-.647c0-.072 0-.144-.072-.216zm-12.873-8.27H8.628c-.288 0-.288.144-.288.36v8.846c0 .072.072.144.216.144h.647c.144 0 .216-.072.216-.288v-3.812c0-.072 0-.144.144-.144h3.524c1.654 0 2.805-1.08 2.805-2.59 0-1.223-.935-2.517-3.02-2.517zm1.942 2.59c0 .79-.647 1.582-1.87 1.582H9.635c-.072 0-.144-.072-.144-.144v-2.95c0-.072.072-.072.072-.072h3.38c.647 0 1.15.216 1.438.503s.432.647.432 1.08zm33.37-2.66H38.69c-.144 0-.144.072-.144.216v.575c0 .144 0 .216.216.216h4.1v8.127c0 .144.072.216.216.216h.72c.144 0 .216-.072.216-.216v-8.055h4.1c.216 0 .216-.072.216-.216V40.9c.072-.216-.072-.216-.144-.216zm34.017 2.59c0-1.295-.935-2.59-3.02-2.59h-4.243c-.288 0-.288.216-.288.36V49.9c0 .144.072.216.216.216h.647c.144 0 .216-.072.216-.288v-3.812c0-.072 0-.144.144-.144h1.438c.36.503 2.086 2.517 3.308 4.027a.55.55 0 0 0 .36.144h.863s.36 0 .216-.144l-.144-.144-3.236-3.955h.575c1.798.144 2.95-.935 2.95-2.517zm-1.08.072c0 .79-.647 1.582-1.87 1.582h-3.308c-.072 0-.144-.072-.144-.144v-2.95c0-.072.072-.072.072-.072h3.38c.647 0 1.15.216 1.438.503s.432.647.432 1.08zm-22.222-2.517h-7.264a.31.31 0 0 0-.288.288v8.918c0 .144.072.216.144.216h.79c.072 0 .144-.072.144-.144v-4.027h5.466c.072 0 .144-.072.144-.144v-.72c0-.072-.072-.144-.144-.144h-5.466v-2.95c0-.072 0-.072.072-.072h6.4c.144 0 .216-.072.216-.216v-.647c0-.072 0-.144-.072-.144 0-.216-.072-.216-.144-.216zm35.96-.144h-.575c-.144 0-.216.072-.288.144l-3.524 3.596s-.072 0-.072-.072l-3.452-3.524s-.144-.072-.288-.072h-.575c-.072 0-.216 0-.216.216v9c0 .216.072.216.216.216h.72c.072 0 .216 0 .216-.216V42.78L90.1 45.8a.55.55 0 0 0 .36.144c.216 0 .36-.144.36-.144l3.092-3.092v7.264c0 .144.072.216.216.216h.79c.144 0 .216-.072.216-.216v-9c-.072-.072-.072-.216-.288-.288zm-28.623-.216c-2.877 0-5.178 2.23-5.178 4.962s2.3 4.962 5.178 4.962 5.178-2.23 5.178-4.962-2.3-4.962-5.178-4.962zm4.027 4.9c0 2.086-1.798 3.812-4.027 3.812s-4.027-1.726-4.027-3.812 1.798-3.812 4.027-3.812c2.23.072 4.027 1.726 4.027 3.812z" fill="#00000a"/><path d="M82.068 16.98l-7.633-3.127-9.196-3.678-7.817-3.22c-.184-.092-.276 0-.276 0l-7.725 3.127-1.38.552-6.437 2.667L32.4 16.98s-.092.092 0 .092l8.644 3.494 16.093 6.62h.276l16-6.53 8.644-3.494c.276-.092 0-.184 0-.184zm-10.483-3.127l-6.437 2.575-6.437-2.575 6.437-2.667zm-7.817 3.22L57.33 19.74l-6.437-2.575 6.437-2.667zM57.24 8.06l6.437 2.667-6.437 2.667-6.437-2.667zm-7.817 3.127l6.437 2.667-6.437 2.667-6.53-2.667zM35.17 17.073l6.437-2.575 6.437 2.667-6.437 2.575zm7.91 3.22l6.437-2.667 6.437 2.667-6.437 2.575zm14.162 5.793l-6.437-2.667 6.437-2.667 6.437 2.575zm7.91-3.22l-6.437-2.575 6.437-2.667 6.437 2.575zm7.91-3.22l-6.437-2.575 6.437-2.575 6.437 2.575z" fill="#00aae7"/><path d="M63.768 17.073L57.33 19.74l-6.437-2.667 6.437-2.667zm7.817 3.22l-6.437 2.575-6.437-2.575 6.437-2.667zm-7.91 3.22l-6.437 2.575-6.345-2.575 6.437-2.667z" fill="#008ccc"/><path d="M81.15 23.878l-24 9.84-24.093-9.84 7.91-3.22 16.093 6.62h.276l16-6.53z" fill="#007bb6"/><path d="M48.043 17.073l-6.437 2.667-6.437-2.667 6.345-2.667z" fill="#68cef2"/><path d="M55.86 20.292l-6.437 2.667-6.345-2.667 6.345-2.575z" fill="#008ccc"/><path d="M55.952 13.855l-6.53 2.667-6.437-2.667 6.437-2.667zm7.817-3.22l-6.437 2.667-6.437-2.667L57.24 8.06zm7.817 3.22l-6.437 2.667-6.437-2.667 6.437-2.575zm7.817 3.22l-6.345 2.575-6.437-2.575 6.345-2.667z" fill="#68cef2"/></svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 299 KiB |
|
After Width: | Height: | Size: 286 KiB |
|
After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 69 KiB |