diff --git a/.docs/Dockerfile b/.docs/Dockerfile new file mode 100644 index 0000000..096ed9d --- /dev/null +++ b/.docs/Dockerfile @@ -0,0 +1,3 @@ +FROM nginx:latest + +COPY ./web /usr/share/nginx/html \ No newline at end of file diff --git a/_docs/img/bridge.png b/.docs/web/img/bridge.png similarity index 100% rename from _docs/img/bridge.png rename to .docs/web/img/bridge.png diff --git a/_docs/img/bridge_added.png b/.docs/web/img/bridge_added.png similarity index 100% rename from _docs/img/bridge_added.png rename to .docs/web/img/bridge_added.png diff --git a/_docs/img/briefing_me.png b/.docs/web/img/briefing_me.png similarity index 100% rename from _docs/img/briefing_me.png rename to .docs/web/img/briefing_me.png diff --git a/_docs/img/briefing_mission.png b/.docs/web/img/briefing_mission.png similarity index 100% rename from _docs/img/briefing_mission.png rename to .docs/web/img/briefing_mission.png diff --git a/_docs/img/cap_routes.png b/.docs/web/img/cap_routes.png similarity index 100% rename from _docs/img/cap_routes.png rename to .docs/web/img/cap_routes.png diff --git a/_docs/img/carrierroutes.png b/.docs/web/img/carrierroutes.png similarity index 100% rename from _docs/img/carrierroutes.png rename to .docs/web/img/carrierroutes.png diff --git a/_docs/img/cas_mission.png b/.docs/web/img/cas_mission.png similarity index 100% rename from _docs/img/cas_mission.png rename to .docs/web/img/cas_mission.png diff --git a/_docs/img/first-start/1.png b/.docs/web/img/first-start/1.png similarity index 100% rename from _docs/img/first-start/1.png rename to .docs/web/img/first-start/1.png diff --git a/_docs/img/kutaisi_dock_after.png b/.docs/web/img/kutaisi_dock_after.png similarity index 100% rename from _docs/img/kutaisi_dock_after.png rename to .docs/web/img/kutaisi_dock_after.png diff --git a/_docs/img/kutaisi_dock_before.png b/.docs/web/img/kutaisi_dock_before.png similarity index 100% rename from _docs/img/kutaisi_dock_before.png rename to .docs/web/img/kutaisi_dock_before.png diff --git a/_docs/img/kutaisi_loading_dock.png b/.docs/web/img/kutaisi_loading_dock.png similarity index 100% rename from _docs/img/kutaisi_loading_dock.png rename to .docs/web/img/kutaisi_loading_dock.png diff --git a/_docs/img/kutaisi_me.png b/.docs/web/img/kutaisi_me.png similarity index 100% rename from _docs/img/kutaisi_me.png rename to .docs/web/img/kutaisi_me.png diff --git a/_docs/img/sa2_mission_editor.png b/.docs/web/img/sa2_mission_editor.png similarity index 100% rename from _docs/img/sa2_mission_editor.png rename to .docs/web/img/sa2_mission_editor.png diff --git a/_docs/img/sa2_result.png b/.docs/web/img/sa2_result.png similarity index 100% rename from _docs/img/sa2_result.png rename to .docs/web/img/sa2_result.png diff --git a/_docs/img/script_install.png b/.docs/web/img/script_install.png similarity index 100% rename from _docs/img/script_install.png rename to .docs/web/img/script_install.png diff --git a/_docs/img/starting_stages.png b/.docs/web/img/starting_stages.png similarity index 100% rename from _docs/img/starting_stages.png rename to .docs/web/img/starting_stages.png diff --git a/_docs/img/strike_target.png b/.docs/web/img/strike_target.png similarity index 100% rename from _docs/img/strike_target.png rename to .docs/web/img/strike_target.png diff --git a/_docs/index.html b/.docs/web/index.html similarity index 100% rename from _docs/index.html rename to .docs/web/index.html diff --git a/_docs/js/components.js b/.docs/web/js/components.js similarity index 100% rename from _docs/js/components.js rename to .docs/web/js/components.js diff --git a/_docs/js/components/code-block.js b/.docs/web/js/components/code-block.js similarity index 98% rename from _docs/js/components/code-block.js rename to .docs/web/js/components/code-block.js index d21ec5d..90146f5 100644 --- a/_docs/js/components/code-block.js +++ b/.docs/web/js/components/code-block.js @@ -1,29 +1,29 @@ -class CodeBlock extends HTMLElement { - connectedCallback() { - // Get the code content as text, preserving whitespace - let code = this.textContent.replace(/\r\n?/g, "\n"); - // Remove leading/trailing blank lines - code = code.replace(/^\s*\n/, '').replace(/\n\s*$/, ''); - // Find leading spaces from the first non-empty line - const lines = code.split("\n"); - const firstLine = lines.find(line => line.trim().length > 0) || ''; - const leadingSpaces = firstLine.match(/^\s*/)[0].length; - // Remove that many leading spaces from all lines - const stripped = lines.map(line => line.slice(leadingSpaces)).join("\n"); - // Escape HTML special characters - const escaped = stripped - .replace(/&/g, "&") - .replace(//g, ">"); - const lang = this.getAttribute('lang') || ''; - const langClass = lang ? `language-${lang}` : ''; - this.innerHTML = `
${escaped}
`; - // If Prism or highlight.js is present, trigger highlighting - if (window.Prism && Prism.highlightElement) { - Prism.highlightElement(this.querySelector('code')); - } else if (window.hljs && hljs.highlightElement) { - hljs.highlightElement(this.querySelector('code')); - } - } -} -customElements.define('code-block', CodeBlock); +class CodeBlock extends HTMLElement { + connectedCallback() { + // Get the code content as text, preserving whitespace + let code = this.textContent.replace(/\r\n?/g, "\n"); + // Remove leading/trailing blank lines + code = code.replace(/^\s*\n/, '').replace(/\n\s*$/, ''); + // Find leading spaces from the first non-empty line + const lines = code.split("\n"); + const firstLine = lines.find(line => line.trim().length > 0) || ''; + const leadingSpaces = firstLine.match(/^\s*/)[0].length; + // Remove that many leading spaces from all lines + const stripped = lines.map(line => line.slice(leadingSpaces)).join("\n"); + // Escape HTML special characters + const escaped = stripped + .replace(/&/g, "&") + .replace(//g, ">"); + const lang = this.getAttribute('lang') || ''; + const langClass = lang ? `language-${lang}` : ''; + this.innerHTML = `
${escaped}
`; + // If Prism or highlight.js is present, trigger highlighting + if (window.Prism && Prism.highlightElement) { + Prism.highlightElement(this.querySelector('code')); + } else if (window.hljs && hljs.highlightElement) { + hljs.highlightElement(this.querySelector('code')); + } + } +} +customElements.define('code-block', CodeBlock); diff --git a/_docs/js/components/code-inline.js b/.docs/web/js/components/code-inline.js similarity index 97% rename from _docs/js/components/code-inline.js rename to .docs/web/js/components/code-inline.js index a5f1627..6e890ea 100644 --- a/_docs/js/components/code-inline.js +++ b/.docs/web/js/components/code-inline.js @@ -1,32 +1,32 @@ -class CodeInline extends HTMLElement { - connectedCallback() { - // Get the code content as text - let code = this.textContent; - - // Escape HTML special characters - code = code - .replace(/&/g, "&") - .replace(//g, ">"); - - // Highlight variables: $variable, {variable}, or %variable% - code = code.replace(/(\$[a-zA-Z_][\w]*)|(\{[^\}]+\})|(%[^%]+%)/g, match => - `${match}` - ); - - // Get language attribute for potential syntax highlighting - const lang = this.getAttribute('lang') || ''; - const langClass = lang ? `language-${lang}` : ''; - - this.innerHTML = `${code}`; - - // If Prism or highlight.js is present, trigger highlighting - if (window.Prism && Prism.highlightElement) { - Prism.highlightElement(this.querySelector('code')); - } else if (window.hljs && hljs.highlightElement) { - hljs.highlightElement(this.querySelector('code')); - } - } -} - -customElements.define('code-inline', CodeInline); +class CodeInline extends HTMLElement { + connectedCallback() { + // Get the code content as text + let code = this.textContent; + + // Escape HTML special characters + code = code + .replace(/&/g, "&") + .replace(//g, ">"); + + // Highlight variables: $variable, {variable}, or %variable% + code = code.replace(/(\$[a-zA-Z_][\w]*)|(\{[^\}]+\})|(%[^%]+%)/g, match => + `${match}` + ); + + // Get language attribute for potential syntax highlighting + const lang = this.getAttribute('lang') || ''; + const langClass = lang ? `language-${lang}` : ''; + + this.innerHTML = `${code}`; + + // If Prism or highlight.js is present, trigger highlighting + if (window.Prism && Prism.highlightElement) { + Prism.highlightElement(this.querySelector('code')); + } else if (window.hljs && hljs.highlightElement) { + hljs.highlightElement(this.querySelector('code')); + } + } +} + +customElements.define('code-inline', CodeInline); diff --git a/_docs/js/components/header.js b/.docs/web/js/components/header.js similarity index 100% rename from _docs/js/components/header.js rename to .docs/web/js/components/header.js diff --git a/_docs/js/components/latest-version-download.js b/.docs/web/js/components/latest-version-download.js similarity index 100% rename from _docs/js/components/latest-version-download.js rename to .docs/web/js/components/latest-version-download.js diff --git a/_docs/js/components/note.js b/.docs/web/js/components/note.js similarity index 96% rename from _docs/js/components/note.js rename to .docs/web/js/components/note.js index 8bd79f7..9f84344 100644 --- a/_docs/js/components/note.js +++ b/.docs/web/js/components/note.js @@ -1,35 +1,35 @@ -class Note extends HTMLElement { - connectedCallback() { - // Get the note content - const content = this.innerHTML; - - // Get optional type attribute for different note styles - const type = this.getAttribute('type') || 'default'; - - // Get optional title attribute - const title = this.getAttribute('title'); - - // Build the note HTML - let noteHTML = '
'; - - // Add title if provided - if (title) { - noteHTML += `

${title}

`; - } - - // Add the content - noteHTML += content; - noteHTML += '
'; - - this.innerHTML = noteHTML; - } -} - -customElements.define('note-box', Note); +class Note extends HTMLElement { + connectedCallback() { + // Get the note content + const content = this.innerHTML; + + // Get optional type attribute for different note styles + const type = this.getAttribute('type') || 'default'; + + // Get optional title attribute + const title = this.getAttribute('title'); + + // Build the note HTML + let noteHTML = '
'; + + // Add title if provided + if (title) { + noteHTML += `

${title}

`; + } + + // Add the content + noteHTML += content; + noteHTML += '
'; + + this.innerHTML = noteHTML; + } +} + +customElements.define('note-box', Note); diff --git a/_docs/js/components/sidebar.js b/.docs/web/js/components/sidebar.js similarity index 96% rename from _docs/js/components/sidebar.js rename to .docs/web/js/components/sidebar.js index f4e146f..3724238 100644 --- a/_docs/js/components/sidebar.js +++ b/.docs/web/js/components/sidebar.js @@ -1,198 +1,198 @@ -class Sidebar extends HTMLElement { - constructor() { - super(); - this.navItems = []; - } - - connectedCallback() { - this.render(); - this.scanHeaders(); - this.setupScrollListener(); - this.highlightActiveSection(); - } - - scanHeaders() { - // Clear existing nav items - this.navItems = []; - - // Find all h2, h3, and h4 elements with IDs in the content area - const contentWrapper = document.querySelector('.content-wrapper'); - if (!contentWrapper) return; - - const headers = contentWrapper.querySelectorAll('h2[id], h3[id], h4[id]'); - - headers.forEach(header => { - const id = header.getAttribute('id'); - const text = header.textContent.trim(); - const level = header.tagName.toLowerCase(); - - this.navItems.push({ - id, - text, - level, - element: header - }); - }); - - this.renderNavigation(); - } - - renderNavigation() { - const ul = this.querySelector('ul'); - if (!ul) return; - - // Clear existing content - ul.innerHTML = ''; - - let currentH2Li = null; - let currentH3Li = null; - - this.navItems.forEach(item => { - if (item.level === 'h2') { - // Create h2 item - const li = document.createElement('li'); - const a = document.createElement('a'); - a.href = `#${item.id}`; - a.className = 'side-nav-h2'; - a.textContent = item.text; - a.addEventListener('click', (e) => this.handleNavClick(e, item.id)); - - li.appendChild(a); - ul.appendChild(li); - currentH2Li = li; - currentH3Li = null; - } else if (item.level === 'h3' && currentH2Li) { - // Create h3 item under current h2 - let subUl = currentH2Li.querySelector('ul'); - if (!subUl) { - subUl = document.createElement('ul'); - currentH2Li.appendChild(subUl); - } - - const li = document.createElement('li'); - const a = document.createElement('a'); - a.href = `#${item.id}`; - a.className = 'side-nav-h3'; - a.textContent = item.text; - a.addEventListener('click', (e) => this.handleNavClick(e, item.id)); - - li.appendChild(a); - subUl.appendChild(li); - currentH3Li = li; - } else if (item.level === 'h4' && currentH3Li) { - // Create h4 item under current h3 - let subUl = currentH3Li.querySelector('ul'); - if (!subUl) { - subUl = document.createElement('ul'); - currentH3Li.appendChild(subUl); - } - - const li = document.createElement('li'); - const a = document.createElement('a'); - a.href = `#${item.id}`; - a.className = 'side-nav-h4'; - a.textContent = item.text; - a.addEventListener('click', (e) => this.handleNavClick(e, item.id)); - - li.appendChild(a); - subUl.appendChild(li); - } - }); - } - - handleNavClick(e, targetId) { - e.preventDefault(); - - // Remove active class from all links - this.querySelectorAll('a').forEach(link => { - link.classList.remove('active'); - }); - - // Add active class to clicked link - e.target.classList.add('active'); - - // Smooth scroll to target - const targetElement = document.getElementById(targetId); - if (targetElement) { - targetElement.scrollIntoView({ - behavior: 'smooth', - block: 'start' - }); - } - } - - setupScrollListener() { - let ticking = false; - - const handleScroll = () => { - if (!ticking) { - requestAnimationFrame(() => { - this.highlightActiveSection(); - ticking = false; - }); - ticking = true; - } - }; - - window.addEventListener('scroll', handleScroll); - } - - highlightActiveSection() { - const scrollTop = window.pageYOffset || document.documentElement.scrollTop; - const offset = 100; // Offset for highlighting - - let activeId = ''; - - // Find the currently visible section - this.navItems.forEach(item => { - const element = item.element; - const rect = element.getBoundingClientRect(); - const elementTop = rect.top + scrollTop; - - if (elementTop <= scrollTop + offset) { - activeId = item.id; - } - }); - - // Update active state - this.querySelectorAll('a').forEach(link => { - link.classList.remove('active'); - }); - - if (activeId !== nil && activeId !== '') { - const activeLink = this.querySelector(`a[href="#${activeId}"]`); - if (activeLink) { - activeLink.classList.add('active'); - } - } - } - - render() { - this.innerHTML = ` -
-

- -
- `; - } - - // Method to refresh the sidebar when content changes - refresh() { - this.scanHeaders(); - } - - // Method to set the sidebar title - setTitle(title) { - const titleElement = this.querySelector('.side-nav-title'); - if (titleElement) { - titleElement.textContent = title; - } - } -} - -// Register the custom element -customElements.define('app-sidebar', Sidebar); - +class Sidebar extends HTMLElement { + constructor() { + super(); + this.navItems = []; + } + + connectedCallback() { + this.render(); + this.scanHeaders(); + this.setupScrollListener(); + this.highlightActiveSection(); + } + + scanHeaders() { + // Clear existing nav items + this.navItems = []; + + // Find all h2, h3, and h4 elements with IDs in the content area + const contentWrapper = document.querySelector('.content-wrapper'); + if (!contentWrapper) return; + + const headers = contentWrapper.querySelectorAll('h2[id], h3[id], h4[id]'); + + headers.forEach(header => { + const id = header.getAttribute('id'); + const text = header.textContent.trim(); + const level = header.tagName.toLowerCase(); + + this.navItems.push({ + id, + text, + level, + element: header + }); + }); + + this.renderNavigation(); + } + + renderNavigation() { + const ul = this.querySelector('ul'); + if (!ul) return; + + // Clear existing content + ul.innerHTML = ''; + + let currentH2Li = null; + let currentH3Li = null; + + this.navItems.forEach(item => { + if (item.level === 'h2') { + // Create h2 item + const li = document.createElement('li'); + const a = document.createElement('a'); + a.href = `#${item.id}`; + a.className = 'side-nav-h2'; + a.textContent = item.text; + a.addEventListener('click', (e) => this.handleNavClick(e, item.id)); + + li.appendChild(a); + ul.appendChild(li); + currentH2Li = li; + currentH3Li = null; + } else if (item.level === 'h3' && currentH2Li) { + // Create h3 item under current h2 + let subUl = currentH2Li.querySelector('ul'); + if (!subUl) { + subUl = document.createElement('ul'); + currentH2Li.appendChild(subUl); + } + + const li = document.createElement('li'); + const a = document.createElement('a'); + a.href = `#${item.id}`; + a.className = 'side-nav-h3'; + a.textContent = item.text; + a.addEventListener('click', (e) => this.handleNavClick(e, item.id)); + + li.appendChild(a); + subUl.appendChild(li); + currentH3Li = li; + } else if (item.level === 'h4' && currentH3Li) { + // Create h4 item under current h3 + let subUl = currentH3Li.querySelector('ul'); + if (!subUl) { + subUl = document.createElement('ul'); + currentH3Li.appendChild(subUl); + } + + const li = document.createElement('li'); + const a = document.createElement('a'); + a.href = `#${item.id}`; + a.className = 'side-nav-h4'; + a.textContent = item.text; + a.addEventListener('click', (e) => this.handleNavClick(e, item.id)); + + li.appendChild(a); + subUl.appendChild(li); + } + }); + } + + handleNavClick(e, targetId) { + e.preventDefault(); + + // Remove active class from all links + this.querySelectorAll('a').forEach(link => { + link.classList.remove('active'); + }); + + // Add active class to clicked link + e.target.classList.add('active'); + + // Smooth scroll to target + const targetElement = document.getElementById(targetId); + if (targetElement) { + targetElement.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + } + } + + setupScrollListener() { + let ticking = false; + + const handleScroll = () => { + if (!ticking) { + requestAnimationFrame(() => { + this.highlightActiveSection(); + ticking = false; + }); + ticking = true; + } + }; + + window.addEventListener('scroll', handleScroll); + } + + highlightActiveSection() { + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + const offset = 100; // Offset for highlighting + + let activeId = ''; + + // Find the currently visible section + this.navItems.forEach(item => { + const element = item.element; + const rect = element.getBoundingClientRect(); + const elementTop = rect.top + scrollTop; + + if (elementTop <= scrollTop + offset) { + activeId = item.id; + } + }); + + // Update active state + this.querySelectorAll('a').forEach(link => { + link.classList.remove('active'); + }); + + if (activeId !== nil && activeId !== '') { + const activeLink = this.querySelector(`a[href="#${activeId}"]`); + if (activeLink) { + activeLink.classList.add('active'); + } + } + } + + render() { + this.innerHTML = ` +
+

+ +
+ `; + } + + // Method to refresh the sidebar when content changes + refresh() { + this.scanHeaders(); + } + + // Method to set the sidebar title + setTitle(title) { + const titleElement = this.querySelector('.side-nav-title'); + if (titleElement) { + titleElement.textContent = title; + } + } +} + +// Register the custom element +customElements.define('app-sidebar', Sidebar); + export default Sidebar; \ No newline at end of file diff --git a/_docs/js/prism.js b/.docs/web/js/prism.js similarity index 99% rename from _docs/js/prism.js rename to .docs/web/js/prism.js index 78f88d1..0be31c9 100644 --- a/_docs/js/prism.js +++ b/.docs/web/js/prism.js @@ -1,10 +1,10 @@ -/* Prism.js core and Lua support (minified for brevity, real project should use CDN or npm for updates) */ -// This is a placeholder. In production, use the official Prism.js CDN or npm package for updates and more languages. -// For demo purposes, you can use the CDN below in your HTML: -// -// -// -/* PrismJS 1.30.0 -https://prismjs.com/download#themes=prism-okaidia&languages=lua */ -var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=g.reach);A+=w.value.length,w=w.next){var P=w.value;if(n.length>e.length)return;if(!(P instanceof i)){var E,S=1;if(y){if(!(E=l(b,A,e,m))||E.index>=e.length)break;var L=E.index,O=E.index+E[0].length,C=A;for(C+=w.value.length;L>=C;)C+=(w=w.next).value.length;if(A=C-=w.value.length,w.value instanceof i)continue;for(var j=w;j!==n.tail&&(Cg.reach&&(g.reach=W);var I=w.prev;if(_&&(I=u(n,I,_),A+=_.length),c(n,I,S),w=u(n,I,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),S>1){var T={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,T),g&&T.reach>g.reach&&(g.reach=T.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); -Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/}; +/* Prism.js core and Lua support (minified for brevity, real project should use CDN or npm for updates) */ +// This is a placeholder. In production, use the official Prism.js CDN or npm package for updates and more languages. +// For demo purposes, you can use the CDN below in your HTML: +// +// +// +/* PrismJS 1.30.0 +https://prismjs.com/download#themes=prism-okaidia&languages=lua */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=g.reach);A+=w.value.length,w=w.next){var P=w.value;if(n.length>e.length)return;if(!(P instanceof i)){var E,S=1;if(y){if(!(E=l(b,A,e,m))||E.index>=e.length)break;var L=E.index,O=E.index+E[0].length,C=A;for(C+=w.value.length;L>=C;)C+=(w=w.next).value.length;if(A=C-=w.value.length,w.value instanceof i)continue;for(var j=w;j!==n.tail&&(Cg.reach&&(g.reach=W);var I=w.prev;if(_&&(I=u(n,I,_),A+=_.length),c(n,I,S),w=u(n,I,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),S>1){var T={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,T),g&&T.reach>g.reach&&(g.reach=T.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/}; diff --git a/_docs/js/site.js b/.docs/web/js/site.js similarity index 97% rename from _docs/js/site.js rename to .docs/web/js/site.js index 0375401..035a762 100644 --- a/_docs/js/site.js +++ b/.docs/web/js/site.js @@ -1,91 +1,91 @@ - -document.addEventListener('DOMContentLoaded', function() { - const themeToggle = document.getElementById('theme-toggle'); - const sunIcon = document.getElementById('sun-icon'); - const moonIcon = document.getElementById('moon-icon'); - if (!themeToggle || !sunIcon || !moonIcon) return; - - function setTheme(theme) { - document.documentElement.setAttribute('data-theme', theme); - localStorage.setItem('theme', theme); - sunIcon.style.display = theme === 'light' ? 'block' : 'none'; - moonIcon.style.display = theme === 'light' ? 'none' : 'block'; - } - - themeToggle.addEventListener('click', function() { - const current = document.documentElement.getAttribute('data-theme') || 'dark'; - setTheme(current === 'dark' ? 'light' : 'dark'); - }); - - // Initialize - const saved = localStorage.getItem('theme') || 'dark'; - setTheme(saved); - - // Set side-nav-title to the first h1's text - var h1 = document.querySelector('.content-wrapper h1'); - var sideNavTitle = document.querySelector('.side-nav-title'); - if (h1 && sideNavTitle) { - sideNavTitle.textContent = h1.textContent; - } -}); - -// Highlight sidenav link on scroll (shared for all pages) -function setupSideNavHighlight() { - const navLinks = document.querySelectorAll('.side-nav a'); - if (!navLinks.length) return; - const sections = Array.from(navLinks).map(link => { - const id = link.getAttribute('href').replace('#', ''); - return document.getElementById(id); - }); - function getHeaderOffset() { - const header = document.querySelector('header'); - return header ? header.offsetHeight : 0; - } - // Custom scroll on nav click - navLinks.forEach((link, i) => { - link.addEventListener('click', function(e) { - const section = sections[i]; - if (section) { - e.preventDefault(); - const headerOffset = getHeaderOffset(); - const targetY = window.innerHeight * 0.10; - const sectionTop = section.getBoundingClientRect().top + window.scrollY; - const scrollTo = sectionTop - headerOffset - targetY; - window.scrollTo({ top: scrollTo, behavior: 'smooth' }); - } - }); - }); - function onScroll() { - const headerOffset = getHeaderOffset(); - const targetY = window.innerHeight * 0.1; // 30% from the top - let closestIdx = 0; - let minDist = Infinity; - for (let i = 0; i < sections.length; i++) { - const section = sections[i]; - if (section) { - const dist = Math.abs(section.getBoundingClientRect().top - headerOffset - targetY); - if (dist < minDist) { - minDist = dist; - closestIdx = i; - } - } - } - navLinks.forEach((link, i) => { - if (i === closestIdx) { - link.classList.add('active'); - } else { - link.classList.remove('active'); - } - }); - } - window.addEventListener('scroll', onScroll, { passive: true }); - window.addEventListener('resize', onScroll); - onScroll(); // Initial call -} - -// Run on DOMContentLoaded -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', setupSideNavHighlight); -} else { - setupSideNavHighlight(); + +document.addEventListener('DOMContentLoaded', function() { + const themeToggle = document.getElementById('theme-toggle'); + const sunIcon = document.getElementById('sun-icon'); + const moonIcon = document.getElementById('moon-icon'); + if (!themeToggle || !sunIcon || !moonIcon) return; + + function setTheme(theme) { + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); + sunIcon.style.display = theme === 'light' ? 'block' : 'none'; + moonIcon.style.display = theme === 'light' ? 'none' : 'block'; + } + + themeToggle.addEventListener('click', function() { + const current = document.documentElement.getAttribute('data-theme') || 'dark'; + setTheme(current === 'dark' ? 'light' : 'dark'); + }); + + // Initialize + const saved = localStorage.getItem('theme') || 'dark'; + setTheme(saved); + + // Set side-nav-title to the first h1's text + var h1 = document.querySelector('.content-wrapper h1'); + var sideNavTitle = document.querySelector('.side-nav-title'); + if (h1 && sideNavTitle) { + sideNavTitle.textContent = h1.textContent; + } +}); + +// Highlight sidenav link on scroll (shared for all pages) +function setupSideNavHighlight() { + const navLinks = document.querySelectorAll('.side-nav a'); + if (!navLinks.length) return; + const sections = Array.from(navLinks).map(link => { + const id = link.getAttribute('href').replace('#', ''); + return document.getElementById(id); + }); + function getHeaderOffset() { + const header = document.querySelector('header'); + return header ? header.offsetHeight : 0; + } + // Custom scroll on nav click + navLinks.forEach((link, i) => { + link.addEventListener('click', function(e) { + const section = sections[i]; + if (section) { + e.preventDefault(); + const headerOffset = getHeaderOffset(); + const targetY = window.innerHeight * 0.10; + const sectionTop = section.getBoundingClientRect().top + window.scrollY; + const scrollTo = sectionTop - headerOffset - targetY; + window.scrollTo({ top: scrollTo, behavior: 'smooth' }); + } + }); + }); + function onScroll() { + const headerOffset = getHeaderOffset(); + const targetY = window.innerHeight * 0.1; // 30% from the top + let closestIdx = 0; + let minDist = Infinity; + for (let i = 0; i < sections.length; i++) { + const section = sections[i]; + if (section) { + const dist = Math.abs(section.getBoundingClientRect().top - headerOffset - targetY); + if (dist < minDist) { + minDist = dist; + closestIdx = i; + } + } + } + navLinks.forEach((link, i) => { + if (i === closestIdx) { + link.classList.add('active'); + } else { + link.classList.remove('active'); + } + }); + } + window.addEventListener('scroll', onScroll, { passive: true }); + window.addEventListener('resize', onScroll); + onScroll(); // Initial call +} + +// Run on DOMContentLoaded +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', setupSideNavHighlight); +} else { + setupSideNavHighlight(); } \ No newline at end of file diff --git a/_docs/pages/about_us.html b/.docs/web/pages/about_us.html similarity index 100% rename from _docs/pages/about_us.html rename to .docs/web/pages/about_us.html diff --git a/_docs/pages/advanced/CAP.html b/.docs/web/pages/advanced/CAP.html similarity index 100% rename from _docs/pages/advanced/CAP.html rename to .docs/web/pages/advanced/CAP.html diff --git a/_docs/pages/advanced/map-markings.html b/.docs/web/pages/advanced/map-markings.html similarity index 100% rename from _docs/pages/advanced/map-markings.html rename to .docs/web/pages/advanced/map-markings.html diff --git a/_docs/pages/advanced/missions.html b/.docs/web/pages/advanced/missions.html similarity index 100% rename from _docs/pages/advanced/missions.html rename to .docs/web/pages/advanced/missions.html diff --git a/_docs/pages/first-start.html b/.docs/web/pages/first-start.html similarity index 100% rename from _docs/pages/first-start.html rename to .docs/web/pages/first-start.html diff --git a/_docs/pages/include-script.html b/.docs/web/pages/include-script.html similarity index 100% rename from _docs/pages/include-script.html rename to .docs/web/pages/include-script.html diff --git a/_docs/pages/persistence.html b/.docs/web/pages/persistence.html similarity index 100% rename from _docs/pages/persistence.html rename to .docs/web/pages/persistence.html diff --git a/_docs/pages/reference.html b/.docs/web/pages/reference.html similarity index 100% rename from _docs/pages/reference.html rename to .docs/web/pages/reference.html diff --git a/_docs/pages/spearheadapi.html b/.docs/web/pages/spearheadapi.html similarity index 97% rename from _docs/pages/spearheadapi.html rename to .docs/web/pages/spearheadapi.html index 3965b3f..3ce88c9 100644 --- a/_docs/pages/spearheadapi.html +++ b/.docs/web/pages/spearheadapi.html @@ -1,60 +1,60 @@ - - - - - - - Spearhead API - - - - - - - - - - -
- -
-
- - -
-

Spearhead API

- -
-

NOTE: The Spearhead.API space is only released in the Beta branch at the moment.

-
- -

Introduction

-

- The Spearhead.API space is specifically created to make sure mission makers can interact with the framework. -

-

- Simply alter logic, get the current state in Spearhead, and give the whole Mission Editor more control. -

-

- For example, late activate the entire framework by calling Spearhead.API.Stages.changeStage(1) later or on demand and setting the starting config stage to -1 in the Spearhead configuration file. -

- -

Stages

-
-                    @@API_CODE@@
-                
-
-
-
-
-

© 2025 Spearhead Project

-
- - - + + + + + + + Spearhead API + + + + + + + + + + +
+ +
+
+ + +
+

Spearhead API

+ +
+

NOTE: The Spearhead.API space is only released in the Beta branch at the moment.

+
+ +

Introduction

+

+ The Spearhead.API space is specifically created to make sure mission makers can interact with the framework. +

+

+ Simply alter logic, get the current state in Spearhead, and give the whole Mission Editor more control. +

+

+ For example, late activate the entire framework by calling Spearhead.API.Stages.changeStage(1) later or on demand and setting the starting config stage to -1 in the Spearhead configuration file. +

+ +

Stages

+
+                    @@API_CODE@@
+                
+
+
+
+
+

© 2025 Spearhead Project

+
+ + + \ No newline at end of file diff --git a/_docs/pages/tutorials.html b/.docs/web/pages/tutorials.html similarity index 100% rename from _docs/pages/tutorials.html rename to .docs/web/pages/tutorials.html diff --git a/_docs/style/prism.css b/.docs/web/style/prism.css similarity index 99% rename from _docs/style/prism.css rename to .docs/web/style/prism.css index f3b8295..6d98055 100644 --- a/_docs/style/prism.css +++ b/.docs/web/style/prism.css @@ -1,3 +1,3 @@ -/* PrismJS 1.30.0 -https://prismjs.com/download#themes=prism-okaidia&languages=lua */ -code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help} +/* PrismJS 1.30.0 +https://prismjs.com/download#themes=prism-okaidia&languages=lua */ +code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help} diff --git a/_docs/style/style.css b/.docs/web/style/style.css similarity index 100% rename from _docs/style/style.css rename to .docs/web/style/style.css diff --git a/.gitea/workflows/update-docs.yml b/.gitea/workflows/update-docs.yml index 3a0dade..1d278bf 100644 --- a/.gitea/workflows/update-docs.yml +++ b/.gitea/workflows/update-docs.yml @@ -20,8 +20,10 @@ jobs: - name: Upload spearhead.lua artifact uses: actions/upload-artifact@v3 with: - name: spearhead-lua - path: ./output/spearhead.lua + name: spearhead-docs + path: ./.docs/**/* + retention-days: 1 + build-image: runs-on: ubuntu-latest diff --git a/_docs/Dockerfile b/_docs/Dockerfile deleted file mode 100644 index a5d9275..0000000 --- a/_docs/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM nginx:latest - -COPY ./ /usr/share/nginx/html \ No newline at end of file