Site updates for the weekend

This commit is contained in:
Eric Woodward 2023-02-27 02:51:18 -05:00
parent 3e53235230
commit c4b0500e10
107 changed files with 3504 additions and 679 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
gm-notes/
node_modules/ node_modules/
out/ out/
IDEAS.md IDEAS.md

View File

@ -1,6 +1,6 @@
{ {
"name": "planar-vagabond", "name": "planar-vagabond",
"version": "0.9.1", "version": "0.9.2",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,2 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/images/favicons/ms-icon-70x70.png"/><square150x150logo src="/images/favicons/ms-icon-150x150.png"/><square310x310logo src="/images/favicons/ms-icon-310x310.png"/><TileColor>#0d1852</TileColor></tile></msapplication></browserconfig> <browserconfig>
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#8fffff</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

View File

@ -1,348 +0,0 @@
/*!
* jQLite JavaScript Library v1.1.1 (http://code.google.com/p/jqlite/)
* Copyright (c) 2010 Brett Fattori (bfattori@gmail.com)
* Licensed under the MIT license
* http://www.opensource.org/licenses/mit-license.php
*
* Many thanks to the jQuery team's efforts. Some code is
* Copyright (c) 2010, John Resig. See
* http://jquery.org/license
*
* @author Brett Fattori (bfattori@gmail.com)
* @author $Author: bfattori $
* @version $Revision: 145 $
*
* Created: 03/29/2010
* Modified: $Date: 2010-06-21 11:08:14 -0400 (Mon, 21 Jun 2010) $
*/
(function(){function B(){return+new Date}var D=function(a,b){if(a===""&&b)return b;var d=a.split(" "),c=d.shift(),e;if(c.charAt(0)=="#"){var g=i.getElementById(c.substring(1));e=g?[g]:[]}else{e=c.charAt(0)!=="."?c.split(".")[0]:"*";var h=c.split("."),j=null;if(e.indexOf("[")!=-1){j=e;e=e.substr(0,e.indexOf("["))}g=function(o){var n=arguments.callee,k;if(!(k=!n.needClass)){k=n.classes;if(o.className.length==0)k=false;else{for(var r=o.className.split(" "),l=k.length,p=0;p<k.length;p++)f.inArray(k[p],
r)!=-1&&l--;k=l==0}}if(k=k){if(!(k=!n.needAttribute)){n=n.attributes;k=true;for(r=0;r<n.length;r++){l=n[r].split("=");p=l[0].indexOf("!")!=-1||l[0].indexOf("*")!=-1?l[0].charAt(l[0].length-1)+"=":"=";if(p!="=")l[0]=l[0].substring(0,l[0].length-1);switch(p){case "=":k&=o.getAttribute(l[0])===l[1];break;case "!=":k&=o.getAttribute(l[0])!==l[1];break;case "*=":k&=o.getAttribute(l[0]).indexOf(l[1])!=-1;break;default:k=false}}k=k}k=k}if(k)return o};for(var u=[],s=0;s<b.length;s++)for(var C=b[s].getElementsByTagName(e),
v=0;v<C.length;v++)u.push(C[v]);h&&h.shift();e=[];g.classes=h;if(j!=null){var w=j.indexOf("[");s=j.lastIndexOf("]");w=j.substring(w+1,s).split("][")}g.attributes=j!=null?w:null;g.needClass=c.indexOf(".")!=-1&&h.length>0;g.needAttribute=j!=null;for(c=0;c<u.length;c++)g(u[c])&&e.push(u[c])}return D(d.join(" "),e)},Q=function(a,b){b=b||i;if(a.nodeType&&a.nodeType===E){a=i.body;if(a===null)return[i]}if(a.nodeType&&a.nodeType===m)return[a];if(a.jquery&&typeof a.jquery==="string")return a.toArray();if(b)b=
F(b);if(f.isArray(a))return a;else if(typeof a==="string"){for(var d=[],c=0;c<b.length;c++){var e=[b[c]];if(!f.forceSimpleSelectorEngine&&e[0].querySelectorAll){e=e[0].querySelectorAll(a);for(var g=0;g<e.length;g++)d.push(e.item(g))}else d=d.concat(D(a,e))}return d}else return null},G=false;setTimeout(function(){var a=i.body;if(a){var b=i.createElement("script"),d="i"+(new Date).getTime();b.type="text/javascript";try{b.appendChild(i.createTextNode("window."+d+"=1;"))}catch(c){}a.insertBefore(b,a.firstChild);
var e=true;if(window[d])delete window[d];else e=false;a.removeChild(b);G=e}else setTimeout(arguments.callee,33)},33);var H=function(a){var b=i.createElement("div");b.innerHTML=a;return{scripts:b.getElementsByTagName("script"),data:a}},I=function(a){a=a.replace(/-/g," ");a=a;var b=true;b=b||false;a=!a?"":a.toString().replace(/^\s*|\s*$/g,"");var d="";if(a.length<=0)a="";else{var c=false;d+=b?a.charAt(0):a.charAt(0).toUpperCase();for(b=1;b<a.length;b++){d+=c?a.charAt(b).toUpperCase():a.charAt(b).toLowerCase();
var e=a.charCodeAt(b);c=e==32||e==45||e==46;if(e==99||e==67)if(a.charCodeAt(b-1)==77||a.charCodeAt(b-1)==109)c=true}a=d}return a.replace(/ /g,"")},J={click:"MouseEvents",dblclick:"MouseEvents",mousedown:"MouseEvents",mouseup:"MouseEvents",mouseover:"MouseEvents",mousemove:"MouseEvents",mouseout:"MouseEvents",contextmenu:"MouseEvents",keypress:"KeyEvents",keydown:"KeyEvents",keyup:"KeyEvents",load:"HTMLEvents",unload:"HTMLEvents",abort:"HTMLEvents",error:"HTMLEvents",resize:"HTMLEvents",scroll:"HTMLEvents",
select:"HTMLEvents",change:"HTMLEvents",submit:"HTMLEvents",reset:"HTMLEvents",focus:"HTMLEvents",blur:"HTMLEvents",touchstart:"MouseEvents",touchend:"MouseEvents",touchmove:"MouseEvents"},K=function(a,b,d){if(f.isFunction(d)){if(typeof b==="string")b=b.toLowerCase();var c=J[b];if(b.indexOf("on")==0)b=b.substring(2);if(c){c=function(e){var g=arguments.callee,h=e.data||[];h.unshift(e);g=g.fn.apply(a,h);if(typeof g!="undefined"&&g===false){if(e.preventDefault&&e.stopPropagation){e.preventDefault();
e.stopPropagation()}else{e.returnValue=false;e.cancelBubble=true}return false}return true};c.fn=d;a.addEventListener?a.addEventListener(b,c,false):a.attachEvent("on"+b,c)}else{if(!a._handlers)a._handlers={};c=a._handlers[b]||[];c.push(d);a._handlers[b]=c}}},f=function(a,b){return(new x).init(a,b)},i=window.document,y=Object.prototype.hasOwnProperty,z=Object.prototype.toString,L=Array.prototype.push,R=Array.prototype.slice,m=1,E=9,A=[],M=false,N=false,q;f.forceSimpleSelectorEngine=false;f.each=function(a,
b){var d,c=0,e=a.length;if(e===undefined||f.isFunction(a))for(d in a){if(b.call(a[d],d,a[d])===false)break}else for(d=a[0];c<e&&b.call(d,c,d)!==false;d=a[++c]);return a};f.noop=function(){};f.isFunction=function(a){return z.call(a)==="[object Function]"};f.isArray=function(a){return z.call(a)==="[object Array]"};f.isPlainObject=function(a){if(!a||z.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!y.call(a,"constructor")&&!y.call(a.constructor.prototype,"isPrototypeOf"))return false;
var b;for(b in a);return b===undefined||y.call(a,b)};f.merge=function(a,b){var d=a.length,c=0;if(typeof b.length==="number")for(var e=b.length;c<e;c++)a[d++]=b[c];else for(;b[c]!==undefined;)a[d++]=b[c++];a.length=d;return a};f.param=function(a){var b="";a&&f.each(a,function(d,c){b+=(b.length!=0?"&":"")+c+"="+encodeURIComponent(d)});return b};f.evalScripts=function(a){for(var b=i.getElementsByTagName("head")[0]||i.documentElement,d=0;d<a.length;d++){var c=i.createElement("script");c.type="text/javascript";
if(G)c.appendChild(i.createTextNode(a[d].text));else c.text=a[d].text;b.insertBefore(c,b.firstChild);b.removeChild(c)}};f.ready=function(){for(M=true;A.length>0;)A.shift()()};var t="jQuery"+B(),S=0,O={};f.noData={embed:true,object:true,applet:true};f.cache={};f.data=function(a,b,d){if(!(a.nodeName&&jQuery.noData[a.nodeName.toLowerCase()])){a=a==window?O:a;var c=a[t];c||(c=a[t]=++S);if(b&&!jQuery.cache[c])jQuery.cache[c]={};if(d!==undefined)jQuery.cache[c][b]=d;return b?jQuery.cache[c][b]:c}};f.removeData=
function(a,b){a=a==window?O:a;var d=a[t];if(b){if(jQuery.cache[d]){delete jQuery.cache[d][b];b="";for(b in jQuery.cache[d])break;b||jQuery.removeData(a)}}else{try{delete a[t]}catch(c){a.removeAttribute&&a.removeAttribute(t)}delete jQuery.cache[d]}};f.ajax={status:-1,statusText:"",responseText:null,responseXML:null,send:function(a,b,d){if(f.isFunction(b)){d=b;b={}}if(a){var c=true,e=null,g=null;if(typeof b.async!=="undefined"){c=b.async;delete b.async}if(typeof b.username!=="undefined"){e=b.username;
delete b.username}if(typeof b.password!=="undefined"){g=b.password;delete b.password}b=f.param(b);if(b.length!=0)a+=(a.indexOf("?")==-1?"?":"&")+b;b=new XMLHttpRequest;b.open("GET",a,c,e,g);b.send();if(c){a=function(h){var j=arguments.callee;h.status==200?f.ajax.complete(h,j.cb):f.ajax.error(h,j.cb)};a.cb=d;d=function(){var h=arguments.callee;h.req.readyState!=4?setTimeout(h,250):h.xcb(h.req)};d.req=b;d.xcb=a;setTimeout(d,250)}}},complete:function(a,b){f.ajax.status=a.status;f.ajax.responseText=a.responseText;
f.ajax.responseXML=a.responseXML;f.isFunction(b)&&b(a.responseText,a.status)},error:function(a,b){f.ajax.status=a.status;f.ajax.statusText=a.statusText;f.isFunction(b)&&b(a.status,a.statusText)}};f.makeArray=function(a,b){var d=b||[];if(a!=null)a.length==null||typeof a==="string"||jQuery.isFunction(a)||typeof a!=="function"&&a.setInterval?L.call(d,a):f.merge(d,a);return d};f.inArray=function(a,b){for(var d=0;d<b.length;d++)if(b[d]===a)return d;return-1};f.trim=function(a){return a!=null?a.toString().replace(/^\s*|\s*$/g,
""):""};var x=function(){};x.prototype={selector:"",context:null,length:0,jquery:"jqlite-1.1.1",init:function(a,b){if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1}else if(typeof a==="function")this.ready(a);else{var d=[];if(a.jquery&&typeof a.jquery==="string")d=a.toArray();else if(f.isArray(a))d=a;else if(typeof a==="string"&&f.trim(a).indexOf("<")==0&&f.trim(a).indexOf(">")!=-1){d=f.trim(a).toLowerCase();d=d.indexOf("<option")==0?"SELECT":d.indexOf("<li")==0?"UL":d.indexOf("<tr")==
0?"TBODY":d.indexOf("<td")==0?"TR":"DIV";d=i.createElement(d);d.innerHTML=a;d=[d.removeChild(d.firstChild)]}else{if(a.indexOf(",")!=-1){d=a.split(",");for(var c=0;c<d.length;c++)d[c]=f.trim(d[c])}else d=[a];c=[];for(var e=0;e<d.length;e++)c=c.concat(Q(d[e],b));d=c}L.apply(this,d)}return this},each:function(a){return f.each(this,a)},size:function(){return this.length},toArray:function(){return R.call(this,0)},ready:function(a){if(M)a();else{A.push(a);return this}},data:function(a,b){if(typeof a===
"undefined"&&this.length)return jQuery.data(this[0]);else if(typeof a==="object")return this.each(function(){jQuery.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===undefined){if(data===undefined&&this.length)data=jQuery.data(this[0],a);return data===undefined&&d[1]?this.data(d[0]):data}else return this.each(function(){jQuery.data(this,a,b)})},removeData:function(a){return this.each(function(){jQuery.removeData(this,a)})},addClass:function(a){return this.each(function(){if(this.className.length!=
0){var b=this.className.split(" ");if(f.inArray(a,b)==-1){b.push(a);this.className=b.join(" ")}}else this.className=a})},removeClass:function(a){return this.each(function(){if(this.className.length!=0){var b=this.className.split(" "),d=f.inArray(a,b);if(d!=-1){b.splice(d,1);this.className=b.join(" ")}}})},hasClass:function(a){if(this[0].className.length==0)return false;return f.inArray(a,this[0].className.split(" "))!=-1},isElementName:function(a){return this[0].nodeName.toLowerCase()===a.toLowerCase()},
toggleClass:function(a){return this.each(function(){if(this.className.length==0)this.className=a;else{var b=this.className.split(" "),d=f.inArray(a,b);d!=-1?b.splice(d,1):b.push(a);this.className=b.join(" ")}})},hide:function(a){return this.each(function(){if(this.style&&this.style.display!=null)if(this.style.display.toString()!="none"){this._oldDisplay=this.style.display.toString()||(this.nodeName!="span"?"block":"inline");this.style.display="none"}f.isFunction(a)&&a(this)})},show:function(a){return this.each(function(){this.style.display=
(this._oldDisplay&&this._oldDisplay!=""?this._oldDisplay:null)||(this.nodeName!="span"?"block":"inline");f.isFunction(a)&&a(this)})},css:function(a,b){if(typeof a==="string"&&b==null)return this[0].style[I(a)];else{a=typeof a==="string"?P(a,b):a;return this.each(function(){var d=this;typeof d.style!="undefined"&&f.each(a,function(c,e){e=typeof e==="number"?e+"px":e;var g=I(c);d.style[g]||(g=c);d.style[g]=e})})}},load:function(a,b,d){if(f.isFunction(b)){d=b;b={}}return this.each(function(){var c=function(e,
g){var h=arguments.callee;if(e){var j=H(e);h.elem.innerHTML=j.data;f.evalScripts(j.scripts)}f.isFunction(h.cback)&&h.cback(e,g)};c.cback=d;c.elem=this;f.ajax.send(a,b,c)})},html:function(a){return a?this.each(function(){var b=H(a);this.innerHTML=b.data;f.evalScripts(b.scripts)}):this[0].innerHTML},attr:function(a,b){return typeof a==="string"&&b==null?this[0]?this[0].getAttribute(a):"":this.each(function(){a=typeof a==="string"?P(a,b):a;for(var d in a)this.setAttribute(d,a[d])})},eq:function(a){var b=
this.toArray();this.context=this[0]=a<0?b[b.length+a]:b[a];this.length=1;return this},first:function(){this.context=this[0]=this.toArray()[0];this.length=1;return this},last:function(){var a=this.toArray();this.context=this[0]=a[a.length-1];this.length=1;return this},index:function(a){var b=-1;if(this.length!=0){var d=this[0];if(a){var c=f(a)[0];this.each(function(g){if(this===c){b=g;return false}})}else{a=this.parent()[0].firstChild;for(var e=[];a!=null;){a.nodeType===m&&e.push(a);a=a.nextSibling}f.each(a,
function(g){if(this===d){b=g;return false}})}}return b},next:function(a){var b=[];if(a){var d=f(a);this.each(function(){for(var c=this.nextSibling;c!=null&&c.nodeType!==m;)c=c.nextSibling;if(c!=null){var e=false;d.each(function(){if(this==c){e=true;return false}});e&&b.push(c)}})}else this.each(function(){for(var c=this.nextSibling;c!=null&&c.nodeType!==m;)c=c.nextSibling;c!=null&&b.push(c)});return f(b)},prev:function(a){var b=[];if(a){var d=f(a);this.each(function(){for(var c=this.previousSibling;c!=
null&&c.nodeType!==m;)c=c.previousSibling;if(c!=null){var e=false;d.each(function(){if(this==c){e=true;return false}});e&&b.push(c)}})}else this.each(function(){for(var c=this.previousSibling;c!=null&&c.nodeType!==m;)c=c.previousSibling;c!=null&&b.push(c)});return f(b)},parent:function(a){var b=[];if(a){var d=f(a);this.each(function(){var c=this.parentNode,e=false;d.each(function(){if(this==c){e=true;return false}});e&&b.push(c)})}else this.each(function(){b.push(this.parentNode)});return f(b)},parents:function(a){var b=
[];if(a){var d=f(a);this.each(function(){for(var c=this;c!=i.body;){d.each(function(){this==c&&b.push(c)});c=c.parentNode}})}else this.each(function(){for(var c=this;c!=i.body;){c=c.parentNode;b.push(c)}});return f(b)},children:function(a){var b=[];if(a){var d=f(a);this.each(function(){for(var c=this.firstChild;c!=null;){c.nodeType==m&&d.each(function(){this===c&&b.push(c)});c=c.nextSibling}})}else this.each(function(){for(var c=this.firstChild;c!=null;){c.nodeType==m&&b.push(c);c=c.nextSibling}});
return f(b)},append:function(a){a=F(a);return this.each(function(){for(var b=0;b<a.length;b++)this.appendChild(a[b])})},remove:function(a){return this.each(function(){a?$(a,this).remove():this.parentNode.removeChild(this)})},empty:function(){return this.each(function(){this.innerHTML=""})},val:function(a){if(a==null){var b=null;if(this&&this.length!=0&&typeof this[0].value!="undefined")b=this[0].value;return b}else return this.each(function(){if(typeof this.value!="undefined")this.value=a})},bind:function(a,
b){return this.each(function(){K(this,a,b)})},trigger:function(a,b){return this.each(function(){var d;var c;c=a;if(typeof c==="string")c=c.toLowerCase();var e=null,g=J[c]||"Event";if(i.createEvent){e=i.createEvent(g);e._eventClass=g;c&&e.initEvent(c,true,true)}if(i.createEventObject){e=i.createEventObject();if(c){e.type=c;e._eventClass=g}}c=e;if(c._eventClass!=="Event"){c.data=b;d=this.dispatchEvent(c)}else if(e=(this._handlers||{})[a])for(g=0;g<e.length;g++){var h=f.isArray(b)?b:[];h.unshift(c);
h=e[g].apply(this,h);if(!(typeof h=="undefined"?true:h))break}return d})},submit:function(a){return this.each(function(){if(f.isFunction(a))K(this,"onsubmit",a);else this.submit&&this.submit()})}};if(i.addEventListener)q=function(){i.removeEventListener("DOMContentLoaded",q,false);f.ready()};else if(i.attachEvent)q=function(){if(i.readyState==="complete"){i.detachEvent("onreadystatechange",q);f.ready()}};if(!N){N=true;if(i.readyState==="complete")return f.ready();if(i.addEventListener){i.addEventListener("DOMContentLoaded",
q,false);window.addEventListener("load",f.ready,false)}else if(i.attachEvent){i.attachEvent("onreadystatechange",q);window.attachEvent("onload",f.ready)}}var P=function(a,b){var d={};d[a]=b;return d},F=function(a){if(a.nodeType&&(a.nodeType===m||a.nodeType===E))a=[a];else if(typeof a==="string")a=f(a).toArray();else if(a.jquery&&typeof a.jquery==="string")a=a.toArray();return a};if(typeof window.jQuery=="undefined"){window.jQuery=f;window.jQuery.fn=x.prototype;window.$=window.jQuery;window.now=B}jQuery.extend=
jQuery.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,c=false,e,g,h,j;if(typeof a==="boolean"){c=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!jQuery.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(g in e){h=a[g];j=e[g];if(a!==j)if(c&&j&&(jQuery.isPlainObject(j)||jQuery.isArray(j))){h=h&&(jQuery.isPlainObject(h)||jQuery.isArray(h))?h:jQuery.isArray(j)?[]:{};a[g]=jQuery.extend(c,h,j)}else if(j!==undefined)a[g]=j}return a};jQuery.each("click,dblclick,mouseover,mouseout,mousedown,mouseup,keydown,keypress,keyup,focus,blur,change,select,error,load,unload,scroll,resize,touchstart,touchend,touchmove".split(","),
function(a,b){jQuery.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)}})})();
(function() {
this.Dosbox = (function() {
function Dosbox(options) {
this.onload = options.onload;
this.onrun = options.onrun;
this.ui = new Dosbox.UI(options);
this.module = new Dosbox.Module({
canvas: this.ui.canvas
});
this.ui.onStart((function(_this) {
return function() {
_this.ui.showLoader();
return _this.downloadScript();
};
})(this));
}
Dosbox.prototype.run = function(archiveUrl, executable) {
return new Dosbox.Mount(this.module, archiveUrl, {
success: (function(_this) {
return function() {
var func, hide;
_this.ui.updateMessage("Launching " + executable);
hide = function() {
return _this.ui.hideLoader();
};
func = function() {
return _this._dosbox_main(_this, executable);
};
setTimeout(func, 1000);
return setTimeout(hide, 3000);
};
})(this),
progress: (function(_this) {
return function(total, current) {
return _this.ui.updateMessage("Mount " + executable + " (" + (current * 100 / total | 0) + "%)");
};
})(this)
});
};
Dosbox.prototype.requestFullScreen = function() {
if (this.module.requestFullScreen) {
return this.module.requestFullScreen(true, false);
}
};
Dosbox.prototype.downloadScript = function() {
this.module.setStatus('Downloading js-dos');
this.ui.updateMessage('Downloading js-dos');
return new Dosbox.Xhr('https://js-dos.com/cdn/js-dos-v3.js', {
success: (function(_this) {
return function(script) {
var func;
_this.ui.updateMessage('Initializing dosbox');
func = function() {
return _this._jsdos_init(_this.module, script, _this.onload);
};
return setTimeout(func, 1000);
};
})(this),
progress: (function(_this) {
return function(total, current) {
return _this.ui.updateMessage("Downloading js-dos (" + (current * 100 / total | 0) + "%)");
};
})(this)
});
};
Dosbox.prototype._jsdos_init = function(module, script, onload) {
var Module;
Module = module;
eval(script);
if (onload) {
return onload(this);
}
};
Dosbox.prototype._dosbox_main = function(dosbox, executable) {
var exception, func;
try {
if (dosbox.onrun) {
func = function() {
return dosbox.onrun(dosbox, executable);
};
setTimeout(func, 1000);
}
return dosbox.module.ccall('dosbox_main', 'int', ['string'], [executable]);
} catch (error) {
exception = error;
if (exception === 'SimulateInfiniteLoop') {
} else {
return typeof console !== "undefined" && console !== null ? typeof console.error === "function" ? console.error(exception) : void 0 : void 0;
}
}
};
return Dosbox;
})();
}).call(this);
(function() {
Dosbox.Module = (function() {
function Module(options) {
this.elCanvas = options.canvas;
this.canvas = this.elCanvas[0];
}
Module.prototype.preRun = [];
Module.prototype.postRun = [];
Module.prototype.totalDependencies = 0;
Module.prototype.print = function(text) {
text = Array.prototype.slice.call(arguments).join(' ');
return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(text) : void 0 : void 0;
};
Module.prototype.printErr = function(text) {
text = Array.prototype.slice.call(arguments).join(' ');
return typeof console !== "undefined" && console !== null ? typeof console.error === "function" ? console.error(text) : void 0 : void 0;
};
Module.prototype.setStatus = function(text) {
return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(text) : void 0 : void 0;
};
Module.prototype.monitorRunDependencies = function(left) {
var status;
this.totalDependencies = Math.max(this.totalDependencies, left);
status = left ? "Preparing... (" + (this.totalDependencies - left) + "/" + this.totalDependencies + ")" : 'All downloads complete.';
return this.setStatus(status);
};
return Module;
})();
}).call(this);
(function() {
Dosbox.Mount = (function() {
function Mount(module, url, options) {
this.module = module;
new Dosbox.Xhr(url, {
success: (function(_this) {
return function(data) {
var bytes;
bytes = _this._toArray(data);
if (_this._mountZip(bytes)) {
return options.success();
} else {
return typeof console !== "undefined" && console !== null ? typeof console.error === "function" ? console.error('Unable to mount', url) : void 0 : void 0;
}
};
})(this),
progress: options.progress
});
}
Mount.prototype._mountZip = function(bytes) {
var buffer, extracted;
buffer = this.module._malloc(bytes.length);
this.module.HEAPU8.set(bytes, buffer);
extracted = this.module.ccall('extract_zip', 'int', ['number', 'number'], [buffer, bytes.length]);
this.module._free(buffer);
return extracted === 0;
};
Mount.prototype._toArray = function(data) {
var arr, i, len;
if (typeof data === 'string') {
arr = new Array(data.length);
i = 0;
len = data.length;
while (i < len) {
arr[i] = data.charCodeAt(i);
++i;
}
return arr;
}
return data;
};
return Mount;
})();
}).call(this);
(function() {
Dosbox.UI = (function() {
function UI(options) {
this.appendCss();
this.div = $('#' + (options.id || 'dosbox'));
this.wrapper = $('<div class="dosbox-container">');
this.canvas = $('<canvas class="dosbox-canvas" oncontextmenu="event.preventDefault()">');
this.overlay = $('<div class="dosbox-overlay">');
this.loaderMessage = $('<div class="dosbox-loader-message">');
this.loader = $('<div class="dosbox-loader">').append($('<div class="st-loader">').append($('<span class="equal">'))).append(this.loaderMessage);
this.start = $('<div class="dosbox-start">Click to start');
this.div.append(this.wrapper);
this.wrapper.append(this.canvas);
this.wrapper.append(this.loader);
this.wrapper.append(this.overlay);
this.overlay.append($('<div class="dosbox-powered">Powered by &nbsp;').append($('<a href="http://js-dos.com">js-dos.com')));
this.overlay.append(this.start);
}
UI.prototype.onStart = function(fun) {
return this.start.click((function(_this) {
return function() {
fun();
return _this.overlay.hide();
};
})(this));
};
UI.prototype.appendCss = function() {
var head, style;
head = document.head || document.getElementsByTagName('head')[0];
style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = this.css;
} else {
style.appendChild(document.createTextNode(this.css));
}
return head.appendChild(style);
};
UI.prototype.showLoader = function() {
this.loader.show();
return this.loaderMessage.html('');
};
UI.prototype.updateMessage = function(message) {
return this.loaderMessage.html(message);
};
UI.prototype.hideLoader = function() {
return this.loader.hide();
};
UI.prototype.css = '.dosbox-container { position: relative; min-width: 320px; min-height: 200px; } .dosbox-canvas { } .dosbox-overlay, .dosbox-loader { position: absolute; left: 0; right: 0; top: 0; bottom: 0; background-color: #333; } .dosbox-start { text-align: center; position: absolute; left: 0; right: 0; bottom: 50%; color: #f80; font-size: 1.5em; text-decoration: underline; cursor: pointer; } .dosbox-overlay a { color: #f80; } .dosbox-loader { display: none; } .dosbox-powered { position: absolute; right: 1em; bottom: 1em; font-size: 0.8em; color: #9C9C9C; } .dosbox-loader-message { text-align: center; position: absolute; left: 0; right: 0; bottom: 50%; margin: 0 0 -3em 0; box-sizing: border-box; color: #f80; font-size: 1.5em; } @-moz-keyframes loading { 0% { left: 0; } 50% { left: 8.33333em; } 100% { left: 0; } } @-webkit-keyframes loading { 0% { left: 0; } 50% { left: 8.33333em; } 100% { left: 0; } } @keyframes loading { 0% { left: 0; } 50% { left: 8.33333em; } 100% { left: 0; } } .st-loader { width: 10em; height: 2.5em; position: absolute; top: 50%; left: 50%; margin: -1.25em 0 0 -5em; box-sizing: border-box; } .st-loader:before, .st-loader:after { content: ""; display: block; position: absolute; top: 0; bottom: 0; width: 1.25em; box-sizing: border-box; border: 0.25em solid #f80; } .st-loader:before { left: -0.76923em; border-right: 0; } .st-loader:after { right: -0.76923em; border-left: 0; } .st-loader .equal { display: block; position: absolute; top: 50%; margin-top: -0.5em; left: 4.16667em; height: 1em; width: 1.66667em; border: 0.25em solid #f80; box-sizing: border-box; border-width: 0.25em 0; -moz-animation: loading 1.5s infinite ease-in-out; -webkit-animation: loading 1.5s infinite ease-in-out; animation: loading 1.5s infinite ease-in-out; }';
return UI;
})();
}).call(this);
(function() {
Dosbox.Xhr = (function() {
function Xhr(url, options) {
var e;
this.success = options.success;
this.progress = options.progress;
if (window.ActiveXObject) {
try {
this.xhr = new ActiveXObject('Microsoft.XMLHTTP');
} catch (error) {
e = error;
this.xhr = null;
}
} else {
this.xhr = new XMLHttpRequest();
}
this.xhr.open('GET', url, true);
this.xhr.overrideMimeType('text/plain; charset=x-user-defined');
this.xhr.addEventListener('progress', (function(_this) {
return function(evt) {
if (_this.progress) {
return _this.progress(evt.total, evt.loaded);
}
};
})(this));
this.xhr.onreadystatechange = (function(_this) {
return function() {
return _this._onReadyStateChange();
};
})(this);
this.xhr.send();
}
Xhr.prototype._onReadyStateChange = function() {
if (this.xhr.readyState === 4 && this.success) {
return this.success(this.xhr.responseText);
}
};
return Xhr;
})();
}).call(this);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,41 +0,0 @@
{
"name": "Its Eric Woodward! (dotcom)",
"icons": [
{
"src": "\/images\/favicons\/android-icon-36x36.png",
"sizes": "36x36",
"type": "image\/png",
"density": "0.75"
},
{
"src": "\/images\/favicons\/android-icon-48x48.png",
"sizes": "48x48",
"type": "image\/png",
"density": "1.0"
},
{
"src": "\/images\/favicons\/android-icon-72x72.png",
"sizes": "72x72",
"type": "image\/png",
"density": "1.5"
},
{
"src": "\/images\/favicons\/android-icon-96x96.png",
"sizes": "96x96",
"type": "image\/png",
"density": "2.0"
},
{
"src": "\/images\/favicons\/android-icon-144x144.png",
"sizes": "144x144",
"type": "image\/png",
"density": "3.0"
},
{
"src": "\/images\/favicons\/android-icon-192x192.png",
"sizes": "192x192",
"type": "image\/png",
"density": "4.0"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 165 KiB

View File

@ -0,0 +1,54 @@
{
"name": "The Planar Vagabond's Guide to the Multiverse",
"short_name": "Planar Vagabond",
"icons": [
{
"src": "/android-chrome-36x36.png",
"sizes": "36x36",
"type": "image/png"
},
{
"src": "/android-chrome-48x48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "/android-chrome-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "/android-chrome-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "/android-chrome-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "/android-chrome-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"start_url": "https://www.planarvagabond.com/"
}

View File

@ -0,0 +1,49 @@
Copyright (c) 2010, Matt McInerney (matt@pixelspread.com),
Copyright (c) 2011, Pablo Impallari (www.impallari.com|impallari@gmail.com),
Copyright (c) 2011, Rodrigo Fuenzalida (www.rfuenzalida.com|hello@rfuenzalida.com), with Reserved Font Name Raleway
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,93 @@
Copyright 2022 The Unbounded Project Authors (https://github.com/googlefonts/unbounded)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -4,6 +4,5 @@
https://github.com/eligrey/classList.js https://github.com/eligrey/classList.js
The Unlicense The Unlicense
*/ */
"document"in self&&(("classList"in document.createElement("_")&&(!document.createElementNS||"classList"in document.createElementNS("http://www.w3.org/2000/svg","g")))||!(function(t){"use strict";if("Element"in t){var e="classList",n="prototype",i=t.Element[n],s=Object,r=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},o=Array[n].indexOf||function(t){for(var e=0,n=this.length;n>e;e+=1){if(e in this&&this[e]===t){return e}}return -1},c=function(t,e){(this.name=t),(this.code=DOMException[t]),(this.message=e)},a=function(t,e){if(""===e){throw new c("SYNTAX_ERR","The token must not be empty.")}if(/\s/.test(e)){throw new c("INVALID_CHARACTER_ERR","The token must not contain space characters.")}return o.call(t,e)},l=function(t){for(var e=r.call(t.getAttribute("class")||""),n=e?e.split(/\s+/):[],i=0,s=n.length;s>i;i+=1){this.push(n[i])}this._updateClassName=function(){t.setAttribute("class",this.toString())}},u=(l[n]=[]),h=function(){return new l(this)};if(((c[n]=Error[n]),(u.item=function(t){return this[t]||null}),(u.contains=function(t){return~a(this,t+"")}),(u.add=function(){var t,e=arguments,n=0,i=e.length,s=!1;do{(t=e[n]+""),~a(this,t)||(this.push(t),(s=!0))}while(++n<i);s&&this._updateClassName()}),(u.remove=function(){var t,e,n=arguments,i=0,s=n.length,r=!1;do{for(t=n[i]+"",e=a(this,t);~e;){this.splice(e,1),(r=!0),(e=a(this,t))}}while(++i<s);r&&this._updateClassName()}),(u.toggle=function(t,e){var n=this.contains(t),i=n?e!==!0&&"remove":e!==!1&&"add";return i&&this[i](t),e===!0||e===!1?e:!n}),(u.replace=function(t,e){var n=a(t+"");~n&&(this.splice(n,1,e),this._updateClassName())}),(u.toString=function(){return this.join(" ")}),s.defineProperty)){var f={get:h,enumerable:!0,configurable:!0};try{s.defineProperty(i,e,f)}catch(p){(void 0!==p.number&&-2146823252!==p.number)||((f.enumerable=!1),s.defineProperty(i,e,f))}}else{s[n].__defineGetter__&&i.__defineGetter__(e,h)}}})(self),(function(){"use strict";var t=document.createElement("_");if((t.classList.add("c1","c2"),!t.classList.contains("c2"))){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var n,i=arguments.length;for(n=0;i>n;n+=1){(t=arguments[n]),e.call(this,t)};;};e("add"),e("remove")}if((t.classList.toggle("c3",!1),t.classList.contains("c3"))){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(t,e){return 1 in arguments&&!this.contains(t)==!e?e:n.call(this,t)}}"replace"in document.createElement("_").classList||(DOMTokenList.prototype.replace=function(t,e){var n=this.toString().split(" "),i=n.indexOf(t+"");~i&&((n=n.slice(i)),this.remove.apply(this,n),this.add(e),this.add.apply(this,n.slice(1)))}),(t=null)})()); "document"in self&&("classList"in document.createElement("_")&&(!document.createElementNS||"classList"in document.createElementNS("http://www.w3.org/2000/svg","g"))||!function(t){"use strict";if("Element"in t){var e="classList",n="prototype",i=t.Element[n],s=Object,r=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},o=Array[n].indexOf||function(t){for(var e=0,n=this.length;n>e;e++)if(e in this&&this[e]===t)return e;return-1},c=function(t,e){this.name=t,this.code=DOMException[t],this.message=e},a=function(t,e){if(""===e)throw new c("SYNTAX_ERR","The token must not be empty.");if(/\s/.test(e))throw new c("INVALID_CHARACTER_ERR","The token must not contain space characters.");return o.call(t,e)},l=function(t){for(var e=r.call(t.getAttribute("class")||""),n=e?e.split(/\s+/):[],i=0,s=n.length;s>i;i++)this.push(n[i]);this._updateClassName=function(){t.setAttribute("class",this.toString())}},u=l[n]=[],h=function(){return new l(this)};if(c[n]=Error[n],u.item=function(t){return this[t]||null},u.contains=function(t){return~a(this,t+"")},u.add=function(){var t,e=arguments,n=0,i=e.length,s=!1;do t=e[n]+"",~a(this,t)||(this.push(t),s=!0);while(++n<i);s&&this._updateClassName()},u.remove=function(){var t,e,n=arguments,i=0,s=n.length,r=!1;do for(t=n[i]+"",e=a(this,t);~e;)this.splice(e,1),r=!0,e=a(this,t);while(++i<s);r&&this._updateClassName()},u.toggle=function(t,e){var n=this.contains(t),i=n?e!==!0&&"remove":e!==!1&&"add";return i&&this[i](t),e===!0||e===!1?e:!n},u.replace=function(t,e){var n=a(t+"");~n&&(this.splice(n,1,e),this._updateClassName())},u.toString=function(){return this.join(" ")},s.defineProperty){var f={get:h,enumerable:!0,configurable:!0};try{s.defineProperty(i,e,f)}catch(p){void 0!==p.number&&-2146823252!==p.number||(f.enumerable=!1,s.defineProperty(i,e,f))}}else s[n].__defineGetter__&&i.__defineGetter__(e,h)}}(self),function(){"use strict";var t=document.createElement("_");if(t.classList.add("c1","c2"),!t.classList.contains("c2")){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var n,i=arguments.length;for(n=0;i>n;n++)t=arguments[n],e.call(this,t)}};e("add"),e("remove")}if(t.classList.toggle("c3",!1),t.classList.contains("c3")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(t,e){return 1 in arguments&&!this.contains(t)==!e?e:n.call(this,t)}}"replace"in document.createElement("_").classList||(DOMTokenList.prototype.replace=function(t,e){var n=this.toString().split(" "),i=n.indexOf(t+"");~i&&(n=n.slice(i),this.remove.apply(this,n),this.add(e),this.add.apply(this,n.slice(1)))}),t=null}());
// @license-end // @license-end

View File

@ -2,16 +2,12 @@
/**************************************************************************** /****************************************************************************
* It's Eric Woodward's Site * It's Eric Woodward's Site
* *
* Copyright 2014-2022 Eric Woodward * Copyright 2014-2023 Eric Woodward
* Source released under CC0 Public Domain License v1.0 * Source released under CC0 Public Domain License v1.0
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
****************************************************************************/ ****************************************************************************/
(function () {
"use strict";
// Checking if browser "cuts the mustard" - https://gomakethings.com/ditching-jquery/
if (!(!!document.querySelector && !!window.addEventListener)) return;
export const onLoad = () => {
if (window.dayjs) dayjs.extend(window.dayjs_plugin_relativeTime); if (window.dayjs) dayjs.extend(window.dayjs_plugin_relativeTime);
// Indicate JS is loaded // Indicate JS is loaded
@ -23,23 +19,31 @@
document.documentElement.className += " js-hasFontsLoaded"; document.documentElement.className += " js-hasFontsLoaded";
} }
docReady(function () { docReady(() => {
setTimeout(function () { setTimeout(() => {
if (!window.Cookies || !window.FontFaceObserver) return; if (!window.Cookies || !window.FontFaceObserver) return;
// Handle Fonts // Handle Fonts
const font_ls = new FontFaceObserver("liberation_serif"), const fontRaleway = new FontFaceObserver("raleway"),
font_msc = new FontFaceObserver("marcellus_sc"); fontUnbounded = new FontFaceObserver("unbounded");
Promise.all([font_ls.load(), font_msc.load()]).then(function () { Promise.all([
if ( fontRaleway.load(null, 5000),
document.documentElement.className.indexOf( fontUnbounded.load(null, 6000),
"js-hasFontsLoaded" ])
) == -1 .then(() => {
) { if (
document.documentElement.className += " js-hasFontsLoaded"; document.documentElement.className.indexOf(
} "js-hasFontsLoaded"
Cookies.set("fonts_loaded", true); ) == -1
}); ) {
document.documentElement.className +=
" js-hasFontsLoaded";
}
Cookies.set("fonts_loaded", true);
})
.catch((err) => {
console.log("Error!", err);
});
// Lazy-Load Media // Lazy-Load Media
if (typeof loadMedia === "function") { if (typeof loadMedia === "function") {
@ -76,5 +80,5 @@
}); });
}, 1); }, 1);
}); });
})(); };
// @license-end // @license-end

