diff --git a/source/_posts/chinwag.md b/source/_posts/chinwag.md index c187736..dce4fe9 100644 --- a/source/_posts/chinwag.md +++ b/source/_posts/chinwag.md @@ -1,7 +1,7 @@ --- title: Chinwag BBS comments: false -date: 2018-08-31 16:00:24 +date: 2018-08-31 thumbnail: /images/chinwag.png category: - BBS @@ -12,26 +12,28 @@ Chinwag is a BBS running on a Raspberry Pi under Docker. If you would like to explore BBS, Echomail and Netmail without having to setup a BBS for yourself, you are welcome to connect to mine. Just press the *Connect* button below, and create an account. The first time you login you'll have limited abilities, but send me a note and I'll upgrade you so that you can use the Echomail and Netmail areas. -
+
There is some useful terminal emulation software available on the Net. diff --git a/source/_posts/oztex.md b/source/_posts/oztex.md new file mode 100644 index 0000000..8b8ef5c --- /dev/null +++ b/source/_posts/oztex.md @@ -0,0 +1,107 @@ +--- +title: OzTex Videotex +comments: false +date: 2019-01-01 +thumbnail: /images/oztex.png +category: + - BBS + - OzTex Videotex +--- +OzTex is a re-invention of Videotex - which dominated many countries in the 80's and 90's. Its currently under development, providing two presentation experiences: the original Mode 7 Videotex and in a new fusion with ANSI. This post is about the Videotex impementation. + +It is still being developed, so the current functionality is very limited. You can see it in action by pressing the **Connect** button below. + +**NOTE:** For some keyboards, the hash (#) key is the UK Pound (£) symbol. You should be able to use your **ENTER** key in place of **#**, otherwise you can try your **'** (apostrophe) key. +**TIP:** You can click inside the terminal to zoom full screen. Click outside to unzoom. +{% raw %} + +
+
+ + + + +  +
+
                                         +    +    +    +    +    A vBBS by ...deon                    +                                         +                                +                            +                          +                       +                    +                  Welcome to  +                   +                  OzTex  +                    +                     +                                  +                                    +                                     +                                         +                                         + Press Connect to begin.                 +                                         +
+ + + + + + + + + +
+{% endraw %} +If you would like to own some pages on this system, please let me know. Alternatively, if you have some old videotex frames from old systems like Prestel, Viatel, etc that you would like to bring back to life get in contact with me and we'll make it happen. + +If you are creative, you can create some frames at http://edit.tf or http://zxnet.co.uk/teletext/editor. I use the http://edit.tf becuase it has some block copy/paste functions, great if you want to move things around. After using http://edit.tf I normally "Export" (E->zxnet Editor) to http://zxnet.co.uk/teletext/editor so that I can save the frame as _Binary dump of level 1 page data_. After saving the frame, its easy for me to import it into the system. + +At the moment importing frames is a manual entry by me, but in time, I'll enable that in the system - as well as hopefully create an editor. + +If you would like to help me build this, please get in contact. diff --git a/source/_posts/oztex/viewdata/MODE7GX3.TTF b/source/_posts/oztex/viewdata/MODE7GX3.TTF new file mode 100644 index 0000000..c9678ae Binary files /dev/null and b/source/_posts/oztex/viewdata/MODE7GX3.TTF differ diff --git a/source/_posts/oztex/viewdata/TELETEXT.CSS b/source/_posts/oztex/viewdata/TELETEXT.CSS new file mode 100644 index 0000000..6e1a186 --- /dev/null +++ b/source/_posts/oztex/viewdata/TELETEXT.CSS @@ -0,0 +1,144 @@ +/* + Teletext stylesheet + Galax 2014-2015 http://galax.xyz + + MODE7GX3.TTF font by Galax 2014 - based on ModeSeven, created in 1998 by Andrew Bulhak +*/ + +/* Hard reset */ +/* +html,body,div,span,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym, +address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub, +sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption, +tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption, +footer,header,hgroup,menu,nav,output,section,summary,time,audio,video { + padding: 0; + margin: 0; + border: 0; + font-smooth: never; + -webkit-font-smoothing: none; +} +*/ + +/* + Teletext palette + 000000 0 black + ff0000 1 red + 00ff00 2 green + ffff00 3 yellow + 0000ff 4 blue + ff00ff 5 magenta + 00ffff 6 cyan + ffffff 7 white +*/ + + +/* +a { + text-decoration: none; +} +*/ + +/* unvisited link */ +/* +a:link { + color: #00ffff; +} +*/ + +/* visited link */ +/* +a:visited { + color: #00ff00; +} +*/ + +/* mouse over link */ +/* +a:hover { + color: #ffff00; +} +a.yellow:hover, .yellow a:hover { + color: #00ff00; +} +*/ + +/* selected link */ +/* +a:active { + color: #ff0000; +} +a.yellow:active, .yellow a:active { + color: #ff0000; +} +a.red:active, .red a:active { + color: #ffff00; +} +*/ + +/* flashing class, it's like the 'blink' tag is back */ +/* +.flashing { + animation: flashing 1.3s steps(5, start) infinite; + -webkit-animation: flashing 1.3s steps(5, start) infinite; +} +@keyframes flashing { to { visibility: hidden; } } +@-webkit-keyframes flashing { to { visibility: hidden; } } +*/ + +/* concealed text is initially hidden, reveal by modifying class */ +/* +.conceal { opacity: 0; } + +.colour0, .black, a.black, .black a {color: #000000;} +.colour1, .red, a.red, .red a {color: #ff0000;} +.colour2, .green, a.green, .green a {color: #00ff00;} +.colour3, .yellow, a.yellow, .yellow a {color: #ffff00;} +.colour4, .blue, a.blue, .blue a {color: #0000ff;} +.colour5, .magenta, a.magenta, .magenta a{color: #ff00ff;} +.colour6, .cyan, a.cyan, .cyan a {color: #00ffff;} +.colour7, .white, a.white, .white a {color: #ffffff;} + +.colour0bg, .blackbg {background-color: #000000;} +.colour1bg, .redbg {background-color: #ff0000;} +.colour2bg, .greenbg {background-color: #00ff00;} +.colour3bg, .yellowbg {background-color: #ffff00;} +.colour4bg, .bluebg {background-color: #0000ff;} +.colour5bg, .magentabg {background-color: #ff00ff;} +.colour6bg, .cyanbg {background-color: #00ffff;} +.colour7bg, .whitebg {background-color: #ffffff;} +*/ + +@font-face { + font-family: Mode7; + src: url('MODE7GX3.TTF'), url('MODE7GX3.EOT'); /* .EOT is for IE */ +} + +div.viewdata > table { + margin-left: auto; + margin-right: auto; + width: 0%; +} + +td.teletext { + font-family: Mode7, monospace, courier, fixed; + font-size: 20px; + font-smooth: never; + -webkit-font-smoothing : none; + color: #ffffff; + background: #000000; + line-height: 20px; + text-align: left; + white-space: pre; + display: block; + font-size: 20px; + font-smooth: never; + -webkit-font-smoothing : none; +} + +/* +body { + border-width: 20px 20px 20px 20px; /* t r b l */ + padding: 20px; +} +*/ diff --git a/source/_posts/oztex/viewdata/base64.js b/source/_posts/oztex/viewdata/base64.js new file mode 100644 index 0000000..8733612 --- /dev/null +++ b/source/_posts/oztex/viewdata/base64.js @@ -0,0 +1,114 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js + +/*jslint white: false, bitwise: false, plusplus: false */ +/*global console */ + +var Base64 = { + +/* Convert data (an array of integers) to a Base64 string. */ +toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''), +base64Pad : '=', + +encode: function (data) { + "use strict"; + var result = ''; + var toBase64Table = Base64.toBase64Table; + var base64Pad = Base64.base64Pad; + var length = data.length; + var i; + // Convert every three bytes to 4 ascii characters. + /* BEGIN LOOP */ + for (i = 0; i < (length - 2); i += 3) { + result += toBase64Table[data[i] >> 2]; + result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; + result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)]; + result += toBase64Table[data[i+2] & 0x3f]; + } + /* END LOOP */ + + // Convert the remaining 1 or 2 bytes, pad out to 4 characters. + if (length%3) { + i = length - (length%3); + result += toBase64Table[data[i] >> 2]; + if ((length%3) === 2) { + result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; + result += toBase64Table[(data[i+1] & 0x0f) << 2]; + result += base64Pad; + } else { + result += toBase64Table[(data[i] & 0x03) << 4]; + result += base64Pad + base64Pad; + } + } + + return result; +}, + +/* Convert Base64 data to a string */ +toBinaryTable : [ + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +], + +decode: function (data, offset) { + "use strict"; + offset = typeof(offset) !== 'undefined' ? offset : 0; + var toBinaryTable = Base64.toBinaryTable; + var base64Pad = Base64.base64Pad; + var result, result_length, idx, i, c, padding; + var leftbits = 0; // number of bits decoded, but yet to be appended + var leftdata = 0; // bits decoded, but yet to be appended + var data_length = data.indexOf('=') - offset; + + if (data_length < 0) { data_length = data.length - offset; } + + /* Every four characters is 3 resulting numbers */ + result_length = (data_length >> 2) * 3 + Math.floor((data_length%4)/1.5); + result = new Array(result_length); + + // Convert one by one. + /* BEGIN LOOP */ + for (idx = 0, i = offset; i < data.length; i++) { + c = toBinaryTable[data.charCodeAt(i) & 0x7f]; + padding = (data.charAt(i) === base64Pad); + // Skip illegal characters and whitespace + if (c === -1) { + console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i); + continue; + } + + // Collect data into leftdata, update bitcount + leftdata = (leftdata << 6) | c; + leftbits += 6; + + // If we have 8 or more bits, append 8 bits to the result + if (leftbits >= 8) { + leftbits -= 8; + // Append if not padding. + if (!padding) { + result[idx++] = (leftdata >> leftbits) & 0xff; + } + leftdata &= (1 << leftbits) - 1; + } + } + /* END LOOP */ + + // If there are any bits left, the base64 string was corrupted + if (leftbits) { + throw {name: 'Base64-Error', + message: 'Corrupted base64 string'}; + } + + return result; +} + +}; /* End of Base64 namespace */ diff --git a/source/_posts/oztex/viewdata/keysym.js b/source/_posts/oztex/viewdata/keysym.js new file mode 100644 index 0000000..404d1a3 --- /dev/null +++ b/source/_posts/oztex/viewdata/keysym.js @@ -0,0 +1,98 @@ +/* + * from noVNC: HTML5 VNC client + * Copyright (C) 2010 Joel Martin + * Licensed under LGPL-3 (see LICENSE.txt) + */ + +/* Translate DOM key down/up event to keysym value */ +function getKeysym(e) { + var evt, keysym; + evt = (e ? e : window.event); + + /* Remap modifier and special keys */ + switch ( evt.keyCode ) { + case 8 : keysym = 0xFF08; break; // BACKSPACE + case 9 : keysym = 0xFF09; break; // TAB + case 13 : keysym = 0xFF0D; break; // ENTER + case 27 : keysym = 0xFF1B; break; // ESCAPE + case 45 : keysym = 0xFF63; break; // INSERT + case 46 : keysym = 0xFFFF; break; // DELETE + case 36 : keysym = 0xFF50; break; // HOME + case 35 : keysym = 0xFF57; break; // END + case 33 : keysym = 0xFF55; break; // PAGE_UP + case 34 : keysym = 0xFF56; break; // PAGE_DOWN + case 37 : keysym = 0xFF51; break; // LEFT + case 38 : keysym = 0xFF52; break; // UP + case 39 : keysym = 0xFF53; break; // RIGHT + case 40 : keysym = 0xFF54; break; // DOWN + case 112 : keysym = 0xFFBE; break; // F1 + case 113 : keysym = 0xFFBF; break; // F2 + case 114 : keysym = 0xFFC0; break; // F3 + case 115 : keysym = 0xFFC1; break; // F4 + case 116 : keysym = 0xFFC2; break; // F5 + case 117 : keysym = 0xFFC3; break; // F6 + case 118 : keysym = 0xFFC4; break; // F7 + case 119 : keysym = 0xFFC5; break; // F8 + case 120 : keysym = 0xFFC6; break; // F9 + case 121 : keysym = 0xFFC7; break; // F10 + case 122 : keysym = 0xFFC8; break; // F11 + case 123 : keysym = 0xFFC9; break; // F12 + case 16 : keysym = 0xFFE1; break; // SHIFT + case 17 : keysym = 0xFFE3; break; // CONTROL + //case 18 : keysym = 0xFFE7; break; // Left Meta (Mac Option) + case 18 : keysym = 0xFFE9; break; // Left ALT (Mac Command) + default : keysym = evt.keyCode; break; + } + + /* Remap symbols */ + switch (keysym) { + case 186 : keysym = 59; break; // ; (IE) + case 187 : keysym = 61; break; // = (IE) + case 188 : keysym = 44; break; // , (Mozilla, IE) + case 109 : // - (Mozilla) + if (Util.Engine.gecko) { + keysym = 45; } + break; + case 189 : keysym = 45; break; // - (IE) + case 190 : keysym = 46; break; // . (Mozilla, IE) + case 191 : keysym = 47; break; // / (Mozilla, IE) + case 192 : keysym = 96; break; // ` (Mozilla, IE) + case 219 : keysym = 91; break; // [ (Mozilla, IE) + case 220 : keysym = 92; break; // \ (Mozilla, IE) + case 221 : keysym = 93; break; // ] (Mozilla, IE) + case 222 : keysym = 39; break; // ' (Mozilla, IE) + } + + /* Remap shifted and unshifted keys */ + if (!!evt.shiftKey) { + switch (keysym) { + case 48 : keysym = 41 ; break; // ) (shifted 0) + case 49 : keysym = 33 ; break; // ! (shifted 1) + case 50 : keysym = 64 ; break; // @ (shifted 2) + case 51 : keysym = 35 ; break; // # (shifted 3) + case 52 : keysym = 36 ; break; // $ (shifted 4) + case 53 : keysym = 37 ; break; // % (shifted 5) + case 54 : keysym = 94 ; break; // ^ (shifted 6) + case 55 : keysym = 38 ; break; // & (shifted 7) + case 56 : keysym = 42 ; break; // * (shifted 8) + case 57 : keysym = 40 ; break; // ( (shifted 9) + + case 59 : keysym = 58 ; break; // : (shifted `) + case 61 : keysym = 43 ; break; // + (shifted ;) + case 44 : keysym = 60 ; break; // < (shifted ,) + case 45 : keysym = 95 ; break; // _ (shifted -) + case 46 : keysym = 62 ; break; // > (shifted .) + case 47 : keysym = 63 ; break; // ? (shifted /) + case 96 : keysym = 126; break; // ~ (shifted `) + case 91 : keysym = 123; break; // { (shifted [) + case 92 : keysym = 124; break; // | (shifted \) + case 93 : keysym = 125; break; // } (shifted ]) + case 39 : keysym = 34 ; break; // " (shifted ') + } + } else if ((keysym >= 65) && (keysym <=90)) { + /* Remap unshifted A-Z */ + keysym += 32; + } + + return keysym; +} diff --git a/source/_posts/oztex/viewdata/util.js b/source/_posts/oztex/viewdata/util.js new file mode 100644 index 0000000..67d2133 --- /dev/null +++ b/source/_posts/oztex/viewdata/util.js @@ -0,0 +1,379 @@ +/* + * from noVNC: HTML5 VNC client + * Copyright (C) 2012 Joel Martin + * Licensed under MPL 2.0 (see LICENSE.txt) + * + * See README.md for usage and integration instructions. + */ + +"use strict"; +/*jslint bitwise: false, white: false */ +/*global window, console, document, navigator, ActiveXObject */ + +// Globals defined here +var Util = {}; + + +/* + * Make arrays quack + */ + +Array.prototype.push8 = function (num) { + this.push(num & 0xFF); +}; + +Array.prototype.push16 = function (num) { + this.push((num >> 8) & 0xFF, + (num ) & 0xFF ); +}; +Array.prototype.push32 = function (num) { + this.push((num >> 24) & 0xFF, + (num >> 16) & 0xFF, + (num >> 8) & 0xFF, + (num ) & 0xFF ); +}; + +// IE does not support map (even in IE9) +//This prototype is provided by the Mozilla foundation and +//is distributed under the MIT license. +//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license +if (!Array.prototype.map) +{ + Array.prototype.map = function(fun /*, thisp*/) + { + var len = this.length; + if (typeof fun != "function") + throw new TypeError(); + + var res = new Array(len); + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + { + if (i in this) + res[i] = fun.call(thisp, this[i], i, this); + } + + return res; + }; +} + +// +// requestAnimationFrame shim with setTimeout fallback +// + +window.requestAnimFrame = (function(){ + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback){ + window.setTimeout(callback, 1000 / 60); + }; +})(); + +/* + * ------------------------------------------------------ + * Namespaced in Util + * ------------------------------------------------------ + */ + +/* + * Logging/debug routines + */ + +Util._log_level = 'warn'; +Util.init_logging = function (level) { + if (typeof level === 'undefined') { + level = Util._log_level; + } else { + Util._log_level = level; + } + if (typeof window.console === "undefined") { + if (typeof window.opera !== "undefined") { + window.console = { + 'log' : window.opera.postError, + 'warn' : window.opera.postError, + 'error': window.opera.postError }; + } else { + window.console = { + 'log' : function(m) {}, + 'warn' : function(m) {}, + 'error': function(m) {}}; + } + } + + Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; + switch (level) { + case 'debug': Util.Debug = function (msg) { console.log(msg); }; + case 'info': Util.Info = function (msg) { console.log(msg); }; + case 'warn': Util.Warn = function (msg) { console.warn(msg); }; + case 'error': Util.Error = function (msg) { console.error(msg); }; + case 'none': + break; + default: + throw("invalid logging type '" + level + "'"); + } +}; +Util.get_logging = function () { + return Util._log_level; +}; +// Initialize logging level +Util.init_logging(); + + +// Set configuration default for Crockford style function namespaces +Util.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) { + var getter, setter; + + // Default getter function + getter = function (idx) { + if ((type in {'arr':1, 'array':1}) && + (typeof idx !== 'undefined')) { + return cfg[v][idx]; + } else { + return cfg[v]; + } + }; + + // Default setter function + setter = function (val, idx) { + if (type in {'boolean':1, 'bool':1}) { + if ((!val) || (val in {'0':1, 'no':1, 'false':1})) { + val = false; + } else { + val = true; + } + } else if (type in {'integer':1, 'int':1}) { + val = parseInt(val, 10); + } else if (type === 'str') { + val = String(val); + } else if (type === 'func') { + if (!val) { + val = function () {}; + } + } + if (typeof idx !== 'undefined') { + cfg[v][idx] = val; + } else { + cfg[v] = val; + } + }; + + // Set the description + api[v + '_description'] = desc; + + // Set the getter function + if (typeof api['get_' + v] === 'undefined') { + api['get_' + v] = getter; + } + + // Set the setter function with extra sanity checks + if (typeof api['set_' + v] === 'undefined') { + api['set_' + v] = function (val, idx) { + if (mode in {'RO':1, 'ro':1}) { + throw(v + " is read-only"); + } else if ((mode in {'WO':1, 'wo':1}) && + (typeof cfg[v] !== 'undefined')) { + throw(v + " can only be set once"); + } + setter(val, idx); + }; + } + + // Set the default value + if (typeof defaults[v] !== 'undefined') { + defval = defaults[v]; + } else if ((type in {'arr':1, 'array':1}) && + (! (defval instanceof Array))) { + defval = []; + } + // Coerce existing setting to the right type + //Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]); + setter(defval); +}; + +// Set group of configuration defaults +Util.conf_defaults = function(cfg, api, defaults, arr) { + var i; + for (i = 0; i < arr.length; i++) { + Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1], + arr[i][2], arr[i][3], arr[i][4]); + } +}; + + +/* + * Cross-browser routines + */ + + +// Dynamically load scripts without using document.write() +// Reference: http://unixpapa.com/js/dyna.html +// +// Handles the case where load_scripts is invoked from a script that +// itself is loaded via load_scripts. Once all scripts are loaded the +// window.onscriptsloaded handler is called (if set). +Util.get_include_uri = function() { + return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "include/"; +} +Util._loading_scripts = []; +Util._pending_scripts = []; +Util.load_scripts = function(files) { + var head = document.getElementsByTagName('head')[0], script, + ls = Util._loading_scripts, ps = Util._pending_scripts; + for (var f=0; f 0 && (ls[0].readyState === 'loaded' || + ls[0].readyState === 'complete')) { + // For IE, append the script to trigger execution + var s = ls.shift(); + //console.log("loaded script: " + s.src); + head.appendChild(s); + } + if (!this.readyState || + (Util.Engine.presto && this.readyState === 'loaded') || + this.readyState === 'complete') { + if (ps.indexOf(this) >= 0) { + this.onload = this.onreadystatechange = null; + //console.log("completed script: " + this.src); + ps.splice(ps.indexOf(this), 1); + + // Call window.onscriptsload after last script loads + if (ps.length === 0 && window.onscriptsload) { + window.onscriptsload(); + } + } + } + }; + // In-order script execution tricks + if (Util.Engine.trident) { + // For IE wait until readyState is 'loaded' before + // appending it which will trigger execution + // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order + ls.push(script); + } else { + // For webkit and firefox set async=false and append now + // https://developer.mozilla.org/en-US/docs/HTML/Element/script + script.async = false; + head.appendChild(script); + } + ps.push(script); + } +} + +// Get DOM element position on page +Util.getPosition = function (obj) { + var x = 0, y = 0; + if (obj.offsetParent) { + do { + x += obj.offsetLeft; + y += obj.offsetTop; + obj = obj.offsetParent; + } while (obj); + } + return {'x': x, 'y': y}; +}; + +// Get mouse event position in DOM element +Util.getEventPosition = function (e, obj, scale) { + var evt, docX, docY, pos; + //if (!e) evt = window.event; + evt = (e ? e : window.event); + evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt); + if (evt.pageX || evt.pageY) { + docX = evt.pageX; + docY = evt.pageY; + } else if (evt.clientX || evt.clientY) { + docX = evt.clientX + document.body.scrollLeft + + document.documentElement.scrollLeft; + docY = evt.clientY + document.body.scrollTop + + document.documentElement.scrollTop; + } + pos = Util.getPosition(obj); + if (typeof scale === "undefined") { + scale = 1; + } + return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale}; +}; + + +// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events +Util.addEvent = function (obj, evType, fn){ + if (obj.attachEvent){ + var r = obj.attachEvent("on"+evType, fn); + return r; + } else if (obj.addEventListener){ + obj.addEventListener(evType, fn, false); + return true; + } else { + throw("Handler could not be attached"); + } +}; + +Util.removeEvent = function(obj, evType, fn){ + if (obj.detachEvent){ + var r = obj.detachEvent("on"+evType, fn); + return r; + } else if (obj.removeEventListener){ + obj.removeEventListener(evType, fn, false); + return true; + } else { + throw("Handler could not be removed"); + } +}; + +Util.stopEvent = function(e) { + if (e.stopPropagation) { e.stopPropagation(); } + else { e.cancelBubble = true; } + + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } +}; + + +// Set browser engine versions. Based on mootools. +Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; + +Util.Engine = { + // Version detection break in Opera 11.60 (errors on arguments.callee.caller reference) + //'presto': (function() { + // return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()), + 'presto': (function() { return (!window.opera) ? false : true; }()), + + 'trident': (function() { + return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()), + 'webkit': (function() { + try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()), + //'webkit': (function() { + // return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()), + 'gecko': (function() { + return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }()) +}; +if (Util.Engine.webkit) { + // Extract actual webkit version if available + Util.Engine.webkit = (function(v) { + var re = new RegExp('WebKit/([0-9\.]*) '); + v = (navigator.userAgent.match(re) || ['', v])[1]; + return parseFloat(v, 10); + })(Util.Engine.webkit); +} + +Util.Flash = (function(){ + var v, version; + try { + v = navigator.plugins['Shockwave Flash'].description; + } catch(err1) { + try { + v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + } catch(err2) { + v = '0 r0'; + } + } + version = v.match(/\d+/g); + return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; +}()); diff --git a/source/_posts/oztex/viewdata/vdata.js b/source/_posts/oztex/viewdata/vdata.js new file mode 100644 index 0000000..4fe605e --- /dev/null +++ b/source/_posts/oztex/viewdata/vdata.js @@ -0,0 +1,320 @@ +// VD.js -- a viewdata terminal emulator + +// constructor +function VD(wd, ht, scr_id) +{ + var r; + var c; + var scr = document.getElementById(scr_id); + this.wd_ = wd; + this.ht_ = ht; + this.text_ = new Array(ht); + for (r = 0; r < ht; ++r) { + this.text_[r] = new Array(wd); + } + this.scr_ = scr; + this.cursor_vis_ = true; + this.getch_isr_ = undefined; + this.grab_events_ = false; + this.key_buf_ = []; + this.esc_state_ = 0; + this.col_ = 0; + this.row_ = 0; + // Internal debug setting. + this.clear(); + //this.refresh(); +} + +VD.A_REVERSE = 2; +VD.A_BLINK = 4; + +VD.browser_ie_ = (navigator.appName.indexOf("Microsoft") != -1); +VD.browser_opera_ = (navigator.appName.indexOf("Opera") != -1); +// class variables +VD.the_vt_ = undefined; + +// object methods + +VD.prototype.html_colours_ = function(at_fg, at_bg, at_mode) +{ + var co0, co1; + if (at_mode & VD.A_REVERSE) { + co0 = 'ff'; + co1 = '00'; + } else { + co0 = '00'; + co1 = 'ff'; + } + + return { + f: '#' + (at_fg & 1 ? co1 : co0) + + (at_fg & 2 ? co1 : co0) + + (at_fg & 4 ? co1 : co0), + b: '#' + (at_bg & 1 ? co1 : co0) + + (at_bg & 2 ? co1 : co0) + + (at_bg & 4 ? co1 : co0) + }; +} + + +VD.prototype.clear = function() +{ + this.row_ = this.col_ = 0; + for (r = 0; r < this.ht_; ++r) { + for (c = 0; c < this.wd_; ++c) { + this.text_[r][c] = ' '; + } + } +} + +VD.prototype.curs_set = function(vis, grab, eventist) +{ + if (vis !== undefined) + this.cursor_vis_ = (vis > 0); +} + +VD.prototype.getch = function(isr) +{ +// this.refresh(); + this.getch_isr_ = isr; + setTimeout(VD.go_getch_, 0); +} + +VD.go_getch_ = function VD_go_getch() +{ + var vt = VD.the_vt_; + if (vt === undefined) + return; + var isr = vt.getch_isr_; + vt.getch_isr_ = undefined; + if (isr === undefined) + return; + var ch = vt.key_buf_.shift(); + if (ch === undefined) { + vt.getch_isr_ = isr; + return; + } + isr(ch, vt); +} + +VD.prototype.move = function(r, c) +{ + if (r < 0) + r = 0; + else if (r >= this.ht_) + r = this.ht_ - 1; + if (c < 0) + c = 0; + else if (c >= this.wd_) + c = this.wd_ - 1; + this.row_ = r; + this.col_ = c; +} + + +VD.prototype.refresh = function() +{ + var r, c, stuff = "", start_tag = "", end_tag = "", ch, + pair, cr, cc, ht, wd, cv, n_fg, n_bg, n_mode, n_type, a_fg=-1, a_bg=-1, a_mode=-1; + ht = this.ht_; + wd = this.wd_; + cr = this.row_; + cc = this.col_; + cv = this.cursor_vis_; +// var innerHTML = this.scr_.innerHTML; + if (cc >= wd) + cc = wd - 1; + for (r = 0; r < ht; ++r) { + if (r > 0) { + stuff += '\n'; + } + n_fg = 7; + n_bg = 0; + n_mode = 0; + n_type = 0; + for (c = 0; c < wd; ++c) { + if (cv && r == cr && c == cc) { + // Draw the cursor here. + n_mode |= VD.A_REVERSE; + } else { + n_mode &= ~VD.A_REVERSE; + } + + ch = this.text_[r][c]; +//console.log('CH: %i (%s) [%i,%i]',ch.charCodeAt(0),ch,r,c); + if (ch.charCodeAt(0) >= 129 && ch.charCodeAt(0) <= 135) { + n_fg = ch.charCodeAt(0)-128; + n_type &= ~2; + n_type &= ~16; + } + if (ch.charCodeAt(0) >= 145 && ch.charCodeAt(0) <= 151) { + n_fg = ch.charCodeAt(0)-144; + n_type |= 2; + n_type &= ~16; + } + if (ch == '\x88') + n_mode |= VD.A_BLINK; + if (ch == '\x89') + n_mode &= ~VD.A_BLINK; + if (ch == '\x8c') + n_type &= ~8; + if (ch == '\x8d') + n_type |= 8; + if (ch == '\x98') + n_type |= 16; + if (ch == '\x99') + n_type &= ~1; + if (ch == '\x9a') + n_type |= 1; + if (ch == '\x9c') + n_bg = 0; + if (ch == '\x9d') + n_bg = n_fg; + if (ch == '\x9e') + n_type |= 32; + if (ch == '\x9f') + n_type &= ~32; + + // If the attributes changed, make a new span. + if (n_mode != a_mode || n_fg != a_fg || n_bg != a_bg) { + stuff += end_tag; + pair = this.html_colours_(n_fg, n_bg, n_mode); + stuff += ''; + // + (n_mode & VD.A_BLINK ? ' class="blink"' : '') + '>'; + end_tag = ""; + a_fg = n_fg; + a_bg = n_bg; + a_mode = n_mode; + } + + if (ch.charCodeAt(0) >= 128) + ch = ' '; + + if (n_type & 2) { + if ( ch.charCodeAt(0) >= 0x20 && ch.charCodeAt(0) <= 0x3f) { + ch = '&#x' + (ch.charCodeAt(0)+0xe1e0+((n_type & 1)*0xc0)).toString(16) +";"; + } else if ( ch.charCodeAt(0) >= 0x60 && ch.charCodeAt(0) <= 0x7f) { + ch = '&#x' + (ch.charCodeAt(0)+0xe1c0+((n_type & 1)*0xc0)).toString(16) +";"; + } + } + + switch (ch) { + case '&': + stuff += '&'; break; + case '<': + stuff += '<'; break; + case '>': + stuff += '>'; break; + case ' ': + // stuff += ' '; break; + stuff += '\xa0'; break; + case '\x7e': + case '~': + stuff += '\xf7'; break; + case '\x7f': + stuff += ""; break + case '_': + stuff += '#'; break + case '{': + stuff += '\xbc'; break + case '\\': + stuff += '\xbd'; break + case '}': + stuff += '\xbe'; break + case '#': + stuff += '\xa3'; break + default: + stuff += ch; + } + } + } + stuff += end_tag + //this.scr_.innerHTML = "" + stuff + "\n"; + this.scr_.innerHTML = stuff + "\n"; +} + + +VD.prototype.write = function(stuff) +{ + var ch, i; + for (i = 0; i < stuff.length; ++i) { + ch = stuff.charCodeAt(i); + if (this.esc_state_ && ch > 31) + ch = (ch % 32) + 128; + this.esc_state_ = 0; + switch (ch) { + case 8: + if (this.col_ != 0) { + --this.col_; + } else { + this.col_ = this.wd_-1; + if (this.row_ == 0) { + this.row_ = this.ht_-1; + } else { + --this.row_; + } + } + break; + case 9: + if (this.col_ >= this.wd_) { + this.col_ = 0; + if (this.row_ == this.ht_-1) { + this.row_ = 0; + } else { + ++this.row_; + } + } else { + ++this.col_; + } + break; + case 10: + if (this.row_ >= this.ht_-1) { + this.row_ = 0; + } else { + ++this.row_; + } + break; + case 11: + if (this.row_ == 0) { + this.row_ = this.ht_-1; + } else { + --this.row_; + } + break; + case 12: + this.clear(); + this.move(0, 0); + break; + case 13: + this.col_ = 0; + break; + case 17: + this.curs_set(1); + break; + case 20: + this.curs_set(0); + break; + case 27: + this.esc_state_ = 1; + break; + case 30: + this.move(0, 0); + break; + default: + if (ch > 31) { + this.text_[this.row_][this.col_] = String.fromCharCode(ch); + if (this.col_ >= this.wd_-1) { + this.col_ = 0; + if (this.row_ >= this.ht_-1) { + this.row_ = 0; + } else { + ++this.row_; + } + } else { + ++this.col_; + } + } + } + } + this.refresh(); +} diff --git a/source/_posts/oztex/viewdata/websock.js b/source/_posts/oztex/viewdata/websock.js new file mode 100644 index 0000000..0e4718a --- /dev/null +++ b/source/_posts/oztex/viewdata/websock.js @@ -0,0 +1,424 @@ +/* + * Websock: high-performance binary WebSockets + * Copyright (C) 2012 Joel Martin + * Licensed under MPL 2.0 (see LICENSE.txt) + * + * Websock is similar to the standard WebSocket object but Websock + * enables communication with raw TCP sockets (i.e. the binary stream) + * via websockify. This is accomplished by base64 encoding the data + * stream between Websock and websockify. + * + * Websock has built-in receive queue buffering; the message event + * does not contain actual data but is simply a notification that + * there is new data available. Several rQ* methods are available to + * read binary data off of the receive queue. + */ + +/*jslint browser: true, bitwise: false, plusplus: false */ +/*global Util, Base64 */ + + +// Load Flash WebSocket emulator if needed + +// To force WebSocket emulator even when native WebSocket available +//window.WEB_SOCKET_FORCE_FLASH = true; +// To enable WebSocket emulator debug: +//window.WEB_SOCKET_DEBUG=1; + +if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) { + Websock_native = true; +} else if (window.MozWebSocket && !window.WEB_SOCKET_FORCE_FLASH) { + Websock_native = true; + window.WebSocket = window.MozWebSocket; +} else { + /* no builtin WebSocket so load web_socket.js */ + + Websock_native = false; + (function () { + window.WEB_SOCKET_SWF_LOCATION = Util.get_include_uri() + + "web-socket-js/WebSocketMain.swf"; + if (Util.Engine.trident) { + Util.Debug("Forcing uncached load of WebSocketMain.swf"); + window.WEB_SOCKET_SWF_LOCATION += "?" + Math.random(); + } + Util.load_scripts(["web-socket-js/swfobject.js", + "web-socket-js/web_socket.js"]); + }()); +} + + +function Websock() { +"use strict"; + +var api = {}, // Public API + websocket = null, // WebSocket object + mode = 'base64', // Current WebSocket mode: 'binary', 'base64' + rQ = [], // Receive queue + rQi = 0, // Receive queue index + rQmax = 10000, // Max receive queue size before compacting + sQ = [], // Send queue + + eventHandlers = { + 'message' : function() {}, + 'open' : function() {}, + 'close' : function() {}, + 'error' : function() {} + }, + + test_mode = false; + + +// +// Queue public functions +// + +function get_sQ() { + return sQ; +} + +function get_rQ() { + return rQ; +} +function get_rQi() { + return rQi; +} +function set_rQi(val) { + rQi = val; +} + +function rQlen() { + return rQ.length - rQi; +} + +function rQpeek8() { + return (rQ[rQi] ); +} +function rQshift8() { + return (rQ[rQi++] ); +} +function rQunshift8(num) { + if (rQi === 0) { + rQ.unshift(num); + } else { + rQi -= 1; + rQ[rQi] = num; + } + +} +function rQshift16() { + return (rQ[rQi++] << 8) + + (rQ[rQi++] ); +} +function rQshift32() { + return (rQ[rQi++] << 24) + + (rQ[rQi++] << 16) + + (rQ[rQi++] << 8) + + (rQ[rQi++] ); +} +function rQshiftStr(len) { + if (typeof(len) === 'undefined') { len = rQlen(); } + var arr = rQ.slice(rQi, rQi + len); + rQi += len; + return String.fromCharCode.apply(null, arr); +} +function rQshiftBytes(len) { + if (typeof(len) === 'undefined') { len = rQlen(); } + rQi += len; + return rQ.slice(rQi-len, rQi); +} + +function rQslice(start, end) { + if (end) { + return rQ.slice(rQi + start, rQi + end); + } else { + return rQ.slice(rQi + start); + } +} + +// Check to see if we must wait for 'num' bytes (default to FBU.bytes) +// to be available in the receive queue. Return true if we need to +// wait (and possibly print a debug message), otherwise false. +function rQwait(msg, num, goback) { + var rQlen = rQ.length - rQi; // Skip rQlen() function call + if (rQlen < num) { + if (goback) { + if (rQi < goback) { + throw("rQwait cannot backup " + goback + " bytes"); + } + rQi -= goback; + } + //Util.Debug(" waiting for " + (num-rQlen) + + // " " + msg + " byte(s)"); + return true; // true means need more data + } + return false; +} + +// +// Private utility routines +// + +function encode_message() { + if (mode === 'binary') { + // Put in a binary arraybuffer + return (new Uint8Array(sQ)).buffer; + } else { + // base64 encode + return Base64.encode(sQ); + } +} + +function decode_message(data) { + //Util.Debug(">> decode_message: " + data); + if (mode === 'binary') { + // push arraybuffer values onto the end + var u8 = new Uint8Array(data); + for (var i = 0; i < u8.length; i++) { + rQ.push(u8[i]); + } + } else { + // base64 decode and concat to the end + rQ = rQ.concat(Base64.decode(data, 0)); + } + //Util.Debug(">> decode_message, rQ: " + rQ); +} + + +// +// Public Send functions +// + +function flush() { + if (websocket.bufferedAmount !== 0) { + Util.Debug("bufferedAmount: " + websocket.bufferedAmount); + } + if (websocket.bufferedAmount < api.maxBufferedAmount) { + //Util.Debug("arr: " + arr); + //Util.Debug("sQ: " + sQ); + if (sQ.length > 0) { + websocket.send(encode_message(sQ)); + sQ = []; + } + return true; + } else { + Util.Info("Delaying send, bufferedAmount: " + + websocket.bufferedAmount); + return false; + } +} + +// overridable for testing +function send(arr) { + //Util.Debug(">> send_array: " + arr); + sQ = sQ.concat(arr); + return flush(); +} + +function send_string(str) { + //Util.Debug(">> send_string: " + str); + api.send(str.split('').map( + function (chr) { return chr.charCodeAt(0); } ) ); +} + +// +// Other public functions + +function recv_message(e) { + //Util.Debug(">> recv_message: " + e.data.length); + + try { + decode_message(e.data); + if (rQlen() > 0) { + eventHandlers.message(); + // Compact the receive queue + if (rQ.length > rQmax) { + //Util.Debug("Compacting receive queue"); + rQ = rQ.slice(rQi); + rQi = 0; + } + } else { + Util.Debug("Ignoring empty message"); + } + } catch (exc) { + if (typeof exc.stack !== 'undefined') { + Util.Warn("recv_message, caught exception: " + exc.stack); + } else if (typeof exc.description !== 'undefined') { + Util.Warn("recv_message, caught exception: " + exc.description); + } else { + Util.Warn("recv_message, caught exception:" + exc); + } + if (typeof exc.name !== 'undefined') { + eventHandlers.error(exc.name + ": " + exc.message); + } else { + eventHandlers.error(exc); + } + } + //Util.Debug("<< recv_message"); +} + + +// Set event handlers +function on(evt, handler) { + eventHandlers[evt] = handler; +} + +function init(protocols, ws_schema) { + rQ = []; + rQi = 0; + sQ = []; + websocket = null; + + var bt = false, + wsbt = false, + try_binary = false; + + // Check for full typed array support + if (('Uint8Array' in window) && + ('set' in Uint8Array.prototype)) { + bt = true; + } + // Check for full binary type support in WebSocket + // Inspired by: + // https://github.com/Modernizr/Modernizr/issues/370 + // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/websockets/binary.js + try { + if (bt && ('binaryType' in WebSocket.prototype || + !!(new WebSocket(ws_schema + '://.').binaryType))) { + Util.Info("Detected binaryType support in WebSockets"); + wsbt = true; + } + } catch (exc) { + // Just ignore failed test localhost connections + } + + // Default protocols if not specified + if (typeof(protocols) === "undefined") { + if (wsbt) { + protocols = ['binary', 'base64']; + } else { + protocols = 'base64'; + } + } + + // If no binary support, make sure it was not requested + if (!wsbt) { + if (protocols === 'binary') { + throw("WebSocket binary sub-protocol requested but not supported"); + } + if (typeof(protocols) === "object") { + var new_protocols = []; + for (var i = 0; i < protocols.length; i++) { + if (protocols[i] === 'binary') { + Util.Error("Skipping unsupported WebSocket binary sub-protocol"); + } else { + new_protocols.push(protocols[i]); + } + } + if (new_protocols.length > 0) { + protocols = new_protocols; + } else { + throw("Only WebSocket binary sub-protocol was requested and not supported."); + } + } + } + + return protocols; +} + +function open(uri, protocols) { + var ws_schema = uri.match(/^([a-z]+):\/\//)[1]; + protocols = init(protocols, ws_schema); + + if (test_mode) { + websocket = {}; + } else { + websocket = new WebSocket(uri, protocols); + if (protocols.indexOf('binary') >= 0) { + websocket.binaryType = 'arraybuffer'; + } + } + + websocket.onmessage = recv_message; + websocket.onopen = function() { + Util.Debug(">> WebSock.onopen"); + if (websocket.protocol) { + mode = websocket.protocol; + Util.Info("Server chose sub-protocol: " + websocket.protocol); + } else { + mode = 'base64'; + Util.Error("Server select no sub-protocol!: " + websocket.protocol); + } + eventHandlers.open(); + Util.Debug("<< WebSock.onopen"); + }; + websocket.onclose = function(e) { + Util.Debug(">> WebSock.onclose"); + eventHandlers.close(e); + Util.Debug("<< WebSock.onclose"); + }; + websocket.onerror = function(e) { + Util.Debug(">> WebSock.onerror: " + e); + eventHandlers.error(e); + Util.Debug("<< WebSock.onerror"); + }; +} + +function close() { + if (websocket) { + if ((websocket.readyState === WebSocket.OPEN) || + (websocket.readyState === WebSocket.CONNECTING)) { + Util.Info("Closing WebSocket connection"); + websocket.close(); + } + websocket.onmessage = function (e) { return; }; + } +} + +// Override internal functions for testing +// Takes a send function, returns reference to recv function +function testMode(override_send, data_mode) { + test_mode = true; + mode = data_mode; + api.send = override_send; + api.close = function () {}; + return recv_message; +} + +function constructor() { + // Configuration settings + api.maxBufferedAmount = 200; + + // Direct access to send and receive queues + api.get_sQ = get_sQ; + api.get_rQ = get_rQ; + api.get_rQi = get_rQi; + api.set_rQi = set_rQi; + + // Routines to read from the receive queue + api.rQlen = rQlen; + api.rQpeek8 = rQpeek8; + api.rQshift8 = rQshift8; + api.rQunshift8 = rQunshift8; + api.rQshift16 = rQshift16; + api.rQshift32 = rQshift32; + api.rQshiftStr = rQshiftStr; + api.rQshiftBytes = rQshiftBytes; + api.rQslice = rQslice; + api.rQwait = rQwait; + + api.flush = flush; + api.send = send; + api.send_string = send_string; + + api.on = on; + api.init = init; + api.open = open; + api.close = close; + api.testMode = testMode; + + return api; +} + +return constructor(); + +} diff --git a/source/_posts/oztex/viewdata/webutil.js b/source/_posts/oztex/viewdata/webutil.js new file mode 100644 index 0000000..2c82c73 --- /dev/null +++ b/source/_posts/oztex/viewdata/webutil.js @@ -0,0 +1,216 @@ +/* + * from noVNC: HTML5 VNC client + * Copyright (C) 2012 Joel Martin + * Licensed under MPL 2.0 (see LICENSE.txt) + * + * See README.md for usage and integration instructions. + */ + +"use strict"; +/*jslint bitwise: false, white: false */ +/*global Util, window, document */ + +// Globals defined here +var WebUtil = {}, $D; + +/* + * Simple DOM selector by ID + */ +if (!window.$D) { + window.$D = function (id) { + if (document.getElementById) { + return document.getElementById(id); + } else if (document.all) { + return document.all[id]; + } else if (document.layers) { + return document.layers[id]; + } + return undefined; + }; +} + + +/* + * ------------------------------------------------------ + * Namespaced in WebUtil + * ------------------------------------------------------ + */ + +// init log level reading the logging HTTP param +WebUtil.init_logging = function(level) { + if (typeof level !== "undefined") { + Util._log_level = level; + } else { + Util._log_level = (document.location.href.match( + /logging=([A-Za-z0-9\._\-]*)/) || + ['', Util._log_level])[1]; + } + Util.init_logging(); +}; + + +WebUtil.dirObj = function (obj, depth, parent) { + var i, msg = "", val = ""; + if (! depth) { depth=2; } + if (! parent) { parent= ""; } + + // Print the properties of the passed-in object + for (i in obj) { + if ((depth > 1) && (typeof obj[i] === "object")) { + // Recurse attributes that are objects + msg += WebUtil.dirObj(obj[i], depth-1, parent + "." + i); + } else { + //val = new String(obj[i]).replace("\n", " "); + if (typeof(obj[i]) === "undefined") { + val = "undefined"; + } else { + val = obj[i].toString().replace("\n", " "); + } + if (val.length > 30) { + val = val.substr(0,30) + "..."; + } + msg += parent + "." + i + ": " + val + "\n"; + } + } + return msg; +}; + +// Read a query string variable +WebUtil.getQueryVar = function(name, defVal) { + var re = new RegExp('[?][^#]*' + name + '=([^&#]*)'), + match = document.location.href.match(re); + if (typeof defVal === 'undefined') { defVal = null; } + if (match) { + return decodeURIComponent(match[1]); + } else { + return defVal; + } +}; + + +/* + * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html + */ + +// No days means only for this browser session +WebUtil.createCookie = function(name,value,days) { + var date, expires; + if (days) { + date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + expires = "; expires="+date.toGMTString(); + } + else { + expires = ""; + } + document.cookie = name+"="+value+expires+"; path=/"; +}; + +WebUtil.readCookie = function(name, defaultValue) { + var i, c, nameEQ = name + "=", ca = document.cookie.split(';'); + for(i=0; i < ca.length; i += 1) { + c = ca[i]; + while (c.charAt(0) === ' ') { c = c.substring(1,c.length); } + if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length,c.length); } + } + return (typeof defaultValue !== 'undefined') ? defaultValue : null; +}; + +WebUtil.eraseCookie = function(name) { + WebUtil.createCookie(name,"",-1); +}; + +/* + * Setting handling. + */ + +WebUtil.initSettings = function(callback) { + var callbackArgs = Array.prototype.slice.call(arguments, 1); + if (window.chrome && window.chrome.storage) { + window.chrome.storage.sync.get(function (cfg) { + WebUtil.settings = cfg; + console.log(WebUtil.settings); + if (callback) { + callback.apply(this, callbackArgs); + } + }); + } else { + // No-op + if (callback) { + callback.apply(this, callbackArgs); + } + } +}; + +// No days means only for this browser session +WebUtil.writeSetting = function(name, value) { + if (window.chrome && window.chrome.storage) { + //console.log("writeSetting:", name, value); + if (WebUtil.settings[name] !== value) { + WebUtil.settings[name] = value; + window.chrome.storage.sync.set(WebUtil.settings); + } + } else { + localStorage.setItem(name, value); + } +}; + +WebUtil.readSetting = function(name, defaultValue) { + var value; + if (window.chrome && window.chrome.storage) { + value = WebUtil.settings[name]; + } else { + value = localStorage.getItem(name); + } + if (typeof value === "undefined") { + value = null; + } + if (value === null && typeof defaultValue !== undefined) { + return defaultValue; + } else { + return value; + } +}; + +WebUtil.eraseSetting = function(name) { + if (window.chrome && window.chrome.storage) { + window.chrome.storage.sync.remove(name); + delete WebUtil.settings[name]; + } else { + localStorage.removeItem(name); + } +}; + +/* + * Alternate stylesheet selection + */ +WebUtil.getStylesheets = function() { var i, links, sheets = []; + links = document.getElementsByTagName("link"); + for (i = 0; i < links.length; i += 1) { + if (links[i].title && + links[i].rel.toUpperCase().indexOf("STYLESHEET") > -1) { + sheets.push(links[i]); + } + } + return sheets; +}; + +// No sheet means try and use value from cookie, null sheet used to +// clear all alternates. +WebUtil.selectStylesheet = function(sheet) { + var i, link, sheets = WebUtil.getStylesheets(); + if (typeof sheet === 'undefined') { + sheet = 'default'; + } + for (i=0; i < sheets.length; i += 1) { + link = sheets[i]; + if (link.title === sheet) { + Util.Debug("Using stylesheet " + sheet); + link.disabled = false; + } else { + //Util.Debug("Skipping stylesheet " + link.title); + link.disabled = true; + } + } + return sheet; +}; diff --git a/source/_posts/oztex/viewdata/wsvdata.js b/source/_posts/oztex/viewdata/wsvdata.js new file mode 100644 index 0000000..c279dd1 --- /dev/null +++ b/source/_posts/oztex/viewdata/wsvdata.js @@ -0,0 +1,203 @@ +function Telnet(target, connect_callback, disconnect_callback) { + +var that = {}, // Public API interface + vd, ws, sQ = []; + termType = "Viewdata"; + + +Array.prototype.pushStr = function (str) { + var n = str.length; + for (var i=0; i < n; i++) { + this.push(str.charCodeAt(i)); + } +} + +function do_send() { + if (sQ.length > 0) { + ws.send(sQ); + sQ = []; + } +} + +function do_recv() { + vd.write(ws.rQshiftStr(ws.rQlen())); +} + + + +that.connect = function(host, port, encrypt, url) { + var host = host, + port = port, + scheme = "ws://", uri; + + if ((!host) || (!port)) { + console.log("must set host and port"); + return; + } + + if (ws) { + ws.close(); + } + + if (encrypt) { + scheme = "wss://"; + } + uri = scheme + host + ":" + port + url; + + ws.open(uri); +} + +that.disconnect = function() { + if (ws) { + ws.close(); + } + vd.curs_set(true, false); + + disconnect_callback(); +} + + +function constructor() { + /* Initialize Websock object */ + ws = new Websock(); + + ws.on('message', do_recv); + ws.on('open', function(e) { + vd.curs_set(true, true); + connect_callback(); + }); + ws.on('close', function(e) { + that.disconnect(); + }); + ws.on('error', function(e) { + that.disconnect(); + }); + + /* Initialize the terminal emulator/renderer */ + + vd = new VD(40, 24, target); + + /* + * Override VD I/O routines + */ + + // Set handler for sending characters + vd.getch( + function send_chr(chr, vt) { + var i; + for (i = 0; i < chr.length; i++) { + sQ.push(chr.charCodeAt(i)); + } + do_send(); + vd.getch(send_chr); + } + ); + + vd.curs_set = function(vis, grab, eventist) + { + if (vis !== undefined) + this.cursor_vis_ = (vis > 0); + if (eventist === undefined) + eventist = window; + if (grab === true || grab === false) { + if (grab === this.grab_events_) + return; + if (grab) { + this.grab_events_ = true; + VD.the_vt_ = this; + Util.addEvent(eventist, 'keydown', vd.key_down); + Util.addEvent(eventist, 'keyup', vd.key_up); + } else { + Util.removeEvent(eventist, 'keydown', vd.key_down); + Util.removeEvent(eventist, 'keyup', vd.key_up); + this.grab_events_ = false; + VD.the_vt_ = undefined; + } + } + } + + vd.key_down = function(e) { + var vt = VD.the_vt_, keysym, ch, str = ""; + + if (vt === undefined) + return true; + + keysym = getKeysym(e); + + if (keysym < 128) { + if (e.ctrlKey) { + if (keysym == 64) { + // control 0 + ch = 0; + } else if ((keysym >= 97) && (keysym <= 122)) { + // control codes 1-26 + ch = keysym - 96; + } else if ((keysym >= 91) && (keysym <= 95)) { + // control codes 27-31 + ch = keysym - 64; + } + } else { + ch = keysym; + switch (ch) { + case 34: + ch = 126; break; + case 126: + ch = 0x40; break; + case 64: + ch = 0x22; break; + case 39: + ch = 0x5f; break; + case 95: + ch = 0x23; break; + case 96: + ch = 0x27; break; + } + } + str = String.fromCharCode(ch); + } else { + switch (keysym) { + case 65505: // Shift, do not send directly + break; + case 65507: // Ctrl, do not send directly + break; + case 65293: // Carriage return, line feed + str = '_'; break; + case 65288: // Backspace + str = '\b'; break; + case 65307: // Escape + str = '\x1b'; break; + case 65361: // Left arrow + str = '\x08'; break; + case 65362: // Up arrow + str = '\x0b'; break; + case 65363: // Right arrow + str = '\x09'; break; + case 65364: // Down arrow + str = '\x0a'; break; + } + } + + if (str) { + vt.key_buf_.push(str); + setTimeout(VD.go_getch_, 0); + } + + Util.stopEvent(e); + return false; + } + + vd.key_up = function(e) { + var vt = VD.the_vt_; + if (vt === undefined) + return true; + Util.stopEvent(e); + return false; + } + + + return that; +} + +return constructor(); // Return the public API interface + +} diff --git a/source/images/oztex.png b/source/images/oztex.png new file mode 100644 index 0000000..b28b2e8 Binary files /dev/null and b/source/images/oztex.png differ diff --git a/themes/hueman/source/libs/zoomooz/js/jquery.zoomooz.min.js b/themes/hueman/source/libs/zoomooz/js/jquery.zoomooz.min.js new file mode 100644 index 0000000..7b96bd5 --- /dev/null +++ b/themes/hueman/source/libs/zoomooz/js/jquery.zoomooz.min.js @@ -0,0 +1 @@ +function Matrix(){}var Sylvester={version:"0.1.3",precision:1e-6};Matrix.prototype={dup:function(){return Matrix.create(this.elements)},canMultiplyFromLeft:function(e){var t=e.elements||e;return t[0][0]===void 0&&(t=Matrix.create(t).elements),this.elements[0].length==t.length},multiply:function(e){var t=e.modulus?!0:!1,n=e.elements||e;if(n[0][0]===void 0&&(n=Matrix.create(n).elements),!this.canMultiplyFromLeft(n))return null;var r,o,a,i,s,l,u=this.elements.length,c=u,f=n[0].length,m=this.elements[0].length,d=[];do{r=c-u,d[r]=[],o=f;do{a=f-o,i=0,s=m;do l=m-s,i+=this.elements[r][l]*n[l][a];while(--s);d[r][a]=i}while(--o)}while(--u);return n=Matrix.create(d),t?n.col(1):n},isSquare:function(){return this.elements.length==this.elements[0].length},toRightTriangular:function(){var e,t,n,r,o=this.dup(),a=this.elements.length,i=a,s=this.elements[0].length;do{if(t=i-a,0===o.elements[t][t])for(j=t+1;i>j;j++)if(0!==o.elements[j][t]){e=[],n=s;do r=s-n,e.push(o.elements[t][r]+o.elements[j][r]);while(--n);o.elements[t]=e;break}if(0!==o.elements[t][t])for(j=t+1;i>j;j++){var l=o.elements[j][t]/o.elements[t][t];e=[],n=s;do r=s-n,e.push(t>=r?0:o.elements[j][r]-o.elements[t][r]*l);while(--n);o.elements[j]=e}}while(--a);return o},determinant:function(){if(!this.isSquare())return null;var e,t=this.toRightTriangular(),n=t.elements[0][0],r=t.elements.length-1,o=r;do e=o-r+1,n*=t.elements[e][e];while(--r);return n},isSingular:function(){return this.isSquare()&&0===this.determinant()},augment:function(e){var t=e.elements||e;t[0][0]===void 0&&(t=Matrix.create(t).elements);var n,r,o,a=this.dup(),i=a.elements[0].length,s=a.elements.length,l=s,u=t[0].length;if(s!=t.length)return null;do{n=l-s,r=u;do o=u-r,a.elements[n][i+o]=t[n][o];while(--r)}while(--s);return a},inverse:function(){if(!this.isSquare()||this.isSingular())return null;var e,t,n,r,o,a,i,s=this.elements.length,l=s,u=this.augment(Matrix.I(s)).toRightTriangular(),c=u.elements[0].length,f=[];do{e=s-1,o=[],n=c,f[e]=[],a=u.elements[e][e];do r=c-n,i=u.elements[e][r]/a,o.push(i),r>=l&&f[e].push(i);while(--n);for(u.elements[e]=o,t=0;e>t;t++){o=[],n=c;do r=c-n,o.push(u.elements[t][r]-u.elements[e][r]*u.elements[t][e]);while(--n);u.elements[t]=o}}while(--s);return Matrix.create(f)},setElements:function(e){var t,n=e.elements||e;if(n[0][0]!==void 0){var r,o,a,i=n.length,s=i;this.elements=[];do{t=s-i,r=n[t].length,o=r,this.elements[t]=[];do a=o-r,this.elements[t][a]=n[t][a];while(--r)}while(--i);return this}var l=n.length,u=l;this.elements=[];do t=u-l,this.elements.push([n[t]]);while(--l);return this}},Matrix.create=function(e){var t=new Matrix;return t.setElements(e)},Matrix.I=function(e){var t,n,r,o=[],a=e;do{t=a-e,o[t]=[],n=a;do r=a-n,o[t][r]=t==r?1:0;while(--n)}while(--e);return Matrix.create(o)},PureCSSMatrix=function(){"use strict";function e(e){e&&null!==e&&"none"!=e?e instanceof Matrix?this.setMatrix(e):this.setMatrixValue(e):this.m=Matrix.I(3)}function t(e){var t=parseFloat(n(e));return e.match(o)&&(t=2*Math.PI*t/360),t}function n(e){return e.match(a)}function r(e){return Number(e).toFixed(6)}var o=/deg$/,a=/([0-9.\-e]+)/g,i=/([a-zA-Z]+)\(([^\)]+)\)/g;return e.prototype.setMatrix=function(e){this.m=e},e.prototype.setMatrixValue=function(e){for(var r,o=Matrix.I(3);null!==(r=i.exec(e));){var a,s=r[1].toLowerCase(),l=r[2].split(",");if("matrix"==s)a=Matrix.create([[parseFloat(l[0]),parseFloat(l[2]),parseFloat(n(l[4]))],[parseFloat(l[1]),parseFloat(l[3]),parseFloat(n(l[5]))],[0,0,1]]);else if("translate"==s)a=Matrix.I(3),a.elements[0][2]=parseFloat(n(l[0])),a.elements[1][2]=parseFloat(n(l[1]));else if("scale"==s){var u,c=parseFloat(l[0]);u=l.length>1?parseFloat(l[1]):c,a=Matrix.create([[c,0,0],[0,u,0],[0,0,1]])}else"rotate"==s?a=Matrix.RotationZ(t(l[0])):"skew"==s||"skewx"==s?(a=Matrix.I(3),a.elements[0][1]=Math.tan(t(l[0]))):"skewy"==s?(a=Matrix.I(3),a.elements[1][0]=Math.tan(t(l[0]))):console.log("Problem with setMatrixValue",s,l);o=o.multiply(a)}this.m=o},e.prototype.multiply=function(t){return new e(this.m.multiply(t.m))},e.prototype.inverse=function(){return 1e-6>Math.abs(this.m.elements[0][0])&&(this.m.elements[0][0]=0),new e(this.m.inverse())},e.prototype.translate=function(t,n){var r=Matrix.I(3);return r.elements[0][2]=t,r.elements[1][2]=n,new e(this.m.multiply(r))},e.prototype.scale=function(t,n){var r=Matrix.create([[t,0,0],[0,n,0],[0,0,1]]);return new e(this.m.multiply(r))},e.prototype.rotate=function(t){var n=Matrix.RotationZ(t);return new e(this.m.multiply(n))},e.prototype.toString=function(){var e=this.m.elements,t="";return($.browser.mozilla||$.browser.opera)&&(t="px"),"matrix("+r(e[0][0])+", "+r(e[1][0])+", "+r(e[0][1])+", "+r(e[1][1])+", "+r(e[0][2])+t+", "+r(e[1][2])+t+")"},e.prototype.elements=function(){var e=this.m.elements;return{a:e[0][0],b:e[1][0],c:e[0][1],d:e[1][1],e:e[0][2],f:e[1][2]}},e}(),$.zoomooz||($.zoomooz={}),$.zoomooz.helpers=function(e,t){"use strict";var n=["-moz-","-webkit-","-o-","-ms-"];return t.forEachPrefix=function(e,t){for(var r=0;n.length>r;r++)e(n[r]);t&&e("")},t.getElementTransform=function(n){var r;return t.forEachPrefix(function(t){r=r||e(n).css(t+"transform")},!0),r},t}(jQuery,{}),function(e){"use strict";function t(e,t,n){var r={};if(b.forEachPrefix(function(t){r[t+"transform"]=e},!0),t){var o=d(t/1e3,6)+"s";r["-webkit-transition-duration"]=o,r["-o-transition-duration"]=o,r["-moz-transition-duration"]=o}if(n){var a=i(n);r["-webkit-transition-timing-function"]=a,r["-o-transition-timing-function"]=a,r["-moz-transition-timing-function"]=a}return r}function n(e,t,n,a,i,l){t||(t=o(new PureCSSMatrix)),p=(new Date).getTime(),v&&(clearInterval(v),v=null),a.easing&&(a.easingfunction=s(a.easing,a.duration)),r(e,t,n,a,i),l&&l(),v=setInterval(function(){r(e,t,n,a,i)},1)}function r(e,n,r,o,i){var s,l=(new Date).getTime()-p;s=o.easingfunction?o.easingfunction(l/o.duration):l/o.duration,e.css(t(a(m(n,r,s)))),l>o.duration&&(clearInterval(v),v=null,s=1,i&&i())}function o(e){var t=e.elements(),n=t.a,r=t.b,o=t.c,a=t.d,i=t.e,s=t.f;if(.01>Math.abs(n*a-r*o))return console.log("fail!"),void 0;var l=i,u=s,c=Math.sqrt(n*n+r*r);n/=c,r/=c;var f=n*o+r*a;o-=n*f,a-=r*f;var m=Math.sqrt(o*o+a*a);o/=m,a/=m,f/=m,0>n*a-r*o&&(n=-n,r=-r,o=-o,a=-a,c=-c,m=-m);var d=Math.atan2(r,n);return{tx:l,ty:u,r:d,k:Math.atan(f),sx:c,sy:m}}function a(e){var t="";return t+="translate("+d(e.tx,6)+"px,"+d(e.ty,6)+"px) ",t+="rotate("+d(e.r,6)+"rad) skewX("+d(e.k,6)+"rad) ",t+="scale("+d(e.sx,6)+","+d(e.sy,6)+")"}function i(e){return e instanceof Array?"cubic-bezier("+d(e[0],6)+","+d(e[1],6)+","+d(e[2],6)+","+d(e[3],6)+")":e}function s(e,t){var n=[];if(e instanceof Array)n=e;else switch(e){case"linear":n=[0,0,1,1];break;case"ease":n=[.25,.1,.25,1];break;case"ease-in":n=[.42,0,1,1];break;case"ease-out":n=[0,0,.58,1];break;case"ease-in-out":n=[.42,0,.58,1]}var r=function(e){return l(e,n[0],n[1],n[2],n[3],t)};return r}function l(e,t,n,r,o,a){function i(e){return((m*e+d)*e+h)*e}function s(e){return((p*e+v)*e+g)*e}function l(e){return(3*m*e+2*d)*e+h}function u(e){return 1/(200*e)}function c(e,t){return s(f(e,t))}function f(e,t){function n(e){return e>=0?e:0-e}var r,o,a,s,u,c;for(a=e,c=0;8>c;c++){if(s=i(a)-e,t>n(s))return a;if(u=l(a),1e-6>n(u))break;a-=s/u}if(r=0,o=1,a=e,r>a)return r;if(a>o)return o;for(;o>r;){if(s=i(a),t>n(s-e))return a;e>s?r=a:o=a,a=.5*(o-r)+r}return a}var m=0,d=0,h=0,p=0,v=0,g=0;return h=3*t,d=3*(r-t)-h,m=1-h-d,g=3*n,v=3*(o-n)-g,p=1-g-v,c(e,u(a))}function u(e,t){var n,r=b.getElementTransform(e);n=r?new PureCSSMatrix(r):new PureCSSMatrix,t&&(n=n.translate(t.x,t.y));var a=o(n);return a.r=c(r),a}function c(e){for(var t,n=0;null!==(t=y.exec(e));){var r=t[1].toLowerCase(),a=t[2].split(",");if("matrix"==r){var i=r+"("+t[2]+")";n+=o(new PureCSSMatrix(i)).r}else if("rotate"==r){var s=a[0],l=parseFloat(h(s));s.match(z)&&(l=2*Math.PI*l/360),n+=l}}return n}function f(e,t){if(Math.abs(e.r-t.r)>Math.PI)if(t.rMath.PI;)t.r+=2*Math.PI;else for(;Math.abs(e.r-t.r)>Math.PI;)t.r-=2*Math.PI;return t}function m(e,t,n){var r={};for(var o in e)e.hasOwnProperty(o)&&(r[o]=e[o]+(t[o]-e[o])*n);return r}function d(e,t){t=Math.abs(parseInt(t,10))||0;var n=Math.pow(10,t);return Math.round(e*n)/n}function h(e){return e.match(x)}var p,v,g,x=/([0-9.\-e]+)/g,y=/([a-z]+)\(([^\)]+)\)/g,z=/deg$/,b=e.zoomooz.helpers,w={duration:450,easing:"ease",nativeanimation:!1};jQuery.cssHooks.MsTransform={set:function(e,t){e.style.msTransform=t}},jQuery.cssHooks.MsTransformOrigin={set:function(e,t){e.style.msTransformOrigin=t}},e.fn.animateTransformation=function(r,i,s,l,c){i=jQuery.extend({},w,i),g&&(clearTimeout(g),g=null),i.nativeanimation&&l&&(g=setTimeout(l,i.duration)),this.each(function(){var m=e(this);r||(r=new PureCSSMatrix);var d=u(m,s),h=f(d,o(r));i.nativeanimation?(m.css(t(a(h),i.duration,i.easing)),c&&c()):n(m,d,h,i,l,c)})},e.fn.setTransformation=function(n){this.each(function(){var r=e(this),i=u(r),s=f(i,o(n));r.css(t(a(s)))})}}(jQuery),function(e){"use strict";function t(t,n){var r=jQuery.extend({},n);e.zoomooz.defaultSettings||e.zoomooz.setup();var o,a=e.zoomooz.defaultSettings,i=jQuery.extend({},r);for(o in a)a.hasOwnProperty(o)&&!i[o]&&(i[o]=t.data(o));for(var s=0;v.length>s;s++)o=v[s],i[o]||(i[o]=t.data(o));return jQuery.extend({},a,i)}function n(){var t=document.createElement("style");t.type="text/css";var n="";p.forEachPrefix(function(e){n+=e+"transform-origin: 0 0;"},!0),t.innerHTML="html {height:100%;}.noScroll{overflow:hidden !important;}* {"+n+"}",document.getElementsByTagName("head")[0].appendChild(t),e(document).ready(function(){var n=window.innerWidth-e("body").width();t.innerHTML+="body.noScroll,html.noScroll body{margin-right:"+n+"px;}"})}function r(){var t={targetsize:.9,scalemode:"both",root:e(document.body),debug:!1,animationendcallback:null,closeclick:!1},n=void 0!==window.mozInnerScreenX;return t.scrollresetbeforezoom=n,t}function o(t,n){var r,o=n.scrollresetbeforezoom,u=null;(function(){var e=n.root,s=e.parent();t[0]===e[0]?u=a(e,s):e.data("original-scroll")?o||(u=a(e,s)):(r=!0,u=i(e,s,o))})();var c,f=null;s(n.root);var d=null;if(t[0]!==n.root[0]){var h=m(t,n.root).inverse();o||(d=u),c=l(t,h,d,n),n.animationendcallback&&(f=function(){n.animationendcallback.call(t[0])})}else o&&(c=(new PureCSSMatrix).translate(-u.x,-u.y)),f=function(){var r=e(n.root),a=u.elem;a.removeClass("noScroll"),r.setTransformation(new PureCSSMatrix),r.data("original-scroll",null),e(document).off("touchmove"),o&&(a[0]==document.body||a[0]==window?window.scrollTo(u.x,u.y):(a.scrollLeft(u.x),a.scrollTop(u.y))),n.animationendcallback&&n.animationendcallback.call(t[0])};var p=null;o&&u&&u.animationstartedcallback&&(p=u.animationstartedcallback),r||(d=!1),e(n.root).animateTransformation(c,n,d,f,p)}function a(e,t){var n=e.data("original-scroll");return n||(n={elem:t,x:0,"y:":0}),n}function i(t,n,r){var o=t.scrollTop(),a=t.scrollLeft(),i=t;o||(o=n.scrollTop(),a=n.scrollLeft(),i=n);var s={elem:i,x:a,y:o};t.data("original-scroll",s),e(document).on("touchmove",function(e){e.preventDefault()});var l="translate(-"+a+"px,-"+o+"px)";return p.forEachPrefix(function(e){t.css(e+"transform",l)}),i.addClass("noScroll"),r&&(s.animationstartedcallback=function(){i[0]==document.body||i[0]==document?window.scrollTo(0,0):(i.scrollLeft(0),i.scrollTop(0))}),s}function s(t){var n=e(t).parent(),r=n.width(),o=n.height(),a=r/2,i=o/2,s=d(a)+"px "+d(i)+"px";p.forEachPrefix(function(e){t.css(e+"transform-origin",s)})}function l(t,n,r,o){var a,i=o.targetsize,s=o.scalemode,l=o.root,u=e(l).parent(),c=u.width(),f=u.height(),m=c/t.outerWidth(),d=f/t.outerHeight();if("width"==s)a=i*m;else if("height"==s)a=i*d;else if("both"==s)a=i*Math.min(m,d);else{if("scale"!=s)return console.log("wrong zoommode"),void 0;a=i}var h=(c-t.outerWidth()*a)/2,p=(f-t.outerHeight()*a)/2,v=c/2,g=f/2,x=-parseFloat(l.css("margin-left"))||0,y=-parseFloat(l.css("margin-top"))||0,z=new PureCSSMatrix;r&&(z=z.translate(r.x,r.y));var b=z.translate(x,y).translate(-v,-g).translate(h,p).scale(a,a).multiply(n).translate(v,g);return b}function u(e,t,n){return[e.a*t+e.c*n+e.e,e.b*t+e.d*n+e.f]}function c(e,t){var n=m(e,t.root).elements();f(u(n,0,0)),f(u(n,0,e.outerHeight())),f(u(n,e.outerWidth(),e.outerHeight())),f(u(n,e.outerWidth(),0))}function f(t){var n="width:4px;height:4px;background-color:red;position:absolute;margin-left:-2px;margin-top:-2px;";n+="left:"+t[0]+"px;top:"+t[1]+"px;";var r='
';e("#debug").append(r)}function m(t,n){var r=t[0];if(!r||!r.ownerDocument)return null;var o,a=new PureCSSMatrix;if(r===r.ownerDocument.body){var i=jQuery.offset.bodyOffset(r);return o=new PureCSSMatrix,o=o.translate(i.left,i.top),a=a.multiply(o)}var s;jQuery.offset.initialize?(jQuery.offset.initialize(),s={fixedPosition:jQuery.offset.supportsFixedPosition,doesNotAddBorder:jQuery.offset.doesNotAddBorder,doesAddBorderForTableAndCells:jQuery.support.doesAddBorderForTableAndCells,subtractsBorderForOverflowNotVisible:jQuery.offset.subtractsBorderForOverflowNotVisible}):s=jQuery.support;var l,u,c=r.offsetParent,f=r.ownerDocument,m=f.documentElement,d=f.body,p=n[0],v=f.defaultView;u=v?v.getComputedStyle(r,null):r.currentStyle;var g=r.offsetTop,x=r.offsetLeft,y=h().translate(x,g);for(y=y.multiply(h(r)),a=y.multiply(a);(r=r.parentNode)&&r!==p&&(g=0,x=0,!s.fixedPosition||"fixed"!==u.position);)l=v?v.getComputedStyle(r,null):r.currentStyle,g-=r.scrollTop,x-=r.scrollLeft,r===c&&(g+=r.offsetTop,x+=r.offsetLeft,!s.doesNotAddBorder||s.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(r.nodeName)||(g+=parseFloat(l.borderTopWidth)||0,x+=parseFloat(l.borderLeftWidth)||0),c=r.offsetParent),s.subtractsBorderForOverflowNotVisible&&"visible"!==l.overflow&&(g+=parseFloat(l.borderTopWidth)||0,x+=parseFloat(l.borderLeftWidth)||0),u=l,r.offsetParent==p&&(g-=parseFloat(e(r.offsetParent).css("margin-top"))||0,x-=parseFloat(e(r.offsetParent).css("margin-left"))||0),y=h().translate(x,g),y=y.multiply(h(r)),a=y.multiply(a);g=0,x=0,("relative"===u.position||"static"===u.position)&&(g+=d.offsetTop,x+=d.offsetLeft),s.fixedPosition&&"fixed"===u.position&&(g+=Math.max(m.scrollTop,d.scrollTop),x+=Math.max(m.scrollLeft,d.scrollLeft));var z=(new PureCSSMatrix).translate(x,g);return a=a.multiply(z)}function d(e){return Number(e).toFixed(6)}function h(e){var t=p.getElementTransform(e);return t?new PureCSSMatrix(t):new PureCSSMatrix}var p=e.zoomooz.helpers,v=["duration","easing","nativeanimation"];n(),e.zoomooz||(e.zoomooz={}),e.zoomooz.setup=function(t){e.zoomooz.defaultSettings=jQuery.extend(r(),t)},e.fn.zoomSettings=function(n){var r;return this.each(function(){var o=e(this);r=t(o,n)}),r},e.fn.zoomTo=function(t,n){return this.each(function(){var r=e(this);n||(t=r.zoomSettings(t)),o(r,t),t.debug?(0===e("#debug").length?e(t.root).append('
'):e("#debug").html(""),c(r,t)):0!==e("#debug").length&&e("#debug").html("")}),this}}(jQuery),function(e){"use strict";function t(n,r,o){n.addClass("zoomTarget"),o.animationendcallback||(o.animationendcallback=o.closeclick?function(){e(".selectedZoomTarget").removeClass("selectedZoomTarget zoomNotClickable"),n.addClass("selectedZoomTarget")}:function(){e(".selectedZoomTarget").removeClass("selectedZoomTarget zoomNotClickable"),n.addClass("selectedZoomTarget zoomNotClickable")});var a=r.closest(".zoomContainer");0!==a.length&&(o.root=a);var i=o.root;if(!i.hasClass("zoomTarget")){var s=i.zoomSettings({});s.animationendcallback=function(){var t=e(this);e(".selectedZoomTarget").removeClass("selectedZoomTarget zoomNotClickable"),t.addClass("selectedZoomTarget zoomNotClickable"),t.parent().addClass("selectedZoomTarget zoomNotClickable")},t(i,i,s),t(i.parent(),i,s),i.click()}n.on("click",function(e){o.closeclick&&r.hasClass("selectedZoomTarget")?o.root.click():r.zoomTo(o),e.stopPropagation()})}function n(){function e(e){var t="-webkit-touch-callout: "+(e?"default":"none")+";";return r.forEachPrefix(function(n){t+=n+"user-select:"+(e?"text":"none")+";"},!0),t}var t=document.createElement("style");t.type="text/css",t.innerHTML=".zoomTarget{"+e(!1)+"}"+".zoomTarget:hover{cursor:pointer!important;}"+".zoomNotClickable{"+e(!0)+"}"+".zoomNotClickable:hover{cursor:auto!important;}"+".zoomContainer{position:relative;padding:1px;margin:-1px;}",document.getElementsByTagName("head")[0].appendChild(t)}e.zoomooz||(e.zoomooz={});var r=e.zoomooz.helpers;e.fn.zoomTarget=function(n){this.each(function(){var r=e(this).zoomSettings(n);t(e(this),e(this),r)})},n(),e(document).ready(function(){e(".zoomTarget").zoomTarget()})}(jQuery),function(e){"use strict";e.zoomooz||(e.zoomooz={}),e.fn.zoomContainer=function(){},e(document).ready(function(){e(".zoomContainer").zoomContainer()})}(jQuery),function(e){function t(t,r){var o=n(),a=jQuery.extend({},r);for(var i in o)o.hasOwnProperty(i)&&!a[i]&&(a[i]=o[i]instanceof jQuery?e(t.data(i)):t.data(i));return jQuery.extend({},o,a)}function n(){return{type:"next",root:e(document.body),wrap:"true"}}function r(e,t){e.addClass("zoomButton");var n;n=t.root.hasClass("zoomContainer")?t.root:t.root.find(".zoomContainer");var r=function(){function e(e){return i.indexOf(e)}function t(t){var n=e(t)+1;return i.length>n&&0!==n?i[n]:null}function r(t){var n=e(t)-1;return 0>n?null:i[n]}function o(){return i[0]}function a(){return i[i.length-1]}var i=jQuery.makeArray(n.find(".zoomTarget"));return{next:t,prev:r,last:a,first:o}}();e.on("click",function(e){var o,a=!0,i=n.find(".selectedZoomTarget");0===i.length&&(i=r.first()),0===t.type.indexOf("prev")?(o=r.prev(i[0]),null===o&&(t.wrap?o=r.last():a=!1)):(o=r.next(i[0]),null===o&&(t.wrap?o=r.first():a=!1)),a&&o.click(),e.stopPropagation()})}e.zoomooz||(e.zoomooz={}),e.zoomooz.helpers,e.fn.zoomButton=function(n){this.each(function(){var o=t(e(this),n);r(e(this),o)})},e(document).ready(function(){e(".zoomButton").zoomButton()})}(jQuery); \ No newline at end of file