View File

@ -1,43 +1,49 @@
@font-face { @font-face {
font-family: 'exo_2'; font-family: "raleway";
src: url('/files/fonts/Exo2-Regular-webfont.eot'); src: url("/fonts/raleway/raleway-regular-webfont.woff2") format("woff2"),
src: url('/files/fonts/Exo2-Regular-webfont.eot?#iefix') format('embedded-opentype'), url("/fonts/raleway/raleway-regular-webfont.woff") format("woff"),
url('/files/fonts/Exo2-Regular-webfont.woff') format('woff'), url("/fonts/raleway/raleway-regular-webfont.ttf") format("truetype"),
url('/files/fonts/Exo2-Regular-webfont.ttf') format('truetype'), url("/fonts/raleway/raleway-regular-webfont.eot");
url('/files/fonts/Exo2-Regular-webfont.svg#exo_2') format('svg'); font-weight: 400;
font-weight: 400; font-style: normal;
font-style: normal;
} }
@font-face { @font-face {
font-family: 'exo_2'; font-family: "raleway";
src: url('/files/fonts/Exo2-Italic-webfont.eot'); src: url("/fonts/raleway/raleway-italic-webfont.woff2") format("woff2"),
src: url('/files/fonts/Exo2-Italic-webfont.eot?#iefix') format('embedded-opentype'), url("/fonts/raleway/raleway-italic-webfont.woff") format("woff"),
url('/files/fonts/Exo2-Italic-webfont.woff') format('woff'), url("/fonts/raleway/raleway-italic-webfont.ttf") format("truetype"),
url('/files/fonts/Exo2-Italic-webfont.ttf') format('truetype'), url("/fonts/raleway/raleway-italic-webfont.eot");
url('/files/fonts/Exo2-Italic-webfont.svg#exo_2') format('svg'); font-weight: 400;
font-weight: 400; font-style: italic;
font-style: italic;
} }
@font-face { @font-face {
font-family: 'exo_2'; font-family: "raleway";
src: url('Exo2-Bold-webfont.eot'); src: url("/fonts/raleway/raleway-bold-webfont.woff2") format("woff2"),
src: url('Exo2-Bold-webfont.eot?#iefix') format('embedded-opentype'), url("/fonts/raleway/raleway-bold-webfont.woff") format("woff"),
url('Exo2-Bold-webfont.woff') format('woff'), url("/fonts/raleway/raleway-bold-webfont.ttf") format("truetype"),
url('Exo2-Bold-webfont.ttf') format('truetype'), url("/fonts/raleway/raleway-bold-webfont.eot");
url('Exo2-Bold-webfont.svg#exo_2') format('svg'); font-weight: 700;
font-weight: 600; font-style: normal;
font-style: normal;
} }
@font-face { @font-face {
font-family: 'exo_2'; font-family: "raleway";
src: url('Exo2-BoldItalic-webfont.eot'); src: url("/fonts/raleway/raleway-bolditalic-webfont.woff2") format("woff2"),
src: url('Exo2-BoldItalic-webfont.eot?#iefix') format('embedded-opentype'), url("/fonts/raleway/raleway-bolditalic-webfont.woff") format("woff"),
url('Exo2-BoldItalic-webfont.woff') format('woff'), url("/fonts/raleway/raleway-bolditalic-webfont.ttf") format("truetype"),
url('Exo2-BoldItalic-webfont.ttf') format('truetype'), url("/fonts/raleway/raleway-bolditalic-webfont.eot");
url('Exo2-BoldItalic-webfont.svg#exo_2') format('svg'); font-weight: 700;
font-weight: 600; font-style: italic;
font-style: italic; }
@font-face {
font-family: "unbounded";
src: url("/fonts/unbounded/unbounded-medium-webfont.woff2") format("woff2"),
url("/fonts/unbounded/unbounded-medium-webfont.woff") format("woff"),
url("/fonts/unbounded/unbounded-medium-webfont.ttf") format("truetype"),
url("/fonts/unbounded/unbounded-medium-webfont.eot");
font-weight: 500;
font-style: normal;
} }

View File

@ -28,6 +28,9 @@
other: #E8A384 other: #E8A384
*/ */
html {
font-size: 16px;
}
body { body {
background: #252837; /* Old browsers */ background: #252837; /* Old browsers */
background: url("/images/portal-header.jpg") top fixed; background: url("/images/portal-header.jpg") top fixed;
@ -156,10 +159,6 @@ li ul {
margin-top: 0.6em; margin-top: 0.6em;
} }
main {
font-size: 0.95em;
}
main img { main img {
max-width: 100%; max-width: 100%;
} }
@ -247,7 +246,7 @@ table th {
border-bottom: none; border-bottom: none;
display: block; display: block;
margin: 0 auto; margin: 0 auto;
max-width: 60em; max-width: 100%;
min-height: 100vh; min-height: 100vh;
padding: 0; padding: 0;
position: relative; position: relative;
@ -295,79 +294,6 @@ table th {
font-weight: bold; font-weight: bold;
} }
.anaCardImg {
height: auto;
margin: 0;
vertical-align: middle;
width: 100%;
}
.anaCardLink {
display: block;
margin: 0 auto;
max-width: 15em;
padding: 0.5em;
}
.anaLink-billy {
background: url("/images/anachronism/links/billy_the_kid.jpg") no-repeat
center;
background-size: cover;
}
.anaLink-constitution {
background: url("/images/anachronism/links/the_us_constitution.jpg")
no-repeat center;
background-size: cover;
}
.anaLink-dictator {
background: url("/images/anachronism/links/the_dictator.jpg") no-repeat
center;
background-size: cover;
}
.anaLink-earp {
background: url("/images/anachronism/links/wyatt_earp.jpg") no-repeat center;
background-size: cover;
}
.anaLink-grant {
background: url("/images/anachronism/links/ulysses_s_grant.jpg") no-repeat
center;
background-size: cover;
}
.anaLink-lee {
background: url("/images/anachronism/links/robert_e_lee.jpg") no-repeat
center;
background-size: cover;
}
.anaLink-lincoln {
background: url("/images/anachronism/links/abraham_lincoln.jpg") no-repeat
center;
background-size: cover;
}
.anaLink-stetson {
background: url("/images/anachronism/links/stetson_hat.jpg") no-repeat
center;
background-size: cover;
}
.anaLink-washington {
background: url("/images/anachronism/links/george_washington.jpg") no-repeat
center;
background-size: cover;
}
.anaLogo {
display: block;
margin: 0 auto 1em;
width: 100%;
}
.asideBio { .asideBio {
line-height: 1.35em; line-height: 1.35em;
padding: 0.5em; padding: 0.5em;
@ -738,6 +664,7 @@ table th {
position: relative; position: relative;
text-decoration: none; text-decoration: none;
transition-duration: 0.5s; transition-duration: 0.5s;
white-space: nowrap;
} }
.navMenu li.hasSubMenu:hover, .navMenu li.hasSubMenu:hover,
@ -782,7 +709,6 @@ table th {
align-items: stretch; align-items: stretch;
opacity: 1; opacity: 1;
visibility: visible; visibility: visible;
white-space: nowrap;
} }
.navMenu ul li ul li { .navMenu ul li ul li {
@ -1025,18 +951,41 @@ table th {
font-size: 1.75em; font-size: 1.75em;
} }
/*
.searchBox { .searchBox {
margin-left: auto; margin-left: auto;
white-space: nowrap; white-space: nowrap;
} }
*/
.searchBox {
position: absolute;
top: 0;
right: 0;
padding: 1rem;
width: 100%;
text-align: right;
}
.searchBox-query { .searchBox-query {
background-color: #3d81a5; background-color: #3d81a5;
border-radius: 0.3rem; border-radius: 0.3rem;
color: #000; color: #fff;
width: 10em; width: 10em;
} }
.sectionBackLink {
border: 1px solid #726f6a;
border-radius: 0.3em;
display: inline-block;
margin: 1em auto;
padding: 0.25em;
text-align: center;
}
.sectionBackLink-wrapper {
text-align: center;
}
.siteTitle { .siteTitle {
text-align: center; text-align: center;
width: 100%; width: 100%;
@ -1072,7 +1021,6 @@ table th {
.siteTitle-text { .siteTitle-text {
max-width: 48rem; max-width: 48rem;
text-align: left;
} }
.spellTable { .spellTable {
@ -1241,10 +1189,6 @@ a.pageTitle-link:visited {
display: none; display: none;
} }
.asideUpdates .reacji {
float: left;
}
.feature hr { .feature hr {
border: 1px 0 0 0; border: 1px 0 0 0;
border-color: #7c4c52; border-color: #7c4c52;
@ -1253,8 +1197,24 @@ a.pageTitle-link:visited {
max-width: 90%; max-width: 90%;
} }
.js-hasFontsLoaded body { body {
font-family: "Exo 2", sans-serif; font-family: "raleway", "Optima", arial, helvetica, sans-serif;
}
h1,
h1 a,
h2,
h2 a,
h3,
h3 a,
h4,
h4 a,
h5,
h5 a,
h6,
h6 a {
font-family: "unbounded", "Luminari", impact, arial, helvetica, sans-serif;
font-weight: 500;
} }
.pageMenu-link.isCurrent .pageMenu-text { .pageMenu-link.isCurrent .pageMenu-text {
@ -1305,8 +1265,31 @@ a.pageTitle-link:visited {
* Media Queries * Media Queries
****************************************************************************/ ****************************************************************************/
/* Mobile */ @media all and (min-width: 960px) {
@media all and (max-width: 1000px) { html {
font-size: 18px;
}
.page {
max-width: 960px;
}
}
ampaign/shazz-journals @media all and (max-width: 960px) {
h1 {
font-size: 1.5em;
}
h2 {
font-size: 1.3em;
}
h3 {
font-size: 1.2em;
}
h1 svg {
scale: 0.75;
}
.menubar { .menubar {
max-height: 1px; max-height: 1px;
} }
@ -1361,6 +1344,12 @@ a.pageTitle-link:visited {
top: 8px; top: 8px;
} }
/* Prevents close toggle from scrolling offscreen */
#menu__toggle:checked + .menu__btn {
position: fixed;
top: 1rem;
}
.navMenu { .navMenu {
background: #252837; background: #252837;
display: flex; display: flex;
@ -1369,17 +1358,19 @@ a.pageTitle-link:visited {
left: -100%; left: -100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0 2rem 0 4rem; padding: 0;
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.4); box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.4);
transition-duration: 0.25s; transition-duration: 0.25s;
flex-direction: column; flex-direction: column;
overflow-y: auto;
} }
.navMenu ul { .navMenu ul {
flex-direction: column; flex-direction: column;
} }
.navMenu > ul {
padding: 1rem 2rem 1rem 4rem;
overflow-y: auto;
}
.navMenu > ul > li { .navMenu > ul > li {
margin-left: -1rem;
margin-top: 1rem; margin-top: 1rem;
} }
.navMenu > ul > li > a { .navMenu > ul > li > a {
@ -1400,84 +1391,58 @@ a.pageTitle-link:visited {
position: relative; position: relative;
visibility: visible; visibility: visible;
} }
.searchBox { .siteTitle-text {
margin: 1rem 0 2rem; max-width: 60%;
}
}
/*
@media all and (max-width: 900px) {
html {
font-size: 14px;
}
h1 {
font-size: 1.5em;
}
h2 {
font-size: 1.3em;
} }
.siteTitle { h3 {
font-size: 1.2em;
}
h1 svg {
scale: 0.75;
}
.siteTitle-text {
max-width: 60%;
}
}
*/
@media all and (max-width: 600px) {
h1 {
margin-top: 3rem; margin-top: 3rem;
} }
}
@media all and (min-width: 38em) { .siteTitle-text {
.navMenu {
padding: 0 0.25rem;
}
.navMenu-list {
float: left;
text-align: left; text-align: left;
} }
}
.navMenu-list-item { @media all and (max-width: 320px) {
margin-left: 0.75em; nav {
max-width: 90%;
} }
}
@media all and (min-width: 1000px) {
.menubar {
position: relative;
}
.searchBox { .searchBox {
float: right; top: -3rem;
margin-right: 0.75em;
}
}
@media all and (min-width: 34em) {
.magic-commander-img {
float: right;
}
}
@media all and (min-width: 52em) {
body {
font-size: 1.1em;
}
}
@media all and (min-width: 70em) {
.asideContent {
background: #1a0608;
background: rgba(4, 3, 8, 0.9);
border: 1px solid #252837;
font-size: 0.8em;
position: absolute;
top: 5em;
}
.asideLeft {
left: -14em;
width: 14em;
}
.asideMenu-divider {
display: none;
}
.asideRight {
right: -15em;
width: 15em;
}
.asideRight .asideMenu-link {
max-width: 13em;
}
.postMainIndex .feedLine:last-child {
display: block;
}
.postMenu {
max-height: none;
}
.socialList-item {
display: inherit;
} }
} }

View File

@ -28,6 +28,8 @@
<%- content %> <%- content %>
<%- include('partials/backLink') %>
<% } -%> <% } -%>
</div> </div>

View File

@ -0,0 +1,33 @@
<%
var titlesBySection = {
// top-level
astral: "Astral Info",
campaign: "Campaign Info",
classes: "Character Classes",
"magic-items": "Magic Items",
planes: "Other Planes",
races: "Character Races",
rules: "House Rules",
// planes
elemental: "Elemental Planes",
material: "Material Planes",
transcendental: "Transcendental Planes",
};
%>
<% if (page.subsection && page.path && !page.path.endsWith(`${page.subsection}/index.html`)) { %>
<div class="sectionBackLink-wrapper">
<a href="./index.html" class="sectionBackLink">
&lt; Back to <%= titlesBySection[page.subsection] ?? page.subsection.charAt(0).toUpperCase() + page.subsection.slice(1) %>
</a>
</div>
<% } else if (page.section && page.path && !page.path.endsWith(`${page.section}/index.html`)) { -%>
<div class="sectionBackLink-wrapper">
<a href="<%=page.subsection ? '..' : '.'-%>/index.html" class="sectionBackLink">
&lt; Back to <%= titlesBySection[page.section] ?? page.section.charAt(0).toUpperCase() + page.section.slice(1) %>
</a>
</div>
<% } -%>

View File

@ -9,7 +9,11 @@
<script type="text/javascript" src="/scripts/5-fontfaceobserver.min.js"></script> <script type="text/javascript" src="/scripts/5-fontfaceobserver.min.js"></script>
<script type="text/javascript" src="/scripts/6-classlist.min.js"></script> <script type="text/javascript" src="/scripts/6-classlist.min.js"></script>
<script type="text/javascript" src="/scripts/7-dayjs.min.js"></script> <script type="text/javascript" src="/scripts/7-dayjs.min.js"></script>
<script type="text/javascript" src="/scripts/scripts.js"></script> <script type="module">
// using module import to target ES6+ (95% global coverage in 2023)
import { onLoad } from './scripts/scripts.js';
onLoad?.();
</script>
</body> </body>
</html> </html>

View File

@ -39,8 +39,11 @@
<p>
Fonts: <a href="https://fonts.google.com/specimen/Unbounded">Unbounded by NaN</a> and
<a href="https://fonts.google.com/specimen/Raleway">Raleway by Matt McInerney, Pablo Impallari, and Rodrigo Fuenzalida</a>;
both used under the SIL Open Font License, Version 1.1.
</p>
<p> <p>
Background image by <a href="https://pixabay.com/illustrations/ai-art-ai-generated-outdoor-7717011/">AlanFrijns / Pixabay</a>, used under the <a href="https://pixabay.com/service/terms/">Pixabay License</a>. Background image by <a href="https://pixabay.com/illustrations/ai-art-ai-generated-outdoor-7717011/">AlanFrijns / Pixabay</a>, used under the <a href="https://pixabay.com/service/terms/">Pixabay License</a>.
</p> </p>

View File

@ -7,6 +7,18 @@
<span></span> <span></span>
</label> </label>
<div class="searchBox">
<form method="get" class="searchBox-form" id="searchForm" action="https://duckduckgo.com/" role="search">
<input id="searchQuery" class="searchBox-query" type="search" value="" name="q" maxlength="255" role="searchbox">
<input type="hidden" name="kl" value="us-en" /><!-- language -->
<input type="hidden" name="kh" value="1" /><!-- force https -->
<input type="hidden" name="kae" value="r" /><!-- theme = retri -->
<input type="hidden" name="k1" value="1" /><!-- tracker-less ads -->
<input type="hidden" name="sites" value="<%= site.base_uri %>"/>
<input aria-label="Search" type="submit" class="searchBox-go" value="🔍">
</form>
</div>
<nav class="navMenu" role="navigation"> <nav class="navMenu" role="navigation">
<ul> <ul>
@ -22,9 +34,9 @@
</li> </li>
<li class="hasSubMenu"><a href="/planes/index.html" aria-haspopup="true">Other Planes</a> <li class="hasSubMenu"><a href="/planes/index.html" aria-haspopup="true">Other Planes</a>
<ul class="dropdown" aria-label="submenu"> <ul class="dropdown" aria-label="submenu">
<li><a href="/planes/elemental.html">Elemental Planes</a></li> <li><a href="/planes/elemental/index.html">Elemental Planes</a></li>
<li><a href="/planes/material.html">Material Planes</a></li> <li><a href="/planes/material/index.html">Material Planes</a></li>
<li><a href="/planes/outer.html">Outer Planes</a></li> <li><a href="/planes/transcendental/index.html">Transcendental Planes</a></li>
<!--<li><a href="/planes/infernus.html">Infernus</a></li>--> <!--<li><a href="/planes/infernus.html">Infernus</a></li>-->
</ul> </ul>
</li> </li>
@ -41,7 +53,7 @@
<li><a href="/classes/warlock.html">Warlock</a></li> <li><a href="/classes/warlock.html">Warlock</a></li>
</ul> </ul>
</li> </li>
<li class="hasSubMenu"><a href="/" aria-haspopup="true">Races</a> <li class="hasSubMenu"><a href="/races/index.html" aria-haspopup="true">Races</a>
<ul class="dropdown" aria-label="submenu"> <ul class="dropdown" aria-label="submenu">
<li><a href="/races/automaton.html">Automaton</a></li> <li><a href="/races/automaton.html">Automaton</a></li>
<li><a href="/races/dracokin.html">Dracokin</a></li> <li><a href="/races/dracokin.html">Dracokin</a></li>
@ -76,24 +88,6 @@
</ul> </ul>
</li> </li>
</ul> </ul>
<!--
<ul class="navMenu-list">
<li class="navMenu-hasSubnav">
<a href="/"><span class="navMenu-subTitle-short">Game</span><span class="navMenu-subTitle-long">The Game</span></a>
<ul class="navMenu-list navMenu-lev2 navMenu-game">
<li>
<a href="/clash.html" class="navMenu-list-clash">Clash of the Gods</a>
</li>
<li>
<a href="/cthulhu.html">Cthulhu Rises</a>
</li>
<li>
<a href="/nemesis.html">Nemesis</a>
</li>
</ul>
</li>
</ul>
-->
</nav> </nav>
</div> </div>

View File

@ -21,26 +21,26 @@
<base href="<%= getUrl() %>" /> <base href="<%= getUrl() %>" />
<title><%= page.title ? page.title + ' | ' : ''%><%= page.sub_title ? page.sub_title + ' | ' : ''%><%= site.title %></title> <title><%= page.title ? page.title + ' | ' : ''%><%= page.sub_title ? page.sub_title + ' | ' : ''%><%= site.title %></title>
<link rel="pgpkey" type="application/pgp-keys" title="PGP Public Key" href="/files/public.aexpk" /> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#f03733">
<meta name="msapplication-TileColor" content="#8fffff">
<meta name="theme-color" content="#8fffff">
<!-- Courtesy of https://www.favicon-generator.org/ -->
<link rel="apple-touch-icon" sizes="57x57" href="/images/favicons/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/images/favicons/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="72x72" href="/images/favicons/apple-icon-72x72.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="apple-touch-icon" sizes="76x76" href="/images/favicons/apple-icon-76x76.png"> <link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png">
<link rel="apple-touch-icon" sizes="114x114" href="/images/favicons/apple-icon-114x114.png"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="apple-touch-icon" sizes="120x120" href="/images/favicons/apple-icon-120x120.png"> <link rel="manifest" href="/site.webmanifest">
<link rel="apple-touch-icon" sizes="144x144" href="/images/favicons/apple-icon-144x144.png"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#f03733">
<link rel="apple-touch-icon" sizes="152x152" href="/images/favicons/apple-icon-152x152.png"> <meta name="msapplication-TileColor" content="#8fffff">
<link rel="apple-touch-icon" sizes="180x180" href="/images/favicons/apple-icon-180x180.png"> <meta name="theme-color" content="#ffffff">
<link rel="icon" type="image/png" sizes="192x192" href="/images/favicons/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/images/favicons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicons/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<meta name="msapplication-TileColor" content="#9aa8bc">
<meta name="msapplication-TileImage" content="/images/favicons/ms-icon-144x144.png">
<meta name="theme-color" content="#9aa8bc">
<meta name="description" content="<%= getPageField('description') %>"> <meta name="description" content="<%= getPageField('description') %>">
<meta name="author" content="<%= (page.author || site.author).name %>"> <meta name="author" content="<%= (page.author || site.author).name %>">

View File

@ -0,0 +1,87 @@
---
title: Bloodmage
description: The Bloodmage class for Old School Essentials.
date_pub: 2023-02-26T17:46:00-05:00
section: classes
content_type: feature
short_code: cw1
---
<div class='headlessTableWrapper'>
| | |
| ------------------- | --------------------------------------------- |
| **Requirements** | None |
| **Prime requisite** | INT |
| **Hit Dice** | 1d6 |
| **Maximum Level** | 14 |
| **Armour** | Leather, no shields |
| **Weapons** | One-handed melee weapons, all missile weapons |
| **Languages** | Alignment, Common |
</div>
Bloodmages are arcane spellcasters that use their own life force, rather than their memories, to cast spells.
[[toc]]
### Arcane Magic
See [Spells](https://oldschoolessentials.necroticgnome.com/srd/index.php/Spells) for full details on arcane magic.
**Magical research**: A bloodmage of any level may spend time and money on magical research. This allows them to add new spells to their spell book and to research other magical effects. When a bloodmage reaches 9th level, they are also able to create magic items.
**Spell books**: Bloodmages carry spell books containing the formulae for arcane spells. The number of spells in a bloodmages spell book is equal to the characters experience level, and the spell casting chart (below) shows the maximum spell level a bloodmage can have in their spellbook Thus, a 1st level bloodmage has one spell in their spell book, selected by the referee (who may allow the player to choose). The list of spells available to bloodmages is found in [Magic-User Spells](https://oldschoolessentials.necroticgnome.com/srd/index.php/Magic-User_Spells).
**Spell casting**: Bloodmages cast spells by shedding blood, rather than by memorizing. To cast a spell, a bloodmage must sacrifice one of their own HP per level of the spell being cast.
**Using magic items**: As spell casters, bloodmages are able to use magic scrolls of spells on their spell list. They can also use items that may only be used by arcane spell casters (e.g. magic wands).
### Combat
Bloodmages are capable warriors as well as spellcasters, but they need freedom of movement for spellcasting. For this reason, they can use any melee weapon that can be wielded one handed, and can use all missile weapons, but can only wear leather armour, and are unable use shields.
### Healing
Bloodmages can make animal sacrifices to heal. The victims should be intelligent or magical creatures (although mundane animals can be used at the referee's discretion). To heal, the bloodmage must slay the intended sacrifice with a dagger or other bladed weapon. A sacrifice will restore a number of HP equal to the victim's HD. Creatures that are particularly innocent, powerful, or dear to the caster will produce increasingly better results (details to be left to the referee).
Alternatively, the referee may roll 1d6 for each fallen enemy, with a roll of 1 indicating that they are still alive and thus eligible to be sacrificed by the bloodmage.
### After Reaching 11th Level
A bloodmage may establish a stronghold, often in a cave or similar structure. 1d6 apprentices of levels 13 will then arrive to study under the bloodmage.
### Bloodmage Level Progression
<div class="dividedTableWrapper levelTable">
| |||| Saving Throws ||||||
| Level | XP | HD | THAC0 | D[^1] | W[^1] | P[^1] | B[^1] | S[^1] | Max Spell Level |
| :---: | :-------: | :-------: | :-----: | :---: | :---: | :---: | :---: | :---: | :-: |
| 1 | 0 | 1d6 | 19 [0] | 13 | 14 | 13 | 16 | 15 | 1 |
| 2 | 2,500 | 2d6 | 19 [0] | 13 | 14 | 13 | 16 | 15 | 1 |
| 3 | 5,000 | 3d6 | 19 [0] | 13 | 14 | 13 | 16 | 15 | 2 |
| 4 | 10,000 | 4d6 | 19 [0] | 13 | 14 | 13 | 16 | 15 | 2 |
| 5 | 20,000 | 5d6 | 17 [+2] | 13 | 14 | 13 | 16 | 15 | 3 |
| 6 | 40,000 | 6d6 | 17 [+2] | 11 | 12 | 11 | 14 | 12 | 3 |
| 7 | 80,000 | 7d6 | 17 [+2] | 11 | 12 | 11 | 14 | 12 | 4 |
| 8 | 150,000 | 8d6 | 17 [+2] | 11 | 12 | 11 | 14 | 12 | 4 |
| 9 | 300,000 | 9d6 | 14 [+5] | 11 | 12 | 11 | 14 | 12 | 5 |
| 10 | 450,000 | 9d6+1[^2] | 14 [+5] | 11 | 12 | 11 | 14 | 12 | 5 |
| 11 | 600,000 | 9d6+2[^2] | 14 [+5] | 8 | 9 | 8 | 11 | 8 | 6 |
| 12 | 750,000 | 9d6+3[^2] | 14 [+5] | 8 | 9 | 8 | 11 | 8 | 6 |
| 13 | 900,000 | 9d6+4[^2] | 12 [+7] | 8 | 9 | 8 | 11 | 8 | 6 |
| 14 | 1,050,000 | 9d6+5[^2] | 12 [+7] | 8 | 9 | 8 | 11 | 8 | 6 |
[Bloodmage Level Progression]
</div>
[^1]: D: Death / poison; W: Wands; P: Paralysis / petrify; B: Breath attacks; S: Spells / rods / staves.
[^2]: [Modifiers from CON](https://oldschoolessentials.necroticgnome.com/srd/index.php/Ability_Scores#Constitution_.28CON.29) no longer apply.
### Available Races and Max Level
When using the optional Character races rule, any race that may be a magic-user may also be a Bloodmage, and may advance to the same maximum level listed for the magic-user class (unless otherwise noted).
Adapted from _[Alternate Magic](https://www.drivethrurpg.com/product/397412/Alternate-Magic-OSR)_ by [Eric Diaz](http://methodsetmadness.blogspot.com/)

View File

@ -1,23 +1,26 @@
--- ---
title: Custom Character Classes title: Custom Character Classes
description: TBD description: Some unofficial characters classes for OSE.
date_pub: 2023-02-17T00:15:00-05:00 date_pub: 2023-02-17T00:15:00-05:00
section: classes section: classes
content_type: feature content_type: feature
short_code: c1 short_code: c1
--- ---
- [Automaton](./automaton.html) Below, you'll find some unofficial character classes for Old School Essentials. Most are only minimally tested (if at all), and some may need a bit of tweaking, but you can't beat the price!
- [Corsair](./corsair.html)
- [Corsair, Astral](./astral-corsair.html) - [Automaton](./automaton.html) - Mechanical beings powered by ancient, arcane magicks.
- [Dracokin](./dracokin.html) - [Corsair](./corsair.html) - A sailor living a life of adventure on the high seas.
- [Felinar](./felinar.html) - [Corsair, Astral](./astral-corsair.html) - A sailor living a life of adventure on the [astral plane](/astral)
- [Firfolk](./firfolk.html) - [Dracokin](./dracokin.html) - Lizardfolk with distant relations dragons.
- [Mimikin](./mimikin.html) - [Felinar](./felinar.html) - A race of anthropomorphic, catlike beings.
- [Tortokin](./tortokin.html) - [Firfolk](./firfolk.html) - Magical, gray half-giants that live in harmony with nature.
- [Warlock](./warlock.html) - [Mimikin](./mimikin.html) - A race of demihumans able to shift their physical forms at will.
- [Tortokin](./tortokin.html) - Anthropomorphic, upright turtles.
- [Warlock](./warlock.html) - Spellcasters that gain access to magic by making pacts with powerful, otherworldly beings
<!-- <!--
- [Planetouched](./corsair.md) - [Bloodmage](./bloodmage.html) - Arcane spellcasters that use their own life force, rather than their memories, to cast spells.
- [Summoner](./corsair.md) - [Planetouched](./planetouched.md)
- [Summoner](./summoner.md)
--> -->

View File

@ -0,0 +1,147 @@
## Additional Kineticist Mental Powers
_The Kineticist_ class by Gavin Norman (as presented in issue #1 of [Carcass Crawler](https://www.drivethrurpg.com/product/367602/Carcass-Crawler-Issue-One)) offers a unique take on the classic "monk" or "mystic" class. I particularly like the way their "mental powers" work - although the ones in the zine seem to be designed to replicate the abilities of the classic class (as is the OSE way), there's nothing to prevent one from adding new powers to increase the build possibilities for that class. In my mind, based on the powers learned, a Kineticist could be anything from a powerful psychic to a supernatural tournament fighter, or even a superhero.
### Enlargement
**Duration: Focus, up to 1 round per level**
**Range: The kineticist**
The kineticists body, clothing, and armour (but not other equipment) double in size for the duration.
**Focus**: This power requires the kineticist to concentrate for one round to activate. Being distracted (e.g. attacked) or performing any other action (except moving) during this focus round causes the power to end.
**Melee**: While enlarged, the kineticists melee attacks inflict double damage.
<!--
### ESP (WIP)
_Duration: Concentration, 1 round_
_Range: 90'_
By concentrating for 1 round, the kineticist can read the thoughts of an intelligent, living creature within range.
_Unwilling targets_: May _save vs spells_ to resist.
_Concentration_: Being distracted (e.g. attacked) or performing any other action (except moving) causes the power to end.
-->
### Freeze
**Duration: Up to 1 round per level**
**Range: 30**
The kineticist subjects a creature or object within sight to an icy cold, literally freezing them in place.
**Stun**: The target is unable to move or act unless they **save versus paralysis**. They may make a save each round that they are paralyzed, and once a save has been made, the effect ends.
<!--
### Gestalt (WIP)
_Duration: Concentration, 1 round_
_Range: Touch_
The kineticist can read the memories of a living creature that they are in physical contact with, and share their own memories with the creature in return.
_Unwilling targets_: May _save vs spells_ to resist.
_Concentration_: Being distracted (e.g. attacked) or performing any other action (except moving) causes the power to end.
-->
### Healing Trance
**Duration: 1 turn**
**Range: The kineticist**
The kineticist can enter a meditative state for the duration, during which time they are completely unaware of their surroundings and can neither attack nor defend themselves.
**Healing**: The trance heals 1d6+1 hit points per use (2d6+2 hit points per use at 6th level or higher).
### Heat
**Duration: Focus, up to 1 round per level**
**Range: Sight**
The kineticist subjects a creature or object within sight to a scorching heat.
**Targetted creatures**: May **save versus spells** to prevent damages.
**Envrionmental Effect**: Paper or cloth ignite, liquids boil, and metals glow.
**Damage**: Applied to flesh or to metal in contact with a creature (e.g. armour), the heat inflicts 1d4 damage per round.
-->
### Invisibility
**Duration: Concentration, up to 1 round per level**
**Range: The kineticist**
The kineticist disappears from the sight of one or more creatures (selected when the power is activated) for the duration.
**Effect**: Up to 1HD of creatures per level of the kineticist are affected.
**Combat**: Affected creatures may attack the kineticist with a 4 penalty.
**Concentration**: Being distracted (e.g. attacked) or performing any other action (except moving) causes the power to end.
### Kinetic Blast
**Duration: Instant**
**Range: 10 per level**
A blast of kinetic energy surges from the kineticists hand at a single target in range.
**Hit**: The target must **save vs spells** to avoid being hit.
**If the save fails**: The target suffers 2d4 damage.
### Kinetic Pull
**Duration: Instant**
**Range: 10 per level**
A wave of kinetic force surges from the kineticists hand at a single target in range, grabbing them, and pulling them towards the kineticist.
**Pull**: The target must save vs paralysis or be grabbed by the kinetic force.
**If the save fails**: The target suffers 1d6 damage and is pulled towards the kineticist, stopping at any space of the kineticist's choosing in between.
### Kinetic Transmission
**Duration: Instant**
**Range: 30'**
The kineticist instantly teleports to any location they can see within range.
### Life Drain
**Duration: Concentration, 1 round**
**Range: Touch**
The kineticist draws vital energy out of a living target that they are in physical contact with, absorbing the target's life force. This dark ability is usually forbidden for lawful kineticists.
**Damage**: The target must **save vs spells** or suffer 1d4 points of damage.
**Absorb**: The kineticist gains a number of hit points equal to the damage inflicted.
**Concentration**: Being distracted (e.g. attacked) or performing any other action (except moving) causes the power to end.
### Mind Shield
**Duration: Focus, 2 turns**
**Range: The kineticist**
The kineticist can shield their mind for a period of time up to the duration.
**Focus**: This power requires the kineticist to concentrate for one round to activate. Being distracted (e.g. attacked) or performing any other action (except moving) during this focus round causes the power to end.
**Protection**: The kineticist gets a +4 bonus to any saving throws to resist the effects of mental powers and mind-affecting spells and magic items.
### Psychic Blast
**Duration: Instant**
**Range: 10 per level**
A blast of psychic energy surges from the kineticist at a single target in range.
**Hit**: The target must save vs spells to avoid being hit.
**If the save fails**: The target suffers 2d4 damage.
### Shrinking
**Duration: Focus, up to 2 turns**
**Range: The kineticist**
The kineticist and all equipment shrinks to 6” tall for the duration.
**Focus**: This power requires the kinetcist to concentrate for one round to activate. Being distracted (e.g. attacked) or performing any other action (except moving) during this focus round causes the power to end.
**Tiny Size**: While shrunk, the kineticist can slip through narrow spaces and, when remaining motionless, has a 90% chance of going unnoticed. A shrunk kineticist cannot harm creatures larger than 1 tall.
### Telepathy
**Duration: Focus, 1 turn**
**Range: Sight**
The kineticist can establish bidirectional mental communication with one other willing, living, intelligent creature within range for the duration.
**Focus**: This power requires the kineticist to concentrate for one round to activate. Being distracted (e.g. attacked) or performing any other action (except moving) during this focus round causes the power to end.
**Language**: The creature need not share a language with the kineticist.
<!--
### Terrify
-->

View File

@ -17,7 +17,7 @@ short_code: cm1
| **Weapons** | Any | | **Weapons** | Any |
| **Languages** | Alignment, Common, any 2 other languages | | **Languages** | Alignment, Common, any 2 other languages |
Mimikin are a rarely-seen type of demihuman, able to shift their physical forms at will. Human-like in stature, their true forms usually have naturally pale, grey skin, unnervingly blank facial features, and silvery hair. However, because of their shapeshifting nature, they usuallly pass as humans or other similarly-sized demihumans, only returning to their true forms on death. Mimikin are a rarely-seen type of demihuman, able to shift their physical forms at will. Usually human-like in stature, their true forms usually have naturally pale, grey skin, unnervingly blank facial features, and silvery hair. However, because of their shapeshifting nature, they usuallly pass as humans or other similarly-sized demihumans, only returning to their true forms on death.
Many mimikin use their gifts as a form of artistic or emotional expression, but some see them as invaluable tools for grifting, spying, and general deception, leading to their distrust by the other races. Many mimikin use their gifts as a form of artistic or emotional expression, but some see them as invaluable tools for grifting, spying, and general deception, leading to their distrust by the other races.

View File

@ -1,5 +1,5 @@
--- ---
title: Welcome to the Multiverse! title:
description: TBD description: TBD
date_pub: 2023-02-15T00:26:00-05:00 date_pub: 2023-02-15T00:26:00-05:00
section: main section: main
@ -9,7 +9,7 @@ short_code: m1
My name is Drogo Wanderfoot, but most know me as the Planar Vagabond. My name is Drogo Wanderfoot, but most know me as the Planar Vagabond.
I've spent decades wandering around the vast multiverse, collecting stories, ... I've spent decades wandering around the vast multiverse, collecting stories and hearing about others adventures...
And now, I'm presenting them to you! And now, I'm presenting them to you!

View File

@ -1,6 +1,6 @@
--- ---
title: Astral Compass title: Astral Compass
description: description: A magical device for navigating to a desired location on the astral plane.
date_pub: 2023-02-19T18:46:00-05:00 date_pub: 2023-02-19T18:46:00-05:00
section: magic items section: magic items
content_type: feature content_type: feature
@ -18,4 +18,5 @@ A 1.5" diameter, golden medallion, etched with 4 lines (marking the 4 cardinal d
<!-- <!--
* If the desired location is within (1? 2? 4?) hours of travel, the pilot can "reach out" and see it in a similar "tactical" view. * If the desired location is within (1? 2? 4?) hours of travel, the pilot can "reach out" and see it in a similar "tactical" view.
* This view can also be used during combat, focusing on other ships * This view can also be used during combat, focusing on other ships
* The compass only works with "where" queries - where is so-and-so? where is the source of this effect? where is the last resting place of some artifact?
--> -->

View File

@ -1,6 +1,6 @@
--- ---
title: The Crystal Skull of Jund title: The Crystal Skull of Jund
description: description: A magical, elongated, and (apparently) nearly omniscient crystal skull.
date_pub: 2023-02-19T20:59:00-05:00 date_pub: 2023-02-19T20:59:00-05:00
section: magic items section: magic items
content_type: feature content_type: feature

View File

@ -9,8 +9,11 @@ short_code: mi1
Below you'll find a small sampling of the magic items that can be encountered in the astral plane. Below you'll find a small sampling of the magic items that can be encountered in the astral plane.
- [Astral Compass](./astral-compass.html) - [Astral Compass](./astral-compass.html) - A magical device for navigating to a desired location on the astral plane.
- [The Crystal Skull of Jund](./crystal-skull-of-jund.html) - [The Crystal Skull of Jund](./crystal-skull-of-jund.html) - A magical, elongated, and (apparently) nearly omniscient crystal skull.
- [Pet Rock](./pet-rock.html) - A magical rock that obeys its owner's commands.
- [Ring of Eldritch Blasting](./ring-of-eldritch-blasting.html) - A magical ring that grants the wearer the ability to fire eldritch blasts.
- [Tyrhung, Wolf Hunter](./tyrhung-wolf-hunter.html) - A magical sword that specializes in identifying and killing lycanthropes.
<!-- <!--
- [Mirror of Meeting](./mirror-of-meeting.html) - [Mirror of Meeting](./mirror-of-meeting.html)

View File

@ -0,0 +1,27 @@
---
title: Mirror of Meeting
description: A magical mirror that allows its user to meet with other remotely.
date_pub: 2023-02-20T22:56:00-05:00
section: magic items
content_type: feature
short_code: mimom
---
A mirror with intricately-carved detailing.
**Sizes**: Vary based on usage. Can be small and compact, or large and ornate.
**Bell**: Most mirrors come with a bell (or similar component) that rings to indicate that someone is trying to connect via the mirror.
**Using**: Meetings can be started by swiping sigils on the mirror.
- The sigils are tied to a specific mirror, and it rings that bell and tries to connect
- When someone else is trying to connect to one's mirror, you can "answer" the request, or dismiss it.
**Usage Frequency**: May be used to connect to another mirror up to 3 times per day. Each connection lasts at most 10 minutes.
In Game Examples
- Lord Stengar had a smaller one on his desk, about the size of a book.
- Amary's shop carried several different types and sizes
- The one on the Sky Runner is a 3' x 2' rectangle with 6" frame on one side, and a 4" notification bell inside the frame.

View File

@ -0,0 +1,20 @@
---
title: Pet Rock
description: A magical rock that obeys its owner's commands.
date_pub: 2023-02-20T22:56:00-05:00
section: magic items
content_type: feature
short_code: mipr
---
A small polished stone, about 2-inches in diameter.
**Bonds**: With anyone who gives it a command while holding it, treating that person as it's master.
**Commands**: Responds to (at least) 3 commands:
- **Attack** - When spoken while being held by its master, the pet rock will leap from its master's hand and fly at any one opponent of its master's choice within 60 feet, attacking with a +3 to hit. On a successful hit, the pet rock inflicts 1d8 damage. If the pet rock hits a creature or object made of stone, roll a d20. On a 15 or less, the rock shatters instantly, but not before dealing an additional 2d10 points of damage to the target. Once used for an attack, if it isn't destroyed, the pet rock will immediately fly back to it's master's hand.
- **Heel** - When spoken while being held by its master, the pet rock moves to a space just behind its master and floats about a foot off the ground.
- **Come** - When spoken by its master, the pet rock leaps from wherever it is (within sight) to its master's hand.
_Adapted from original version by Roger E. Moore, as published in Dragon Magazine #45._

Some files were not shown because too many files have changed in this diff Show More